# #304 W2 — field plan for the repaired numeric-enforcement candidate

**Subject:** `85f84d738fa702f35c83910f314aae17849d125c`
**Subject blob** (`crates/spt-daemon/src/bootstrap_firewall/windows.rs`): `848a23fe18e5ca819774f9881ef13504221992f3`
**Worktree:** `.worktrees/304-w2-repr`, detached at the subject sha.
**Author:** todlando. **Gater:** doyle. **Rig owner:** hertz.
**Status at time of writing (2026-09-12):** plan only. No build grant, no field grant, no elevation
grant. Build and field admission require an explicit grant and fresh preflight evidence.

This document is the plan and its evidence ceiling. It is **not** the driver; hertz owns the
integrated driver successor and its fixture controls. Where the two must agree on a string, this
document is the source and the driver quotes it.

---

## 1. What the candidate changed

Three commits sit between the sha the driver's product contract was originally read at
(`53d625cd`) and the subject:

| sha | shape |
| --- | --- |
| `a5f2186c` | production — judge enforcement by raw code, never display spelling |
| `96080953` | production — validate enforcement evidence before converting it |
| `85f84d73` | test-only — migrate the enforcement suite to numeric codes |

Only `windows.rs` and `traceable-reqs.toml` differ across the whole range. `serveverb.rs` is
byte-identical, so every citation into it made at `53d625cd` still holds.

Two consequences the rig must reflect, both measured rather than recalled:

1. **The enforcement refusal string changed.** `ActiveStore enforcement is` occurs **zero** times in
   `crates/` outside tests at the subject sha. The repaired arm emits
   `ActiveStore enforcement codes are` (`windows.rs:826-828`). All thirteen other product face
   strings still resolve to at least one production site; each was checked individually.
2. **A new refusal surface exists.** `ENFORCEMENT_REPRESENTATION_FAULT`, five throw sites in the
   query script, all below the test module. It reports that the host could not transport the codes —
   a different finding from the codes being wrong.

Both refusals reach stderr wrapped as `LAN_FIREWALL_UNVERIFIED: <reason>`, because
`serveverb.rs:310-315` interpolates the reason. A classifier that does not match them by their own
text therefore does not merely lose a count: it collapses them into the generic face.

**What the generic face does and does not mean.** Generic `LAN_FIREWALL_UNVERIFIED` establishes only
that `verify()` did not return `Ok(true)`. It does **not** mean "the pair is absent or misspelled".
That gloss is **the old driver's interpretation, and it is unsound** — it is recorded here as the
defect being corrected, not as the meaning of the string. Many distinct causes arrive under that one
wrapper, and the wrapper distinguishes none of them.

**Only the specific enforcement-code refusal establishes that `decide()` passed
`pair_satisfied_by`.** That is what makes it the representation-accepted discriminator: the check
order puts `pair_satisfied_by` first, so reaching the enforcement arm requires it to have matched.

**A representation fault establishes no such thing.** It reports that the host could not transport
the codes — the query failed, and `decide()`'s verdict is simply not in evidence. It is neither a
representation-accepted result nor a pair-absent one, and it must never be folded into either.

Keeping these three causes distinguishable is a correctness requirement of the rig, not a reporting
nicety.

**Line anchors shifted.** Offsets re-derived by content, not arithmetic: **+73** at or below line
749, **+75** at or above 754, because `decide()`'s body gained two hunks. Spot-checked:
`snapshot` 675 to 748, `decide` 713 to 786, the `pair_satisfied_by` call 724 to 797, `reconcile`
760 to 835, `mismatch_message` 817 to 892, `cleanup` 888 to 963.

---

## 2. Build and staging

**One release build, via `debug-rollout --build-current`.** Not build-then-build. The cargo producer
runs inside that verb (`crates/xtask/src/main.rs:2738-2746`), so the capacity floor is read
immediately before it.

