---
name: f029-pickerpolish-progress
description: "BUILD-F029-PICKERPOLISH wave progress — W1 shipped pending doyle gate, W2 next"
metadata: 
  node_type: memory
  type: project
  originSessionId: c1598c2d-5568-42bb-8024-36494822dfff
---

**F-029 PICKER-POLISH** (post-v0.23.0). Work order: `docs/NEXT-MILESTONE-PICKER-POLISH-TRIAGE.md` @b6d8357 (doyle, all 4 v0.23.0 bugs code-anchored, no re-RCA). Branch `f028-runtruth`. [twohost]=NO. doyle sequences: register REQs first, per-wave activation, red-first per item, doyle worktree-gate per sha.

**W1 label/render cluster SHIPPED @9ef4501 (pushed), doyle-gate PENDING** (pinged doyle w/ sha). Pure unit-only chunk. Items:
- A-1 (extended REQ-PICKER-PROJECT-DISPLAY-NAME): confirm-panel history line rendered raw `github-com-*` slugs — the ONE A1 site v0.22.0 missed. Fixed via existing `project_history_display(ep)` seam in view.rs render_selection_summary (disambiguate over project_refs, raw-history fallback on refs-less remote rows).
- A-2/A-3 (new REQ-PICKER-CURRENT-DIR-LABEL): build_project_choices (model.rs). A-2 = `(CURRENT DIR)` marker on history row where r.dir==run_cwd (new `history_row_label`); A-3 = `CURRENT DIR --> <folder tail>` replaces `Here: <path>` (new pure `current_dir_display` = Path::file_name tail, honest path fallback — kept build_project_choices unit-pure, NO git/FS probe).
- B-3 (new REQ-PICKER-FORK-LABEL-CWD) + B-4 (new REQ-PICKER-SHORTCUT-LABEL-FILENAME): `confirm_option_label` split into `confirm_option_label_static(opt)` (fixed text) + `confirm_option_label(model, opt)` (dir-relative Fork/Shortcut). B-3 = "Fork endpoint here --> {run_cwd}". B-4 = "Set shortcut here --> {run_cwd}/{file}" where file = `shortcut::shortcut_filename(data::shortcut_basename(&ep.adapter_profile), &ep.id)` — SAME fns the writer (write_shortcut_now) uses → zero drift.

All 5 red-first proven (guard-revert reproduced each exact bug). Grep-tests rule applied: 3 model.rs `"Here: "` asserts + 1 view.rs render assert updated to A-3 label (whole-tree sweep clean). Gate: traceable EXIT=0, clippy --workspace clean, picker nextest 57/57. No int/sibling tests reference the changed labels (grep confirmed).

**GOTCHA (banked)**: `data::shortcut_basename(adapter)` does REGISTRY I/O (reads perch::adapters_dir manifest) → a view unit test asserting a specific shortcut filename FLAKES on a box with the adapter installed (claude-spt manifest could set basename `cc` → `cc-doyle` not `spt-doyle`). FIX in test: use a non-resolvable adapter (`no-such-adapter-xyz`) → falls to DEFAULT_BASENAME `spt`, deterministic across boxes. shortcut_filename is cfg!(windows) → `.cmd` suffix, so assert cfg-aware.

