# D2 successor receipt — driver `bafed7a7`, the scheduling + observation-gated cleanup change

Author: hertz. Date: 2026-09-13. Authorized directly by doyle (msg Z4DQXYNA, 04:41Z).
Predecessor: the frozen field driver `2e3aec1b`, preserved BYTE-IDENTICAL at
`history/fp-driver-d2-2e3aec1b.sh` (snapshotted before any edit; `cmp` clean).

**Source edits and harmless controls only. NOTHING HERE TOUCHED A HOST.** No build, no host
query, no listener, no elevation, no process kill, no field run — none was authorized and none
was attempted. No product source was modified. `fp-home-d2` was not touched.

## 1. Pins

| what | sha256 |
| --- | --- |
| SUBJECT `fp-driver-d2.sh` (successor) | `bafed7a7e24c8f1ae2e14e0d5ef96a5ebec124afe1e9d2fdbad4c4ea7ca749b2` |
| predecessor `history/fp-driver-d2-2e3aec1b.sh` | `2e3aec1beceefd92947d1eb65a86ad2a843b2c10e1b6e718a09db51a99fd5688` |
| controls `rig-d2/gate-controls.sh` | see `rig-d2/gate-controls.out`, which prints both subject and predecessor hashes as it runs |

Assembled by `rig-d2/assemble.sh` from the same parts as its predecessor, so the change is
reproducible from its base rather than hand-edited. The assembler's own `bash -n` gate passed.

## 2. What changed

**A THIRD BUDGET: PREPARATION, 600 s, SEPARATE.** The experimental clock no longer starts at
process start. `RUN_EPOCH` is EMPTY until `go()`, and `go()` is reached only after the executor's
acknowledgment verifies. Read-only preflight and the acknowledgment are paid for out of
`PREP_BUDGET_S`. MEASURED REASON: run `20260913T041410Z` spent 134 s of its 300 s window
(`handoff_interval` 04:17:02Z..04:19:16Z) waiting for an elevated operator to read a request, and
reached neither t1 nor t2. An overrun in preparation is a REFUSAL TO START (exit 8), not a
truncated experiment: nothing has been dispatched, so there is nothing to tear down.

**PREPARED / NOT_STARTED, HASH-VERIFIED, BEFORE THE WINDOW OPENS.** The executor must return all
three of `PREPARED`, `NOT_STARTED` and `executable_sha256=<EXE_SHA>` — the hash AS THE EXECUTOR
MEASURES IT. An acknowledgment saying only PREPARED proves a request was answered; one carrying
the subject's hash proves the answering leg can see the subject this run is about, and it moves
the identity check into preparation where a mismatch costs no experimental time.

**THE AUTOSTARTING STOP IS NOW OBSERVATION-GATED (IR-124).** The predecessor ran `serve lan
--stop` on `has_state listener_may_exist` alone. That marker is set BEFORE dispatch, deliberately,
so a refused setup still tears down — which makes it a statement about INTENT, never about the
host. In the field run the setup was DECLINED, nothing was started, and the stop ran anyway;
because it reaches the broker through `ensure_running` it CREATED supervisor 45944 and brain
22524. The marker now decides whether the question is ASKED; a fresh native measurement decides
whether the command RUNS: LIVE → stop; measured-GONE → no command; UNREADABLE → no command,
PENDING/review. The existing run-bound identity machinery (pid + creation time + parent +
executable + command line) is what answers — no home-string attribution, nothing new invented.

**THE RESIDUE SCAN BECAME A FUNCTION CALLED TWICE.** `residue_scan TAG VERDICT` — once as the
GATE before anything is stopped, once as the VERDICT after cleanup. Only the verdict pass raises
cleanup failures: a live process BEFORE the stop is the reason to stop, a live process AFTER it
is a finding. Each pass writes its own `residue-<tag>.txt`, so neither overwrites the other.

**t3 AND THE 180 s CLEANUP REPORTING BOUND ARE UNCHANGED**, as required: t3 is still captured
immediately before the teardown request, the manifest is still hashed before teardown, and the
reporting deadline still means THE REPORT IS DUE and never that the host is tidy.

**THE TEARDOWN COMMAND IS PINNED, NEVER COMPOSED.** `serve lan --stop` is gone from the teardown
handoff. Its replacement is the product's own rendered cleanup command, and until that literal is
emitted, decoded, reviewed and pinned (`TEARDOWN_COMMAND_FILE` + `TEARDOWN_COMMAND_SHA256`, both
or neither) cleanup dispatches NO teardown and reports PENDING/review. A hash mismatch refuses
identically. **No removal script is reconstructed here**: composing the payload from the source
constants would produce a command that looks like the product's and is not one, and the elevated
leg cannot tell them apart. The pin lives with the preserved review, not in a scratchpad a
session teardown can delete.

## 3. Controls — `rig-d2/gate-controls.sh`, 17/17, output in `rig-d2/gate-controls.out`

The harness executes THE SUBJECT'S OWN BYTES: each block under test is cut from the assembled
driver by line range at run time, so no control can pass against a paraphrase. `residue_scan`
itself is NOT exercised — it queries `Win32_Process`, which is a host query this work is not
authorized to make. What is exercised is the DECISION taken on its result, which is where IR-124
lived. No spt, no pwsh, no product, no process the harness did not create.

* **A–D** the four gate arms: LIVE issues the stop; measured-absent, unreadable and unmarked all
  issue NOTHING, each with its own recorded state.
* **E, THE NEGATIVE CONTROL THAT MAKES A–D MEAN ANYTHING** — the frozen predecessor's step 1, run
  under the same stubs on the same arm, MUST issue the autostarting stop. It does. IR-124
  reproduces on demand, so the harness can see the defect it claims the successor fixed.
* **F–I** the clocks, each with its own negative control: an activity step refuses before GO and
  is admitted after; `exp_left` reads `UNSTARTED` before GO and `300` after; a second `go` does
  not restart the window; a preparation step refuses after GO and is admitted before.
* **J–L** the pin: unpinned withholds, a wrong hash withholds, a correct pin dispatches — and the
  dispatched body is asserted to be the pinned bytes VERBATIM.

Two of these controls went red on first run. Both were harness faults, not subject faults: the
stub `die` RETURNED where the subject's `die` EXITS 1, so `deadline_check` fell through to
`exp_left` and hit "integer expression expected". The stub was corrected to exit and the
refusal controls now run in subshells. Recorded because a red that is dismissed without being
explained is the one that was real.

## 4. What is NOT established

The successor **has never been executed**. Every statement above is about its source and about
blocks of it run under stubs. It has no field evidence, and it must not acquire any until the
product-emitted cleanup command is obtained, decoded, reviewed and pinned — which is a separate
authorization that does not exist yet.