**Rollout state — ruled, do not change.** `state_path` in `crates/xtask/src/main.rs` at the subject
sha has exactly two uses: a read at `:2424`, reached **only** through
`version.unwrap_or_else(next_debug_version)` and therefore only when `--version` is absent; and an
unconditional write at `:2502`. The plan passes `--version 1` explicitly, so the retained
`target/fp-rollout-state.json` is **never read** — it is write-only in this configuration, and
`write_debug_version` stores nothing but that one integer (no artifact hash, no channel, no product
version, no expiry). Keep the existing state path. **No reset, no deletion, no fresh
attempt-specific path** — there is no collision for one to close.

**The applied-marker containment is what actually closes version reuse.** `debug_mark_applied`
writes into `<home>/releases` via `ReleaseCache::record_applied_state`. The plan passes `--home`
explicitly and the isolated home is proven absent before the run. A **fresh isolated home and an
explicit `--home` are mandatory**: `debug_mark_applied`'s home falls back to
`spt_store::perch::spt_home()` when the flag is absent, which would write the marker into the real
`LOCALAPPDATA` spt-core home.

---

## 3. Provenance — the old binary must not be able to pass

`target/release/spt.exe` in the worktree currently **is** the pre-repair executable,
`edd3d8e0566690493182a0e1807b1a6b43c52cff45511b9e81490e256dd10e21`. The three-way provenance check
derives all three of its hashes from that one path, so it is an **internal-consistency** check: it
proves the staged set is self-consistent and says nothing about which source the executable came
from. A build that left the binary in place would record a three-way pass on the old bytes.

Required, as ruled:

- Capture the pre-build executable hash and mtime **as evidence, not as a mandatory inequality.**
  Identical bytes do not prove no build ran, and changed bytes do not prove the intended source.
  PE nondeterminism must not be encoded as a correctness invariant.
- **Reject the known pre-repair hash**
  `edd3d8e0566690493182a0e1807b1a6b43c52cff45511b9e81490e256dd10e21` in the provenance step,
  alongside the existing three-way equality checks.
- **Reassert subject HEAD, blob and clean tree immediately before the rollout producer**, and record
  the same checks after it. These are **boundary observations, not proof of continuous
  immutability.**
- Preserve rollout/build output and native exit status.

Describe the resulting chain accurately and in these terms: *checked source tree, successful
producer, rejected known-old artifact, internally consistent signed set.* No extra build, no target
deletion, no universal "hash must change" rule.

---

## 4. The four outcomes, kept separate

They are reported as four independent results. None is inferred from another.

1. **Enforcement codes** — whether the ActiveStore codes the host reported were accepted. This has a
   third state, not two: a representation fault means no codes were transported at all, so the
   result is *not in evidence* rather than accepted or refused. It is reported as its own value.
2. **Reconciliation** — whether `verify()` returned `Ok(true)`, with the census that supplies the arm.
3. **Registered populated timing** — see the ceiling; earned only by completed valid B trials.
4. **Actual reachability** — **not measurable by this rig.** See the ceiling.

Attempt 2's non-success statuses `{ProfileInactive, NoLocalUser}` remain **unexplained**. The
ValueMap runs 0..25 with the Values qualifier **absent**, so a name is never to be asserted for a
code. Nothing in this plan resolves them.

---

## 5. Evidence ceiling (revision 3 — final, accepted)

### What "a fully green run" means

The ceiling below takes a fully green run as its subject four times and, until this was ruled, the
document never said what one is. It is defined here rather than inside the ceiling text, so that
revision 3 stays byte-stable as the string the plan and the driver both quote.

> A fully green run requires all three registered trials in each arm to complete validly, successful
> D1 capture, and all existing admission, provenance, preservation and cleanup gates to pass; partial
> measurements remain evidence, never success.

Execution policy is kept separate from that definition, because one is about what counts as success
and the other is about what the run is permitted to do:

> No retries or replacement trials; retain every attempted trial's outcome, stop on existing abort
> conditions, and preserve original failure precedence.