**W2 IN PROGRESS — chunked finely (doyle gates while I build; ping per chunk).**
- CHUNK-1 @b0399cd GATE=PASS: A-4 profile-preserve precedence (REQ-HAZARD-ADAPTER-PROFILE-STAMP-CLOBBER; home.rs stamp_creation_fields keeps prior parent:profile when incoming is bare parent; tiny duplicated split fn — spt-runtime→spt-store dep forbids importing adapter_parent_matches back) + B-5 picker title (REQ-PICKER-WINDOW-TITLE, SetTitle set-only, impl-only HITL).
- CHUNK-2 @2f09d3d GATE=PASS: B-1 launch-key gating (REQ-PICKER-KEY-GATE-LAUNCH-CAPABLE; single launch_keys_live(screen,highlight) predicate gates every h/s site AND the footer legends = hint truth; added missing s to Choose/Resume; dropped stale pick-list hint).
- CHUNK-3 @d7d6024 gating (content review PASS): B-2 change-adapter flow (REQ-PICKER-CHANGE-ADAPTER-FLOW; new Screen::ChangeAdapterPick + Outcome::ChangeAdapter, pick-only→mutate_info write→return to Confirm, no id/home/launch; Instantiate still uses create flow).
- CHUNK-4 @15d48bf C-1 SHIPPED (pushed, gate-pending). B6 ROOT FIX. Built via delegate affc1b649e730af8a, I reviewed whole diff + re-ran all gates + own guard-revert (forced miss->fault = RED, stamp appears). broker.rs run_inject_worker miss!=fault + N=3 strike budget + respool-once/dead-letter + respawn_faulted_translation (bounded, give-up counter reset-on-commit, off-lock rebuild from stored translation_argv) + InfoJson.translation_fault stamp (additive N-1) + 5 distinct FORCE_NATIVE_UNDELIVERED leg= markers + ADR-0022 amendment + manifest docs. Traceable: LIVENESS-DECAY->SUPERSEDED pointer, 2 new REQs impl/unit/int. Red-first 2 units + 2 ints (c1_miss_once, c1_strike_fault). clippy clean, inject_control_wedge 16/16, xtask docs-drift OK. See [[b6-root-pinned-translation-fault]].

**F-029 WAVE FULLY GATED — MY SLICE DONE (doyle verdict: conformance-grade).** ALL chunks isolated-worktree GREEN, all REQ activations satisfied, [twohost] NO: W1 @9ef4501 + A-4/B-5 @b0399cd + B-1 @2f09d3d + B-2 @d7d6024 + C-1 @15d48bf (1543/1543) + A-4-int @30886f3 (GATE PASS 1544/1544). Nine operator items + B6 root fix, one day. STOOD DOWN. Remaining wave threads NOT mine: perri wake-survival e2e @ RC window (floor v0.13.1); SEAM-2 open under its own future REQ (perri discriminant in flight — doyle may cut a late chunk + ping); deployah v0.24.0 counter-44 bump-in-PR when operator calls cut. Reachable for: doyle SEAM-2 late-chunk, v0.24.0 gate assist, any gate-red (none expected).

**A-4 WAVE-FINAL INT @30886f3** (doyle ruled YES — operator field regression = paid-for = conformance E2E): bind_over_created_profile_endpoint_preserves_the_profile (crates/spt/tests/bind_adapter_profile_persist_e2e.rs). REAL bind over REAL spt binary: seed perch adapter=dummyharness:fast, re-bind `spt api --adapter dummyharness --manifest <m> bind <id> --set-session-id <sid>` (same-session reconnect; bare --adapter threads verbatim api::run->cmd_bind->establish_perch->stamp_creation_fields = ADR-0021 agnostic bare-parent resolution), assert info.json.adapter STILL dummyharness:fast. RED-first THROUGH real bind (guard-revert -> BOUND then clobbers to dummyharness). Pattern = live_bind_firsthost (in-proc seed daemon start_inproc_daemon + registered manifest + auto-daemon reap). REQ-HAZARD-ADAPTER-PROFILE-STAMP-CLOBBER now impl/unit/int. GOTCHA: I built it MYSELF — the spt-test-engineer subagent DIED instantly (0 tokens) on a FALSE-POSITIVE cybersecurity safeguard flag (prompt had process-sweep/kill phrasing). If delegating test work again, avoid "kill/sweep/machine-wide" phrasing or use general-purpose agent. api-level --adapter/--manifest go BEFORE the `bind` subcommand; --set-session-id is a bind flag; api bind id is POSITIONAL.

**F-029 COMPLETE — ALL GATED (doyle: "exceptional wave", ten items + two-seam B6 kill). STOOD DOWN.** Full ledger GATE PASS: W1 @9ef4501, A-4/B-5 @b0399cd, B-1 @2f09d3d, B-2 @d7d6024, C-1 @15d48bf (1543/1543), A-4-int @30886f3 (1544/1544), C-2 @e7b514c (1545/1545). deployah has v0.24.0 counter-44 GO. Reachable ONLY for a v0.24.0 gate assist if doyle asks (he drives). Backlog seeds at my pace or idle.

