---
name: nextwave-f025-listredesign
description: "BUILD-F025-LISTREDESIGN wave order (dispatched to todlando 2026-07-02): F-025 update-apply honesty triplet → STORE-INIT-RACE → endpoint-list redesign resume (rebase endpoint-list-redesign onto main@3043f4e, activate the two @1fe3c51 stubs). Doyle gates per sha, detached-worktree protocol."
metadata: 
  node_type: memory
  type: project
  originSessionId: 45ac468c-e421-4a86-b48a-3de186e3ba15
---

Wave BUILD-F025-LISTREDESIGN dispatched to todlando 2026-07-02 (post v0.20.0 counter 40). Base: main @3043f4e. Order (field-critical first):

**Item 1 — F-025 update-apply honesty (3 REQs, todlando mints from doyle titles in first wave commit, stages [] then incremental):**
- REQ-UPDATE-RUNNING-IMAGE-SURFACE: running BROKER image version reported beside disk version (must come FROM the running broker process over IPC, not inferred; brain restarts on apply per ADR-0018 D3-3, broker survives = broker is the stale half).
- REQ-UPDATE-APPLY-RESTART-NOTICE: apply prints loud restart-required notice (public wording, no internal codes — [[update-apply-confident-message]]) when the surviving broker stays on the old image.
- REQ-UPDATE-APPLY-ALREADY-APPLIED: apply gets fetch's v0.18.0 already-staged/already-applied classifier (friendly exit 0; never reaches binary-aside rename — fixes the os-error-5). Mirror ALL apply reject sites like fetch did.
- OUT of scope: broker-restart choreography (ADR-0004 design-first).

**Item 2 — REQ-HAZARD-STORE-INIT-RACE:** BranchStore::open_or_init TOCTOU (branchstore.rs:47) — concurrent first-touch of one fresh store → git config.lock collision → hard Err (G3-gate field proof: pump.rs:442 flake). Fix shape free (open-after-lose success / init lockfile / bounded config.lock retry); red-first unit = concurrent open_or_init on one fresh dir.

**Item 3 — endpoint-list redesign resume:** branch endpoint-list-redesign (@025b305 additive foundation + @1fe3c51 REQ stubs) REBASED onto main@3043f4e (predates F-023 wave; toml conflicts expected). Design = the two stub titles verbatim (REQ-ENDPOINT-LIST-NODE-GROUPED + REQ-ENDPOINT-LIST-REST-FILTER, grill-with-docs ruling — node-grouped unique instances, freshest-epoch merge, suspended hidden + --show-all, corrupt ALWAYS visible, disclosure totals, --json frozen additive). Build hazards pre-recorded in stub comments: old-subnet-shape test assertions, whoami shares the path, xtask docs regen.

**Protocol:** wave branch off main@3043f4e, REQ mints first commit, incremental activation, red-first, push-per-checkpoint + ping; doyle interim-gates each sha (detached-worktree + fresh throwaway target + nextest --retries 2), FINAL gate full protocol at wave-complete; release after (likely v0.21.0, counter 41 from PUBLISHED metadata). CLI-surface items (apply messages + endpoint list) BOTH need xtask docs regen — drift gate is CI-enforced.

