# D2 integrated into the field driver — receipt

**Date:** 2026-09-13. **Author:** hertz (rig owner). **Gater:** doyle.
**Base:** frozen r10 `staged-r10-queue-guard.sh` sha256
`a78f4ba6ed5491ccb38d26f8a3fe4f1a7a9f23296d85a133511b1bf9396d1fbf` — re-verified here with
`sha256sum -c R10-FROZEN.sha256` (12/12 OK). **NOT v9** (`a9510e1e`), which predates the accepted
binder-path, classifier, cleanup-exit and queue-guard repairs.
**Contract:** `docs/297-OUT-OF-BAND-CAPTURE-PLAN.md` @ `687ddd69`.
**Authorization used:** source edits and harmless controls only. **No host query, no rule creation,
no elevation, no build, no field execution.** Two of the controls invoked real `powershell.exe`
against throwaway probe scripts that read nothing; everything else is stubs and fixtures.

---

## 1. Deliverables and their pins

| artifact | sha256 |
| --- | --- |
| `fp-driver-d2.sh` (**the subject**, current) | `f7b7773f6988768421fb4a4f19eeb6a6e12faec6136e7c1cad3032f0c1e2fde0` |
| `fp-driver-d2.diff` (exact diff of the CURRENT driver against r10, regenerated) | `cddcd197e687e7039bdf1e1fcf120b3f2fa9c3149f6246fab4a2512e090cdcab` |
| `fp-driver-d2-81dc4fe8-to-f7b7773f.diff` (the timestamp repair, focused) | `3340f3b6973c94cfa4bee79d5fd3e999d8252d091ee86922ba1902becdc429be` |
| `history/fp-driver-d2-2bd12fc8.sh` (superseded; the subject of Sec. 5) | `2bd12fc8ff333b6c7a49dc3b64c2dd1d3608d7a3f0a6f1b67e44e2ecedd5b1db` |
| `history/fp-driver-d2-81dc4fe8.sh` (superseded) | `81dc4fe8288105ed65998f2b152896f1cd4e068e29f1d3b1defe3ae5ed1c315d` |
| `d2_validate.py` (new instrument) | `b922d4b4084466f1298258c33bcff7c9c30b5bd6dc44af66f971ddede9ef8f85` |
| `rig-d2/assemble.sh` | `1c8e8f6abefe80898973c2738336ae27d0dac4e7d5405948703c81293ff27f11` |
| `rig-d2/make-d2-stubs.sh` (repaired, Sec. 5b) | `ca79593372cd1ddf17027c142cbc8a7d8616c27c88604af79a617c998f06e839` |
| `rig-d2/bin/pwsh` (the GENERATED stub both reruns used) | `e09f829dfc6bb71531f7e683707aa1d5f2dd63ceb05feb1390b6e2a86667e826` |
| `rig-d2/run-d2.sh` (R7 arm corrected, Sec. 5b) | `639000288e2b43a6902eb394ce43826eec140db04e491fbdedc39181316e57ce` |
| `rig-d2/mkdoc.py` | `346f967f2c7f0fb8961537a13ae27943e9a895a34017b13c3c0e8798fa58c79f` |
| `rig-d2/all-run.txt` (the full-suite output, driver `2bd12fc8`) | `8008a2c2d38668e410ed803d88a71860052dc449d03d86c366da4576605f209a` |
| `rig-d2/residual-run.txt` (the focused run, Sec. 5a) | `19903f7a535141fdbffc30a8b3a25dd65c99fc1d82bc40d933c9c1fc5d6aa22a` |
| `rig-d2/r7-run.txt` (R7 corrected rerun) | `13e8332203c8a8b2f033d9e98d3ef7961b997df313d27b1add053496864395b3` |
| `rig-d2/r9-rerun.txt` (R9 rerun on the repaired fixture) | `fd0ad1e4d80b32d7776d8b7dca2b7b376680bb32e53cc6b51d512a6ced8e0f5d` |
| `rig-d2/r10-rerun.txt` (R10 rerun on the repaired fixture) | `7d75004dfc09b42e3cca3cd34bb21ba03e21842e2fe6429d995cdd69d3e5f7df` |
| `rig-d2/pin.sh` (manifest extended to the lineage and the reruns) | `d120d2ec7868073b105c30e4dcaa47332a3bc54a533554f74b0e59ead5ce8fce` |
| `receipt-psform-control.txt` (the measured PowerShell controls) | `6ca5fa459c12c182ab3f96ece3735d40b2752508365a54974be12df77e1ce808` |
| `INVALIDATED-RUNS.md` (two contaminated attempts, recorded as such) | `25d503c46f88b383097e2d29546718785e07abb6adae94a976d22bbdf0c913c1` |

