Timers 1.5.1: a failed capture-tool build must not park the listener forever #30

Merged
michael merged 1 commits from claude/timers-build-retry into main 2026-09-27 10:59:21 -04:00
Owner

Found live on AB this morning: the capture-tool build failed (AB's broken CLT), the compiled binary was then scp'd in — and the listener never noticed. It had observed "build in flight", skipped scheduling its retry, and waited for ensureCaptureBinary's onReady… which only fires on build success. The tile said "Capture tool building…" indefinitely with a working binary sitting on disk; a module remount was needed to recover.

onReady stays as the fast path (successful build → immediate start). The 30-second retry now stays armed in every not-ready state, so a failed build keeps re-checking, and a binary that arrives from outside — the shipped-binary path for machines that can't compile — is picked up within half a minute, no remount.

Reproduced the exact production shape in a swiftc-less environment: build fails at 0s, binary copied in at 3s, retry at 30s spawns it (the capture's own "no input device matches" answer proves the real binary ran). Before the fix: permanent deadlock. Both selftests pass; module 1.5.0 → 1.5.1, no shell changes.

Note: spl-listener.js has the same latent pattern (missing !== BUILDING skip + success-only restart) — flagged separately for the SPL lane rather than touched here.

🤖 Generated with Claude Code

Found live on AB this morning: the capture-tool build failed (AB's broken CLT), the compiled binary was then scp'd in — and the listener never noticed. It had observed "build in flight", skipped scheduling its retry, and waited for `ensureCaptureBinary`'s `onReady`… which only fires on build **success**. The tile said "Capture tool building…" indefinitely with a working binary sitting on disk; a module remount was needed to recover. `onReady` stays as the fast path (successful build → immediate start). The 30-second retry now stays armed in **every** not-ready state, so a failed build keeps re-checking, and a binary that arrives from outside — the shipped-binary path for machines that can't compile — is picked up within half a minute, no remount. Reproduced the exact production shape in a swiftc-less environment: build fails at 0s, binary copied in at 3s, retry at 30s spawns it (the capture's own "no input device matches" answer proves the real binary ran). Before the fix: permanent deadlock. Both selftests pass; module 1.5.0 → 1.5.1, no shell changes. Note: `spl-listener.js` has the same latent pattern (`missing !== BUILDING` skip + success-only restart) — flagged separately for the SPL lane rather than touched here. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
michael added 1 commit 2026-09-27 10:56:09 -04:00
Found live on AB: the build failed (its CLT is broken), the compiled
binary was then copied in by hand — and the listener never noticed. It
had seen 'build in flight' and stopped scheduling retries, waiting for
ensureCaptureBinary's onReady, which only fires on SUCCESS. The tile said
'Capture tool building…' indefinitely with a working binary on disk; only
a module remount recovered it.

onReady stays as the fast path; the 30 s retry now stays armed in every
not-ready state, so a failed build keeps re-checking and a binary that
arrives from outside (scp'd to a machine that can't compile) is picked up
within half a minute.

Reproduced the exact shape in a swiftc-less environment: build fails,
binary copied in at 3 s, retry at 30 s spawns it (the capture's own
unknown-device answer proves the real binary ran) — previously a
permanent deadlock.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
michael merged commit b3b7b29007 into main 2026-09-27 10:59:21 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: michael/ProdDash#30