**Gate ledger:**
- Item 1 (F-025 triplet) INTERIM PASS @ff87861 (2026-07-02, doyle): traceable 344/344, clippy clean, nextest 1288/1288 on virgin target. Non-blocking for FINAL wave: (a) render_broker_image_line None arm over-claims "predates version reporting" when None can also be transient IPC failure (+ JSON broker_stale=true conservative false-positive on cold_start Err); (b) int must round-trip KIND_BROKER_IMAGE vs REAL broker incl old-broker→None leg. GATE-HARNESS GOTCHA: virgin target + `nextest --lib --bins` does NOT build plain `[[bin]]` fixtures (translate_proof_fixture) → cli unit `adapter_translate_proof_gates_on_commit` false-red; run `cargo build -p spt --bins` first. todlando post-gate: softening None-arm wording immediately; broker_stale Err-vs-Ok(None) threading + int leg ride final wave.
- Item 2 (STORE-INIT-RACE) IN FLIGHT: todlando's red-first surfaced race BROADER than config.lock — concurrent `git init` also collides on template-hook copy (File-exists, exit 128); fix = bounded backoff-retry on init+config.lock, open-after-lose on racer-created HEAD. INCIDENT 2026-07-02 CLOSED: his PRE-GUARD red-first test dumped bare git-init droppings (HEAD/config/description/hooks/info, mtime 16:44:14) into shared checkout ROOT — pinned via his own heads-up quoting root-path init output; guard edit inadvertently fixed the path bug so post-guard couldn't repro. Cleanup verified; test now asserts absolute+under-TempDir+not-under-cwd pre-spawn. PRODUCTION EXONERATED: open_or_init takes explicit path, spt_home() panics rather than returning empty — no prod path inits cwd. Ruling: push without bisecting. THIRD symptom accepted pre-push: Win sharing-violation on config.lock→config rename ('Permission denied'/'unable to access config'/exit 128, NOT POSIX could-not-lock) → broadened bounded-retryable set + --get skip-if-already-set herd-cutter. Item 2 INTERIM PASS @0214143 (2026-07-02, doyle): traceable 0 findings, clippy workspace clean, nextest 1290/1290, race test 3× stable + worktree root droppings-free. Checklist all met (isolation guard / KH 7.26 rule-4 / prod determination in commit body / pure classifier both families + controls + deliberate-ACL-trade). Item-1 None-arm wording softening folded into this commit — accepted. FIX-FORWARD nits owed in a later Item-3 commit: (a) KH condensed-table tag adjacency — 7.26 row inserted between 7.25 row and 7.25's doc tag, needs own tag + 7.25's tag restored adjacent; (b) config_set_locked_retry doc comment stacked onto config_error_is_retryable, move to its fn.
- Item 3 (endpoint-list redesign) IN FLIGHT. Foundation cherry-picked (stubs @1b71185, endpoint_type @1cfc38d, epoch+nit-folds @54e7c48). Phase A (NODE-GROUPED) INTERIM PASS @2e6acc5 (2026-07-02, doyle): traceable 347/0, clippy clean, xtask OK, nextest 1295/1295; title clause-by-clause conformant; evidence re-homing verified via tag-inventory diff (PICKER-5/MERGE-LOCAL/NODE-IDENT/PALETTE/UNBOUND re-homed, REQ-CLI-1 covered elsewhere); Item-2 nits folded. Phase A was subagent-built, todlando-reviewed — held up. Phase B (REST-FILTER) INTERIM PASS @8697dbd (9d54a72 rest-filter + 8697dbd REQ-CLI-1 superseded-pointer fold): traceable 349/0, clippy clean, nextest 1298/1298, xtask OK w/ --show-all in reference.md. Corrupt-always + disclosure verbatim + band order all conformant; red-first agreed shape. NIT owed fold-forward: all-hidden roster renders '(no local perches)' beside 'Total: 0 (+M suspended hidden)' — suppress marker when hidden>0. Phase C LANDED @48597d8 (--json additive endpoint_type, DTO frozen) + Item-1 folds @a29c5f1 (real-broker int + broker_stale tri-state) + marker fold @04a3622.

**FINAL GATE PASS @04a3622 (2026-07-02, doyle) — WAVE COMPLETE, GO FOR RELEASE.** 14 commits linear off origin/main tip 3043f4e (PR-clean). traceable 0 · clippy workspace clean · xtask OK · FULL nextest --workspace 1477/1477, ZERO flaky (retries available, none consumed), incl int/e2e. 4 leaked spt.exe swept scoped to my throwaway target. All interim verdicts stand; every find/nit folded + verified in head. GOTCHA: worktree removal blocked post-suite by lingering handle on crates/spt-daemon (holders = live infra, untouchable) — residue dir in Temp harmless; sweep BOTH the external throwaway target AND worktree-local target paths before removal next time.

**Release next: v0.21.0** (counter RECOUNT from PUBLISHED metadata at cut, expect 41; bump-in-PR; todlando or deployah drives; doyle gates CHANGELOG-vet + cut sha). No [twohost] transport surface this wave — plain PR defensible; tag goes in PR TITLE if used. CHANGELOG surfaces: apply restart-notice, already-applied exit-0, daemon-status broker-image line + broker_image/broker_stale JSON, node-grouped list + --show-all + disclosure + ENDPOINTS: removal, --json endpoint_type. Consider update-set-before-flip-public (v0.19.1 stale-window candidate). GATE-HARNESS GOTCHA 2: xtask spt_bin() hardcodes <root>/target/debug, IGNORES CARGO_TARGET_DIR — run drift gate on default target (worktree-local), throwaway-target protocol breaks it.