`D2-INTEGRATION-MANIFEST.sha256` verifies them together. The driver is **reproducible from its
base**: `bash rig-d2/assemble.sh` copies r10's retained blocks by line range, inserts the D2 parts,
and must reproduce the pinned hash byte for byte.

## 2. What changed, and what deliberately did not

**Removed — the build and timing WORKLOAD, each with its reason:** keygen / pin / rollout
`--build-current` / mark-applied and the `subject_boundary` pair that bracketed the producer (D2
reuses r10's executable, so there is no new artifact to sign, stage or agree with); the three-way
provenance check (replaced by an exact executable-hash gate); pool claim/release (nothing runs
cargo); `capacity_gate` (it gates PRODUCERS, and there is no producer); `cpubracket.ps1`, `trial()`,
both arms, `expect_pair`, `completion_verdict` and `populated_timing_report` (no timed workload).

**Retained, because none of it is workload:** the **status-filtered CI axis** and the
**ancestry-authenticated box census**, at preflight AND again immediately before the elevated leg
(this box is shared with a self-hosted runner, and those readings are point-in-time); the **5470
guard in full** (the run mutates the host firewall, so preserving the production port is a property
of the mutation); the binder-path canonical comparison; the classifier `face_report`; the r8
cleanup-exit handler; exactly-once state-aware cleanup; signal handling; the handoff mechanics.

**Added:** `t1` riding the seq-001 request (the only elevated read the design has, one nonce being
one execution); `t2` at the setup's outcome beside D1 and before any teardown; `t3` immediately
before the teardown request, with the manifest hashed first; the **two separate budgets**; **bounded
captures** with `CAPTURE_TIMEOUT` as its own outcome; **residual-identity reporting** with its own
positive control; and a **run ledger** carrying the four exits separately and the two verdicts.

**Two in-place corrections to retained text**, both visible in the diff and both by REPLACEMENT
rather than annotation: the analyzer exemption's rationale (r10 justified it by "what the per-trial
CPU bracket measures", and there is no bracket here), and a note at `handoff_await trial`, whose
context name is kept verbatim because renaming it would edit a function this change has no reason
to touch.

## 3. The executable-hash gate (doyle, 2026-09-13)

S1 measures `$EXE` and refuses unless it equals
`72d309011415b419aabfdb0b4065df1183bfd0069a9f95b5779da62e43349b10`. **A clean source tree does not
identify reused executable bytes**, so S0e's subject check and this one are both required and
neither substitutes for the other. The same hash is written into the seq-001 request with an
instruction to refuse the leg if the file does not carry it, because liam runs that command in a leg
this driver cannot observe.

## 4. The measured PowerShell invocation form

Measured directly against real `powershell.exe` on this box, against a three-line throwaway probe
that reads nothing. **Scoped to exactly this invocation shape** — a `[string[]]` parameter reached
from bash through `powershell.exe` — and NOT a claim that `-File` is broken in general:

| form | received |
| --- | --- |
| `-File <script> -RuleName a,b` | **ONE element `"a,b"`** — a name that cannot exist. The capture would have recorded `NO_RULE` for both halves of a pair that is present. |
| `-File <script> -RuleName a b` | binding failure, "A positional parameter cannot be found", exit 1 |
| `-Command "& '<script>' -RuleName @('a','b'); exit $LASTEXITCODE"` | **TWO elements** |
| the same `-Command` form with an **msys-style path** (`/c/Users/...`) | `CommandNotFoundException` on stderr and **exit 0** — a clean zero from a command that never ran |

That last arm is why the driver never treats a capture's exit 0 as proof of a capture: it asserts
the DOCUMENT exists and reports `CLAIMED_OK_WITHOUT_DOCUMENT` when a zero arrives without one.

And the trailing propagation, measured the same way: with `exit $LASTEXITCODE` a script exit of 0/2/3
arrived as 0/2/3; **without it, a script exit of 2 arrived as 1** — laundering the one exit that is
this instrument's entire failure report. The driver uses the third form, and the seq-001 request
spells it out for the same reason.

## 5. The actual-sequence control, against driver `2bd12fc8`

**This table measures driver `2bd12fc8` and nothing else** (doyle, 2026-09-13). That driver has
since been superseded twice -- `81dc4fe8`, then `f7b7773f` -- and the arms changed with it: case
J alone went from 7 assertions to 12 when residual tracking was reworked onto run-bound identity.
The 92/0 below stays true of the bytes it ran against and is **historical evidence, not a suite
result for the current candidate**. The candidate's own measured results are Sec. 5a and 5b. A
full-suite rerun on `f7b7773f` is **held by doyle** pending his source review.

One superseded driver in that lineage, `f42d333b`, was not preserved at the time -- and **that gap
is now CLOSED by bytes**, on doyle's route (2026-09-13): every case directory holds the driver copy
the case executed plus the config-only delta the runner recorded beside it, and reversing that
recorded substitution reproduces the subject. `f42d333b`'s 7-arm 44/0 therefore rests on
**reproducible bytes**, not on a filename. The reconstruction is preserved as
`history/fp-driver-d2-f42d333b.sh` under an explicitly POST-RUN attestation
(`history/RECOVERED-SUBJECTS.md`); nothing was backfilled into any original log. See Sec. 5c for the
method, its positive controls, and the two traps that produced confident wrong answers first.

Twelve scenarios through **the real driver** — no wrapper, no parallel orchestrator — plus the
validator's own arms. Each case edits only the config block (`SP`, `EXE`, `EXE_SHA`,
`EXP_BUDGET_S`) and the runner **refuses** if the diff touches anything else, so no case can quietly
patch logic to make itself pass. The operator loop stands in for liam and **follows the t1 rider
exactly as the request writes it** — that the rider is machine-followable is part of what this
exercises.

