gen3ric-labs
← AI Lab Work

Money & property · Sep–Oct 2026 · with Gemini + Claude Delivered A−

Dividend payout calendar sync

A monthly script was supposed to turn dividend payouts into calendar events automatically. It mostly worked, until it quietly didn't.

The problem

I keep a handful of brokerage positions spread across a few accounts, and I wanted calendar events showing roughly what dividend income to expect and when, instead of checking statements by hand. Gemini helped me put together a first version: a Google Sheet listing each holding's payout rate and schedule, and an Apps Script that ran on the 1st of each month and wrote the results to Google Calendar.

It ran. It just wasn't right.

What it produces

Two kinds of events: one on each payout day listing the holdings that pay that day, and a recap on the last day of the month with the total. The numbers, tickers and account labels below are made up.

Div - Total today is $62.50
Payout-day event
• ACME ($0.25/share): $62.50 [Account A]
Total payout for the month: $1184.25
Month-end recap
Calculated actual/estimated total monthly dividend payout

Mock-up of the two event styles with sample data. The real events show my actual holdings and amounts, which stay private.

What was actually broken

Working through it with Claude surfaced a handful of separate bugs stacked on top of each other:

None of these were exotic bugs. Each one looks fine on a spot check and only shows up a month or two later, once the underlying data has moved on.

Fixing it

Claude's fixes, roughly in order:

  1. Added a per-holding override for which months a payout actually lands in, instead of assuming every quarterly payer follows the calendar quarter.
  2. Rewrote the cleanup step to clear every event the script had created that month before regenerating, rather than only checking the current day, so a schedule correction can't leave a stale event behind.
  3. Replaced the silent skip with an explicit list of anything the script couldn't confidently include, surfaced in the monthly recap event, so a new or misconfigured holding is hard to miss.
  4. Tested the sync logic against mocked Sheets and Calendar data in a small Node.js harness before running it live, which caught several of these issues before they reached the real calendar.
  5. Cross-checked a few holdings' historical payout dates against outside data, since a couple of funds don't pay on a fixed day of the month at all. The date drifts by a few days each cycle.
  6. Rebuilt the settings sheet so the list of current holdings (pulled live from the brokerage tabs) and the payout settings for each one are joined by name instead of row position. The original design broke whenever the holdings list re-sorted itself, which a live formula will do on its own. Added a status column that flags, right on the sheet, any holding missing its payout settings.

Verifying this one meant mocking out SpreadsheetApp and CalendarApp in plain Node.js and running the real script logic against fake data. Nothing touched the live calendar until the math checked out offline.

Where it ended up

The monthly sync now runs on its own, produces totals that check out against the real calendar history, and flags anything it's unsure about instead of guessing or quietly dropping it. It's a small tool, but a tool like this is worse than useless if it's quietly wrong. Better for it to say "I don't know" about a holding than to make up a number.

This is entry 23 of AI Lab Work.