This does **not** require continuing scheduled trials after a safety or control abort. Stopping there
is correct; what it forfeits is the green, not the evidence already gathered.

The consequence for the ceiling's own values: `POPULATED_TIMING=PARTIAL` and
`POPULATED_TIMING=NOT_TESTED` are reported results and can never accompany a green run. A partial
measurement is kept, reported and cited as what it is — it never becomes a success, and a successful
D1 capture does not redeem an incomplete arm.

### The ceiling

> EVIDENCE CEILING — what a fully green run of this rig does and does not establish.
>
> `REACHABILITY=NOT_TESTED`.
>
> Emit the ceiling before the first preflight and again in the normal summary. After an uncatchable
> termination, only output and artifacts actually preserved may be cited; neither the initial print
> nor state-marker persistence is guaranteed.
>
> This rig makes no connection attempt, from this box or any other. Rule shape is not arrival:
> `LAN_FIREWALL_RECONCILED` means `verify()` returned `Ok(true)` over the rule store at that
> instant, and the product states the converse itself in `LAN_FIREWALL_UNVERIFIED` — "this does not
> prove the listener unreachable" (`serveverb.rs:310-315`).
>
> A fully green local run establishes exactly three things:
>
> 1. **Observed enforcement-code acceptance** — the ActiveStore codes the host reported were
>    accepted by the repaired comparison.
> 2. **Reconciliation under the measured rule-store and census conditions** — conditioned on those
>    conditions, which are recorded alongside it, not a standing property of the host.
> 3. **The registered child-query timings for completed trials, with their brackets** — `wall_ms` as
>    measured inside the process around the child (`bootstrap_firewall.rs:99-109`). **Not
>    interchangeable with end-to-end invocation wall time.**
>
> It establishes **none** of the following, and a green must never be read as any of them:
>
> - remote connectivity;
> - ACL disposition;
> - end-to-end #297 acceptance.
>
> **Populated timing is earned by completed valid B trials, never by admission.** Arm B being
> admitted supplies no timing at all. Three registered B trials:
>
> - no completed valid B trial — `POPULATED_TIMING=NOT_TESTED`
> - fewer than the registered three — `POPULATED_TIMING=PARTIAL`, printed with completed and
>   required counts, e.g. `completed=2 required=3`
> - all three completed and valid — registered populated timing satisfied
>
> It is never inferred from setup timing: the elevated setup's own wall is a different path with a
> different child and is not a substitute for a trial that ran against a populated store.
>
> **Two-host acceptance remains outstanding.** It requires its own plan and its own execution grant.
> This local rig does not discharge it and no combination of green results here converts into it.

### Ceiling revision history — superseded, retained

- **rev 1** (2026-09-12 22:22). Said the ceiling line would be "never omitted from an early exit".
  Withdrawn: no handler runs after an uncatchable kill, so an end-of-run line is absent from exactly
  the runs where its absence misleads.
- **rev 2** (2026-09-12 22:23). Moved the print before the preflight, but asserted that the early
  print "is the one that survives" and that a SIGKILL "leaves print (a) and the state markers on
  disk — that is the guarantee". Withdrawn: an early print can sit unflushed in a buffer, and a kill
  can land before a marker is written or mid-write. Neither is promised.
- **rev 3** (2026-09-12 22:24). Accepted. Cites only what was actually preserved and promises
  nothing about what survives.

Rev 1 and rev 2 are kept as history because the correction they record is the reusable part: each
was an unguaranteed property asserted as a guarantee, inside a passage whose purpose was to be
careful. Being careful is when that move stops feeling like a claim.

---

## 6. Out of scope

- No reachability probe is added here, and none is proposed.
- No build estimate is offered. It is **unknown**, and is not to be borrowed from a debug-build
  figure or a CI wall.
- Driver internals, fixture controls and the staged helper manifest belong to hertz's integrated
  successor. This document does not duplicate them.