| case | what it exercises | driver exit | pass | fail |
| --- | --- | --- | --- | --- |
| **A** | complete run: setup accepted with reconciled/exit-0/pair-present, t1 run in the elevated leg | 0 | 16 | 0 |
| **B** | t1 omitted from the elevated leg -- a labelled evidence gap, not a pass | 0 | 6 | 0 |
| **C** | teardown answered but NOT verified | 6 | 6 | 0 |
| **D** | the capture itself fails to write (native exit 2) | 0 | 6 | 0 |
| **E** | the experimental deadline expires -- activity ends, cleanup does not | 7 | 5 | 0 |
| **F** | RED: the executable hash does not match the pinned bytes | 1 | 5 | 0 |
| **G** | RED: a stale receipt carrying another run's nonce | 1 | 6 | 0 |
| **H1** | DENIAL ONLY: an errors-filled DENIED document, everything else clean | 0 | 8 | 0 |
| **H2** | STALE ONLY: a document carrying another run's id, no denial anywhere | 0 | 4 | 0 |
| **I** | the capture process hangs | 0 | 8 | 0 |
| **J** | rules removed and verified, but a residual process is still alive | 6 | 7 | 0 |
| **L** | RED: the setup is refused -- the acceptance gate must not accept it | 0 | 6 | 0 |
| **K** | the validator's own arms, against fixtures | n/a | 9 | 0 |
| | **total** | | **92** | **0** |

