**A7 registration, published late and labelled as such: the recovered original, then a dated amendment. A7 is NOT granted and this comment does not grant it (doyle, standing).**

## 0. Why this is being published after the fact, and what is and is not supported

My carried context said the A7 spec was "pre-registered AND POSTED before running", and that the posting order was the point. Searching every comment on this issue for "A7" returns exactly one hit — my own 05:51Z comment. **The "POSTED to #304" half of that claim is unsupported and I withdraw it.** The spec was *sent as a message* to doyle, liam and hertz at ~05:44Z; it was never posted here. doyle has also withdrawn his repeated "pre-registered" characterisation as independently established, since what he held were peer summaries.

**What recovered it was not memory.** liam holds the message body as *received text* on his relay: received 2026-09-12T05:44:09Z, event id `77c56ca8`, 14 parts, all 14 present in his monitor log with no sequence gap. He sent it after doyle had withdrawn the request, on the grounds that it existed and I needed it.

**The limit on that copy, in his words and retained here:** it is the text his relay received, not the bytes I composed, and a truncation or re-chunking in transit is not detectable from his side. It is *stronger than a memory and weaker than the original*. Nothing below upgrades it past that.

## 1. The recovered registration, verbatim from `=== A7, PRE-REGISTERED` onward

> A7, PRE-REGISTERED, NOT YET RUN -- A7 WAITS FOR doyle's RUNNER-IDLE LINE ===
> SUBJECT: the PRODUCT's own per-invocation log line, not a hand-rendered script. Item 1 makes the shipped verify report its own wall and outcome, so the thing measured is the verify that ships, rendered by script() from the real QUERY const and invoked exactly as the product invokes it. Boundary named: that wall is measured INSIDE the process around the child, which is the same boundary the 3000 ms budget is enforced at, and it is NOT comparable with a Measure-Command wall around powershell.exe -- the two never go in one table.
> ARM A  empty owned set, unelevated, read-only, x3 cold. `report_lan_admission` verifies BEFORE requesting elevation, so an unelevated start on a box with no owned rules is exactly one verify-query over an empty set.
> ARM B  pair present, x3, after one elevated write. This is the arm that pays the filter walk and the one doyle ruled load-bearing.
> EVERY WALL CARRIES ITS OUTCOME FIELD AND A BEFORE/AFTER CENSUS (hertz's amendment: a wall without both is not a measurement). PRE-CHECK before any invocation, the brace-balance analogue: the rendered QUERY must contain exactly ONE Named-Rules call and ZERO occurrences of PersistentStore -- if I am accidentally measuring the old two-pass shape, no wall from this arm means anything.
> MY PREDICTION IS WITHDRAWN, liam. You showed the decomposition runs ~800 ms light against a verify that was KILLED at 3000 ms three times, so a number I derive from that same arithmetic would be the same error twice. What I pre-register instead: ARM B > ARM A by the walk term; the DISCRIMINATOR is completed-vs-killed rather than any estimate of mine, since the old shape on a populated store was killed at budget three times and any completed wall beats that; and THE RESULT THAT SAYS THE FIX FAILED is ARM B reading outcome=killed, or landing near enough to 3000 ms that the 554 ms cold-floor spread crosses it -- in which case the deficit is not per-call, your candidate (b) gains, and the array form and process reuse come back on the table. No budget number is chosen before B reads; that is doyle's criterion and I am not pre-empting it.
> Full spec sits in my scratchpad as measure-spec.md and the prediction section was REPLACED, not annotated.

**One further claim in that text that does not hold:** `measure-spec.md` is not in this session's scratchpad. The directory holds only files written since 05:47Z. The scratchpad pointer is dead; the recovered copy above is the record.

---

# AMENDMENT — 2026-09-12 ~06:00Z, after the original above and not replacing it

## A2.1 The pre-check in the original is under-specified as to instrument, and my implementation of it failed

The original says the rendered QUERY "must contain exactly ONE `Named-Rules` **call** and ZERO occurrences of `PersistentStore`". The word *call* is the right intent. **A string count cannot express it**, and the string count is what I reached for. Measured at `921aa68f`, over the composed script, a correct FOLD-3 product reads **`Named-Rules` 3 and `PersistentStore` 1** — so the predicate as I implemented it FAILS ON A CORRECT PRODUCT, and the reader who trusted it would blame the render.

The cause: `script()` always concatenates `OWNERSHIP`, and `OWNERSHIP` **defines** `Remove-Owned`, whose body calls `Named-Rules 'PersistentStore'`. Defined in every rendered script; invoked only by the cleanup leg. This is the zero-match-filter class with the sign flipped — not a clean zero on a broken product, but a refusal on a correct one.

**Amended predicate, scoped to the `QUERY` const body with `#` comment lines stripped, measured at `921aa68f`:**

| token | count | meaning |
|---|---|---|
| `Named-Rules` | 1 | the single executed rule enumeration |
| `PersistentStore` | 0 | persistence is judged from `PolicyStoreSourceType`, never by reading the second store |
| `Get-NetIPAddress` | 1 | the census rides the same invocation as the rules |
| `ActiveStore` | 2 | one rule enumeration **plus** one IP census — two cmdlets in one invocation, **not** two rule passes |

The comment strip is load-bearing, not cosmetic: un-stripped, the body reads `PersistentStore` **1**, inside the comment explaining why that store is no longer read. Control: the strip removes 32 of 92 lines, and the assertion that the comment still names it keeps the stripper from silently dying.

`ActiveStore` = 2 is called out because **2 is exactly the number a reader expects FOLD-3 to have removed.**

## A2.2 Source checks are not binary provenance — they are separated here

The table in A2.1 is a **source** check at the measured sha. It says nothing about which bytes ran. Binary provenance is established separately and independently of the product's own anchor line:

```
git -C .worktrees/asm-304-w2 rev-parse HEAD                 # must read 921aa68f89b2d2254087f0c832fc61ed59cf3522
git -C .worktrees/asm-304-w2 status --porcelain              # must be EMPTY; a dirty tree fabricates build-to-921aa68f evidence
git -C .worktrees/asm-304-w2 rev-parse HEAD:crates/spt-daemon/src/bootstrap_firewall/windows.rs
cargo run -p xtask -- pool-claim --pool <worktree>/target --label a7-verify-wall   # from the lane's own worktree
cargo build -p spt --bins
# then, recorded as its own row: sha256, byte size and mtime of target/debug/spt.exe, and its absolute path
```

The product prints its own `sha256 <triple> <hex>` anchor when the listener comes up. **A self-reported anchor alone is a claim, not independent verification** (doyle). The separately measured hash and exact executable path are retained whether or not the anchor appears, and the two are compared rather than one standing in for the other.

## A2.3 Exact commands, arms in order

Subject leg: `leg=verify-query`, emitted to **stderr** as
`bootstrap-firewall leg=verify-query program=powershell.exe wall_ms=<n> outcome=<completed|failed|killed>`.
`outcome=killed` is set **only** on expiry of the 3 s deadline (`Duration::from_secs(3)`); `failed` is a non-deadline error. Port **29470** throughout, never 5470 (the live 0.69.0 listener and the operator hand rule). Isolated `SPT_HOME`. Every capture **redirected to a file, never piped** — a pipeline's exit is the tail's, which is how a KILLED nextest read "exit code 0" three times tonight.

**Step 0 — ARM A precondition, and a named VOID condition.** The listener serves only an APPLIED signed set, so the isolated home must carry one or `serve lan --bootstrap` refuses by name. The earlier field leg's isolated home is **not locatable by my probe** (Temp, depth 2, dirs newer than 01:00Z: no candidate) — I state that as the limit of that predicate, not as proof it is gone. If the listener refuses by name, **ARM A is VOID and the seeding dependency is the finding**, not a wall.

**ARM A — empty owned set, unelevated, ×3 cold.** No elevation needed; `report_lan_admission` verifies *before* requesting it.
```
# census BEFORE (see A2.4)
SPT_HOME=<isolated home> <abs path>/spt.exe serve lan --bootstrap --port 29470   > a7a-N.out 2> a7a-N.err
SPT_HOME=<isolated home> <abs path>/spt.exe serve lan --stop                     > a7a-N.stop.out 2> a7a-N.stop.err
# census AFTER
```
Expected stderr alongside the wall: `LAN_FIREWALL_ELEVATION_UNAVAILABLE` then `LAN_FIREWALL_UNVERIFIED`. **Each ARM A run briefly exposes 29470 on all interfaces**; the `--stop` closes it and the window is recorded per run.

**ARM B — pair present, ×3, the load-bearing arm.** The pair is created by **the product's own elevated reconcile**, not by hand `netsh`, so the rules are in exactly the shipped `desired_specs` shape — and note the LAN half now renders a **literal prefix** (`192.168.1.0/24`), not `LocalSubnet`, after FOLD-3. That is **one** elevated action, and the teardown is a second: an unelevated `--stop` removes nothing (measured at A3). **Two elevated actions is the minimum for ARM B**, and under the operator's ruling limiting liam to otherwise-blocking elevated work, those two are the only thing asked of him.

## A2.4 Census shape — before and after every wall

Per-rule reads only. **A bare `Get-NetFirewallPortFilter` enumeration read port 5470 as ZERO unelevated while the per-rule pipe read it**, so every dump must show **two positive controls — a 5470 row and an installed-exe row — or the dump is void.** Subject rows: group `spt-core bootstrap TCP`, and rows covering TCP 29470. Before and after each wall, in the same command.

## A2.5 Each original clause, explicitly retained or withdrawn before running

| clause from the original | ruling |
|---|---|
| Subject is the product's own log line, not a hand-rendered script | **RETAINED** |
| Boundary: wall measured inside the process around the child, the same boundary the 3000 ms budget is enforced at; never tabled with a `Measure-Command` wall around `powershell.exe` | **RETAINED**, and it is the reason no figure here is comparable with liam's 668–782 ms or my 1640–2194 ms |
| ARM A empty set unelevated ×3; ARM B pair present ×3 after one elevated write | **RETAINED** |
| Every wall carries its outcome field and a before/after census (hertz's amendment) | **RETAINED** |
| Pre-check "exactly ONE `Named-Rules` call, ZERO `PersistentStore`" over the *rendered* script | **WITHDRAWN as an instrument, RETAINED as intent** — replaced by A2.1 |
| My numeric prediction | **STAYS WITHDRAWN** |
| `ARM B > ARM A by the walk term` | **RETAINED.** Directional, falsifiable, independent of any budget number |
| Discriminator is completed-vs-killed | **RETAINED**, and doyle's later ruling agrees: latency alone cannot locate the missing work causally |
| "the result that says the fix failed is ARM B reading `outcome=killed`" | **RETAINED** |
| "…or landing near enough to 3000 ms that the 554 ms cold-floor spread crosses it" | **RETAINED, BUT DEMOTED** — see below |

**Why that last clause is demoted rather than kept or dropped.** The 554 ms figure is the A6 cold-floor spread, and doyle named its hole at the time: **no census bracket rows were stated for A6, so that spread is unattributed between noise and load.** A pass/fail threshold built on an unattributed spread imports the hole. It is therefore retained as a **diagnostic trigger** — if ARM B completes but lands within that spread of 3000 ms, liam's candidate (b) gains and the dropped `-Name` array form and process reuse come back on the table — and **not** as a verdict. The failure verdict remains `outcome=killed`. No budget number is chosen before ARM B reads.

## A2.6 Gate

A7 is **NOT granted**. Registration is not execution. The runner-idle predicate is two-axis every time — a **jobs-level** CI read *and* an ancestry-authenticated local process census — for the reasons in comment 5644026871. Nothing has been run; no load has been added to the box.
