0.7.1g1G5c: close the SURVIVED cohort (1 KILLED, 11 EQUIVALENT) - #463
Conversation
…eal failure class
The existing assertions used startsWith("structured-parse-failed"), which is satisfied
both by the authoritative diagnostic (structured-parse-failed: StructuredOutputException)
and by the negated-conditional mutant's output (structured-parse-failed: unknown). The
assertions now pin the full contract, so the diagnostic's class-name component is
observable behaviour rather than an unchecked prefix.
Adjudicates the 12 frozen SURVIVED identities at base 42d9d94: 12/12 EXACT mappings (the five G5a ambiguities resolved by canonical identity), 1 semantic KILLED (a9760bea3a92, via an exact diagnostic assertion), 11 instruction-level EQUIVALENT proofs (6 caller-discard, 2 catch-handler dominance, 1 compiler guard, 2 successor convergence), 0 UNDETERMINED, 0 KILLED regressions. No production changes; no authority changes.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The reconciliation manifest records the single killed identity as a9760bea3a92f, which does not match its canonical identity or the short prefix used elsewhere in the same file, undermining the artifact's stated exactness.
Review effort: Balanced
Findings: 1
What changed in this PR
This PR closes the "SURVIVED" cohort of an ongoing mutation-testing adjudication effort (task 0.7.1g1G5c) for the approval subsystem. Of the 12 frozen SURVIVED mutation identities, it adjudicates 11 as EQUIVALENT (with instruction/control-flow proofs) and kills exactly 1 by tightening a test assertion. The functional change is a single 2-line test edit; the remainder is evidence documentation. It fits into the broader 0.7.1 control-plane-authority quality campaign, leaving exactly 4 NO_COVERAGE identities for the follow-up task (G5d).
Changes:
- Tightens two assertions in
ApprovalResumeSuspensionContractTestfromstartsWith("structured-parse-failed")toisEqualTo("structured-parse-failed: StructuredOutputException"), which is the discriminator that kills mutanta9760bea3a92. - Adds a narrative adjudication write-up and a structured JSON manifest recording mappings, campaign provenance, reconciliation, and per-identity equivalence proofs.
- No production, baseline, ledger, mutator, timeout, or ceiling changes.
| File | Description |
|---|---|
| tramai-engine/src/test/kotlin/dev/tramai/engine/approval/ApprovalResumeSuspensionContractTest.kt | Strengthens two uncertain-reason assertions to pin the full diagnostic contract, supplying the missing discriminator for the one real kill. |
| docs/roadmap/0.7.0/TASK-0.7.1g1G5c-SURVIVED-ADJUDICATION.md | New narrative documenting mapping repair, measurement reconciliation, and the eleven equivalence proofs. |
| docs/roadmap/0.7.0/TASK-0.7.1g1G5c-SURVIVED-12-MANIFEST.json | New structured manifest of the 12 identities, campaigns, reconciliation, and dispositions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
1. reconciliation.movements[0].identity is the full 64-hex canonical identity (was the malformed prefix a9760bea3a92f). 2. The six NullReturnVals rows carry the mutated areturn PCs (161, 100, 244, 341, 267, 54), each re-verified by javap at the census base against the line table, instead of null. Call-site pop PCs remain as supplementary evidence. No disposition changes: 1 KILLED / 11 EQUIVALENT / 0 UNDETERMINED.
|
Custody corrections on exact head
Every one of the twelve rows now has a non-null |
cd46f17
into
epic/0.7.1-control-plane-authority

