Yesterday morning at 9:05 AM I started receiving some odd emails. Calendar invites were being sent from my personal Gmail account to my work email for meetings from months ago. Weird. At 9:07 AM the Delivery Status Notification failures started to arrive from email addresses that no longer existed. Also weird. At that point the alarm bells started going off in my head, so I Slacked a friend to ask if she had received one of the emails from me. She had not1.

I figured maybe I had absent-mindedly dragged something around in Google Calendar and re-sent a few old invites. Annoying, but small-impact. No biggie for a Friday morning. Then I kept getting another ten or so failures every few minutes. At 9:32 I jumped onto a weekly video call, apologising for being late because "something weird is going on with my email". One of the recipients on the call told me he had already received dozens of emails from me that morning, and more were still arriving every few minutes.

Shit.

Where's the stopcock?

My immediate thought was simple: how do I make it stop?

I Googled it. I ChatGPTed it. Both gave me AI overviews. Both pointed me at settings that did not exist.

One of the actually useful suggestions from ChatGPT was to go to my Google account and revoke third-party apps and services with access to it2. I started disconnecting the things that looked most suspicious: a few old services I hadn't used in a while, cal.com, Zoom, and so on. I left YouTube, my Mac and iOS connections, and a desktop OAuth app I'd created to authenticate Google for an OpenClaw integration.

The emails kept coming.

People started Slacking to ask whether I knew I was sending them a lot of meeting invites. I apologised back that yes, I did know, but unfortunately I didn't know why. When I started browsing the messages in my inbox, it got worse. In late 2025 I had been out fundraising, so I was now seeing failed deliveries and meeting acceptances from the great and the good of deep-tech seed investors in the UK and Europe.

Shit. Shit.

At that point I deleted the remaining third-party connections too: Mac, iOS, OpenClaw, the lot. I deleted some local configuration files related to calendar sync for good measure. If that didn't work, I was genuinely starting to contemplate deleting my personal Gmail account. Gmail launched on 1 April 2004. My account is from 10 September that same year. I've never deleted any of those emails. Twenty-one and a half years of personal email was, in my mind, about to get thrown into /dev/null just to make this stop. I had to shut it off before I alienated every single person I'd ever been in a meeting with3.

Ten minutes went by. No further failures arrived.

Hope.

I WhatsApped the main guy who had been getting hammered. His inbox had gone quiet. I Slacked the concerned people back. Their inboxes had gone quiet too. My heart rate started to come down. One friend made a joke about being too busy to reply because of the avalanche of emails I was sending him. I replied "Too soon" and went out for a run.

At this point you think it was OpenClaw

Let's be honest. By now you've probably decided this was OpenClaw doing something chaotic and agent-y.

It wasn't caused by OpenClaw. But it was definitely because of OpenClaw.

When I set it up a couple of months ago, I was paranoid about two things. First, that I was going to burn through my Codex tokens too quickly4. Second, that I was going to mess up my email or calendar in some exciting new way. My main use case was as a daily personal assistant, which meant it really did need access to those things.

I'm a big believer that this current wave of agentic productivity has been unlocked by giving agents command-line tools and letting them figure out how to stitch them together. Before Google launched their own semi-official CLI, I wanted a way to interact with my email and calendars from the terminal, build a daily local snapshot, and then have OpenClaw read those text files instead of wasting tokens figuring out API calls to Google itself. I also didn't want to hand those API tokens directly to OpenClaw. I'd much rather encapsulate account access inside a local tool and let a cron job call that. I have multiple Gmail and iCloud accounts too, so doing this through one local interface was attractive.

To cut a long story short, I ended up using some properly old-school tooling. vdirsyncer mirrored local versions of my calendars to the Mac, where I could inspect them with khal. Email was similarly local-first, with notmuch as the interface. It was fiddly to set up, but once it worked I was pretty happy with it. It felt low risk. OpenClaw wasn't YOLO-writing to my Google account. It was reading a local mirror that I controlled.

Which, in hindsight, is exactly the sort of sentence you say shortly before a local mirror of a remote system punches you squarely in the face.

The smoking gun

Here's the unsatisfying part: I don't know for certain what went wrong.

Part of my panic response was to nuke the auth access, the config, and the working directories for the calendar sync. Great for containment. Less great for forensics. So I can't prove this. But I do have a theory that fits the symptoms.

The night before, I had been coding late and pulled the monitor plug from my laptop. I normally reconnect a power-only USB cable before bed so OpenClaw can still run overnight cron jobs. That night I forgot. My guess is that one of those overnight calendar syncs was interrupted as the Mac went back to sleep, which corrupted the local sync state for vdirsyncer.

I'd seen that sort of corruption before, but historically it had failed in much more obvious ways and forced me to re-auth or manually clean the cache. Since I moved to a longer-lived auth setup and got into the habit of leaving the laptop on power overnight, I hadn't had the problem for a while. So when the machine woke back up in the morning, I suspect the next sync tried to "recover" from the broken state and instead treated a huge chunk of the local calendar as newly created events with fresh IDs. Then, at 9:05 AM, it started writing those "new" events back to Google Calendar.

That would explain the emails.

It would also explain the scope. The earliest failed invite I saw was for an event exactly one year earlier. I can't prove the sync only had roughly a year of history locally, but that detail made me much more confident this was my local calendar mirror going haywire rather than some random third-party SaaS deciding to ruin my Friday in exactly the same shape.

Also, let's be honest: this is exactly the kind of catastrophic edge case you get when you maintain local sync state for a remote system, and most people are not stupid enough to do that... twice5.

The software I should have written first

So what did I spend the afternoon doing?

I vibe coded a local app called calico that read-only fetches calendar data directly from the Mac's own calendar database. To be fair, I had thought about doing this the first time around. I even hacked something together with AppleScript. It was slow and flaky, so I abandoned it. With current Codex, though, it took no time at all to put together a proper little app that reads via EventKit and formats the output in a way an agent can consume.

To my mind, this is the right solution. It's completely read-only. Authentication is local and implicit. OpenClaw knows nothing about my Google credentials. There is no sync state to corrupt, no remote write path, and therefore no possible way for a background job to start enthusiastically re-inviting half my address book to meetings from last year.

There is a lot of chatter at the moment about the end of software and how everything is going to be generated on demand by agents. Maybe. Who knows. All I know is that this incident made the requirement brutally clear.

I do not need a universal calendar integration layer.

I need a tiny piece of software that safely tells my agent what is on my calendar over the next few days.

Embarrassment, it turns out, is a pretty good product manager. When the failure mode is social rather than purely technical, boring architecture starts to look very attractive. Read-only before read-write. Local before synced. Smaller blast radius before more capability.

To everyone who got an invite from me yesterday morning: I'm sorry. I wrote the boring fix. It won't happen again.6


  1. I Slacked her back "Phew!". It was premature.
  2. It's here if you ever need it: https://myaccount.google.com/
  3. I can absolutely see why people fall for social engineering once panic sets in.
  4. I wrote a local router that tries to train a contextual bandit to auto-route cheaper models for certain types of queries. Turns out I mostly use it as a fallback when I hit my Codex weekly limit. But that's a story for another day.
  5. Yes, this ain't my first rodeo. One of these days I'll tell the story about how I deleted all the contacts from my next-door neighbour's Palm Pilot while helping him fix a sync issue. He was in his sixties and had his whole life on there. It was awkward.
  6. Probably.