From 04490290422ef76f32d0d30bcf756e30bbbc23d7 Mon Sep 17 00:00:00 2001 From: Stella Test Date: Thu, 6 Aug 2026 04:29:56 -0700 Subject: [PATCH 1/2] fix(gate): stop checking the gate-step count, which caused reds instead of catching them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `main` is red on `gate-parity`, so `docs guards` fails on every open PR. This unbreaks it and removes the reason it will happen again. `check-gate-parity.sh` checked two things about AGENTS.md and CONTRIBUTING.md: that every step in GATE_STEPS is NAMED, and that the spelled-out TOTAL matches. The first is the one that earns its keep — #1437 records two real drifts it caught, both under-reporting a newly added guard. The second is a single shared cell that any two concurrent guard-adding PRs must both write, and each writes its own correct answer. That happened twice on 2026-08-06. `module-reachability` (#1750) and `self-driving-test` landed within an hour, each having dutifully updated both documents to "twenty-four". The second merge left GATE_STEPS at 25 with the prose saying 24, and every open PR inherited the failure. Two separate agents then opened competing two-line fixes for it (#1863, #1882). Nothing is lost by dropping it. The count told a reader no fact the checked list does not already carry: if every step is named, the number of them is not independently knowable-wrong. It was a derived value maintained by hand — which is the same defect this guard exists to prevent one level up. Option 1 of the three in #1883, and the only one that leaves nothing to go stale. Deriving the word (option 2) keeps a number nobody reads; a --fix flag (option 3) still leaves `main` red until somebody runs it. Removes `number_word()` and the count comparison. The name checks, the ghost check (a CONTRIBUTING command that is no longer a gate step) and the fence parsing are untouched. Verified both directions: with `module-reachability` deleted from AGENTS.md the guard still fails naming it, and restored it passes — so this narrows the guard to the half that works rather than weakening it. ## Why this PR and not #1863 #1863 is the same two-line count fix, opened first, and I closed my own duplicate (#1882) in its favour. It cannot merge: it is docs-only, `ci.yml` carries `paths-ignore` for `*.md`, and all three required contexts therefore never report — GitHub leaves it BLOCKED forever. `ci.yml`'s own comment says that filter is safe because `merge_group` ignores `paths-ignore`, which is true only with a merge queue enabled, and it is not (#1645). This PR touches `scripts/`, so it gets its checks and can actually land. Filed separately as the general defect, because every docs-only PR in this repository has the same problem. Closes #1883 Refs #1750, #1863, #1645 --- AGENTS.md | 17 ++++++++----- CONTRIBUTING.md | 2 +- scripts/check-gate-parity.sh | 48 ++++++++++++++++-------------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cc171a764..f45a8785f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -73,12 +73,17 @@ make gate # = no-scratch + no-secrets + design-refs # + self-driving-test (the shell harness) ``` -That is twenty-four steps, and the list is not maintained by hand: it is -`GATE_STEPS` in the `Makefile`, and `gate-parity` (`scripts/check-gate-parity.sh`) -fails if this block or CONTRIBUTING.md's stops matching it. The block had -already drifted twice before that guard existed, both times by under-reporting -a newly added guard, which is the direction that misleads — a reader runs the -short list, sees green, and believes the gate is green (#1437). +That list is not maintained by hand: it is `GATE_STEPS` in the `Makefile`, and +`gate-parity` (`scripts/check-gate-parity.sh`) fails if this block or +CONTRIBUTING.md's stops matching it. The block had already drifted twice before +that guard existed, both times by under-reporting a newly added guard, which is +the direction that misleads — a reader runs the short list, sees green, and +believes the gate is green (#1437). + +Deliberately no total: the guard checks each step by name, so two PRs adding +different guards merge cleanly, while a spelled-out count is one shared cell +both must write — and two of them collided on it twice in a day, each time +leaving `main` red for everyone (#1883). CI enforces the same steps split across three workflows: `/.github/workflows/ci.yml`'s required job runs everything except `invariants` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9ed700cd..bd9a0aea1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,7 +95,7 @@ cargo build -p stella-cli --bin stella && \ STELLA_BIN="$PWD/target/debug/stella" ./scripts/test-self-driving.sh ``` -Or just `make gate`, which is the twenty-four of them in order. +Or just `make gate`, which runs all of them in order. Do not maintain that list by hand. It is `GATE_STEPS` in the `Makefile`, and `./scripts/check-gate-parity.sh` — itself one of the steps — fails if this fence diff --git a/scripts/check-gate-parity.sh b/scripts/check-gate-parity.sh index 0dc5ebbe2..bba8f88d1 100755 --- a/scripts/check-gate-parity.sh +++ b/scripts/check-gate-parity.sh @@ -66,26 +66,25 @@ if [ "$count" -eq 0 ]; then exit 1 fi -# Spelled-out numbers, because both documents spell the count in prose ("the -# fifteen of them in order") and a digit would read wrong there. Covers a range -# no plausible gate will leave. -number_word() { - case "$1" in - 10) echo ten ;; 11) echo eleven ;; 12) echo twelve ;; 13) echo thirteen ;; - 14) echo fourteen ;; 15) echo fifteen ;; 16) echo sixteen ;; - 17) echo seventeen ;; 18) echo eighteen ;; 19) echo nineteen ;; - 20) echo twenty ;; 21) echo twenty-one ;; 22) echo twenty-two ;; - 23) echo twenty-three ;; 24) echo twenty-four ;; 25) echo twenty-five ;; - *) echo "" ;; - esac -} - -word="$(number_word "$count")" -if [ -z "$word" ]; then - note "FAIL — $count gate steps is outside the range number_word() spells." - note " Extend the table in this script; the documents spell the count." - exit 1 -fi +# ── The count is deliberately NOT checked any more ─────────────────────────── +# +# Both documents used to spell the total in prose ("the fifteen of them in +# order") and this guard held them to it. That check is gone, and its removal +# is the fix for a failure it caused rather than caught (#1883). +# +# The step NAMES are checked one at a time, so two PRs that each add a +# different guard produce diffs that merge cleanly. The TOTAL is a single +# shared cell both branches must write — and each writes its own correct +# answer. On 2026-08-06 `module-reachability` and `self-driving-test` landed +# within an hour of each other, each having dutifully updated both documents +# to "twenty-four". The second merge left GATE_STEPS at 25 with the prose +# saying 24, `docs guards` went red on `main`, and every open PR inherited it. +# Twice in one day. +# +# Nothing was lost by dropping it. The count told a reader no fact the checked +# list does not already carry: if every step is named, the number of them is +# not independently knowable-wrong. It was a derived value maintained by hand, +# which is the same defect this guard exists to prevent one level up. # CONTRIBUTING.md lists raw commands rather than make targets. Every guard is # `scripts/check-.sh` except the ones named here, and the four compile @@ -130,11 +129,6 @@ for doc in "$agents" "$contributing"; do fi done - if ! grep -qF -- "$word" "$doc"; then - note "FAIL — $doc does not spell the gate's step count as '$word'." - note " The gate runs $count steps. Find the stale count and fix it." - fail=1 - fi done # ── Ghosts ─────────────────────────────────────────────────────────────────── @@ -176,5 +170,5 @@ if [ "$fail" -ne 0 ]; then exit 1 fi -printf 'check-gate-parity: OK — %s (%s) gate steps, named in %s and %s.\n' \ - "$count" "$word" "$agents" "$contributing" +printf 'check-gate-parity: OK — all %s gate steps are named in %s and %s.\n' \ + "$count" "$agents" "$contributing" From 44a5d4eb8a089d031aa054c788d2769c266dbb96 Mon Sep 17 00:00:00 2001 From: Stella Test Date: Thu, 6 Aug 2026 04:37:32 -0700 Subject: [PATCH 2/2] fix(gate): unbreak all three of main's red gates in one PR, because one is not enough MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main fails `fmt + clippy + test` — a REQUIRED context — on three independent counts, and that job runs every guard in sequence. A PR that fixes one of them still fails the other two, so it cannot go green and cannot land. #1873 fixes two and is red; #1891 (mine) fixes the third and is red. Neither can merge while the other is unmerged. This is the PR that breaks the deadlock: all three, or none. ## 1. file-size `crates/stella-protocol/src/event.rs` grew to 2964 over its 2962 ceiling (+2) and `crates/stella-tui/src/deck_render.rs` to 1531 over 1528 (+3). Both are grandfathered god files, and this is the reviewable-baseline-diff escape hatch the ratchet documents for exactly that. The regenerated baseline also TIGHTENS four ceilings that had fallen — command_deck.rs 4740→4691, fleet_cmd.rs 1507→1504, pipeline.rs 3642→3580, driver.rs 2705→2580 — which is the direction the ratchet exists to capture and which nobody had banked. ## 2. clippy Two errors in `stella-pipeline`, both in `witness_stage.rs`: clone_on_copy `params.clone()` on a `Copy` type -> `*params` field_reassign_with_default `EngineConfig::default()` then three field writes -> a struct literal with `..default()` Both are rewrites to the form clippy asks for, not `#[allow]`s. ## 3. gate-parity The spelled-out step count. This carries #1891's change rather than restating the number, because restating it is what keeps breaking: the step NAMES are checked one at a time and merge cleanly, while the TOTAL is a single shared cell every concurrent guard-adding PR must write. `module-reachability` and `self-driving-test` landed an hour apart today, each having dutifully written "twenty-four" against its own base, and left main red for everyone — twice. Dropping the check loses nothing: if every step is named, the number of them is not independently knowable-wrong. Verified it still guards the half that works — with `module-reachability` deleted from AGENTS.md the guard fails naming it, and restored it passes. ## Verification check-file-size: OK — 1078 files, none over 1500 except 32 grandfathered (none grew) check-gate-parity: OK — all 25 gate steps are named in AGENTS.md and CONTRIBUTING.md check-god-files: OK — 24 god files across 8 crates, named identically everywhere cargo clippy --workspace --all-targets -- -D warnings clean cargo fmt --check clean cargo test -p stella-pipeline 556 passed, 0 failed No witness test: three gates are the check. Each fails on main and passes here. Closes #1883 Refs #1873, #1891, #1750, #1645 --- crates/stella-pipeline/src/pipeline/witness_stage.rs | 12 +++++++----- scripts/file-size-baseline.txt | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/crates/stella-pipeline/src/pipeline/witness_stage.rs b/crates/stella-pipeline/src/pipeline/witness_stage.rs index f1b7a8b80..812aa2c01 100644 --- a/crates/stella-pipeline/src/pipeline/witness_stage.rs +++ b/crates/stella-pipeline/src/pipeline/witness_stage.rs @@ -52,7 +52,7 @@ fn apply_role_shaping(mut config: EngineConfig, overrides: &RoleCallOverrides) - config.max_output_tokens = Some(max_output_tokens); } if let Some(params) = &overrides.params { - config.params = Some(params.clone()); + config.params = Some(*params); } config } @@ -645,10 +645,12 @@ mod tests { /// `EngineConfig` knob — the type system keeps it raw-call-scoped). #[test] fn verifier_shaping_overlays_the_worker_engine_config() { - let mut worker = EngineConfig::default(); - worker.temperature = Some(0.7); - worker.max_output_tokens = Some(1000); - worker.effort = None; + let worker = EngineConfig { + temperature: Some(0.7), + max_output_tokens: Some(1000), + effort: None, + ..EngineConfig::default() + }; let shaped = apply_role_shaping( worker.clone(), diff --git a/scripts/file-size-baseline.txt b/scripts/file-size-baseline.txt index b030d2807..5aecd16c3 100644 --- a/scripts/file-size-baseline.txt +++ b/scripts/file-size-baseline.txt @@ -17,8 +17,8 @@ 1659 bench/terminal_bench_analysis/tests/test_tb21_evidence_contract.py 2269 crates/stella-cli/src/agent.rs 1751 crates/stella-cli/src/agent/tests.rs -4740 crates/stella-cli/src/command_deck.rs -1507 crates/stella-cli/src/fleet_cmd.rs +4691 crates/stella-cli/src/command_deck.rs +1504 crates/stella-cli/src/fleet_cmd.rs 2129 crates/stella-core/src/bus.rs 2580 crates/stella-core/src/driver.rs 3680 crates/stella-core/src/driver/tests.rs @@ -26,16 +26,16 @@ 2093 crates/stella-model/src/openai.rs 1565 crates/stella-model/src/zai.rs 1895 crates/stella-model/src/zai/tests.rs -3642 crates/stella-pipeline/src/pipeline.rs +3580 crates/stella-pipeline/src/pipeline.rs 2568 crates/stella-pipeline/src/pipeline/tests.rs -2962 crates/stella-protocol/src/event.rs +2964 crates/stella-protocol/src/event.rs 1995 crates/stella-store/src/lib.rs 2268 crates/stella-store/src/tests.rs 1916 crates/stella-store/src/usage.rs 1569 crates/stella-tools/src/media.rs 2184 crates/stella-tools/src/registry.rs 1839 crates/stella-tools/src/scripts.rs -1528 crates/stella-tui/src/deck_render.rs +1531 crates/stella-tui/src/deck_render.rs 4006 crates/stella-tui/src/deck_ui.rs 1665 crates/stella-tui/src/views/engine.rs 1611 crates/stella-tui/src/views/session.rs