Base
42d9d9487ccf59ca3f348d0babfe9bbda232ef0f— the squash merge of #462. Frozen parent cohort digest92a9d06d5a8e43c5fb659f9d65bdd2e73d6ed5f45c1a8536ac70781b03503584unchanged; admission ledger stilladmissions: [].Scope
The 12 frozen SURVIVED identities, and nothing else. The four NO_COVERAGE identities are untouched (G5d).
Endpoint
G5C SURVIVED COHORT CLOSED — G5 REMAINDER = EXACTLY 4 NO_COVERAGE.
Phase 1 — mappings repaired
The authority is the repository's own
MutationIdentity.stableKey():sha256(module ␟ class ␟ method ␟ descriptor ␟ mutator ␟ description ␟ block ␟ index), line deliberately excluded. It reproduces all 68 identities of the P1 manifest exactly, so the canonical identity carries PIT's block/index and resolves each previously-ambiguous identity uniquely:1ce5967ee60b→108,c7774df8ccdc→305,3658ba45eaed→160,8e18b4b48968andd38ac52f2843→174. G5a's AMBIGUOUS determinations are recorded as superseded, not erased.The SMAP mattered:
ApprovalRunAttributionKthas line-table entries at 171–180 while the file ends at line 169. TheSourceDebugExtensionmap shows output line 174 comes from stratum 2 =_Collections.ktline 1807 (inlined stdlib), debug-mapped back to our line 104 —expected.any { metadata.getValue(it).isBlank() }.Second campaign provenance
Control: family-only narrowing (53 deletions,
approvalbyte-identical), throwaway78458d1e,measuredCommit= that commit, BUILD SUCCESSFUL, census 918 (engine 492 + security 426; 661 KILLED / 133 SURVIVED / 62 NO_COVERAGE / 62 TIMED_OUT).Candidate:
7acbd868, a child of the control throwaway differing by the test commit alone (d3837a58).Measurement reconciliation
918/918 identities shared · control-only 0 · candidate-only 0 · identity loss 0 · identity gain 0 · KILLED regressions 0 · new timeouts 0 · status movements: exactly 1 —
a9760bea3a92SURVIVED → KILLED, killer named:ApprovalResumeSuspensionContractTest› a cancellation resumed into the structured-parse uncertain path is not replaced by the primary failure,resumeline 102.The one real kill, and the eleven proofs
a9760bea3a92is theifnonnullinstructured-parse-failed: ${e::class.simpleName ?: "unknown"}. The path was already exercised — the assertions readstartsWith("structured-parse-failed"), which the mutant'sunknownalso satisfies. The discriminator was missing, not the coverage; the assertion now pins the full contract (isEqualTo(...)), a 2-line change.Eleven equivalences, each proven at instruction/control-flow level on its own identity:
compensateSteppc252,persistSuspendedInvocationpc1231,persistUngovernedpc880,persistGovernedpc1049,requireExistingAttributionMatchespc699rethrowIfCancellation):resumeregistersCancellationException→1088/Exception→1093and pc1100 sits inside the 1093 handler;compensateStepregisters147/150with pc155 in the 150 handler — so the helper's only branch cannot fireIntrinsics.checkNotNull): pc285aload 7→ pc287 check → pc290aload 7→ pc293CreateApprovalChallenge(...); the value is immediately passed as a non-null Kotlin constructor parameter, whose own check raises the same NPE one instruction lateranyfast path,pc186 instanceof Collection; pc189 ifeq): negating it routes Collections onto the plain-Iterable loop; empty input returns false both ways, non-empty runs the identical loopChanges
Zero production changes — no production defect was found. One test-file change (2 lines) plus two documentation artifacts. No change to
mutation-baseline.json, either ledger, the mutator set, timeout policy, family semantics, ceilings, or verifier semantics. The measurement narrowing never landed.Status
P1 mint: still blocked. P2 consumption: still blocked. G4 not reopened; cohort not widened.
Verification: frozen digest unchanged · ledger empty · 12/12 EXACT · 0 UNDETERMINED · 1 movement, 0 regressions · focused tests green ·
spotlessCheck verifyStaticAnalysis verifyChangePolicy -PchangePolicyBase=42d9d948…BUILD SUCCESSFUL. Exact-head CI is the final authority. Not self-merged.