31 runs were queued on igneum-build-1's one runner at 13:15 UK on 7 October 2026 and nothing had concluded since 13:03Z, so no lane could read a conclusion.
- ci.yml: a `changes` job (ubuntu-latest) classifies the push with tools/ci/docs-only-check.sh (docs/, site/, *.md only = code=false; a new branch, a pull request, a force push or an API error = code=true); pow and sims need it and run only on code=true. The site job is unchanged on ubuntu-latest for every push. The classifier's self-test is in the gate.
- provision.sh and runner/register.sh: `--host <ip>` registers another box, forwarding BOX_HOSTNAME, RUNNER_NAME, RUNNER_LABELS, RUNNER_CPUS and RUNNER_JOBS (plain words only); RUNNER_CPUS writes AllowedCPUs into the service drop-in beside Nice=10, so igneum-build-2's runner is bounded like a suite (32 cores). The pool label is igneum-build-1 (both boxes carry it); ci-red marks the box with the record file and the poster, the default labels carry it, and igneum-build-1 got it through the runners API today.
- ci-red.yml runs on the ci-red label, so the red line always lands where the poster reads it.
- CLAUDE.md: the rule reads "read the conclusion when it lands, own a red before the next push"; pushes are never held.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GitHub runs a workflow_run workflow from the default branch only, so a feature branch no longer waits for a merge of master before its reds are posted. record() reads the FAILED run from RED_WATCH_* (id, attempt, workflow, branch, sha, event, url, actor, title, author: the workflow_run payload) and asks the jobs API for that run, not the watcher's own; the inline GITHUB_* shape stays for a branch with the old `red` job (one line per run id either way). The inline job leaves ci.yml. Self-test covers the workflow_run shape and the full line.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The red job's condition drops the master/release-* clause; record() keeps GITHUB_ACTOR and the head commit's author name (RED_WATCH_AUTHOR from the workflow) and formatLine prints "pushed by <actor> (commit by <author>)" before the failed job and step. The self-test covers a feature-branch run and the author in the line. Same updates channel, same box file, same one-line-per-run idempotence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The class (7 October 2026, 11:26 to 12:47 UK): three fork-gate summaries on ca3-v4-node carried the miners' vote-key hashes under "key" and eight CI runs went red on "no secret file names and no 64-hex secrets in the tree" while the pushing lanes saw nothing: the light gate ran only conflict markers and Windows paths.
- tools/ci/pre-push.sh: never_push_checks() (identity grep, no-secrets) runs on every ref from --hook, and inside the full gate where the identity grep already sat; the self-test asserts the wiring; the light gate is about 20 s on the Mac.
- infra/fast-time/lib/redact-keys.mjs: writeSummary() shortens every 64-hex value under a key-shaped field to 8 hex and an ellipsis and refuses a text the no-secrets rule would flag (line named); --self-test and --check; the gate runs the self-test. fork-gate.mjs adopts it on ca3-v4-node.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
the project lead, 7 October 2026 15:02 UK: build-1 at load 139 / 114 / 90 with both slots held and a 1 h 40 min queue while build-2 read 4.5 with
free slots, because the class router pinned each class to its box. Now lib.sh bs_route_spill reads the preferred box (free slots,
1-minute load) with one ssh and hands the job to the other box when the preferred one has no free slot or sits above load 64 and the
other qualifies; neither qualifying queues on the class's own box. The decision travels as BR_ROUTE_* into the JSONL "route" object
for the dashboard. build-2's slots file reads 3; everything on box 2 runs at nice 10 / 32 cores / -j 32, and a bounded run takes
the band its slot owns so three never share a core. Self-test tools/ci/route-spill-check.sh (thirteen cases) in the gate.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The box mirrors carry no infra/, so the test skipped there and the gaps showed only on the Mac and in the class v5 lane's run.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
infra/fast-time/fork-gate.mjs: H1 and H2 honest and mining through every phase, B the third node; modes attack (B's
key fresh, 3 of 5 CPU threads in the split), third (B at about half of the table, accepted) and partition (H1 against
H2, the heavier side wins with the gate on as with it off). A reorg is read from the chain (getVirtualChainFromBlock
of the pre-cut tip lists removed blocks), never from a key; blue work compared as BigInt; leftovers stopped by pid
file, never by name. infra/fast-time/fork-gate-gate.mjs runs the six cases side by side (known-failed first) and is
GREEN only when every case gives the verdict it must and the two partition heals agree. tools/fast-time-remote.sh
runs a harness on a build box under a slot with a holder line and a JSONL row (the node binaries from a fork
worktree's target on the box, results fetched back); it carries the whole-body block and is listed in the check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 7f3e75479e)