One Line of mv Kills the 4x Duplicate Run After Recovery: Making launchd Queue Processing Idempotent A developer running an autonomous side business on Claude Code documented how a day-long Codex outage caused 57 queued JSON files to pile up, and when the service recovered, five launchd lanes fired simultaneously and processed the same file four times. The engineer traced the duplicate runs to launchd's lack of mutual exclusion over a shared file queue, noting that a check-then-act lock file is not atomic and that scheduler-plus-shared-directory designs will always collide unless the pickup script implements explicit locking. Six months ago my side business made ¥0 a month. This month it's ¥1.2M, running on an autonomous setup built with Claude Code. And here's the thing about automation: the moment it breaks is exactly when the sloppiness in your design gets exposed. When automation breaks, the reflex is to reach for a procedural fix: "next time I'll do this instead." Check the logs more often. Retry by hand. Space things out a bit more. All of these are bandages meant to shrink the wound the next time the problem recurs. They don't remove the cause, so once the same conditions line up, it will happen again. After six months of running an automated system, one thing I'm certain of: a scheduler combined with a shared directory will always collide unless you explicitly implement mutual exclusion. Not "it might collide if you're unlucky," but "it will collide whenever the conditions for collision line up." This isn't a probability problem; it's a structural one. On September 17, 2026, Codex was down for an entire day with usage limit exceeded . Under ~/.codex/sessions/2026/09/17/ there were 54 sessions piled up, every one of them terminated with a limit error. Throughout that time, three workflows—note-autolike, ai-portraits-fragments, and social-autolike—kept firing jobs, and unprocessed JSON files accumulated in ~/dev/note-autolike/done/ . Measured the next morning at 05:20, the JSON files flagged needs imagegen thumbnail had swelled from 43 to 57 . Fourteen new files had stacked up, all of them left untouched. The instant Codex came back, five launchd lanes fired at once. Each lane's pickup script grabs the JSON files under done/ with ls or a glob and starts processing. With no mutual exclusion, multiple processes look at the same JSON at the same time. The result: the funnel-pm lane processed the same JSON 4 times, one minute apart . As the numbers show—8 of 11 files were hit 2 or more times—this wasn't a freak accident. It was an inevitable consequence of the design. Look at StartCalendarInterval in com.lily.codex-note-funnel.plist and you'll see two entries: 10:40 and 16:40.