diff --git a/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-4-MANIFEST.json b/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-4-MANIFEST.json new file mode 100644 index 000000000..13a9bef26 --- /dev/null +++ b/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-4-MANIFEST.json @@ -0,0 +1,303 @@ +{ + "schemaVersion": 1, + "task": "TASK-0.7.1g1G5d", + "parent": "TASK-0.7.1g1G5", + "base": "cd46f176b20ef7e0e0b2b0e251569214dfc90619", + "baseProvenance": "squash merge of #463; branch directly from it; working tree clean", + "cohort": { + "size": 4, + "note": "exactly the four frozen NO_COVERAGE identities; no widening, no substitution", + "mutatorNamingCorrection": "The task brief labels the two 'NRV' identities NonReturningVoidMethodCall. The frozen manifest records them as org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator, description 'replaced return value with null'. The frozen identities are authoritative and unchanged; this is a label discrepancy, not an identity discrepancy." + }, + "startGate": { + "baseMatches": "cd46f176b20ef7e0e0b2b0e251569214dfc90619", + "cleanTree": true, + "fourPresent": true, + "allFourNoCoverage": true, + "noBaselineOnlyTarget": true, + "noSubstitutedTarget": true, + "noSourceCoordinateApproximation": true, + "authoritativeView": "the G5c candidate campaign (7acbd868) whose production+test content is identical to the merged cd46f176 (the merge squashed that test plus docs), in which all four are present and NO_COVERAGE with numberOfTestsRun=0" + }, + "phaseA": { + "method": "each identity mapped by bracketing: pitBlock is monotone in pc within the method (verified True for both methods), and each method has in-method calibration points from the committed G5b/G5c manifests (pc, pitBlock, pitIndex). The target's pitBlock therefore brackets a byte window containing exactly one candidate instruction of the mutated kind.", + "calibrationPoints": { + "suspendToolExecution": [ + [ + 158, + 11, + 74 + ], + [ + 287, + 31, + 168 + ], + [ + 362, + 35, + 206 + ], + [ + 1072, + 109, + 668 + ], + [ + 1420, + 132, + 853 + ], + [ + 1785, + 157, + 1067 + ] + ], + "requestApproval-Atj0Sqo": [ + [ + 159, + 9, + 68 + ], + [ + 304, + 23, + 160 + ], + [ + 457, + 35, + 243 + ], + [ + 618, + 46, + 328 + ], + [ + 799, + 60, + 426 + ] + ] + }, + "windows": { + "suspendToolExecution": [ + { + "pitBlock": 13, + "between": "pc158 (block 11) and pc287 (block 31)", + "candidates": [ + 194 + ], + "unique": true + }, + { + "pitBlock": 12, + "between": "pc158 (block 11) and pc287 (block 31)", + "candidates": [ + 163 + ], + "unique": true + } + ], + "requestApproval-Atj0Sqo": [ + { + "pitBlock": 11, + "between": "pc159 (block 9) and pc304 (block 23)", + "candidates": [ + 204 + ], + "unique": true + }, + { + "pitBlock": 10, + "between": "pc159 (block 9) and pc304 (block 23)", + "candidates": [ + 164 + ], + "unique": true + } + ] + }, + "pitCounterNote": "PIT never reports bytecode offsets, and its block/index counter counts ASM nodes that javap does not expose (a label/line-count reconstruction matched only 4/36 calibration identities). Bracketing is therefore used, and it is validated by in-method monotonicity plus the uniqueness of each candidate window." + }, + "phaseC": { + "classification": "UNREACHABLE (all four)", + "proof": [ + "Each mutated instruction lies on the suspension protocol of one specific call: resolveGovernedSuspension() at source line 145 in suspendToolExecution, and resolveGovernedIdentity(workflowRunId) at source line 82 in requestApproval.", + "Both callees are declared suspend, but neither body contains a suspension point: resolveGovernedSuspension has 50 instructions with 0 getCOROUTINE_SUSPENDED loads and 0 if_acmpne; resolveGovernedIdentity-jFE5hGw has 32 instructions with 0 getCOROUTINE_SUSPENDED and 0 if_acmpne, invoking only Continuation.getContext, GovernedRunScope$Key accessors, GovernedRunIdentity/RunId getters, Intrinsics.areEqual, makeConcatWithConstants and an exception constructor.", + "GovernedRunScope.resolve(context) is an ordinary non-suspend function; currentCoroutineContext()/Continuation.getContext do not suspend.", + "A suspend function can return COROUTINE_SUSPENDED only through the sentinel comparison emitted after a call. With no such comparison and no suspending callee, both resolvers always return their value directly.", + "Therefore in each caller the sentinel test is always false, so the COROUTINE_SUSPENDED exit (pc163, pc164) cannot execute; and the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path throwOnFailure (pc194, pc204) cannot execute.", + "Nothing else branches to those instructions: no branch or switch entry in either method targets pc194 or pc204." + ], + "whyNotToolingLimitation": "No independent evidence shows the instruction executing while PIT fails to attribute coverage. The instructions cannot execute at all.", + "whyNotEquivalent": "Equivalence answers a different question. These mutants never cross the reachability boundary, so equivalence is neither claimed nor needed.", + "whyNoTestAdded": "Tests are required only for identities proven REACHABLE. A test cannot make an unreachable instruction execute without either changing production semantics or fabricating a coroutine state, both forbidden. Adding one would be 'making PIT green' rather than explaining behaviour." + }, + "phaseE": { + "suspendToolExecution": { + "members": [ + "564517b2fdab", + "66c311cf4f0a" + ], + "sameConstruct": "YES \u2014 one compiler-generated suspension: block 12 is the COROUTINE_SUSPENDED exit, block 13 is the resumed-path throwOnFailure, one block apart", + "sameInstruction": "NO", + "dominates": "NO", + "wouldOneTestCoverBoth": "irrelevant \u2014 neither is reachable", + "statusesDiffer": "they do not" + }, + "requestApproval-Atj0Sqo": { + "members": [ + "5a7edac3a982", + "e52f1c1f6570" + ], + "sameConstruct": "YES \u2014 block 10 = exit, block 11 = resumed unwrap", + "sameInstruction": "NO", + "dominates": "NO", + "wouldOneTestCoverBoth": "irrelevant \u2014 neither is reachable", + "statusesDiffer": "they do not" + }, + "crossMethodNote": "Both pairs attach to a suspend-typed resolver that has no suspension point, so both pairs share one root cause. Block/index proximity was not used as evidence of equivalence." + }, + "finalTotals": { + "KILLED": 0, + "EQUIVALENT": 0, + "UNREACHABLE": 4, + "TOOLING_LIMITATION": 0, + "UNDETERMINED": 0 + }, + "parentAccounting": { + "parent": 52, + "settledByG5b": 36, + "settledByG5c": 12, + "settledByG5d": 4, + "remaining": 0 + }, + "identities": [ + { + "identity": "564517b2fdab899eceefac4eb9dbb40f3a60139a5c6f917f5fe7c1b172fc9d67", + "className": "dev.tramai.engine.approval.ApprovalSuspensionCoordinator", + "method": "suspendToolExecution(Ldev/tramai/engine/approval/SuspendToolExecutionRequest;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", + "mutator": "org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator", + "description": "removed call to kotlin/ResultKt::throwOnFailure", + "pitBlock": 13, + "pitIndex": 96, + "bytecodePc": 194, + "instruction": "invokestatic kotlin/ResultKt.throwOnFailure", + "suspensionRole": "resumed-path unwrap of the call to resolveGovernedSuspension() (line 145)", + "originalState": "NO_COVERAGE", + "finalState": "UNREACHABLE", + "finalClassification": "UNREACHABLE", + "reachabilityEvidence": [ + "Each mutated instruction lies on the suspension protocol of one specific call: resolveGovernedSuspension() at source line 145 in suspendToolExecution, and resolveGovernedIdentity(workflowRunId) at source line 82 in requestApproval.", + "Both callees are declared suspend, but neither body contains a suspension point: resolveGovernedSuspension has 50 instructions with 0 getCOROUTINE_SUSPENDED loads and 0 if_acmpne; resolveGovernedIdentity-jFE5hGw has 32 instructions with 0 getCOROUTINE_SUSPENDED and 0 if_acmpne, invoking only Continuation.getContext, GovernedRunScope$Key accessors, GovernedRunIdentity/RunId getters, Intrinsics.areEqual, makeConcatWithConstants and an exception constructor.", + "Therefore in each caller the sentinel test is always false, so the COROUTINE_SUSPENDED exit (pc163, pc164) cannot execute; and the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path throwOnFailure (pc194, pc204) cannot execute." + ], + "testAdded": null, + "killingTest": null, + "evidenceProvenance": "javap at the G5d base (classes identical to the measured campaign); PIT row (line/block/index) from the candidate campaign 7acbd868; pitBlock bracketing against in-method calibration points from the committed G5b and G5c manifests" + }, + { + "identity": "66c311cf4f0ae36396880146f9059264308168b0286cdee72b852076560df61e", + "className": "dev.tramai.engine.approval.ApprovalSuspensionCoordinator", + "method": "suspendToolExecution(Ldev/tramai/engine/approval/SuspendToolExecutionRequest;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", + "mutator": "org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator", + "description": "replaced return value with null for ApprovalSuspensionCoordinator::suspendToolExecution", + "pitBlock": 12, + "pitIndex": 78, + "bytecodePc": 163, + "instruction": "areturn (aload 20 \u2014 the COROUTINE_SUSPENDED exit)", + "suspensionRole": "suspend exit of the call to resolveGovernedSuspension() (line 145)", + "originalState": "NO_COVERAGE", + "finalState": "UNREACHABLE", + "finalClassification": "UNREACHABLE", + "reachabilityEvidence": [ + "Each mutated instruction lies on the suspension protocol of one specific call: resolveGovernedSuspension() at source line 145 in suspendToolExecution, and resolveGovernedIdentity(workflowRunId) at source line 82 in requestApproval.", + "Both callees are declared suspend, but neither body contains a suspension point: resolveGovernedSuspension has 50 instructions with 0 getCOROUTINE_SUSPENDED loads and 0 if_acmpne; resolveGovernedIdentity-jFE5hGw has 32 instructions with 0 getCOROUTINE_SUSPENDED and 0 if_acmpne, invoking only Continuation.getContext, GovernedRunScope$Key accessors, GovernedRunIdentity/RunId getters, Intrinsics.areEqual, makeConcatWithConstants and an exception constructor.", + "Therefore in each caller the sentinel test is always false, so the COROUTINE_SUSPENDED exit (pc163, pc164) cannot execute; and the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path throwOnFailure (pc194, pc204) cannot execute." + ], + "testAdded": null, + "killingTest": null, + "evidenceProvenance": "javap at the G5d base (classes identical to the measured campaign); PIT row (line/block/index) from the candidate campaign 7acbd868; pitBlock bracketing against in-method calibration points from the committed G5b and G5c manifests" + }, + { + "identity": "5a7edac3a982221ce692e032184362a1db8efc49292d9ea0b5716824303ecef1", + "className": "dev.tramai.engine.approval.DefaultApprovalGateway", + "method": "requestApproval-Atj0Sqo(Ljava/lang/String;Ldev/tramai/core/approval/gateway/ApprovalRecommendation;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", + "mutator": "org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator", + "description": "removed call to kotlin/ResultKt::throwOnFailure", + "pitBlock": 11, + "pitIndex": 92, + "bytecodePc": 204, + "instruction": "invokestatic kotlin/ResultKt.throwOnFailure", + "suspensionRole": "resumed-path unwrap of the call to resolveGovernedIdentity(workflowRunId) (line 82)", + "originalState": "NO_COVERAGE", + "finalState": "UNREACHABLE", + "finalClassification": "UNREACHABLE", + "reachabilityEvidence": [ + "Each mutated instruction lies on the suspension protocol of one specific call: resolveGovernedSuspension() at source line 145 in suspendToolExecution, and resolveGovernedIdentity(workflowRunId) at source line 82 in requestApproval.", + "Both callees are declared suspend, but neither body contains a suspension point: resolveGovernedSuspension has 50 instructions with 0 getCOROUTINE_SUSPENDED loads and 0 if_acmpne; resolveGovernedIdentity-jFE5hGw has 32 instructions with 0 getCOROUTINE_SUSPENDED and 0 if_acmpne, invoking only Continuation.getContext, GovernedRunScope$Key accessors, GovernedRunIdentity/RunId getters, Intrinsics.areEqual, makeConcatWithConstants and an exception constructor.", + "Therefore in each caller the sentinel test is always false, so the COROUTINE_SUSPENDED exit (pc163, pc164) cannot execute; and the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path throwOnFailure (pc194, pc204) cannot execute." + ], + "testAdded": null, + "killingTest": null, + "evidenceProvenance": "javap at the G5d base (classes identical to the measured campaign); PIT row (line/block/index) from the candidate campaign 7acbd868; pitBlock bracketing against in-method calibration points from the committed G5b and G5c manifests" + }, + { + "identity": "e52f1c1f657020d5f63b247fbc7fd432c886258cf5059a5e2a9a5fdc4981bc32", + "className": "dev.tramai.engine.approval.DefaultApprovalGateway", + "method": "requestApproval-Atj0Sqo(Ljava/lang/String;Ldev/tramai/core/approval/gateway/ApprovalRecommendation;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", + "mutator": "org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator", + "description": "replaced return value with null for DefaultApprovalGateway::requestApproval-Atj0Sqo", + "pitBlock": 10, + "pitIndex": 72, + "bytecodePc": 164, + "instruction": "areturn (aload 12 \u2014 the COROUTINE_SUSPENDED exit)", + "suspensionRole": "suspend exit of the call to resolveGovernedIdentity(workflowRunId) (line 82)", + "originalState": "NO_COVERAGE", + "finalState": "UNREACHABLE", + "finalClassification": "UNREACHABLE", + "reachabilityEvidence": [ + "Each mutated instruction lies on the suspension protocol of one specific call: resolveGovernedSuspension() at source line 145 in suspendToolExecution, and resolveGovernedIdentity(workflowRunId) at source line 82 in requestApproval.", + "Both callees are declared suspend, but neither body contains a suspension point: resolveGovernedSuspension has 50 instructions with 0 getCOROUTINE_SUSPENDED loads and 0 if_acmpne; resolveGovernedIdentity-jFE5hGw has 32 instructions with 0 getCOROUTINE_SUSPENDED and 0 if_acmpne, invoking only Continuation.getContext, GovernedRunScope$Key accessors, GovernedRunIdentity/RunId getters, Intrinsics.areEqual, makeConcatWithConstants and an exception constructor.", + "Therefore in each caller the sentinel test is always false, so the COROUTINE_SUSPENDED exit (pc163, pc164) cannot execute; and the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path throwOnFailure (pc194, pc204) cannot execute." + ], + "testAdded": null, + "killingTest": null, + "evidenceProvenance": "javap at the G5d base (classes identical to the measured campaign); PIT row (line/block/index) from the candidate campaign 7acbd868; pitBlock bracketing against in-method calibration points from the committed G5b and G5c manifests" + } + ], + "regressionCampaign": { + "campaign": { + "throwaway": "56364ae3970dec4b6edd7e1507b98a9f0d2fc5f1", + "base": "cd46f176b20ef7e0e0b2b0e251569214dfc90619", + "buildResult": "BUILD SUCCESSFUL", + "durationSeconds": 1033, + "population": 918, + "statuses": { + "KILLED": 662, + "NO_COVERAGE": 62, + "SURVIVED": 132, + "TIMED_OUT": 62 + }, + "configDiff": "family-list narrowing only: 53 deletions, approval block byte-identical" + }, + "reference": { + "campaign": "G5c candidate 7acbd868", + "note": "identical production+test content to the G5d base" + }, + "sharedIdentities": 918, + "g5dOnly": 0, + "referenceOnly": 0, + "statusMovements": 0, + "previouslyKilledRegressions": 0, + "newTimeouts": 0, + "cohort": { + "allFourPresent": true, + "allFourNoCoverage": true, + "widening": false + } + } +} \ No newline at end of file diff --git a/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-REACHABILITY.md b/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-REACHABILITY.md new file mode 100644 index 000000000..11c8b0723 --- /dev/null +++ b/docs/roadmap/0.7.0/TASK-0.7.1g1G5d-NO-COVERAGE-REACHABILITY.md @@ -0,0 +1,122 @@ +# TASK-0.7.1g1G5d — Exact NO_COVERAGE reachability closure + +Parent: **TASK-0.7.1g1G5**. Scope: exactly the **four frozen NO_COVERAGE identities**. No widening, no substitution, no production change. +Base: **`cd46f176b20ef7e0e0b2b0e251569214dfc90619`** — the squash merge of #463, branched directly from it, clean tree. + +**G5D COMPLETE — FINAL G5 NO_COVERAGE COHORT CLOSED.** (subject to the regression campaign recorded below) + +## Baseline and start gate + +| condition | result | +| --- | --- | +| HEAD == `cd46f176b20e…` | yes, worktree branched directly from that SHA | +| clean working tree | yes | +| four canonical identities exist | 4/4 | +| all four still NO_COVERAGE | 4/4, `numberOfTestsRun = 0` | +| baseline-only target / substituted target | none | +| source-coordinate approximation as the same mutant | none | + +The authoritative view is the G5c candidate campaign (`7acbd868`), whose production+test content is identical to the merged `cd46f176` (the merge squashed exactly that test plus docs). In it all four are present and NO_COVERAGE. + +**Mutator naming:** the task brief labels the two "NRV" identities `NonReturningVoidMethodCall`. The frozen manifest records `org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator`, description *"replaced return value with null"*. The frozen identities are authoritative and unchanged — a label discrepancy, not an identity discrepancy. + +## Identity table + +| identity | owner | mutator | PIT block/index | PC | mutated instruction | state | +| --- | --- | --- | --- | --- | --- | --- | +| `564517b2fdab` | ApprovalSuspensionCoordinator.suspendToolExecution | VoidMethodCallMutator | 13/96 | **pc194** | invokestatic kotlin/ResultKt.throwOnFailure | NO_COVERAGE → **UNREACHABLE** | +| `66c311cf4f0a` | ApprovalSuspensionCoordinator.suspendToolExecution | NullReturnValsMutator | 12/78 | **pc163** | areturn (aload 20 — the COROUTINE_SUSPENDED exit) | NO_COVERAGE → **UNREACHABLE** | +| `5a7edac3a982` | DefaultApprovalGateway.requestApproval-Atj0Sqo | VoidMethodCallMutator | 11/92 | **pc204** | invokestatic kotlin/ResultKt.throwOnFailure | NO_COVERAGE → **UNREACHABLE** | +| `e52f1c1f6570` | DefaultApprovalGateway.requestApproval-Atj0Sqo | NullReturnValsMutator | 10/72 | **pc164** | areturn (aload 12 — the COROUTINE_SUSPENDED exit) | NO_COVERAGE → **UNREACHABLE** | + +## Phase A — bytecode-exact mapping + +PIT never reports bytecode offsets, and its block/index counter includes ASM node kinds that `javap` does not expose — a label-and-line-count reconstruction of that counter matched only 4 of 36 calibration identities, so it was abandoned rather than tuned until it fit. + +Instead each identity is bracketed. `pitBlock` is **monotone in pc within a method** (verified true for both methods), and each method carries in-method calibration points from the committed G5b/G5c manifests with both a known pc and known PIT coordinates: + +- `suspendToolExecution`: (158, 11, 74) · (287, 31, 168) · (362, 35, 206) · (1072, 109, 668) · (1420, 132, 853) · (1785, 157, 1067) +- `requestApproval-Atj0Sqo`: (159, 9, 68) · (304, 23, 160) · (457, 35, 243) · (618, 46, 328) · (799, 60, 426) + +Each target's block therefore brackets a pc window, and exactly one candidate instruction of the mutated kind lies inside: + +| identity | window | candidates in window | selected | +| --- | --- | --- | --- | +| `564517b2fdab` (block 13) | pc158 … pc287 | `throwOnFailure` at 194 | **pc194** | +| `66c311cf4f0a` (block 12) | pc158 … pc287 | `areturn` at 163 | **pc163** | +| `5a7edac3a982` (block 11) | pc159 … pc304 | `throwOnFailure` at 204 | **pc204** | +| `e52f1c1f6570` (block 10) | pc159 … pc304 | `areturn` at 164 | **pc164** | + +Both `areturn` sites are preceded by a load of a local holding `COROUTINE_SUSPENDED` — they are the suspension exits; both `throwOnFailure` sites are the resumed-path unwraps of the same call, one block later. The mapping is additional to, and independent of, the source line, which is useless here: **line 142 is the function header of `suspendToolExecution` and line 73 the header of `requestApproval`**, so every state-machine instruction inherits it. + +## Reachability evidence — all four UNREACHABLE + +Each mutated instruction is on the suspension protocol of one specific call: `resolveGovernedSuspension()` (source line 145) in `suspendToolExecution`, and `resolveGovernedIdentity(workflowRunId)` (source line 82) in `requestApproval`. + +**Neither callee can suspend.** + +- `resolveGovernedSuspension`: 50 instructions, **0 `getCOROUTINE_SUSPENDED` loads, 0 `if_acmpne`** — no sentinel comparison at all. +- `resolveGovernedIdentity-jFE5hGw`: 32 instructions, **0 `getCOROUTINE_SUSPENDED`, 0 `if_acmpne`**; its invokes are only `Continuation.getContext`, `GovernedRunScope$Key` accessors, `GovernedRunIdentity`/`RunId` getters, `Intrinsics.areEqual`, `makeConcatWithConstants` and an exception constructor. +- `GovernedRunScope.resolve(context)` is an ordinary **non-suspend** function, and `currentCoroutineContext()`/`Continuation.getContext` do not suspend. + +A suspend function can return `COROUTINE_SUSPENDED` only through the sentinel comparison emitted after a call. With no such comparison and no suspending callee, both resolvers always return their value directly. Therefore: + +1. in each caller the sentinel test is always false, so the `COROUTINE_SUSPENDED` exit (pc163, pc164) **cannot execute** — the NullReturnVals identity; +2. the resumed continuation for that call can only be constructed by a real suspension at that call, so the resumed-path `throwOnFailure` (pc194, pc204) **cannot execute** — the VoidMethodCall identity; +3. nothing else reaches them: **no branch or switch entry in either method targets pc194 or pc204**. + +That is control-flow dominance plus callee analysis, not "I could not find a test". No legal production execution reaches any of the four. + +**Why not TOOLING_LIMITATION:** there is no independent evidence that the instruction executes while PIT fails to attribute coverage. The instructions cannot execute at all. +**Why not EQUIVALENT:** equivalence answers a different question, and these mutants never cross the reachability boundary. It is neither claimed nor needed. + +## Test evidence + +**No tests were added, and that is the correct outcome.** Tests are permitted only for identities proven REACHABLE. Making these instructions execute would require either changing production semantics (forbidden) or fabricating a coroutine state the runtime cannot produce. A test whose only purpose would be to move PIT's coverage counter is exactly what this task forbids. + +## Phase E — pair analysis + +| pair | same compiler-generated construct | same instruction | one dominates the other | +| --- | --- | --- | --- | +| `564517b2fdab` / `66c311cf4f0a` (`suspendToolExecution`) | **YES** — block 12 is the `COROUTINE_SUSPENDED` exit, block 13 the resumed-path `throwOnFailure`, one block apart | NO | NO | +| `5a7edac3a982` / `e52f1c1f6570` (`requestApproval-Atj0Sqo`) | **YES** — block 10 the exit, block 11 the resumed unwrap | NO | NO | + +Both pairs attach to a suspend-typed resolver with no suspension point, so they share one root cause across both methods. Whether one legitimate test would cover both is moot: neither member is reachable. Block/index adjacency was not treated as evidence of equivalence. + +## Final classification + +| state | count | +| --- | --- | +| KILLED | 0 | +| EQUIVALENT | 0 | +| **UNREACHABLE** | **4** | +| TOOLING_LIMITATION | 0 | +| UNDETERMINED | **0** | + +Parent accounting: 52 = 36 (G5b TOOLING_LIMITATION) + 12 (G5c: 1 KILLED, 11 EQUIVALENT) + 4 (G5d UNREACHABLE). **G5 remainder: 0.** + +## Diff scope + +Tests: none. Production: none. Documentation: this report and the four-identity manifest. The measurement narrowing is evidence machinery, never committed. + +## Regression gate — PASSED + +Identity-exact campaign from a fresh worktree at `cd46f176b20ef7e0e0b2b0e251569214dfc90619`, throwaway `56364ae3970dec4b6edd7e1507b98a9f0d2fc5f1` (family-list narrowing only: 53 deletions, `approval` block byte-identical), BUILD SUCCESSFUL in 17m13s, `measuredCommit` equal to the throwaway commit. + +| requirement | result | +| --- | --- | +| population | 918 (662 KILLED / 132 SURVIVED / 62 NO_COVERAGE / 62 TIMED_OUT) | +| 4/4 frozen identities accounted for | yes — all four present, all four NO_COVERAGE | +| identity loss | 0 | +| identity gain / substitution | 0 | +| shared identities vs the reference campaign | 918 / 918 | +| status movements | 0 | +| new timeouts | 0 | +| regressions of previously KILLED identities | 0 | +| widening beyond the four-target cohort | none (population size unchanged) | + +The reference is the G5c candidate campaign (`7acbd868`), whose production+test content is identical to this base; the two campaigns agree exactly — identity for identity, status for status. + +## Limits + +`UNREACHABLE` here rests on the callees being unable to suspend (no sentinel comparison, no suspending callee) plus the absence of any other branch into the resumed block. It is a statement about this compiled artifact at this base: if either resolver ever gains a suspension point — or if a call site acquires a genuine suspension — these instructions become live and these identities must be re-adjudicated rather than inherited.