# D2 successor — the pinned rule-removal integration

Author: hertz. Date: 2026-09-13. Dispatched by doyle (`2YECTMEN`, `F3VCR5KO`, `V2CLCJBP`).

**No field run.** No product invocation, no elevation, no host query, no process kill, no execution
of the removal instrument. This receipt covers source changes and harmless controls only.

## 1. Pins

| what | sha256 |
| --- | --- |
| SUCCESSOR `fp-driver-d2.sh` | `bb4171924ca921dce6a53f5b5969fafc29bfacdf9ba61474a6361f6503717cbd` |
| PREDECESSOR `history/fp-driver-d2-bafed7a7.sh` | `bafed7a7e24c8f1ae2e14e0d5ef96a5ebec124afe1e9d2fdbad4c4ea7ca749b2` |
| focused diff `fp-driver-d2-bafed7a7-to-bb417192.diff` | `bfef425fcfa9fabae136f4c664bc7b768c5a686a0a4a0da5724d82db53af1e37` (6 hunks, +201/−25) |
| `teardown-command.pinned` (the product's emitted line, verbatim) | `38e0f21b2cf2ef1f9d986c650f2f6b0d36335ba25c8b017fe8dcbd5219c94676` |
| reviewed payload `d3/decoded-todlando/d3-payload.b64` | `416280dbece2601203c74c3f8e2c46e13009125fa5870166894e079329fb1d43` (doyle's pin) |
| `rule-probe.ps1` | `1e007cdc84582b4739137b06505b7e2f242581f6dafc8546a5ae89be2cf11756` |
| controls `rig-d2/cleanup-controls.sh` | `5fc82d4c0ecdebc6e1361d617db62e64b1c1ab9c478d7a1a5bdde4109b3e9c53` |
| control output `rig-d2/cleanup-controls.out` | `39156aaaeb8fb42e5d9427a6559ba450a6e66f331665cad7ba1619e1ffa23b4d` (49/49) |
| probe fixtures `rig-d2/probe-fixtures.ps1` | `28d9a7c96742b8d60a141c481ed84c6fe7de8d573cdbc23ff56c8bb11a29bc99` |
| probe transcripts `rig-d2/probe-transcripts/TRANSCRIPTS.sha256` | `32f78eec8e21328e7da02364f7f2f8f0b5ae15898c25295c3a792e2c7b7416e6` |

**Predecessor description, corrected (doyle `V2CLCJBP`).** `bafed7a7` is the **scheduling
successor** — this lane's previous pin. It is **not** the field-executed driver: the
2026-09-13T04:14Z field run executed **`2e3aec1b`**, which is preserved separately in `history/`.
An earlier message of mine called `bafed7a7` "the frozen field driver"; that was wrong and is
withdrawn here rather than left standing.

**The pin binds the reviewed bytes, independently re-derived.** The base64 inside the captured
stderr hashes to `416280db…` and is byte-identical to `d3-payload.b64`. The driver pins the
REVIEWED file and requires the payload *inside* the dispatchable literal to equal it byte for byte,
so nothing is composed and an unreviewed payload cannot ride inside a well-formed-looking line.

## 2. What changed

1. **Required before GO.** `teardown_pin_verify pre-go` runs in preparation; a failure `die`s
   *before* `go()`, so the window never opens and nothing is created. A run that could not remove
   what it would create does not start. This is a precondition, not a permission.
2. **Verified again immediately before use.** `teardown_pin_verify pre-dispatch`. The pre-GO
   reading was about the file as it stood then; only a reading taken at the dispatch can speak for
   the bytes being handed over.
3. **Native exit preserved.** Unchanged: the teardown receipt's exit goes to `TEARDOWN_RC`,
   `exits.txt` and the ledger. The new probe's exit is recorded the same way
   (`rule_probe_post_EXIT=N`).
4. **Independent post-removal check.** New `removal_check` runs the pinned `rule-probe.ps1`: each
   owned name **by InstanceID**, in **ActiveStore and PersistentStore**, with a per-store positive
   control (a rule known to exist) and negative control (an impossible name) **in the same sample**.
   Outcomes are named separately — `CONFIRMED`, `PARTIAL`, `ACTIVESTORE_RESIDUE`, `FAILED`,
   `UNREADABLE_{NO_PROBE,PROBE_UNPINNED,PROBE_EXIT_n,CONTROLS,INCOMPLETE,STATE}`. `VERIFIED` now
   requires `CONFIRMED` **in addition to** the four previous conditions; everything else is
   `PENDING/review`, with **no retry and no second dispatch**.
5. **It removes rules only.** Stated at the pin, in the dispatch record, and in the request text
   itself: it stops no listener and removes no process. Read from the decoded payload, which
   removes the two owned rules from PersistentStore after asserting each rule's group and TCP
   protocol, then re-reads both stores and throws if anything remains. The listener/process
   disposition stays the separate, observation-gated question it already was.

## 3. Controls — 49/49

**Two layers, and they are not the same claim.**

**Sections A–I stub `pwsh`**: the probe does not run, and what is exercised is the DECISION taken on
a probe result, against transcripts the harness composed.

| section | what it exercises |
| --- | --- |
| **A never-started setup** | the **actual cleanup entry**: the whole firewall section of `cleanup()` is cut from the subject (`if has_state fw_mutation_may_have_occurred; then` … its closing `fi`) and run. Marker unset → no dispatch, `TEARDOWN_DISPATCH=NOT_REACHED`, `removal_check` never reached, no VERIFIED available, and the subject's own two skip records present. **a7 is the extraction's positive control**: the same bytes with the marker set do reach the dispatch. |
| B partial removal | one name ABSENT, one PRESENT → `PARTIAL`, recorded as open admission, `HANDOFFS=0` |
| C ActiveStore residue | persistent clean, live rule present → `ACTIVESTORE_RESIDUE`, named on its own |
| D instrument soundness (5 arms) | dead controls, nonzero probe exit, incomplete readings, unresolved name, unpinned probe → all `UNREADABLE_*`, never `CONFIRMED` |
| E positive control | four ABSENT with controls alive → `CONFIRMED` |
| F the pin (6 arms) | including a well-formed literal carrying **unreviewed** bytes → refused |
| G dispatch gate | refusal withholds and is recorded as a REFUSAL TO ACT; the accepted path dispatches **once**, and the dispatched body is the pinned literal byte for byte |
| H combined verdict | `VERIFIED` only with `CONFIRMED`; `PARTIAL`/residue/unreadable → `PENDING` |
| **I negative control** | the PREDECESSOR's own conjunction, quoted from its bytes, declares `VERIFIED` on a **false self-report** (receipt exit 0, census clean, product `LAN_FIREWALL_CLEAN`) while an owned name is still present; the successor says `PENDING`. `i3`: the predecessor has no independent post-removal reading at all. |

**Section J runs the probe's OWN bytes** (`command pwsh` bypasses the stub) through
`probe-fixtures.ps1`, which dot-sources `rule-probe.ps1` with a **shadowed `Get-NetFirewallRule`**,
then feeds the probe's **real emitted output** back into `removal_check`:

| fixture answer | probe renders | `removal_check` says |
| --- | --- | --- |
| PRESENT (object returned) | `state=PRESENT` ×4 | `FAILED` |
| typed NotFound | `state=ABSENT notfound` ×4 | `CONFIRMED` |
| access denial | `state=UNREADABLE fqid=AccessDenied…` | `UNREADABLE_STATE` |
| unrelated error (RPC fault) | `state=UNREADABLE fqid=RpcFault…` | `UNREADABLE_STATE` |
| empty success | `state=UNREADABLE empty_success_is_not_absence` | `UNREADABLE_STATE` |
| dead per-store control | `RULEPROBE_CONTROL_OK … ok=False` ×2 | `UNREADABLE_CONTROLS` |
| partial (one name left) | one ABSENT, one PRESENT per store | `PARTIAL` |
| ActiveStore residue | persistent clean, active holding a name | `ACTIVESTORE_RESIDUE` |

The probe fixtures pass 11/11 on their own and are the first eight rows of J. Transcripts are
preserved under `rig-d2/probe-transcripts/` with their own manifest.

## 4. What these controls did NOT exercise — stated precisely

- **No remover was executed.** The partial case is an **observation** test: `removal_check` and the
  probe are shown to read and classify a host state in which one rule was deleted and the other was
  not. **Nothing deleted a rule, failed, and left the other in place** — that would be a field run
  of the instrument, which is not authorized and has not happened.
- **`cleanup()` was not run end to end.** Section A runs its **firewall section**, entry to close,
  from the subject's own bytes. The capture/validate/guard subsystems (`d2_capture_at`,
  `d2_validate_at`, `guard_assert`, `cleanup_left`) and the handoff are **stubbed by name**; the
  branch structure, the dispatch gate, the verdict and the records are the subject's.
- **The probe never read a real host.** `Get-NetFirewallRule` is shadowed inside it. That its
  readings match a real firewall's behaviour is inherited from the D3 admission measurements, not
  established here.
- **The pre-GO refusal is not exercised as a whole-driver run**; `teardown_pin_verify` is exercised
  directly (F) and the `die` on its failure is a one-line call at the GO site, visible in the diff.
- **`handoff_await` returns failure in section A's positive-control arm**, so the post-receipt
  verdict path is reached in H via its own conjunction rather than through a simulated receipt.

## 5. Two defects of my own, found and fixed during this work

- **`grep -c … || echo 0` appends a second zero line.** `grep -c` already prints `0` and exits 1,
  so the counter held two lines and every numeric test errored — control **d1** read `PARTIAL`
  where the answer was `UNREADABLE_CONTROLS`. Fixed at all nine sites; the mechanism is now a
  comment at the site. The rig caught this, which is what it is for.
- **My edit helper truncated `_part_main.sh` to zero bytes** by opening the file for write before
  computing the new content. Recovered byte-exact from the assembled driver and **proven** so: the
  reassembled output differed from the pinned predecessor only in the intended hunks, with no diff
  anywhere in that fragment's region. The helper now computes before it opens.

## 6. What this does NOT establish

The instrument has never been run. Nothing here shows that it removes a real rule, that a real
removal failure looks the way the fixtures render it, or that the host behaves as the shadow does.
`CONFIRMED` from the probe is an observation at an instant, in two stores, by name — it is not proof
that nothing existed between samples, and it is not authority to stop a listener or touch a process.
D2 GO remains doyle's to give.

---

# Addendum — the declined-setup gate (doyle `GUS4EENB`)

**New pin `99df52c3b6ff234b27e127288ab02c3a5a764f9f3268441845a6e68b2a466ecc`.** Predecessor
`bb417192` is snapshotted at `history/fp-driver-d2-bb417192.sh`; full diff from the scheduling
successor is `fp-driver-d2-bafed7a7-to-99df52c3.diff` `3903ba59…` (7 hunks, +234/−25).

## Native outcome on FROZEN `bb417192` — the gap, measured before it was fixed

`rig-d2/declined-setup-controls.sh` run against `bb417192`, markers SET and setup `NOT_STARTED`:

| control | outcome on `bb417192` |
| --- | --- |
| k1a/k1b stop gate, resources measured absent | **PASS** — `NOT_NEEDED`, no autostarting stop |
| k1c no removal dispatched | **FAIL** — `HANDOFFS=1` |
| k1d dispatch state | **FAIL** — `DISPATCHED`, not `NOT_NEEDED_MEASURED_ABSENT` |
| k1e disposition | **FAIL** — empty |
| k2a/k2b unreadable: stop withheld, no spawn | **PASS** |
| k2c/k2d unreadable: no dispatch, PENDING | **FAIL** — dispatched anyway |
| k3 positive control (rules present → dispatch) | **PASS** |
| L (the run remover, partial failure) | **PASS 4/4** |

So the listener gate already measured before acting; the **removal** dispatch still fired on the
marker alone — the same class of mistake as IR-124, one step over.

## The change

`removal_check` now takes a **tag**, and is called **twice**: `pre-teardown` before anything is
asked for, `post-teardown` after the receipt. The pre-reading gates the dispatch, in the shape of
the listener gate: **the marker decides whether the question is asked; the measurement decides
whether a command is requested.**

- `CONFIRMED` (both names absent, both stores, controls alive) → `TEARDOWN_DISPATCH=NOT_NEEDED_MEASURED_ABSENT`, `CLEANUP_VERDICT=NOTHING_TO_REMOVE`, **no dispatch**.
- `UNREADABLE*` → `WITHHELD_UNREADABLE_STATE`, `PENDING`, **no dispatch, nothing spawned**.
- anything present → verify the pin, dispatch once.

`NOTHING_TO_REMOVE` is a **terminal measured state**, added to the final verdict rule beside
`VERIFIED`. It still has to clear the same two other facts — no residual process of this home and
no listener still bound — either of which forces `PENDING` exactly as before.

## Controls on `99df52c3`

- `rig-d2/declined-setup-controls.sh` `afa26b7b…` → `declined-setup-controls.out` `ba860e9b…`, **16/16**.
- `rig-d2/cleanup-controls.sh` `22c142e8…` → `cleanup-controls.out` `28f84f4c…`, **49/49** (re-run because this change touches the code they cover, not as an unrelated suite).
- `rig-d2/payload-partial-fixture.ps1` `27f627ae…`, **6/6**: the reviewed decoded payload `46c76fae…` is RUN under shadowed `Import-Module` / `Get-NetFirewallRule` / `Get-NetFirewallPortFilter` / `Remove-NetFirewallRule` over a hashtable store. First removal succeeds and mutates the fixture, second **throws**; the failure text is preserved; one owned rule is gone and one remains in **both** fixture stores. The ACTUAL probe then reads that state (`state=ABSENT` ×2, `state=PRESENT` ×2, both per-store controls alive), and `removal_check` classifies it `PARTIAL` → `PENDING`, with **no retry**. The host was never read or written.

## Three harness defects of mine, disclosed

1. `declined-setup-controls.sh` first loaded only `removal_check`, so `teardown_pin_verify` was
   *command not found* — and a missing definition reads exactly like a refusal. K1/K3 were
   measuring the harness. Fixed before any verdict was read.
2. `cleanup-controls.sh` had no pre-teardown transcript, so the new gate withheld and seven
   controls went red — a harness fault, not a subject one. Its `reset` now presents a host that
   HAS something to remove, and sections about `removal_check` set their own transcript.
3. Section G's extraction started mid-`if`-chain once the gate moved the chain's first line; the
   anchor now cuts the whole chain.

## One process slip, disclosed and repaired

`bb417192` was **not snapshotted before it was superseded**, against this lane's own convention.
It was reconstructed by reverse-applying this change to the fragments and re-assembling: the result
hashes **exactly** `bb417192…`, so the snapshot is proven rather than asserted, and the tree was
then restored to `99df52c3` and re-verified.
