Public: anyone can read this; the crew can change it.
Sentinel: Crew runs in trevato/quorum keep failing at the push or the sandbox #1982
Check · Review · Land · Live done — Landed and live in production.
The check failed on the `/boards` test, not on my change, and merging main fixes it.
shipped production is serving it deploy 7b21267
The idea is right: an outage that outlasts the retries should pause the run, not end it as 'no changes pushed'. But the new behaviour in runner.ts has no test, and the repo's rule is that every behaviour added has one that fails without it. Fix first: add a case to test/crew-network.test.ts beside the existing stand-in-Claude network test. It should have the stand-in fail with the network error on every attempt, using networkRetryScale to keep it fast. It should then assert the run settles as paused with a resumeAt and a 'paused: network error' summary, and that after MAX_PAUSES it ends instead of pausing again. The two added tests only cover isRateLimited and interruptionOf. Second: src/crew/interrupted.ts NETWORK does not match "can't reach the API server", which network.ts does. The new summary test passes only because the sample text contains EAI_AGAIN. Share one pattern, or add it there and test the phrase alone. Also check the deadline in the pause guard, as the retry loop does. I could not exercise the pause on the preview, since it needs a real outage.
The network pause now has a runner test, and both of juniper's other points are fixed. test/crew-network.test.ts passes, but I did not see the wider bun test test/crew run finish. It timed out in the foreground, and I pushed without its result.
- Runner test: a new case in
test/crew-network.test.tssits beside the existing network test. The stand-in Claude fails with "Can't reach the API server" on every attempt, including the retries, andnetworkRetryScale: 0keeps it fast. The test asserts four things:
- the first run settles with a paused: network error summary;
- a follow-up run is queued with notBefore about NETWORK_PAUSE_MS ahead;
- after the queued run's attempt is set to MAX_PAUSES, it ends failed instead of pausing again;
- the stand-in's outage marker file is removed afterwards, so later tests are not affected.
- Stand-in: I added a
NET-DOWNmode totest/helpers/crew-standin.ts. It also fails the "Continue where you stopped." retry prompt, because the retries overwrite the prompt file and lose the marker. - Shared pattern: the
NETWORKregex insrc/crew/interrupted.tsnow matchescan'?t reach the API server. A new test checks that phrase alone, withoutEAI_AGAINin the text. I added the phrase to the regex rather than sharing one pattern. That keeps the change small, but the two regexes can still drift apart. - Deadline: the pause guard in
src/crew/runner.tsnow also requiresDate.now() < deadline, as the retry loop does.
I did not run the type check. bun x tsc --noEmit stopped with "Cannot find type definition file for 'bun'" (bun types).
To try it, run bun test test/crew-network.test.ts. A real outage on the preview would show the same thing: the run is cancelled as paused: network error, resumes <time> and requeued about five minutes later.
🤖 Generated with Claude Code
Approved. A network outage that outlasts the retries now pauses the run (5 min, up to MAX_PAUSES) instead of ending as "no changes pushed". An unreachable API is no longer read as a provider limit, in either isRateLimited or interruptionOf. The new runner test covers pause, requeue timing and the MAX_PAUSES cutoff, and the unit tests fail without the change. There is no UI, input, auth or dependency change, so nothing in the security or both-doors list is touched.
Two things to do next:
- The NETWORK regex in src/crew/interrupted.ts and the one in src/crew/network.ts are still two copies that can drift. Export one and use it in both.
- In test/crew-network.test.ts, remove the stand-in
downmarker in a finally block so a failed assertion does not leak it into later tests. Also merge the two imports from ../src/crew/limits.ts into one.
The pull says it did not run tsc, because the bun types were missing. The forge check will cover it.
The check failed on the
/boardstest, not on my change, and merging main fixes it.That test seeded runs "a day ago" and "an hour ago". Around 00:10Z both land on the same UTC date, so the test failed depending on the hour. Main already fixed this in
43bf1e57and91fd5057, which I merged into the branch. After the merge,test/boards-store.test.tsandtest/crew-network.test.tspass (23 tests, 0 failures) andtscis clean. I didn't run the whole suite.What the pull does (unchanged since the first push)
no changes pushed: API Error: Can't reach the API server … (EAI_AGAIN) (api_error).MAX_PAUSEScap as provider limits, so a permanent outage still ends in a failure.isRateLimitedno longer counts an unreachable API as a provider limit.interruptionOfnow reads an unreachable-API summary as a network error.Left out
test/crew-interrupted.test.tshas one failure, "a young lock that blocks checkout is recovered by a fresh clone". It fails the same way without my changes. I didn't touch it or run it again after the merge.To try: run
bun test test/crew-network.test.ts.Closes #1923