You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
evidence(stage2): the campaign re-recorded against the fixed harness, 11/11
p022-stage2-1 @ 30a4918, dirty:false — 11/11 caught, 0 survived,
0 compile-error, 0 invalid, 0 runner-error, every expected catcher hit, M00
surviving the unmutated tree.
Re-recorded because the previous run measured a census whose ledger key took
the host's path separator, and because S11 changed the definition's hash. A
result that names a tree nobody would want to check out is not evidence,
whatever its counts say.
The Windows verdict on the same eleven mutations is a CI gate
(stage2-windows-mutations) rather than a second recorded file: one campaign has
one recorded provenance.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYLNQy6tLXqsV1CbuNqsSb
"comment": "Recorded mutation-campaign run (scripts/mutate_campaign.py --run). Raw facts only: outcomes, catchers, provenance. Counts are derived by scripts/render_checkpoint_status.py; regenerate this file by re-running the campaign, never by hand.",
Copy file name to clipboardExpand all lines: docs/generated/p022-stage2-mutations.md
+26-1Lines changed: 26 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,4 +10,29 @@ Campaign `p022-stage2-1` — #262 Stage 2 — the CI/dogfood ENGINE-SELECTION se
10
10
11
11
Definition: `docs/evidence/p022-stage2-1.json` (sha256 `fd96f37ba882a9b9…`, 11 mutations). Replay on a clean tree with `python scripts/mutate_campaign.py --campaign docs/evidence/p022-stage2-1.json --run`; the recorded run is raw outcomes and provenance, the counts below are derived from it.
12
12
13
-
**No recorded run** is committed (expected at `docs/evidence/p022-stage2-1.result.json`): the campaign has a definition but no evidence. Nothing below is a number.
| recorded at commit |`30a491864b4fcdd37c5ecee26431326821162948`|
16
+
| layers run (every one, for every mutation) |`stage2`|
17
+
| mutations | 11 |
18
+
| caught | 11 |
19
+
| survived | 0 |
20
+
| compile-error (no evidence either way) | 0 |
21
+
| invalid-mutation | 0 |
22
+
| runner-error | 0 |
23
+
| caught without every expected catcher | none |
24
+
| honesty control `M00` (unmutated tree must pass) | survived — as required |
25
+
26
+
| id | rule | mutation | outcome | caught by |
27
+
|---|---|---|---|---|
28
+
| S01 | dogfood-selects-rust-explicitly | the dog-food job stops asking for an engine — the most likely regression of all, because the job still runs, still analyses, still uploads, and silently goes back to the public Python default | caught |`stage2::internal-default-not-rust`|
29
+
| S02 | dogfood-runs-the-production-core | the dog-food candidate becomes own-shadow-engine — the #260 dev adapter is a Rust binary that this repository really builds, so the substitution looks right and measures a thing that is not the product | caught |`stage2::wrong-rust-candidate`|
30
+
| S03 | the-claim-covers-both-platforms | the Rust-default dogfood matrix loses its Windows leg — 'our CI runs on Rust' quietly becomes a statement about Linux, which is the half of the product whose launcher mechanics never broke | caught |`stage2::platform-leg-lost`|
31
+
| S04 | the-locator-is-owen-rust-core-alone | the dogfood finds its candidate on PATH — 'the binary is right there, why spell out an absolute path', which is precisely how a stale binary stands in for the one under test | caught |`stage2::locator-contract-bypassed`|
32
+
| S05 | a-rust-failure-is-visible | the dogfood run swallows its exit code — the classic 'don't let the dogfood job break the build', which turns every Rust-default claim in this PR into decoration | caught |`stage2::rust-job-falls-back`|
33
+
| S06 | the-public-default-does-not-move | the PRODUCT default flips to Rust — the covert Stage 3, and the single edit that would make every internal Rust job pass by accident while changing what every user gets | caught |`stage2::public-default-moved`|
34
+
| S07 | the-public-default-does-not-move | the ACTION's public engine input defaults to rust — the same cutover through the other public door, and the one a C#-only control would miss | caught |`stage2::public-default-moved`|
35
+
| S08 | compare-evidence-is-not-traded-away | a #260 compare gate is disabled — the cheapest way to make a Rust-default dogfood green is to remove the job that would have disagreed with it | caught |`stage2::compare-gate-dropped`|
36
+
| S09 | no-unclassified-call-site | a new bare launcher invocation appears in a job nobody classified — the hole the census exists to close, and the one that reopens every time somebody adds a convenient scan step | caught |`stage2::stage2-census`|
37
+
| S10 | no-escape-by-relabelling | the dog-food job is reclassified out of the Rust-default population — every other rule is satisfied by shrinking Class D, so without a rule that reads the job's own name this is a green way to stop dogfooding | caught |`stage2::stage2-census`|
38
+
| S11 | dogfood-selects-rust-explicitly | the dog-food's engine selection is COMMENTED OUT rather than deleted — the shape a temporary rollback really takes ('just for one run, we'll put it back'). Its twin S01 deletes the line; this one leaves the words `engine: rust` sitting in the file, which is all a control that greps the job's raw text would need to stay green. It exists because S03 survived for exactly that reason on a different key | caught |`stage2::internal-default-not-rust`|
0 commit comments