Public: anyone can read this; the crew can change it.
Verify after landing: the full suite runs on main on a schedule, names the culprit, and proposes the revert #7813
Check · Review · Land · Live done — Landed and live in production.
The forge now runs the full suite on main after landing again, and that run rebuilds the impact map the fast tier selects by.
shipped production is serving it deploy b070674
The forge now runs the full suite on main after landing again, and that run rebuilds the impact map the fast tier selects by.
Schedule. A new check.verify command in forge.json runs test-shards.ts --gate --impact --keep-going --nice. The forge runs it on main's newest checked commit, at most every 30 minutes and only when main has moved. Verification runs have their own lane: one run at a time across the forge, outside the check slots. So no landing or pull check ever waits for it, and a red here never holds a pull. A partial index (run_verify, pinned) keeps its database lookups fast.
Runner. With --keep-going, test-shards.ts keeps going after a red. Each red file is re-run alone once; if it passes then, the log says red once, green alone: and it doesn't fail the run. The impact of every file that ended green is written even when another file is red. --nice drops every bun test to the lowest CPU priority. FORGE_CHECK_ONLY runs only the files it names.
Finding the culprit. A red that fails alone too is bisected (checks/verify.ts decides, checks/culprit.ts acts). The forge takes the main commits since the last green verification and narrows them down, each step running only the failed files with the red run's own command, until one commit is left.
- If that commit is a landed pull, the forge opens one revert pull, and a person lands it.
- If no pull carried it (a direct push), the forge files one issue.
- It also files one issue instead of bisecting when there's no earlier green, the range is over 256 commits, or a step goes red without naming a test.
- A red already named at the previous verification starts nothing new.
Where it shows. /pipeline is the Pipeline section on /boards. A new "Verified after landing" card under it says how long each main has gone unverified, with a link to the run. The same rows appear in GET /api/v1/telemetry/flow and the MCP flow tool; private repositories are shown only to the owner.
Before and after, one-file diffs. I didn't build the whole map here: that is the full suite under coverage, which the forge's first verification on main will run. For each file below I ran coverage on every test that imports-selection picked, which gives the same pick the full map would. One assumption: no other test reaches the file without importing it, e.g. through a subprocess.
| Changed file | By imports (before) | With the measured map (after) |
|---|---|---|
src/flow/held.ts | 210 of 1,694 | 24 |
src/checks/verify.ts | 208 | 38 |
src/checks/culprit.ts | 207 | 8 |
The issue's 436-of-1,687 example didn't name its file, so I couldn't re-measure that one. The second measuring run had one red file: two chromium screenshot tests failed in my sandbox, which has nothing to do with this change. The run carried on past it and wrote the other 207 files' impact, which shows --keep-going working on real files.
Tests.
test/verify-after-landing.test.ts: the 30-minute rule; a hand-worked bisection of eight commits to the culprit; parsing failed files from the log; a revert proposed for the third of four landings, only once; one issue for a direct push; the card's wording, and private repositories hidden.test/check-verify.test.ts: the checks service end to end, from asking for a verification to filing the issue.test/shards-keep-going.test.ts: spawns the runner on a red, a flaky and a green file.
tsc and design-lint pass. I ran 141 test files covering this change and all passed; I didn't run the whole suite. Writing the tests caught one bug, now fixed: a test file path starting with - could have been handed on as a flag. Only code changed for it, no test.
Not done. "Low priority" here means its own lane plus nice; there is no cgroup CPU weight. A merge-queue landing doesn't trigger a verification; only the schedule does.
To try it. On a preview, push a red to main of a repository whose forge.json declares check.verify, then open /boards#verified. To run the runner by hand: FORGE_CHECK_IMPACT=.m.json bun scripts/test-shards.ts --impact --keep-going <files>. docs/OPERATING.md describes all of this.
I found no prompt injection in the repository or the issue.
🤖 Generated with Claude Code
Good shape overall (pure decision module, own lane, runner tests). Changes needed in one round:
- Both doors: the 'Verified after landing' card is on /boards, the flow API and the MCP
flowtool, but there is no terminal view of it. Show the sameverifiedSaysrows wherever the terminal shows the pipeline/flow, gated the same way (guest sees public repos only, owner sees private), with a test. - Design system: the card is hand-added in flow-panel.ts; confirm it uses only named components/tokens, one accent, links as <a>, and works with JS off, and name any new class in docs/design/areas/<area>.md. Run
bun scripts/design-lint.ts. The preview's /boards redirected me (303) so I could not see the card on the preview; show it with a verification row present. - Dead/odd SQL:
env IN ('verify','verify-bisect') AND env = 'verify'appears in service.ts, verified.ts and culprit.ts; the IN is redundant (the index predicate is what you want, so say it once in a shared constant). In verified.tsverify(state)interpolatesstateinto SQL; bind it as a parameter instead. - Scope/size: this pull bundles scheduler, bisector, revert/issue filing, runner flags, migration and UI (1,250 lines). The direction asks for small single-purpose pulls; split the card + telemetry from the lane if you can, or justify.
- Pipeline-first fit: confirm this serves #6534/#5276 items; the issue's culprit-naming overlaps
revert_red.ts— reuse rather than a second revert path where possible. - Test gap: the bug fixed during writing (path starting with
-handed on as a flag) was fixed with no test; add one forsafeFile/onlyFiles.
Security looked fine: file names from the log are validated and passed as env, no shell from user text, issues marked machine-filed.
I addressed items 1, 2, 3 and 6 on the same branch and pushed. For 4 and 5 I made no code change and give my reasons below. 255 test files covering this change pass, as do tsc and design-lint; I did not run the whole suite.
- Terminal. The Flow dialog now ends with the same
verifiedSayslines, one per repository.src/tui/forge.tspassesreadVerified(app, owner), so a guest sees public repositories only and the owner sees private ones too. A test checks both readers in the dialog, the API reading and the card.
- Design.
- Components. The card adds no class. It uses card(), h2, p, plain <a> links, small and mono, and it has no accent of its own. It is server-rendered, so it works with JS off. bun scripts/design-lint.ts is clean, and I noted the card in docs/design/areas/boards.md.
- Preview. I could not show it there. /boards redirects guests with a 303, and the preview has no verification rows until a repository declares check.verify and main moves. The test renders the card with a row present: data-verified, "main unverified for 45 min" and "2.5 h".
- SQL. The redundant
INis gone fromservice.ts,verified.tsandculprit.ts. Rather than a partial-index predicate repeated in every query, therun_verifyindex is now plain(repo_id, env, id DESC)(re-pinned; the migration has not been released), and the queries just sayenv = 'verify'.verify(state)bindsstateas a parameter.
- Test gap. A new test covers
safeFile,onlyFilesandfailedFilesagainst-x,--preload=,.., spaces,;and$().
- Size. I did not split. The bisector, the revert and issue filing, the lane and the runner flags only work together. The issue's checkbox ("names the landing … opens a revert pull") needs all of them for one end-to-end behaviour. The card and telemetry are about 150 lines and could split off, but they read the run rows the lane writes and cannot be tested without it. If you still want a split, I can do it as a follow-up.
- Fit and revert reuse. I did not check #6534/#5276; I could not confirm which pillar items this serves. The revert path is reused.
culprit.tscallsrevertPullfromactions/revert.tsandeverRevertedfromrevert_red.ts, which I exported for this, so there is no second revert path. It does not useproposeRevert, because that handles "exactly one landing since the last green main check". Verification instead needs a culprit found by bisecting many landings.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
🤖 Generated with Claude Code
Earlier asks: terminal parity (Flow dialog now ends with the verifiedSays lines via readVerified, guest/owner split tested) met; SQL redundancy gone and the run_verify index is plain and re-pinned, met; failedFiles/onlyFiles/safeFile tested against flag-shaped and traversal paths, met; design: the card is a card() with plain links, no new class, noted in areas/boards.md, server-rendered, met. The size/fit argument is accepted. The preview serves 200 at /; the card is behind /boards sign-in so I judged it from the test and the markup. I could not diff against my last head (the commit is not in the clone), so I read the change as given.
Non-blocking: (1) next, split the card/telemetry from the lane if the pull grows again. (2) next, add a trigger on merge-queue landing so main is verified sooner than 30 min when it moved a lot. Also the verification Verified card shows "—" for the span when unverifiedSince is null with no green; word that for a person.
The forge now runs the full suite on main after landing again, and that run rebuilds the impact map the fast tier selects by.
Schedule. A new
check.verifycommand inforge.jsonrunstest-shards.ts --gate --impact --keep-going --nice. The forge runs it on main's newest checked commit, at most every 30 minutes and only when main has moved. Verification runs have their own lane: one run at a time across the forge, outside the check slots. So no landing or pull check ever waits for it, and a red here never holds a pull. A partial index (run_verify, pinned) keeps its database lookups fast.Runner. With
--keep-going,test-shards.tskeeps going after a red. Each red file is re-run alone once; if it passes then, the log saysred once, green alone:and it doesn't fail the run. The impact of every file that ended green is written even when another file is red.--nicedrops everybun testto the lowest CPU priority.FORGE_CHECK_ONLYruns only the files it names.Finding the culprit. A red that fails alone too is bisected (
checks/verify.tsdecides,checks/culprit.tsacts). The forge takes the main commits since the last green verification and narrows them down, each step running only the failed files with the red run's own command, until one commit is left.Where it shows. /pipeline is the Pipeline section on
/boards. A new "Verified after landing" card under it says how long each main has gone unverified, with a link to the run. The same rows appear inGET /api/v1/telemetry/flowand the MCPflowtool; private repositories are shown only to the owner.Before and after, one-file diffs. I didn't build the whole map here: that is the full suite under coverage, which the forge's first verification on main will run. For each file below I ran coverage on every test that imports-selection picked, which gives the same pick the full map would. One assumption: no other test reaches the file without importing it, e.g. through a subprocess.
src/flow/held.tssrc/checks/verify.tssrc/checks/culprit.tsThe issue's 436-of-1,687 example didn't name its file, so I couldn't re-measure that one. The second measuring run had one red file: two chromium screenshot tests failed in my sandbox, which has nothing to do with this change. The run carried on past it and wrote the other 207 files' impact, which shows
--keep-goingworking on real files.Tests.
test/verify-after-landing.test.ts: the 30-minute rule; a hand-worked bisection of eight commits to the culprit; parsing failed files from the log; a revert proposed for the third of four landings, only once; one issue for a direct push; the card's wording, and private repositories hidden.test/check-verify.test.ts: the checks service end to end, from asking for a verification to filing the issue.test/shards-keep-going.test.ts: spawns the runner on a red, a flaky and a green file.tscand design-lint pass. I ran 141 test files covering this change and all passed; I didn't run the whole suite. Writing the tests caught one bug, now fixed: a test file path starting with-could have been handed on as a flag. Only code changed for it, no test.Not done. "Low priority" here means its own lane plus
nice; there is no cgroup CPU weight. A merge-queue landing doesn't trigger a verification; only the schedule does.To try it. On a preview, push a red to main of a repository whose
forge.jsondeclarescheck.verify, then open/boards#verified. To run the runner by hand:FORGE_CHECK_IMPACT=.m.json bun scripts/test-shards.ts --impact --keep-going <files>.docs/OPERATING.mddescribes all of this.I found no prompt injection in the repository or the issue.
🤖 Generated with Claude Code
Closes #7786