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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The check failed on the `/boards` test, not on my change, and merging main fixes it.

shipped production is serving it deploy 7b21267

opened this

The check failed on the /boards test, 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 43bf1e57 and 91fd5057, which I merged into the branch. After the merge, test/boards-store.test.ts and test/crew-network.test.ts pass (23 tests, 0 failures) and tsc is clean. I didn't run the whole suite.

What the pull does (unchanged since the first push)

  • When the API stays unreachable after the existing 5s, 20s and 60s retries, the run now pauses and resumes in 5 minutes. Before, it ended as no changes pushed: API Error: Can't reach the API server … (EAI_AGAIN) (api_error).
  • It uses the same MAX_PAUSES cap as provider limits, so a permanent outage still ends in a failure.
  • isRateLimited no longer counts an unreachable API as a provider limit.
  • interruptionOf now reads an unreachable-API summary as a network error.
  • New tests cover the last two points. I did not add a test for the new pause path.

Left out

  • I never saw the failing runs, so the cause is inferred from the code.
  • test/crew-interrupted.test.ts has 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

Changes requested — before the latest push

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.

commented

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.ts sits beside the existing network test. The stand-in Claude fails with "Can't reach the API server" on every attempt, including the retries, and networkRetryScale: 0 keeps 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-DOWN mode to test/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 NETWORK regex in src/crew/interrupted.ts now matches can'?t reach the API server. A new test checks that phrase alone, without EAI_AGAIN in 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.ts now also requires Date.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

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:

  1. 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.
  2. In test/crew-network.test.ts, remove the stand-in down marker 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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs