CLOUD-480: re-take the mutant acceptance on a tree where the tool does not lie - #669
Conversation
…erage
`mise run mutant` on a tree carrying CLOUD-944's stdin fix reports 223
declarations, not the 204 CLOUD-480's acceptance was recorded against — 19 had
never been applied, because the row loop is fed by `done <<<"$rows"` and the
`bats` calls inside it were reading those rows off stdin. Three of the 19 were
defective, so the published "every one caught" was green over a set that
excluded exactly the broken rows.
`ci-tools-check/spawned-tool-need-not-be-installed` named no case at all. Its
filter was written from memory as "a tool a batten.toml row spawns must be
installed in CI"; the case is "a tool a policy row spawns must be in the install
list". Repointed at the case that actually discriminates — the one asserting
`status -eq 1` on the defect — since the similarly-named case above it asserts
`-eq 0` in both arms and would pass under the mutation either way.
`filed-here-check`'s two overlap rows are removed rather than repaired, because
the property they name is over-determined and no one-line mutation can falsify
it. Measured by disarming each guard in turn: `named=${overlap#*,}` returns the
whole token when there is no comma, so `named` is the literal `0` or `-`, no
changed path equals either, and `paths` comes out empty — the emptiness guard
stops the row, and with that disarmed too the report loop has nothing to
iterate. Three independent structures protect one property. The measurement is
recorded beside the arms so the rows are not re-added; a declaration there
reports as a SURVIVED defect in the SUITE, which is the wrong subject.
Refs: CLOUD-480, CLOUD-944, CLOUD-941
`chore: release v0.0.108` moved the workspace version but left `fuzz/Cargo.lock` recording `batten 0.0.106`, so any cargo invocation under `fuzz/` regenerates it and every contributor's tree comes up dirty. This is that regeneration and nothing else — one version line, produced by the toolchain rather than typed. Carried here because it is drift on `main` that this branch tripped over, not because it belongs to the gate work: it rides its own commit so it is reviewable apart from CLOUD-480's. Refs: CLOUD-480
CLOUD-480 `mise run mutant` enforces five gates; the other ~39 are declared nowhere and are covered by nothing
Why CLOUD-418's mechanism has landed: Those are the gates the landing-loop follow-up bundle touched, so every "mutation-checked per CLOUD-418" obligation in that bundle is cashed rather than cited. This issue carries the remainder. A repo-wide count at that commit: The property that is already held, and the one that is not. Deliberately not done all at once. Declaring ~39 mutants in the same change that reduced landing cost would have put branch age — the quantity that multiplies laps and CI runs — on the critical path of the change that exists to shrink it. The mechanism is the expensive part and it is done; adding a row is now a two-line edit per gate. Refinement — Ready
Acceptance
Filed from the landing-loop follow-up bundle, where the mechanism landed with a deliberately narrow seed list. CLOUD-911 Fleet dispatch: the bash retirement in two bundles, sized for a cross-account handoff — ten rows in one PR, then the wave in another
Eleven rows, two bundles, two lands. The bundles and prompts live here rather than in a chat that dies with its container — CLOUD-607's precedent, CLOUD-784 and CLOUD-839's shape. This row is additionally written to survive its author running out of quota mid-flight: §"Resume protocol" is how a different account computes where the last one stopped, off the tree and the board, without asking anyone. Why two PRs and not twentyThe landing lease is fleet-wide and charges per land, not per gate.
One PR carrying many rows is the intended shape: CLOUD-661 retired the one-PR-per-ticket prescription for exactly this case and CLOUD-502 is Canceled. Why not one PR. Two reasons. Bundle 2's content is created and validated by bundle 1's instruments — in one PR those instruments would never have been exercised against anything but their own fixtures before twenty suite deletions rode on them. And a quota stop mid-branch with everything in one PR leaves nothing landed; with bundle 1 landed, the next account inherits a repo that can already prove a migration faithful, and bundle 2 is resumable per gate. The bundles
Bundle 2 is The precondition a human must clear before dispatch
CLOUD-480 is in Backlog and still assigned (corrected 2026-08-23; it left In Progress at 2026-08-22T20:54Z), and it is inside bundle 1. Either those four are released or reassigned, or bundle 1 ships nine rows and CLOUD-480's mutation coverage slips to bundle 2 — which weakens the batch exactly where batching is most dangerous, since a false-green module hides inside a large green diff and The fidelity chain, which is what bundle 1 exists to buildCLOUD-807's
Dispatch promptsTwo self-contained blocks — one paste per session, nothing to prepend. The workflow contract is repeated verbatim inside each, and the repetition is the point: CLOUD-728 measured five bundles coming up unsupervised because a human pasted one quoted block and dropped a shared contract. Bundle 1 — the floorBundle 2 — the waveVerification, run 2026-08-22 on
|
| row | verdict |
|---|---|
| CLOUD-907, 908, 909, 910, 911 | exit 0 |
| CLOUD-876 | exit 1 — no-ready-block |
| CLOUD-879 | exit 1 — no-ready-block |
Two rows inside bundle 1 are not groomed. Both carry a "Done when" section rather than the DoR's §1–§8, which is close enough to read as refined and is not. They sit in Todo, which is the ready queue — so this is a grooming precondition alongside the claim wall, and it is cheap: both bodies already carry the substance.
The ordering defect this found
The first draft of bundle 1 put 879 first. CLOUD-879's own body says "CLOUD-876 decides the schema mechanism. This issue consumes whatever it chooses — the derivation target differs between # METADATA annotations and regorus Target schemas, so sequence them." That dependency existed only as prose in one row's body; neither row carried a relation. It is now a blockedBy on the board (879 blockedBy 876), and the chain above is corrected. This is CLOUD-784's rule applied: every ordering hazard is a real relation, so the queue refuses a wrong order rather than a reviewer remembering it.
Still unrun, and named rather than implied
graph-check was not run over the six pre-existing bundle-1 rows as one closure (851, 883, 880, 886, plus 480 and 886's own relations). Four get_issue payloads short, and the two edges that could have broken the chain — 910's blockers and 879→876 — are both verified above. A bundle-1 agent should re-run graph-check over its full chain at claim time; it is free and this row may be stale by then.
Resume protocol — how a different account picks this up
Every signal is read off the tree or the board. None of it lives in a chat transcript, which is the point: a container is reclaimed, an account hits a limit, and the work has to be resumable by someone who was never in the room.
| question | answered by |
|---|---|
| Did bundle 1 land? | git log origin/main for the replay task and the schema regeneration; CLOUD-908 and 909 in In Review |
| How far into bundle 2? | the committed mapping table — one block per retired suite. A gate with no block is untouched |
| Is a gate half-migrated? | its .rego exists and its mapping block does not, or its block has unmapped cases |
| Which rows are claimed, and by whom? | the board. claim-check refuses on assigned, so a successor must be handed the assignment, not just the prompt |
| Is the branch resumable? | it is pushed to a draft PR. Committed-and-pushed is the only state that survives a VM reclaim |
| What is "done"? | the census moving down, asserted — CLOUD-843 §2 against the bfda756 baseline |
Progress (each bundle updates this section at every commit — branch, PR, rows done)
-
Bundle 1 — LANDED. Branch
claude/cloud-911-bundle-plan-9n3fsg, PR CLOUD-911 bundle 1 — the floor for the bash retirement merged 2026-08-23 by fast-forward;origin/mainisba08def. Every required check green on that exact SHA (ci,zizmor,darwin-link,semver,perf,windows,final), one lap.Rows complete: 876, 879, 851, 883, 907, 908, 909, 886, 480 — nine of ten. CLOUD-880's fact family landed and that row stays In Progress deliberately: its second acceptance clause asks for one exit-code consumer to become a rule over these facts, and that consumer does not exist in bash — reasoning on 880 and in CLOUD-911 bundle 1 — the floor for the bash retirement #660's body. CLOUD-480 was taken after all and is In Review; CLOUD-911 bundle 1 — the floor for the bash retirement #660's row table says not taken because it was written before the claim wall was cleared under
BATTEN_CLAIM_CHECK_BYPASS=1. A merged body cannot be corrected, so this section is the authority and that table is not.The land held for the whole bundle, as directed — one lease acquisition, which is this row's economic argument. Four blockers were diagnosed getting there and none was a flake to wave through:
config-lintrefusing 908's undeclaredrule-predicate-changed(declared through the two-source path, never re-ranked —trust.rsrefuses to rank deliberately); atests/land-lock.batslease case at 23.9s against a 20s cap, the fourth sibling CLOUD-450 had already raised to 60 and missed;batten-checkfailing closed on twodenyrows spawningopa/regalthatci.yml'sinstall_argsnever installed, a directionci-tools-checkwas structurally blind to and now is not; and disk exhaustion at 120MB free mid-verify.- CLOUD-879 — complete (
cf462c1). Both policy-input schemas are generated fromFact::ALLrather than checked in:Fact::schema_fragmentstates each fragment beside the fact'sClassandtree_key, andgenerate schemagained two surfaces. The suite changed in kind — a round trip that the committed bytes are what the generator produces, byte-stability, and the properties the generator STATES rather than derives (closedness, disjoint surfaces).ConfigSurfacebecameSchemaSurface, a declared break (feat(policy)!):mise run semverrefused the branch withenum_missinguntil the commit said so. - CLOUD-851 — complete (
3395323,e32cbf9,8e7214a).Productionis a third axis besideCost/Surface;the_two_axes_agree_about_every_kindis untouched andEffectstill means "spawns". The decision requests (Scan.requested, pure) and the boundary performs, on the spawning surface only —checkcomputes the identical request set and writes nothing. All three censused kinds are expressible, the keyed baseline reads back throughFact::Produced, and its red arm (same record, a module that does not consult it) is committed beside it. - Two defects in 851 that a green suite could not see, both fixed in
8e7214a, and the second is the more instructive. A record's destination did not name its producing rule, so two branch-keyed rules of one kind silently overwrote each other; the rule id is a path segment now, which makes the collision inexpressible rather than refused. And the store acquisition ran on EVERY run —checkp50 4.76ms → 10.01ms, 2.103x, whichperf-comparerefused. 2134 cargo tests were green across that regression, because none of them measures invocation cost. The full detail is a comment on 851. - A measurement discipline worth carrying to bundle 2.
perf-pairis a wall-clock ratio and its two arms are measured sequentially, so concurrent load on the machine does NOT divide out. Two readings had to be discarded here — one taken while sources were being edited under the release build, one whilemise run fmtran its own test suite alongside. Runperf-gatewith nothing else in flight, or the number it produces is not about the branch. - Preconditions cleared. CLOUD-876 and CLOUD-879 are groomed to the DoR's §1–§8 and both now pass
mise run ready-lintat exit 0 — the RED half of this row's §2 predicate is closed. - The claim wall was real, and it fired on the OTHER arm. Grooming in the implementing session trips
claim-check'srefined-this-session, exactly as this row's dispatch prompt anticipated. Claimed underBATTEN_CLAIM_CHECK_BYPASS=1, which records the self-refinement in the receipt — CLOUD-431's designed path, with the human decision taken explicitly rather than assumed. - The CLOUD-480 claim wall was CLEARED and the row LANDED — In Review on CLOUD-911 bundle 1 — the floor for the bash retirement #660. The account below is left standing because it was accurate about how the wall looked, and because the resolution was the same bypass 876/879/883/880 took:
BATTEN_CLAIM_CHECK_BYPASS=1, with the self-refinement recorded in the receipt. Re-checked 2026-08-23 against a freshget_issue: the row is Backlog and still assigned — it left In Progress at 2026-08-22T20:54Z. That is not a release:claim-checkrefuses onnot-todoas well as onassigned, so the move added a second refusal rather than clearing the first.graph-checkis what found this, refusing onstatus-claim-disagrees (CLOUD-480 claimed In Progress, board says Backlog)— the earlier reading below was true when written and is stale now. The intent to release it was given, the board was not changed, and this note previously said it had been — corrected here rather than left standing, because this section is the resume protocol's only durable channel and a false entry in it is worse than none. Bundle 1 proceeds on the other nine and settles 480 when the chain reaches it. (It did reach it: 480 landed in CLOUD-911 bundle 1 — the floor for the bash retirement #660 and is In Review — see the LANDED entry above. Everything before this parenthesis is how it looked at the time.) - CLOUD-876 — In Progress. The mechanism is decided: (a), and the evaluation is a comment on that row. (b) is refused by two landed gates rather than on the merits this row guessed at:
Target/Schemaare behind regorus'sazure_policyfeature, which adds 28 packages includingjsonschema(evaluator-closure-check's IO_CRATES) andcore-foundation-sysvia chrono (macos-link-check's FRAMEWORK_CRATES, CLOUD-885's chain). Measured, then reverted. - Landed:
af16871.opa1.2.0 andregal0.42.0 pinned, and the skew gate 876's acceptance names — aspolicy/opa-compliance.rego, adenypolicyrow overmise.tomlandCargo.toml. Verified:batten-checkexit 0,batten policy test5 bundles / 50 passed / 0 failed. - The first draft of that gate was bash, and it was reverted before landing.
mise-tasks/opa-compliance-agreement.shplus a bats suite — a new bash gate inside the bundle whose purpose is retiring bash, which is CLOUD-843's own "the bash grew today" one level down. Everything it decides is in two tracked TOML files, i.e. CLOUD-846's structured-config bucket. Census effect of this commit: no newmise-tasks/file, no newtests/*.batssuite, one newkind="policy"row. A useful precedent for bundle 2: the migratable-today claim held on the first attempt. - The draft also derived the compliance level from the vendored crate's README. That asks what does upstream claim right now — a property of the world, which
lock-complete's split puts on a clock, not in a gate. The row now decides only whether the numbers this commit pins agree;REGORUS_OPA_COMPLIANCE_FORties the recorded level to the regorus line it was read against, so a regorus bump reddens rather than the constant rotting. - Still open on 876: the schemars →
# METADATA schemas:→opa check -swiring, the Regal aggregate rule requiring an annotation on every rule, and therego.metadata.*refusal.
- CLOUD-879 — complete (
-
A finding for CLOUD-480, carried forward rather than filed separately.
$MUTANT_GATESheld 54 names when this was written and holds 113 now, not the five 480's body describes — that row's premise is stale and its remaining scope is much smaller than filed. Andmise run mutanton170c7c4reports one pre-existing red:ready-lint/replay-demanded-of-a-warn-gate SURVIVED. Not caused by this branch (ready-lint.shis untouched); it is exactly the "a suite that cannot discriminate is a finding about that suite" case 480 reserves. Resolved as a filed row rather than a forced declaration: CLOUD-941 owns it —ready-lint's mutation is a no-op because its pattern spells[ ]where the code has[[ ]], so the conjunct was covered by nothing.mutant-censuscloses the two-way gap 480 was filed for: 113 gates declared, 100 censused, two exemptions, and a gate added without a declaration now fails. -
Bundle 2 — dispatchable now. CLOUD-910's two blockers, 908 and 909, both landed on
mainin CLOUD-911 bundle 1 — the floor for the bash retirement #660, so the wave has the floor it was waiting for. (Worded without a code span after the id:graph-check's status-claim scanner read the previous phrasing as a claim that CLOUD-910 occupies a status calledblockedBy, and reportedstatus-claim-unscannable. The row's own §Verification records the same arm firing on out-of-closure ids — this one was self-inflicted by an edit and is fixed rather than explained.)
Dispatched by hand — and §Re-probed below downgrades "settled" to "could not look"
create_session is refused upstream: the session-management tools carry a mandatory-approval flag and bypassPermissions, an explicit permissions.allow entry and a PreToolUse allow hook are all recorded as tested and failing. CLOUD-734 is Done and carries the measurement; CLOUD-731, 784 and 839 are the precedents. Do not spend a turn re-attempting it. A human opens two sessions and pastes the prompts above, and confirms each session's permission mode in the UI — get_session is unavailable, so no agent can confirm it, and CLOUD-728 measured five bundles coming up in the wrong mode and running to landed unwatched.
This row's own lifecycle
CLOUD-735: a dispatch record opens no PR and lands no commit, so both gates out of In Progress are unreachable for it by construction. Leave it in Todo and close it by hand once both bundles are away, rather than pulling it and stranding it.
Refinement — Ready
Refinement gate: Definition of Ready & Done. This body carries only specializations.
- Source of truth (§1). The board and the tree. Every ordering claim here is a
blockedByrelation (CLOUD-910 blocked by 908 and 909), and the census baseline is a measurement overbfda756rather than a hand-derived list — if this row and the tree disagree, the tree is right and this row is stale. - Computable predicate (§2).
mise run graph-checkover the piped closure prints a frontier whose roots are the bundle heads and excludes CLOUD-910 behind 908 and 909. Every row in the dispatch passesmise run ready-lintat exit 0. Both were run on 2026-08-22 and the output is quoted verbatim in §Verification, including the two failures it found — CLOUD-876 and CLOUD-879 areno-ready-block, so that half of the predicate is currently RED and grooming them is a dispatch precondition, not a formality. Thegraph-checkrun also carries threestatus-claim-unscannablelines for claims about ids outside the piped closure, which is CLOUD-838's arm behaving correctly (CLOUD-839 recorded the same residue for the same reason). - Effect (§3).
free— a tracker record. Nothing is resolved, built or spawned. - Generated artifacts (§4). None.
- Output / exit (§5). No command surface is touched.
- Commit / bump (§6). none — this row lands no commit.
- Test obligation (§7). None of its own; each bundle's rows carry theirs. The claims here that could be wrong are the bundle membership and the census baseline, and re-running
graph-checkand CLOUD-843 §2 falsifies them. - Blockers (§8). None.
⚠️ Re-probed 2026-08-23 — two of §"Dispatched by hand"'s premises are false, and the third is unverified
That section says "that is settled" and "Do not spend a turn re-attempting it." Neither holds as written. Measured this session, from a plan-mode session on env_01Cwc7vhMyL51NMsPj4aeNHP:
The two false premises
§"Dispatched by hand" reads: "a human … confirms each session's permission mode in the UI — get_session is unavailable, so no agent can confirm it."
get_sessionworks. Called with no argument, it returned this session's full context includingsession_context.permission_mode,external_metadata.permission_mode,permission_mode_seq, the served model and the live rate-limit state.list_sessionsworks. Withmine: trueit returned every live session on this repo with title, branch, status,task_summaryandpost_turn_summary. That read is not a nicety — it is what found two collisions CLOUD-926 would otherwise have walked into.
So the stated reason a human must be in the loop is gone. An agent can confirm a child's mode, which is exactly what CLOUD-728 says must happen and what plan-fleet.md §4 instructs ("Read the child's mode back after the call rather than assuming the parameter took").
The third premise is now UNVERIFIED rather than confirmed — and that is the load-bearing correction
create_session was called twice, ~1 minute apart, with a real bundle prompt, permission_mode: "plan", model: claude-opus-5, source_url and tags per plan-fleet.md §4. Both calls returned, verbatim and identically:
failed to create session: the service is temporarily unavailable — try again
That is not the failure this row describes. §"Dispatched by hand" claims a mandatory-approval refusal — "the session-management tools carry a mandatory-approval flag and bypassPermissions, an explicit permissions.allow entry and a PreToolUse allow hook are all recorded as tested and failing." An approval refusal and a service-availability error are different verdicts with different remedies, and only one of them is permanent.
So the honest state is could not look, not "refused": the call reached the service, the service declined to answer, and nothing was learned about the approval flag. Reading an availability error as confirmation of a policy refusal is the two-valued collapse CLOUD-251 names, applied to a capability instead of a gate.
What changes for the next dispatcher
- "Do not spend a turn re-attempting it" is retired. It was a reasonable economy when the refusal was believed permanent and the read-back was believed impossible. Both halves have moved: the probe costs one call, and its upside is removing a human from the critical path of every future fan-out. Re-probe rather than defer.
- Dispatch from the mode you want the children in.
plan-fleet.md§4's measured table, from one account: dispatcherauto+ omitted → childdefault; dispatcherplan+ passedauto→ refused at the call; dispatcherplan+ passeddefault→ childplan. Passingplanfromplanis untested and is what was attempted here; the service error means it is still untested. Never passautofromplan— that arm is measured. - Hand-pasting still works and nothing is blocked on this. CLOUD-926 carries five prompt blocks and this row carries two, all in fenced blocks, all copy-pasteable. The capability question is an efficiency question, not a dependency.
Provenance
Probed while dispatching CLOUD-926's bundle C — chosen as the probe target because it is the only bundle with no assigned rows, so a success would not start work behind a claim-check wall. The override of this row's "do not re-attempt" instruction was taken deliberately, with the campaign owner's agreement, on the strength of the two falsified premises above rather than in spite of them.
⚠️ Re-probed AGAIN 2026-08-23, later session — the third premise now has a reading, and it is the approval flag
create_session was called once from this session (env_01Cwc7vhMyL51NMsPj4aeNHP, model: claude-opus-5, permission_mode: "plan", source_url and tags per plan-fleet.md §4), carrying bundle 2's full prompt. It returned, verbatim:
MCP tool call requires approval
That is the mandatory-approval refusal §"Dispatched by hand" describes — not the failed to create session: the service is temporarily unavailable the section above measured. So the honest state moves from could not look to refused at the approval layer, and the two remedies stay distinct: an availability error is waited out, an approval flag is not.
Both readings are now on the record, hours apart, and that is itself the finding. The same call with the same parameters returned an availability error once and an approval refusal once, so a single probe is evidence about that probe rather than about the capability. Neither reading retires the other.
What did NOT reproduce: the mode read-back. get_session with no argument returned this session's context and carried no permission_mode field at all — session_context held sources, outcomes, model, effort_level; external_metadata held the container version, branches, last_served_model and the rate-limit state. So §"The two false premises"'s claim that an agent can confirm a child's mode is unverified again: the field that read-back needs was absent. list_sessions with mine: true does still work, and is what confirmed no live session held bundle 2.
Consequence for this row
Bundle 2 was not handed to a sibling. It is being run in-session on branch claude/bundle-2-dispatch-plan-kr630c (keyless, so closing-key-check's branch-name precedence cannot strand rows), together with the rest of this row's outstanding work: CLOUD-880's second acceptance clause, CLOUD-876's residue, and the Done pass over bundle 1's five rows still In Review (876, 886, 908, 909, 480 — 879, 851, 883 and 907 have already moved).
The wave's chain is CLOUD-930 → CLOUD-929 → CLOUD-910, one PR, one land. The two added rows are not scope creep: .rego is the only config format in the tree with no gate and it is the language the wave writes up to twenty modules in (930), and the retirement census is four shell one-liners in an issue body, so a wave that adds bash reports the same green as one that removes it (929) — while CLOUD-910's own acceptance demands the census delta "asserted rather than eyeballed". CLOUD-932 is deliberately held out: its remedy lands in .claude/rules/**, which is PR-D's domain.
Census re-derived on 54442b2 (v0.0.108), against this row's bfda756 baseline, because the wave is sized off it: 145 mise-tasks/*.sh (was 141), 157 top-level tests/*.bats (was 150), 5 kind = "policy" rows (was 4), 3 in-repo policy/*.rego, 4 preset modules (was 4). The bash grew by four task files and seven suites since the baseline — an argument for running the wave now rather than behind PR-E and PR-G.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe changes update mutation-test annotations in two shell scripts. One annotation changes its descriptive text without changing the mutation substitution. Two mutation definitions are removed because redundant empty-path guards and loop behavior prevent independent test coverage. Documentation now records why those mutants survive. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
|
/fast-forward |



CLOUD-480's acceptance was recorded against a number a defective tool produced. This re-takes it and fixes what the honest reading found.
The measurement
mise run mutantwas silently skipping declarations. Its row loop is fed bydone <<<"$rows", so the rows sit on the shell's stdin, and the twobatsinvocations inside the loop body read stdin and swallowed every row after the one they were running. CLOUD-944 measured it onclaimed-keys— 3 declared, the counter reached 2 — and fixed it with two</dev/nullredirects in #651, which merged on top of #660.That makes this the first tree on which CLOUD-480's set can be swept honestly, and the delta is not cosmetic:
Nineteen declarations had never been applied, and three of those nineteen were broken. The tool was reporting green because it was not applying the rows that would have failed — CLOUD-480's own subject, a declaration that reads as coverage, reproduced inside its own acceptance evidence.
221 rather than 223 because two declarations are removed rather than repaired; see below.
The three
ci-tools-check/spawned-tool-need-not-be-installed—names-no-case. My own defect, from the row I added for this gate's third direction: the filter was written from memory asa tool a batten.toml row spawns must be installed in CI, and the case isa tool a policy row spawns must be in the install list. Repointed atno list installs is refused, which is the case assertingstatus -eq 1on the defect. Naming the similar case above it would have repeated the error invisibly — that one asserts-eq 0in both arms and passes under the mutation either way.filed-here-check's two overlap rows —SURVIVED, and they cannot do otherwise.zero-overlap-refusedandoverlap-unanswered-refusedeach disarm onecasearm'scontinue, and the property each names is over-determined, so no one-line mutation can falsify it. Measured by disarming each guard in turn rather than read off the source:named=${overlap#*,}returns the whole token when there is no comma, sonamedis the literal0or-; no changed path equals either, the intersection is empty, and the report loop has nothing to iterate. Three independent structures protect one property.So the rows are removed, per this issue's own posture: a gate whose suite cannot be made to discriminate is a finding about that suite, never a weakened mutant. The measurement is recorded beside the arms so they are not re-added — a declaration there reports as a
SURVIVEDdefect in the suite, which is the wrong subject, and CLOUD-941 spent a section misdiagnosing exactly that.What this settles on CLOUD-941
Two of that row's four survivors are already dead on this tree, neither by anything in this branch:
board-write-record/overlap-frozen-at-write-time— killed by CLOUD-480'srestore_treefix, which removed the sweep-order dependence it was hiding behind. Its own header predicted this: caught when swept alone,SURVIVEDin a full sweep.ready-lint/replay-demanded-of-a-warn-gate— no longer reported.And its published
[ ]vs[[ ]]bracket-mismatch diagnosis is refuted, as its own correction section suspected: a zero-match pattern yieldsinert-mutation, neverSURVIVED. The cause was the incomplete reading, not the pattern. That row's suggested retitle still stands, since its title asserts the refuted cause and a count now known wrong.The remaining two it names are the
filed-here-checkpair resolved here.Also carried
chore(fuzz)is one line:chore: release v0.0.108moved the workspace version and leftfuzz/Cargo.lockrecordingbatten 0.0.106, so any cargo invocation underfuzz/regenerates it and every contributor's tree comes up dirty. Toolchain-produced, on its own commit so it reviews apart from the gate work.Verification
mise run mutant— 221 declared across the 114 enforced gates, every one caught, exit 0, run serially throughmisewith nothing else in flight (a contended run is CLOUD-944's other half and mints false findings).ci-tools-check3/3,filed-here-check6/6.mise run mutant-census— 101 gates, every one declared or exempt by a filed row.mise run verify—fast-forward-green.Closes CLOUD-480