**C-2 LATE CHUNK @e7b514c GATE PASS — SEAM-2 PINNED + FIXED (B6's SECOND HALF).** doyle work order @c8f3e5b. ROOT: at /clear, CC fires SessionEnd(reason=clear) for DEPARTING session BEFORE SessionStart; departing sid still matches pin → adapter soft `api session-end` AUTHENTICATES → removes ready marker (reporting.rs cmd_session_end:206); boundary rotates sid but nothing re-writes ready → is_online false → try_spt_hosted_inject Nones on CLI gate before any broker RPC → every post-clear force-native (incl checkpoint FIRE) UNDELIVERED forever. Single differing gate field = ready-absent (perri wakep9 vs wakep4). FIX (surgical, REQ-HAZARD-BOUNDARY-READY-STRAND): cmd_boundary re-stamps ready marker + set_status online (idempotent) right after the sid-rotation mutate_info. Red-first int boundary_ready_strand_e2e (REAL spt binary: seed bound perch → real `api session-end --session-id <pin>` → ready gone/gate false → real `api boundary clear --to-session-id <new> --session-id <pin>` → ready PRESENT/gate true/sid rotated; RED via guard-revert = boundary rotates but ready stays absent). reporting 19/19, clippy clean, traceable EXIT 0 (impl/int). GOTCHA: api session-end + boundary are auth-gated (gated()) — pass --session-id=<current pin> as proof (matches the field mechanism: departing sid still matches pin pre-rotation); is_spt_hosted_no_relay = is_online(ready file + is_perch_alive) + no relay + controllable==Some(true). Follow-up seeds NOT scope: (a) harness-hosted relay unregister_address casualty of same root, (b) adapter fire-session-end-only-on-genuine-ends, (c) owner-alive guard in soft session-end.

**B6 CLOSED END-TO-END**: (B) zero-record kill [adapter v0.13.1 @52dc092] + C-1 miss-tolerance [gated @15d48bf] + C-2 ready-strand [@e7b514c] = wake alive again. See [[b6-root-pinned-translation-fault]].

Wake-survival e2e (ARM->clear->FIRE->wake) rides ADAPTER-side w/ perri (floor claude-spt v0.13.1 @52dc092).

GOTCHA (banked, C-1): $OWL send message goes via STDIN (`printf '%s' "msg" | $OWL send doyle`), NOT positional — 2nd positional arg is FROM not message; positional msg = EMPTY_MSG silent-fail exit1. See [[owl-send-unquoted]]. Delegate hit disk-full (LNK1318 62MB free) mid-build, reclaimed via deleting target/debug/incremental (safe rebuild cache).

**C-1 spec (doyle-locked @2915eb8, pin=(B) zero-record response):** broker.rs run_inject_worker — miss≠fault (deadline miss on ALIVE binary: keep flush+release floor, respool ONCE, `continue` not return; binary+pending_wake survive) + N=3 consecutive-miss strike budget (commit resets) + respool-once/dead-letter (worker-local HashSet<envelope>; 2nd miss of same = dead-letter LOUD, no re-respool — else infinite 5s floor-hold cycle) + bounded respawn on REAL fault (binary-death/strike-exhaustion, REQ-HAZARD-TRANSLATE-FAULT-PERMANENT-DEATH, reuse C3(b) budget) + perch-visible translation_fault stamp (mutate_info; today stderr-only = F-019 trap) + UNDELIVERED-by-leg stderr (differentiate cli.rs FORCE_NATIVE_UNDELIVERED: gate-refused/no-session/spooled — SEAM-2 rider) + ADR-0022 amendment (never-respawn premise changes; gate-against-documented-design) + docs (manifest.md:323 published stale "raw inject" wording + MANIFEST.md:329 internal missing {commit} vocab + NEW rule "every {type:event} answered with ≥ bare {commit}"). Red-first via SPT_INJECT_COMMIT_DEADLINE_MS Layer-G rig. int REQUIRED. Deadline UNCHANGED (5s whole-sequence). Adapter floor = claude-spt v0.13.1 (perri, bare-commit-on-nothing-armed). SEAM-2 (busy-box immediate-undelivered, t+2s, stalled pump) = SEPARATE open item, NOT this chunk.

**v0.24.0 RC-WINDOW (2026-07-04, doyle-gated) — BOTH ITEMS RC-GREEN, flip cleared.** Draft was FLIP-BLOCKED first: release run 28697155477 Windows checkout EPERM on leaked runner-workspace `target\debug\spt.exe` — RmGetList pinned 4 blank-path cross-account spt.exe PIDs as image-mapped lockers; kill impossible non-elevated (sudo disabled, access-denied even GetOwner) → **DISPLACE not kill** (F-028 C1 pattern: Move-Item locked exe → `C:\actions-runner\_leak\`, repo-dir rename round-trip proved zero residual handles) → rerun --failed green. RC on candidate sha `d89307a6…7cfee` (staged `C:\Users\decid\spt-rc\v0.24.0\`, checksum vs SHA256SUMS): ITEM-1 wake-survival full-stack GREEN 5 boundary runs (C-1 zero faults, C-2 ready re-stamp ≤2s, v0.13.1 unarmed-fires safe); ITEM-2 SEAM-2 strand ELIMINATED (150ms timeline ready=True through rotation; 157/157 force-native hammer 0 UNDELIVERED). Wake TURN still doesn't execute = PRE-EXISTING (identical 0.23 control). **F-031 seed (CORRECTED 2026-07-04 — perri retracted her prompt-queue/draft-restore mechanism chain after operator catch; carry OBSERVABLE + OPENS only):** frozen-state observable = one ARM inject logged, one clear executed (sid rotated once, t+4s), then post-boundary screens show "/clear" TYPED AGAIN unsubmitted in input box + wake unsubmitted in prompt queue, frozen 60s+. Two open mechanism questions: (1) what produced the SECOND "/clear" typing (only actor that types it = ARM clear-half, which shows exactly one ENDPOINT_INJECT — keystroke replay across boundary without second logged delivery, or another emitter?); (2) why neither input-box text nor queued wake ever submits post-boundary while pre-boundary inject+submit provably works. "native mid-active" tell at ARM time = real observable, causal role UNPROVEN. Blind extra Enter still UNSAFE on the observable alone — "/clear" sits in input box, Enter = double clear. **REFRAME (adapter v0.13.2 @363ecab, 2026-07-04, wake arc LAYER 5):** operator found wake ARRIVES on bounced 0.24.0 box (C-1/C-2 field-confirmed) but sat unsubmitted w/ trailing newline — clear/wake halves LACKED the 50ms text→enter settle normal delivery carries; discrete enter's \r coalesced into still-landing text = soft newline instead of submit (short "/clear" usually won the race, paragraph wakes reliably lost). Fix shipped: both halves now ctrl+s/50/text/50/enter/commit. PROBABLE mechanism for the whole frozen-state observable (both halves losing enters = unsubmitted "/clear" + unsubmitted wake, no CC queue anomaly needed) — F-031 two opens PENDING-COLLAPSE on a 0.13.2 wake-survival confirm (operator checkpoint on bounced endpoint = live proof; resident translates carry 0.13.1 until endpoint respawn). Floor stays 0.23.0. If frozen state reproduces ON 0.13.2 → opens revive. **v0.13.2 BAD SHIP (perri-flagged + hall-bf field RCA, 2026-07-04):** 0.13.2 was cut from HEAD carrying the PARKED ephemeral-psyche build (@df402b3, publish was F-030-gated; settle fix tagged with the passenger). On no-F-030 core: [session.psyche_resume] run-to-completion shim exits after seed turn → daemon residency machinery re-hosts every ~5s (reconcile interval) → hosted/controllable teardown removes READY marker, never re-stamped → every force-native gates `leg=cli-gate-not-hosted` (leg labels' first field catch). hall-bf = field case #2: bounced 09:12Z post-apply, fresh translate healthy (EXONERATED — "translation binary broken" symptom was the CLI gate), no ready file, psyche_host_error attempts=54, psyche sessions.log ordinal 6449 boot-churn @5s cadence (= thousands of seed turns burned; C3(b) cooldown bounded it). CONTAINMENT: ephemeral reverted on main (branch psyche-ephemeral-parked keeps it for F-030), v0.13.3 = settle fix on resident model, 0.13.2 superseded-warning, exposure ~1h, recovery = adapter update + live-agent restart. Post-mortem seed: perri runbook needs parked-work exclusion check pre-tag. Unplanned live proof of F-030 residency-expectation floor evidence. **RESOLUTION (2026-07-04): WAKE ARC CLOSED END-TO-END.** perri wakefin3 GREEN on 0.24.0 + 0.13.3: wake turn EXECUTED (side-effect proof file +12s) — full five-layer stack proven (0.13.1 zero-record + C-1 miss≠fault + C-2 ready-restamp + 0.13.3 submit-settle + resident psyche). F-031 opens COLLAPSED: frozen state WAS the enter-coalescing, disproven-by-execution; perri promoting wake-confirm-0133.sh to repo int (REQ-HAZARD-CHECKPOINT-CLEAR-RACE int successor). hall-bf field recovery VERIFIED (doyle bounce via endpoint suspend/wake): ready persisted, real checkpoint /clear at 09:28:39 re-stamped ready at boundary-time = C-2 field-proof; psyche_download +1s. **Field residuals:** (1) relay-unregister casualty FIRST FIELD REPRO — post-clear owl send → NO_PERCH while ready present + inject path healthy (known C-2 follow-up seed (a), core-side, priority-bumped); (2) psyche non-residency churn ROOT PINNED (perri): runner per-pulse poll = `spt ready <id> --once` NO --subnet → multi-subnet node (BIGNET joined 7/3 = exact churn start) refuses READY_FAIL → runner treats ANY poll non-success as perch-gone, exits 0 SILENT → daemon rehosts ~5s forever (ordinal 6491+; synthetic sess-<pid>-<ts> = rehost machinery records; turns still work via daemon-driven paths). Adapter half SHIPPED v0.13.4 @d3506fe (poll_refused: READY_FAIL-marked poll fail → PSYCHE_POLL_FAIL loud exit 4 for psyche_host_error; plain perch-close keeps quiet exit; KH 2.6 second leg + 2 units + REQ extended; node applied — hall-bf churn becomes VISIBLE stamped fault, residency waits on F-030 nested-resolution seam). Core seeds: (a) nested-psyche subnet-less resolution / {subnet}{home} role fill — folds into F-030 wave (daemon fills only {id,session_id,psyche_dir,psyche_prompt}); (b) C3(b) thrash guard BLIND to 12/min rehost cadence (boot records maybe not ledger boundaries) — doyle investigate seed; (c) iso/no-subnet NONRESIDENT plausibly same verb other-branch, verify in F-030. F-030 field case complete BOTH directions; ephemeral parked branch ready for wave call. (3) info.json pid = dead transient (262868) = F-026 deferred #11 dead-pid class. GOTCHA: `endpoint wake` help says "no fresh spawn" but daemon livehost re-host DOES fresh-spawn the session; owl-send NO_PERCH right at a boundary window can be transient — re-probe before concluding. **Other seeds:** bringup dead-harness flake retry/loud-fail hardening (ADAPTER_INSTALL_PENDING race, both versions, not version-pinned); LIVEHOST_PSYCHE_NONRESIDENT in every iso run both versions = daemon expects residency (F-030 floor evidence); broker-PTY probe sessions leave session-env but ZERO transcript jsonl in any config root (rig gap — transcript-based asserts blind; use side-effect proof files). Perri evidence tasks: bwumwwu3t/bt0tqgjb8 (item-1), b30bs5y9g (item-2).

See [[f028-runtruth-w3-progress]] (prior wave, DONE). [[agent-roles]] doyle=gater.

**Index-detail preserved on 2026-07-06 compaction:** COMPLETE incl. C-2 @e7b514c (1545/1545): W1 @9ef4501, A-4/B-5 @b0399cd, B-1 @2f09d3d, B-2 @d7d6024, C-1 @15d48bf, A-4-int @30886f3, C-2 ready-strand @e7b514c. B6 CLOSED end-to-end (v0.13.1 + C-1 + C-2). v0.24.0 RC-WINDOW BOTH-GREEN 2026-07-04, flip cleared (perri: SEAM-2 strand ELIMINATED 157/157; wake-turn non-exec = pre-existing; F-031 seed twice-revised: retraction → then adapter v0.13.2 @363ecab layer-5 REFRAME (missing 50ms text→enter settle, \r coalesced = soft newline; opens PENDING-COLLAPSE on 0.13.2 wake-survival confirm); C-1/C-2 field-confirmed wake arrives); release run EPERM unblocked by DISPLACE-not-kill of leaked runner spt.exe. GOTCHAs: shortcut_basename registry I/O → non-resolvable adapter in view tests; xtask check reds on leaked-e2e-daemon spt.exe lock → sweep scoped first.
