# FIX-199 (a-prime) — the in-flight bring-up ledger

Lane `fix/199-er-hosted-probe`, base main @`8d4c224`, diagnostic @`5db45f9` stays first commit.
doyle's design ruling 2026-08-19 (after the RCA at releases#199 comment 5344133768).

## The defect in one sentence

`engine_room_hosted()` answers the reserved-id bind gate from the SESSIONS TABLE, which records
**completed-ness**; the gate's own premise is "the completion of a bring-up the broker STARTED",
and **nothing anywhere records started-ness**. The broker-spawned harness therefore races its own
registration and is refused `RESERVED_ID` (~7%, arm named 3/3 `ER_HOSTED_PROBE:no-row sessions=0`).

## The ruling (a-prime) — options (b) and (c) REFUSED

- (b) refused on a SOURCE FACT doyle checked: `mint_bringup_admit` (:5747) takes a SESSION id and
  is called at ready-wait SUCCESS, so in the race window the ticket DOES NOT EXIST. Its "reuse an
  existing credential" premise fails on timing.
- (c) refused as primary on my own paragraph (core race exported as an adapter obligation, window
  stays open). Not mandated as a belt either — an adapter's retry is its own business.
- (a) as I ranked it (a PENDING row in the sessions table) superseded by (a-prime): the same fact,
  recorded OUTSIDE the sessions table, so the whole (a) blast radius (wake-gate AlreadyLive,
  `session_is_zombie(None,..)`, every `process_id()` reader, rollback) vanishes **by construction
  rather than by discipline**.

## Build