**92 assertions, zero failures**, on the frozen bytes named above. Every RED case (F, G, L, and
the validator's missing/unreadable arms) failed as required rather than passing quietly, and each
case's DRIVER EXIT is reported beside its tally because the exit is part of the result: 6 where a
cleanup could not be verified, 7 where the experimental deadline ended activity, 1 where the run
refused to start on a wrong executable or a stale receipt, 0 where the sequence ran and the ledger
was written.


## 5a. The focused residual control, against driver `f7b7773f` -- 57 pass / 3 fail

Ten arms -- the residual-cleanup cases only -- through the **current** driver
`f7b7773f6988768421fb4a4f19eeb6a6e12faec6136e7c1cad3032f0c1e2fde0`, frozen for the whole run and
re-hashed unchanged afterwards. Same runner, same config-only diff refusal (**6 lines, 0 outside
config** on every arm), and every count below read out of the run's own output by
`rig-d2/fill_results.py` rather than typed in.

| case | what it exercises | driver exit | pass | fail |
| --- | --- | --- | --- | --- |
| **J** | RESIDUAL: supervisor AND brain live, r10 command lines, no home string | 6 | 12 | 0 |
| **R2** | RESIDUAL: supervisor gone, ORPHANED BRAIN surviving | 6 | 7 | 0 |
| **R3** | RESIDUAL: both tracked identities measured GONE -- VERIFIED / CLEAR / exit 0 | 0 | 5 | 0 |
| **R4** | RESIDUAL: identity unreadable at cleanup -- UNREADABLE, never CLEAR | 6 | 6 | 0 |
| **R5** | RESIDUAL: pid reused by a stranger -- ours is GONE, not residue; VERIFIED / CLEAR / exit 0 by the OTHER route | 0 | 4 | 0 |
| **R6** | RESIDUAL: same pid and instant, differing exe/cmd read -- LIVE-FIELD-MISMATCH, not reuse | 6 | 5 | 0 |
| **R7** | RESIDUAL: creation time unreadable at re-query -- establishes neither reuse nor survival | 6 | 4 | 1 |
| **R8** | RESIDUAL: PARTIAL capture, recorded pid absent, brain never recorded and alive -- UNREADABLE | 6 | 7 | 0 |
| **R9** | RESIDUAL: an empty creation timestamp is not a timestamp -- INCOMPLETE, never comparable | 6 | 4 | 0 |
| **R10** | RESIDUAL: an impossible date (30 February) passes every shape test -- INCOMPLETE | 6 | 3 | 2 |
| | **total** | | **57** | **3** |

**This 57/3 is preserved as run, with its three failures classified** (doyle, 2026-09-13). All
three are RIG defects; none is a driver defect:

- **R7 (4/1) -- a test pinned to prose.** The arm matched `reason=creation-time-unreadable`, a
  spelling the driver stopped using at `81dc4fe8`. It reported a RENAME as a defect. The driver's
  behaviour on that arm was correct throughout.
- **R9 (4/0) -- passing, on a CONTAMINATED fixture.** Its capture carried swallowed generator
  text and three `command not found` lines. It still refused for its own reason -- checked, not
  assumed: `INCOMPLETE (pid 4001 has an unreadable creation timestamp [])` -- but the green was
  not clean evidence.
- **R10 (3/2) -- a VOID arm, not a red.** Its fixture never injected the impossible date; the arm
  was handed an ordinary both-live scenario and the driver answered it correctly
  (`RESIDUE_SUMMARY live=2 gone=0 unreadable=0`, `residual_state=LIVE`, exit 6). The arm never
  reached its subject, so it measured nothing about the 30-February repair.

**Both `R3` and `R5` reach `CLEANUP=VERIFIED` / `residual_state=CLEAR` / exit 0, by different
routes** -- R3 because both tracked identities are measured GONE, R5 because the pid answers and
the identity does not match, so ours is gone and a stranger is not manufactured into residue. An
earlier statement of mine that R3 was the only arm reaching VERIFIED was wrong and is corrected
here rather than annotated; `rig-d2/fill_results.py` carried the same wrong wording in R3's
description and was corrected in the same pass.

## 5b. The three corrected arms, rerun against the SAME unchanged driver

Two rig repairs, no driver edit -- `fp-driver-d2.sh` was re-hashed before and after each rerun and
is still `f7b7773f...`.

1. **R7's reason-wording assertion was REMOVED and deliberately NOT re-pinned to the new prose**
   (doyle's ruling): wording is the driver's to change, and an arm pinned to it reports a rename
   as a defect. R7 now asserts the STATE and the verdict -- both attributed rows `UNREADABLE`,
   `RESIDUE_SUMMARY live=0 gone=0 unreadable=2` so neither is counted gone nor live, no
   `GONE-PID-REUSED` claim, `residual_state=UNREADABLE`, `CLEANUP=PENDING`, driver exit 6.
2. **`rig-d2/make-d2-stubs.sh` was malformed.** In the `badstamp` arm a `printf` format string was
   never closed before its newline, so the entire `impossible)` arm was swallowed as literal text
   INSIDE that string. `impossible)` was therefore not a case arm at all: `FP_IDENT_MODE=impossible`
   matched nothing, fell past the `esac`, and landed on the default live path -- which is exactly
   what R10 was handed. The swallowed text was also EXECUTED as shell in R9's capture. This is the
   same escape-layer class as defect 6 below.

Before the reruns the regenerated stub was **exercised directly**, as doyle required, rather than
only through the driver (stub `e09f829dfc6bb71531f7e683707aa1d5f2dd63ceb05feb1390b6e2a86667e826`,
byte-identical to the one both reruns then used):

| `FP_IDENT_MODE` | native exit | emitted identity record | shell errors |
| --- | --- | --- | --- |
| `badstamp` | 0 | `IDENT role=supervisor pid=4001 created= exe=[...] cmd=[...]` then `IDENT_PROBE=OK tracked=1` | none |
| `impossible` | 0 | `IDENT role=supervisor pid=4001 created=2026-02-30T00:00:00.000Z ...` then `IDENT_PROBE=OK tracked=1` | none |

| arm | driver exit | pass | fail | the driver's own stated reason |
| --- | --- | --- | --- | --- |
| **R7** | 6 | 7 | 0 | both rows `state=UNREADABLE`, `live=0 gone=0 unreadable=2`, `CLEANUP=PENDING` |
| **R9** | 6 | 4 | 0 | `INCOMPLETE (pid 4001 has an unreadable creation timestamp [])` |
| **R10** | 6 | 5 | 0 | `INCOMPLETE (pid 4001 has an unreadable creation timestamp [2026-02-30T00:00:00.000Z])` |

R10's refusal **names the impossible value it rejected**, and R9's and R10's captures contain
**zero** `command not found` lines. That is the first measurement in which the 30-February repair
is exercised by an arm rather than by a standalone predicate test.

## 5c. The integration-control pass -- duration baseline recorded BEFORE dispatch

doyle authorized one integration-control pass on frozen `f7b7773f` covering the **non-residual**
scenarios and the validator's own arms, and required the measured duration of comparable prior runs
to be recorded **before** dispatch rather than reconstructed afterwards. Each figure below is the
run root's own UTC stamp subtracted from the output file's completion time -- the runs' own record,
not an estimate:

| prior run | driver | tallies | duration | per tally |
| --- | --- | --- | --- | --- |
| `all-run-1541dac6.txt` (superseded full suite) | `1541dac6` (see below) | 12 | 624 s | 52 s |
| `all-run.txt` (full suite, Sec. 5) | `2bd12fc8` | 13 | 644 s | 49 s |
| `residual-run.txt` (focused, Sec. 5a) | `f7b7773f` | 10 | 716 s | 71 s |
| `r8-run.txt` | `81dc4fe8` | 1 | 86 s | 86 s |
| `r7-run.txt` / `r9-rerun.txt` / `r10-rerun.txt` (Sec. 5b) | `f7b7773f` | 1 each | 81 / 84 / 75 s | 80 s mean |

**The first row's attribution was wrong when this table was written, and the correction matters more
than the error** (doyle caught it, 2026-09-13). I bound `all-run-1541dac6.txt` to `2bd12fc8`; it is
the run of `1541dac6`, a different driver. Trying to bind it by its recorded subject hash surfaced
the real defect: **no run output records the subject hash it ran against.** Searching every preserved
run output for a 64-hex string returns nothing -- not `all-run.txt`, not `residual-run.txt`, not the
single-arm reruns. The only thing tying a run to a driver was a filename label I typed.

**The binding was recoverable anyway, and every run now has one made of bytes.** On doyle's route:
each case directory holds the driver copy the case executed (`fp-driver-d2-<CASE>.sh`) and the
config-only delta recorded beside it (`config-only.diff`); the runner substitutes only four config
lines and refuses the case otherwise, so reversing that recorded substitution reproduces the subject
exactly. **The method carries its own positive controls** -- three runs whose recovered bytes must
equal a driver already on disk:

| control | recovered bytes identical to the driver on disk |
| --- | --- |
| `2bd12fc8` | yes |
| `81dc4fe8` | yes |
| `f7b7773f` | yes |

Three of three reproduce byte-for-byte, and within each run every case agrees on one subject, so no
binding below rests on a single sample:

| run root | subject, recovered | cases agreeing |
| --- | --- | --- |
| `20260913T012103Z` | `74a9ce79` | 11 |
| `20260913T013228Z` | `bd731161` | 9 |
| `20260913T014045Z` | `1541dac6` -- doyle's correction, confirmed by bytes | 11 |
| `20260913T015149Z` | `2bd12fc8` | 1 (H1) |
| `20260913T015258Z` | `2bd12fc8` -- `all-run.txt`, Sec. 5 | 12 |
| `20260913T021349Z` | `1ac97e22` | 5 |
| `20260913T022053Z` | `f42d333b` -- the 44/0 run | 7 |
| `20260913T023425Z` | `81dc4fe8` -- `r8-run.txt` | 1 |
| `20260913T023628Z` | `f7b7773f` -- the focused run, Sec. 5a | 10 |
| `20260913T025045Z` / `025323Z` / `025447Z` | `f7b7773f` -- the reruns, Sec. 5b | 1 each |

**Both reproducibility gaps are therefore CLOSED.** `1541dac6` and `f42d333b` -- with `74a9ce79`,
`bd731161` and `1ac97e22` -- are preserved in `history/` under the hash their own bytes produce, each
declared a POST-RUN RECONSTRUCTION in `history/RECOVERED-SUBJECTS.md`. Nothing was backfilled into
any original log, and none of those files existed when its run executed.

**Two traps produced confident WRONG answers before this was right**, and both are recorded because
the next person will hit them. Reading the artifacts as TEXT translates line endings and shifts every
hash by a constant -- the first attempt returned eight self-consistent hashes that matched nothing,
which reads exactly like a successful recovery of unknown drivers. And the driver's own lines are
CRLF while the lines `sed -b` substituted are LF, so the delta cannot be reversed by searching for
the replacement text; it is reversed by the line numbers in diff's own hunk headers, which are exact
regardless of terminator.

**Still owed, authorized by doyle for after the running pass exits:** have the runner stamp
`SUBJECT_SHA256=<hash>` into its own output so a future run binds itself without this recovery. No
rerun is to be made merely to add that header.

The residual arms cost more per tally (71 s) than the full suite's mixed average (49 s) because each
drives a process model through capture and re-query. This pass runs **12 tallies** -- A, B, C, D, E,
F, G, H1, H2, I, L and the validator arms K -- so the comparable prediction is **600-900 s**,
dispatched under a 1800 s bound. The ten residual arms are deliberately NOT repeated: they are
already measured on this same driver, their receipts stand on their own, and repeating them would
buy one aggregate tally and nothing else.

The runner gained a `core` mode for exactly this set; it takes a **fresh isolated output root**
(`rig-d2/work/<UTC stamp>-<pid>/`) like every other invocation, so no earlier control can reach this
run's evidence.

## 5d. The integration-control pass -- 85 pass / 0 fail, and full suite coverage on `f7b7773f`

Dispatched 03:03:21Z, ended 03:15:52Z: **751 s**, against the 600-900 s predicted in Sec. 5c before
any result existed. Driver hashed `f7b7773f...fde0` immediately before dispatch and again after it
ended, unchanged. Fresh isolated output root `20260913T030322Z-3754`.

| case | what it exercises | driver exit | pass | fail |
| --- | --- | --- | --- | --- |
| **A** | complete run: setup accepted with reconciled/exit-0/pair-present, t1 run in the elevated leg | 0 | 16 | 0 |
| **B** | t1 omitted from the elevated leg -- a labelled evidence gap, not a pass | 0 | 6 | 0 |
| **C** | teardown answered but NOT verified | 6 | 6 | 0 |
| **D** | the capture itself fails to write (native exit 2) | 0 | 6 | 0 |
| **E** | the experimental deadline expires -- activity ends, cleanup does not | 7 | 5 | 0 |
| **F** | RED: the executable hash does not match the pinned bytes | 1 | 5 | 0 |
| **G** | RED: a stale receipt carrying another run's nonce | 1 | 6 | 0 |
| **H1** | DENIAL ONLY: an errors-filled DENIED document, everything else clean | 0 | 8 | 0 |
| **H2** | STALE ONLY: a document carrying another run's id, no denial anywhere | 0 | 4 | 0 |
| **I** | the capture process hangs | 0 | 8 | 0 |
| **L** | RED: the setup is refused -- the acceptance gate must not accept it | 6 | 6 | 0 |
| **K** | the validator's own arms, against fixtures | n/a | 9 | 0 |
| | **total** | | **85** | **0** |

**Every arm is identical to the same arm on `2bd12fc8`** -- not merely green, but the same count:
A 16, B 6, C 6, D 6, E 5, F 5, G 6, H1 8, H2 4, I 8, L 6, K 9. Twelve of twelve identical, zero
changed, and 85 + J's 7 reproduces the old suite's 92 exactly. The capture-integrity gate and the
calendar parse did not disturb the non-residual behaviour.

### Coverage: every scenario now measured on the current driver

Assembled from four runs rather than one aggregate, per doyle's ruling that completed arms are not
re-run merely to obtain a single tally. Every row is bound to its subject **by bytes**, recovered
from that run's own per-case artifacts (Sec. 5c), not by a filename:

| scenarios | driver, recovered from the run's own artifacts | receipt | result |
| --- | --- | --- | --- |
| A B C D E F G H1 H2 I L K | `f7b7773f` | `rig-d2/core-run.txt`, Sec. 5d | 85 / 0 |
| J R2 R3 R4 R5 R6 R8 | `f7b7773f` | `rig-d2/residual-run.txt`, Sec. 5a | 46 / 0 |
| R7 | `f7b7773f` | `rig-d2/r7-run.txt`, Sec. 5b | 7 / 0 |
| R9 | `f7b7773f` | `rig-d2/r9-rerun.txt`, Sec. 5b | 4 / 0 |
| R10 | `f7b7773f` | `rig-d2/r10-rerun.txt`, Sec. 5b | 5 / 0 |
| | | **all 22 scenarios** | **147 / 0** |

The three superseded results are NOT counted above and are not withdrawn either: R7's 4/1, R9's
contaminated 4/0 and R10's void 3/2 stand in Sec. 5a as run, with their classifications.

### A behavioural change the arms do not assert, found by comparing exits

**Case L's driver exit moved from 0 to 6 between `2bd12fc8` and `f7b7773f`**, while its assertion
count stayed 6/0 -- because case L never asserted its exit. The cause is not a regression; it is the
capture-integrity ruling reaching a path no arm was written for:

| | `2bd12fc8` | `f7b7773f` |
| --- | --- | --- |
| `residual_state` | `CLEAR` | `UNREADABLE` |
| cleanup | `CLEANUP=VERIFIED residue=0` | `CLEANUP=PENDING residue=UNMEASURED` |
| driver exit | 0 | 6 |

Case L is the REFUSED setup. **An enforcement refusal is not "nothing ran"** (doyle, 2026-09-13,
correcting an earlier sentence of mine that said exactly that): the setup may already have started a
daemon and written rules before the refusal, so a refused setup is precisely a state where residue is
possible and unmeasured. What is missing is the identity capture, not necessarily the processes. The
old driver nevertheless called the box **CLEAR and VERIFIED on the strength of no measurement
whatsoever** -- a false-clean of precisely the class this whole effort exists to stop. It survived a
92/0 suite, and it was invisible because the arm read only the refusal and never the verdict. The
current driver refuses instead: a missing capture means UNREADABLE, never CLEAR.

**Authorized by doyle and owed:** case L asserts native exit 6, `residual_state=UNREADABLE` and
`CLEANUP=PENDING` whenever the identity capture is missing, so this path is covered by an arm rather
than by someone diffing two tables. Rig-side, no driver change; it also runs as a focused control
against the successor driver.

## 6. Six defects the control caught — four in the driver, two in the rig

1. **A single `local` built a path from an unset variable.** `local point="$1"
   doc="$R/d2-$point.json"` expands every right-hand side before assigning any name in it, so every
   document was looked for at `d2-.json` and all three captures — present on disk — reported
   `NO_DOCUMENT`. **This is r10's own v7 lesson and I re-broke it**; the control caught it in the
   first run.
2. **A helper that logs cannot also return through stdout.** `record` TEES, so
   `D2_T1_VALID=$(d2_validate_at t1)` captured the whole log block ahead of the verdict.
   `d2_validate_at` now sets `VALIDATE_RESULT` and echoes nothing — r10's own `handoff_request`
   precedent, which I had read and then not applied.
3. **r10's setup-acceptance gate cannot pass on the accepted path.** `setup_face=$(face_report ...)`
   has the same shape: `face_report` calls `record`, so the captured value is the log block plus the
   verdict and can never equal `reconciled`. In r10 that makes Arm B's three-condition acceptance
   **unpassable whenever the setup actually reconciles** — the path its stub cases never exercised,
   because the case that reached this line was a refusal expected to fail anyway (setup suppresses
   the failing arm). **`face_report` is left byte-for-byte as r10 wrote it**; the D2 fix is at the
   call site, which reads the verdict from a file and keeps the tee'd copy as evidence.
   **This is a finding about frozen r10 and is reported as one, not silently patched there.**

4. **The refusal control was testing nothing** (rig). My stub printed
   `ActiveStore enforcement is NotConfigurable` — the **pre-repair** string, the exact stale
   predicate r6 fixed — while the driver carries r10's repaired classifier, which greps
   `ActiveStore enforcement codes are`. The driver read `face=none`, which is CORRECT behaviour on
   that input and a dead control on my side. A case that had only asserted "not accepted" would
   have passed on it. The fixture now emits the repaired string, and the case asserts the FACE, not
   merely the refusal.
5. **A budget is not a hang** (rig). Case I first set the experimental budget to 25 s to force a
   bounded capture; the handoff round-trip consumes ~18 s of it, so the budget expired inside the
   setup wait and the driver correctly ended activity into cleanup — **the capture-timeout path was
   never reached**, and the case's two failures said so. That attempt is preserved with exactly that
   label. The recalibrated case runs a 90 s hang under a 45 s budget and, per doyle, accepts
   `CAPTURE_TIMEOUT` **only on positive evidence**: the stub writes a marker carrying its own pid
   before it sleeps and a completion marker only if the sleep RETURNS, so the case asserts the hang
   was entered, never completed, and the hanging pid is gone.

6. **A backreference that reached the file as a control byte, and a combined case that hid it.**
   The per-point query-failure counter was written with a `sed` backreference passed through a
   Python escape, so `` arrived as byte 0x01: the substitution replaced each match with nothing
   and every count read **zero** — a silent zero from a predicate that looks correct. It survived
   one full run because the case that should have caught it ALSO carried a stale document, and the
   contract was refused for that other reason: **a combined case cannot tell you which of its two
   variables did the work.** Per doyle the case is now split — H1 denial only, H2 stale only — and
   the counter is extracted with `awk` (no backreferences at all), verified before assembly against
   a positive control (a real validator output, reading `denied=1`) and a negative one (a clean
   document, reading `0`). H1 then proved it INTEGRATED: `QUERY_FAILURES=1 (denied=1 error=0)`,
   ledger `t1=0 t2=1 t3=0`, `CAPTURE_CONTRACT=NOT_SATISFIED` **from the denial alone**.

## 6a. Two further defects -- caught by REVIEW, not by the control

Both were found by doyle reading the source, against a suite that was **92/0 at the time**. They
are listed apart from the six above because the provenance is the point: a green suite is not
what surfaced them, and no arm that existed would have failed on either.

7. **A partial capture reads as CLEAR under a re-query-only check.** The identity capture wrote
   one supervisor row and then failed; the brain was never recorded and was still running. The one
   pid that WAS recorded is genuinely absent, so a check asking only whether the recorded pids are
   gone answers yes and reports a tidy box with a live daemon on it. Per doyle a capture may
   support CLEAR only if it is COMPLETE: exit 0, exactly one `IDENT_PROBE=OK tracked=N`, N equal to
   the rows written, and every row carrying a numeric pid, a readable creation time, a non-empty
   exe and a non-empty command line. Anything else is UNREADABLE **including the case where every
   recorded pid is absent**. Arm R8 is that case.
8. **Shape is not validity.** `ts_readable` matched a character-class pattern, so
   `2026-02-30T00:00:00.000Z` -- a day that does not exist -- read as a comparable timestamp and
   could establish pid reuse, the one finding that turns a LIVE process into GONE. It now PARSES
   the value with the calendar (`date -u -d`), rejecting the empty string first because an empty
   argument to `date -d` is accepted as *now*. Measured discriminator, old predicate against new
   on the same inputs: `2026-02-30` READABLE -> unreadable, while the real leap days `2024-02-29`
   and `2028-02-29` stay READABLE under both, so the repair is calendar-aware rather than a
   blanket rejection of late February. Arm R10 is that case -- and see Sec. 5b for why R10 did
   not actually exercise it until the fixture was repaired.

## 7. The cleanup verdict, as doyle ruled it (01:12:44Z)

r10 counted a refused isolated-daemon stop as a **cleanup failure**, which under the r8 rule raises
an otherwise-successful run to exit 6. IR-122 makes that refusal **structural** from an spt-hosted
session — it fires on the caller's `OWL_SESSION_ID` whatever `SPT_HOME` is targeted — so under D2
every run would exit 6 and the code would carry no information. The ruling, and what the driver now
does:

- the refusal **may be reported separately** rather than deciding the verdict by itself — **only if
  fresh checks establish the isolated processes are gone**. `CLEANUP=VERIFIED` therefore requires
  **three measured facts**: the owned rules measured ABSENT (the teardown check), **zero residual
  processes** associated with the isolated home, and a **listener measured no longer bound** on the
  trial port.
- **live OR unreadable residual state means PENDING and a nonzero outcome.** Each branch writes a
  cleanup failure, which the r8 handler turns into exit 6. Identity reporting alone is not cleanup.
- **UNMEASURED is kept distinct from LIVE in the evidence**, even though both refuse verification:
  the ledger carries `residual_state=CLEAR|LIVE|UNREADABLE`, plus `residue=` and
  `listener_after_cleanup=` separately. LIVE is a process or a listener we SAW; UNREADABLE is a
  measurement we could not make, and neither may be reported as the other.
- **the refused command's native exit is preserved in every case** — in `exits.txt`, in the findings
  (`RIG_DAEMON_STOP native_exit=`) and in the ledger (`rig_daemon_stop_exit=`).
- nothing is killed anywhere. The r10 pid authorization was pid-specific and is SPENT; a fresh
  pid-naming authorization is a **STOP, not a step**.

## 7a. The control process's own hygiene

Two earlier attempts at this control are **invalidated and recorded as such** in
`INVALIDATED-RUNS.md`: a stopped background task's bash tree **survived `TaskStop`** and kept
deleting the per-case directories of the run that started after it, which made one case report a
missing evidence directory as four assertion failures. `TaskStop` returning is not proof of
process-tree termination. Both trees were reaped by pid with the post-state asserted, the rig now
uses a **unique per-run root** so an earlier control cannot reach a later run's evidence, and the
results in §5 are from a run made after both trees were confirmed gone. The raw artifacts of the two
attempts no longer exist — I deleted them while restarting, before the instruction to preserve them
arrived, and that is stated in the file rather than papered over.

## 8. Ceilings — what this receipt does NOT support

- **Every host-facing path of the capture has met a STUB and never a real provider.** What is
  exercised is that the driver sequences, invokes, records and reports correctly given a provider
  that behaves as the stub does. The `DENIED` path has never been produced by an actual access
  denial; `Test-Denied` matches on error text and remains the weakest part of the instrument.
- **No elevated capture has ever run.** t1's mechanics are exercised by a rig following the request;
  that is not evidence that an elevated leg will produce a document.
- **The binder behaviour of the stub is not PowerShell's.** The stub can only check that the driver
  COMPOSED the array form with both names and the exit propagation; the binder itself was measured
  separately (§4).
- **Nothing here says anything about the r10 pair**, which was torn down and measured absent, or
  about reachability, ACL disposition, or end-to-end #297 acceptance.
- **`ts_readable` depends on GNU `date -u -d`** (measured against GNU coreutils 8.32 on this box).
  doyle ruled this acceptable for a Windows/MSYS-specific diagnostic and asked for no portability
  gate; it is recorded rather than assumed. On a BSD/macOS `date` the parse would fail and every
  creation stamp would read UNREADABLE -- which refuses rather than fabricates a CLEAR, so it
  fails safe, but every residual verdict on such a box would be UNREADABLE.
- **The full suite has never run against `f7b7773f`.** What is measured on the current driver is
  the ten residual arms of Sec. 5a and 5b. The other eleven cases are measured only on `2bd12fc8`.
- Prerequisites remain outstanding and separate: fresh elevation, fresh residual-process
  authorization, and admission of the complete setup/capture/teardown request plus the
  residual-cleanup path.
