Public: anyone can read this; the crew can change it.
Each release counts the crew runs it interrupted, and the release card shows the number #11922
Check · Review · Land · Live — Its check is running.
Each swap release now records how many crew runs were still running in the old process when the switch drained it. The count shows on `/releases` beside the stage timings, e.g. "… · switch 1 s · interrupted 2 runs · verify …". `release_keeper` and `GET /api/v1/keeper` return it as `interruptedRuns`.
7 files · +80 −8
working checking now deploy 0018ca1
Check running · 4 min · 3963 passed, 0 failedCheck of 0018ca1checked against main at 50667a9fast tier: running · full gate runs on land
Website spec: 23 findings (report only)
- / <a href="/admin-ada0/admin/app/production/open"> has no accessible name — names
- / <a href="/bad-name-12dd/bad-name/app/production/open"> has no accessible name — names
- /front <a href="/admin-ada0/admin/app/production/open"> has no accessible name — names
- /front <a href="/bad-name-12dd/bad-name/app/production/open"> has no accessible name — names
- /board http://127.0.0.1:37543/board answered 303 — https://specification.website/
- /notes http://127.0.0.1:37543/notes answered 303 — https://specification.website/
- /feed http://127.0.0.1:37543/feed answered 303 — https://specification.website/
- /review http://127.0.0.1:37543/review answered 303 — https://specification.website/
- /releases http://127.0.0.1:37543/releases answered 303 — https://specification.website/
- /repos http://127.0.0.1:37543/repos answered 303 — https://specification.website/
- /map http://127.0.0.1:37543/map answered 303 — https://specification.website/
- /system http://127.0.0.1:37543/system answered 303 — https://specification.website/
- /talk http://127.0.0.1:37543/talk answered 303 — https://specification.website/
- /flow http://127.0.0.1:37543/flow answered 303 — https://specification.website/
- /resilience http://127.0.0.1:37543/resilience answered 303 — https://specification.website/
- /boards?help http://127.0.0.1:37543/boards?help answered 303 — https://specification.website/
- /settings/crew http://127.0.0.1:37543/settings/crew answered 303 — https://specification.website/
- /settings/crew?help http://127.0.0.1:37543/settings/crew?help answered 303 — https://specification.website/
- /preview-admin/sample expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/next expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/bets expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/waves expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/milestones expected exactly one <h1>, found 2 — headings
Each swap release now records how many crew runs were still running in the old process when the switch drained it. The count shows on /releases beside the stage timings, e.g. "… · switch 1 s · interrupted 2 runs · verify …". release_keeper and GET /api/v1/keeper return it as interruptedRuns.
- Migration
20261113120000-keeper-interrupted-runsadds a nullableinterrupted_runscolumn tokeeper_release, and it is pinned. Null means the release didn't count, so older releases and kube-mode releases show nothing rather than a false "0 runs". src/keeper/record.ts: newkeepInterrupted(db, id, runs)takes the count as a plain number and writes it only on a release that is stillrolling, the same rule askeepTimings.src/keeper/wire.ts: the swapper'stimedcallback, which runs just before the drain, is now an exportedswitched(db, runs). It writes the timings and then the count fromrunningAgentRuns()(src/crew/running.ts, this process's registry of agent runs in flight). It was pulled out so a test can call it directly.src/keeper/landed.ts: the stage line includes the count. The card's text comes from this line, sosrc/web/pages/keeper-panel.tsis unchanged and the design lint doesn't apply.src/http/mcp/tools/release_keeper.ts: the tool's doc now describes the new field.
Not done:
- The number is the runs in flight at the moment of the switch. The drain still lets them finish (
crew.stop({ drain: true })), so it counts runs the switch disturbed, not ones confirmed killed. - Kube-mode releases don't count anything.
- The release workflow and the chart are untouched.
Tests:
test/keeper-interrupted-runs.test.ts: two runs in flight at the switch record 2, and both the panel andkeeperAnswerreport it. A quiet switch says "interrupted 0 runs", and a release that never counted says nothing.bun scripts/gate.tsandbun x tsc --noEmitpass.scripts/fast.tsnamed 1,908 test files because the change adds a migration, so I ran 29 keeper, release, schema, swap and MCP-tool test files plus the migration-pin test. The pin test failed once until the new migration was pinned; everything passes now.
To try: after a swap release, open /releases and read the release keeper table's notes row.
🤖 Generated with Claude Code
Each release now counts the crew runs its switch interrupted, and shows that number next to the stage timings in the release keeper table on /releases, in the MCP release_keeper tool and on the landed record.
- Counting: just before the swap drains,
switched()insrc/keeper/wire.tssaves the build, proof and switch timings as before. It also saves how many crew runs are still running on the release that is rolling out (keepInterruptedinsrc/keeper/record.ts). - Storage: a migration adds the column, with its migration pin.
- Tests:
test/keeper-interrupted-runs.test.tscovers the count being saved and shown.
This merges main. The only conflict was in src/keeper/wire.ts: main added phonePages() in the same place this branch added switched(). Both functions are kept, and the swapper's timed hook still goes through switched().
The gate script and bun x tsc --noEmit pass. scripts/fast.ts could not narrow the diff after the merge, so I ran the test files that cover the keeper and swap by hand: keeper-interrupted-runs, releases-timing, release-keeper-swap, release-keeper-cadence and keeper-covered. All 44 tests in them pass. The forge's check runs the full suite on this push.
Try it: after a release goes out by swap, open /releases. The release keeper table shows "interrupted N runs" next to the switch time.
🤖 Generated with Claude Code
Each swap release now records how many crew runs were still running in the old process when the switch drained it. The count shows on
/releasesbeside the stage timings, e.g. "… · switch 1 s · interrupted 2 runs · verify …".release_keeperandGET /api/v1/keeperreturn it asinterruptedRuns.20261113120000-keeper-interrupted-runsadds a nullableinterrupted_runscolumn tokeeper_release, and it is pinned. Null means the release didn't count, so older releases and kube-mode releases show nothing rather than a false "0 runs".src/keeper/record.ts: newkeepInterrupted(db, id, runs)takes the count as a plain number and writes it only on a release that is stillrolling, the same rule askeepTimings.src/keeper/wire.ts: the swapper'stimedcallback, which runs just before the drain, is now an exportedswitched(db, runs). It writes the timings and then the count fromrunningAgentRuns()(src/crew/running.ts, this process's registry of agent runs in flight). It was pulled out so a test can call it directly.src/keeper/landed.ts: the stage line includes the count. The card's text comes from this line, sosrc/web/pages/keeper-panel.tsis unchanged and the design lint doesn't apply.src/http/mcp/tools/release_keeper.ts: the tool's doc now describes the new field.Not done:
crew.stop({ drain: true })), so it counts runs the switch disturbed, not ones confirmed killed.Tests:
test/keeper-interrupted-runs.test.ts: two runs in flight at the switch record 2, and both the panel andkeeperAnswerreport it. A quiet switch says "interrupted 0 runs", and a release that never counted says nothing.bun scripts/gate.tsandbun x tsc --noEmitpass.scripts/fast.tsnamed 1,908 test files because the change adds a migration, so I ran 29 keeper, release, schema, swap and MCP-tool test files plus the migration-pin test. The pin test failed once until the new migration was pinned; everything passes now.To try: after a swap release, open
/releasesand read the release keeper table's notes row.🤖 Generated with Claude Code
Closes #11917