1. **REQ** — mint `REQ-ER-BRINGUP-INFLIGHT-LEDGER` (name is doyle's per standing pattern),
   `required_stages = ["impl", "unit"]`, minted in this build's PR.
2. **Broker ledger** — `bringups_in_flight: Mutex<HashMap<String, Instant>>` (endpoint -> deadline),
   TTL = the bring-up's own `ready_wait`, **swept on insert** exactly like `bringup_admits` (:5769).
3. **Written when the broker STARTS the bring-up** — immediately before the launch thread at
   `broker.rs:5646` (`std::thread::spawn` -> `launch_harness_brokered_in`), which is before the child
   exists at :5975. Placed on the BRING-UP path, not in the shared spawn choke: the fact recorded is
   "a bring-up started", and writing it in the generic choke would record every ordinary spawn.
4. **Removed at registration** — at the session insert (`broker.rs:6174`), the moment the row appears.
   A failed spawn writes nothing back and the entry **expires harmlessly**; no phantom row, ever.
5. **Carried to the client** — one added field on the brain sessions reply, `SessionsReply.bringing_up:
   Vec<String>`, additive + `#[serde(default)]` per the KH-2.3 N-1 convention its neighbours use.
   Internal IPC only; the P2P wire is untouched.
6. **The gate reads OR** — `engine_room_hosted()` = an ER sessions row **OR** a live in-flight entry.
   Probe line extends to `ER_HOSTED_PROBE:no-row sessions=<n> inflight=<n>` — the naming population's
   instrument becomes the regression instrument.
7. **Sessions table untouched.**

## Named residual (goes in the lane's design comment — stated, never silently absorbed)

The OR-arm admits a hand-run `spt api bind engine-room` DURING a live in-flight window. Same
"not as a first mover" premise holds (the broker DID start a bring-up), it is bounded by the TTL,
and a colliding bind falls to the existing CONFLICT arm.

## Fences (doyle-set, unchanged)

No 30s-bound change. No broker-side logging around `launch_harness_brokered_in` without
stop-and-refer — **this build adds STATE there, no log line**. Sibling-rig stderr census is
HERTZ-class (IR-50), do not expand into it. Rig hermeticity is IR-51 and must NOT be fixed into
this face (a green bought by turning the net off buries the mechanism unread).

## releases#200 — CONFIRMED and RULED by doyle (comment 5344229135)

Every cite source-verified at `5db45f9`; `establish_perch`'s body holds zero `Brain::` /
`cold_start` / `spt_daemon::` references, so the no-RPC claim is structural fact.

- **Broker-mediated mint REFUSED**, and refuted by `bind_engine_room_perch` (broker.rs:10596): the
  perch store is unauthenticated same-user filesystem, so a raw `write_info` mints without running
  EITHER gate — a round-trip would gate only the population the client check already gates.
- The adversary boundary the rule CAN carry is the one `engineroom.rs:143-150` already states
  (intrinsic bind auth + loud collision).
- **Remedy = doc-premise bound**, and its CARRIER is this lane's held post-ledger reword commit:
  amend the "Why EXISTENCE is the key" block (`:135-141`) to quantify over spt-authored seams in
  honest clients, cite #200. **One rewrite, not two** — fold it into the same commit as the refusal
  sentence, cross-recorded on #200.

## Ordered check — DONE before the build, filed separately as releases#200

Reserved-id enforcement is **client-only at the mint seam**, structurally: `establish_perch`
(`startup.rs:534`) writes `info.json` directly, with no broker RPC in the path, so there is no
daemon-side site that COULD refuse. Daemon-side enforcement does exist for OTHER ops
(`registry.rs:782` rename incl. peer reconciliation, `forkop.rs:79`, `autostart.rs:80`). Every
`is_engine_room` gate in `spt-daemon` governs an engine room that already exists, never who may
mint one. (a-prime)'s correctness does not depend on this; any SECURITY claim about the gate does.

## STATUS 2026-08-19 — built, gated, field leg GREEN; gate waits on doyle's legs

Lane: `5db45f9` (diagnostic) → `8437b26` (product: the ledger) → `0f8f483` (test-side: rig witness).

- clippy `-D warnings` exit 0 · `traceable-reqs check` exit 0 (real exit, not through `tail`;
  REQ reads `[OK] +impl +unit`) · units 2 broker + 2 client green, each with a nonzero
  filtered-out count so the filter is proven to have selected.
- **doyle's diff review: PASS** on both commits, every ruling constraint verified at the tip.
  Non-blocking note he raised and I closed by census: `.output()` also captures the SUCCESS
  path, so bind stdout/stderr no longer reach the PTY — the only rig consuming a bind sentence
  (`listen_seed_retry_e2e.rs:147/:210`) reads a directly-invoked child's stderr, not a PTY.
  **Future-rig face stays on the record both sides.**
- **x40 field leg: 40/40 PASS, 0 FAIL** on tip `0f8f483`. Zero `RESERVED_ID`, zero probe lines,
  zero 30s burns; every run 6.1–8.4s (the red mode burned the full 30s, so duration agrees
  independently). Swept the 40 log files directly rather than trusting the loop's counter, with
  40/40 containing the test name as the positive control on the sweep.
- **Carried caveat:** the panel prints only on a red, so green rows read `probe=0 broughtup=0` —
  the panel not firing, not a channel proven silent. Positive control is INHERITED from the x40
  probe population on the same cell (arm named 3/40); this population adds none of its own.

## LANE COMPLETE — awaiting doyle's light re-gate on `0c86b2d`

`5db45f9` diagnostic → `8437b26` product (the ledger) → `0f8f483` test-side (rig witness) →
`0c86b2d` docs (#200 premise bound). Four commits, each one thing.

**Gate closed on the ledger** (doyle, at `0f8f483`): his broker units 2/2 + client units 2/2 (both
filters proven selective), treqs exit 0 at 781/781 including the mint, clippy `--workspace
--all-targets -D warnings` exit 0, plus his diff-review PASS — combined with the x40 40/40.

**The reword was WITHDRAWN, not skipped.** Sequenced to name the in-flight state; reading it after
the fix showed its only reader was the broker's own harness, which the ledger now lets through. Every
survivor is a first mover for whom the sentence is already correct, and `reserved_bind_refusal`
returns the shared sentence verbatim across NINE seams — naming a one-seam fact would break
single-voice for negative value. doyle adopted the refusal and withdrew his own sequencing.
Surviving narrow face on the record: an in-flight entry that EXPIRES before its bind (spawn slower
than `ready_wait`) still reads first-mover advice — TTL-bounded, and by then the bring-up has given
up, so "try again" is advice rather than circularity.

Lane then queues as a batch candidate for next milestone intake, alongside hertz's six-lane ready
queue and bounded_output.

## Sequencing

- Refusal-sentence reword rides **AFTER** the ledger lands — with (a-prime) the circular-advice
  case (the broker's own harness told to run `spt rc engine-room`) dies with the fix, and the
  sentence then names the in-flight state instead.
- Gate's field leg: x40-with-probe population on the FIX TIP, pre-registered at **0/N**, declared a
  NEW population (`scratchpad/x40-arm.sh` is the template — rewrite its header BEFORE running).
- The rig witness (`engine_room_bringup_e2e.rs` panels + `adapters/mock` breadcrumb/stream capture)
  stays UNCOMMITTED beside the lane and must not mix into the product commit.
