<!-- RECOVERED VERBATIM from doyle's spt send, drain
     sptc-drain-9fae17b4-18b7-4e33-9791-60cb82da7669-1787359473276-37092.txt,
     saved here 2026-08-21 by todlando so the next session does not have to hunt a
     drain file for it. NOT retyped, NOT summarized — copied byte-for-byte out of
     the authoring transcript, which is the only place a dispatch's exact wording
     survives (a digest truncates it).

     ONE THING THE TEXT SAYS THAT IS NOW STALE, flagged rather than edited: the
     header says "HOLD until #209 census report is ruled". That happened —
     #209's census WAS ruled (riders R1-R5 + F1/F2) and Lane 3's [CENSUS-PENDING]
     block is already filled in with the ruling. Lanes 2 (#206) and 4 (#210) are
     GO per doyle 2026-08-21: "W2 lanes (#206/#210 can start immediately per the
     W2 brief) are yours whenever you want them." The brief's own Sequencing
     section says the same. Everything below is doyle's words, unaltered. -->

# TURNKEY W2 — ER/access cluster (#208, #206, #200, #210) — brief for todlando

DRAFT (doyle) — HOLD until #209 census report is ruled; #200's shape rides that census.
Sections marked [CENSUS-PENDING] get finalized from the report. Base: main @ c62904e7.
Gates: witnessed red + pin + clippy + treqs per lane.

## Lane 1 — #208: retained ER briefing rows accumulate; six-copy burst

- Field census + measure-first plan = first comment on #208 (mine, binding as the
  starting checklist): (a) find retention writer + drain reader, keying
  (per-attempt vs per-endpoint); (b) confirm supersession ABSENT vs broken;
  (c) rule supersession site; (d) pin: N failed bring-ups + one success → exactly ONE
  briefing (newest) delivers.
- OPERATOR DESIGN GUIDANCE (on-issue, SaberMage relay): SESSION-SCOPED EPHEMERALITY is
  the honest shape — a briefing row is keyed to the bring-up/session it describes and
  dies with that session; a new bring-up mints a fresh row. Supersession-at-write =
  belt within one session's lifetime; plain time-TTL is the wrong knife (the retained
  row's 'delivered at first idle' promise is what made #204's fix visible).
- Report the writer census BEFORE building; I rule the final shape (session-scoped +
  write-replace belt is the expected outcome, but census may surprise).
- Hazard note: #204's ENGINE_ROOM_BRIEFING_UNPRESENTED false-fire face
  (narrowing-fail-open memory) is adjacent — do not regress it; empty-subject loud
  arm stays quiet on re-attach.

## Lane 2 — #206: is_locked() never reads modes (three faces, one mechanism)

- Measured transcript in the issue (todlando's own filing — you have the repro).
- Ruled shape: ONE predicate. is_locked asks the CHAIN's posture (consult modes /
  the decision chain), not allowed_nodes().is_empty(); BOTH consumers (revoke's
  ACCESS_LOCKED line at cli.rs:18701, JSON view's locked field at cli.rs:18819) take
  that one answer — single-source-discriminant class, no second reading of "locked".
- JSON/human parity pin: same store → same posture in both renderings (the issue's
  face 2 becomes the test).
- Vacant-record face: prune the vacant record in AccessStore::revoke as
  apply_mutation already does on Remove — separable; land it in the same lane but as
  its own commit with its own pin (vacant record must not read as restricted).
- Ways-in census: precise allow arm + knock/redeem paths write through the
  posture-blind mutation seam — pin at least the revoke-after-precise-allow path red
  first (verbatim from the issue transcript).

## Lane 3 — #200: reserved-id gate declared node-wide, enforced in-client at mint seam

[RULED off #209 census §6 (2026-08-21): DAEMON-SIDE enforcement is the shape — move
the reserved-id check to the one site every mint arm must cross. The census's
declare/enforce frame is binding: declare = reserved_id_refusal (engineroom.rs:~85);
today's enforce = mint verbs in-client; defect = any door reaching the identity
without the predicate (engineroom.rs:72's own doc names `spt endpoint run
engine-room`). BUT establish_perch has NO broker RPC structurally — so the honest
fix is two-part: (a) daemon-side refusal at every seam the daemon DOES cross
(registration/attach/rename/fork/autostart already hold; add any found missing),
(b) the CLAIM in engineroom.rs:136-141 re-scoped to what the seams actually hold —
same-user local writes are outside the boundary, same R4 scope-honesty language as
#209's docs amendment (one boundary statement, two consumers — do not fork the
wording). Client-side checks STAY (UX refusal at the verb), they just stop carrying
the security claim.]
- Issue's own enforcement census (todlando): daemon-side = registry.rs:782 rename,
  forkop.rs:79, autostart.rs:80; client-only = startup.rs:910/:1096, ready.rs:73,
  cli.rs x4, picker/model.rs:1029. Mint seam (establish_perch, startup.rs:534) is
  client-only STRUCTURALLY — no broker RPC exists in that path.
- Expected shape (to confirm against census): move/duplicate enforcement to a
  daemon-side seam the mint cannot bypass, OR re-scope the documented claim to what
  the seams actually hold — which, depends on where #209's fix puts the ONE gate
  site; if the #209 gate site sees perch registration, the reserved-id check belongs
  there too. #211 seam constraint binds here as well (intra-node tier must stay
  insertable).
- Re-verify the issue's line numbers at c62904e7 before building (filed against an
  earlier tree).

## Lane 4 — #210: ER Ruleset presentation (thin)

- Two changes: (1) Ruleset renders as a markdown table, not a list; (2) node subjects
  render the node NAME (node:ENLYZEAM), not the truncated hash — resolve via the
  roster; UNRESOLVABLE node id degrades to the hash, never errors, never blank.
- One composer, two renderers memory: check whether the Ruleset block renders through
  more than one path (briefing compose + any status/JSON view) — the table change
  must not fork the composers; JSON surfaces (if any) keep machine shape.
- Rendered-output verification (the #74 discipline): assert on the rendered briefing
  text, not the source literal.

## Sequencing
- #206 + #210 independent — can start immediately at W2 dispatch.
- #208 census-report-then-rule (its own census, not #209's).
- #200 last — needs my post-census ruling; its lane may share the gate site with
  #209's fix (coordinate: if so, build it ON the #209 lane tip, not main).
