**PUBLISHED ✅ counter 32, Latest (deployah 2026-06-23).** Bump-in-PR clean: PR#35 green BOTH runners (Win held — netstream #4 fix in base), merged @365fb0c. hashes linux 98714384… / win 08e8a267…. Cut carried F-019 @4fd028d + ADR-0022 amendment @1eaeef1 + design doc. doyle releasing perri for real-CC validation (idle-submit choreography on real Windows CC = THE #1 blocker close-out criterion).

**NEXT:** perri real-CC validation pending → THEN raw-inject REMOVAL build = todlando's next SEPARATE assignment, OPERATOR-TIMED (doyle sends scope when operator rules timing). Removal = declared-but-failed OR absent translation binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject (per ADR-0022 amendment). GOTCHA reaffirmed: `spt` has NO lib target (`--bin spt`); spt-daemon + spt-runtime DO (`--lib`).

---
name: f019-translation-install-dir-resolve
description: "F-019 (v0.14.2) — adapter-shipped program paths resolve against install_dir; the #1 CC-on-Windows idle-submit blocker. PUBLISHED counter 32 @365fb0c"
metadata:
  node_type: memory
  type: project
  originSessionId: 8fdec519-d622-4c8c-a382-d86ef72d5662
---

**F-019 = v0.14.2 (REQ-INSTALL-11 extension). doyle design @1941eb8 → todlando build → doyle gate → perri verifies real CC.** Branch `fix/f019-translation-install-dir-resolve` off **main @46289ab** (v0.14.1 merged, PR#34). Built @4fd028d, NOT pushed.

**ROOT (perri + doyle, real claude-spt — THE #1 CC-on-Windows blocker):** spt-hosted idle delivery typed the envelope into CC but NEVER submitted ("stacked" unsent). After a multi-hour black-box hunt (byte encoding, win32-input-mode ?9001h, bracketed-paste, focus, pacing — ALL moot), root = the `[message-idle-translation-binary]` ships a BARE relative path `"cc-spt-idle-translate"`; spt-core passed it VERBATIM to the broker → `Command::new` against daemon cwd/PATH → spawn FAILED → session FAILED CLOSED to raw inject → the binary's `{text}{delay}{key:enter}{commit}` choreography never ran. The binary never spawned; the adapter choreography was correct all along. REQ-INSTALL-11 already shipped `resolve_program_in_dir` + session/psyche/digest route through it — the translation binary + notif command were the MISSED surfaces.

**FIX (4 spawn sites, all via resolve_program_in_dir / ManifestRuntime::with_install_dir):**
- `harnesshost::launch_harness_brokered_in`: new `resolve_translation_binary(path, install_dir)` helper for the translation binary, + the harness SESSION program also routed (uniformity — no-op for the PATH harness binary `claude`, future-proofs a shipped launcher). The INITIAL spawn.
- `broker::read_translation_path` (broker.rs): the W3d live-update RESPAWN — was returning the manifest path VERBATIM (doyle's 2nd-site catch; would re-break after the initial fix). Now `.map(|b| resolve_program_in_dir(&b.path, install_dir))`.
- notif command, TWO sites — `notif.rs` shell-render (`record.source_dir`) + `api/reporting.rs` resurface (match manifest→registered record→source_dir): both were `ManifestRuntime::new` (no install_dir) → `with_install_dir`. Third miss-class.
- AUDIT: digest (threads install_dir) + lifecycle/psyche (with_install_dir) confirmed ALREADY-resolved.

**KEPT** the existing `TRANSLATION_SPAWN_FAILED:<path>:<err>` log (broker.rs:1077) — doyle: it's NOT new, the gap is it lands on the DETACHED daemon stderr nobody reads ("silent in practice"). KH diagnosis note added (tied to REQ-INSTALL-11, NOT a new REQ-HAZARD): "confirm an adapter binary actually SPAWNED before behavioral diagnosis." MANIFEST.md contract note: path resolves vs install_dir + extended the resolved-surfaces list.

**FALLBACK FLOW UNTOUCHED** (binding hold): build_translation None → raw inject is unchanged here. **Operator RULED drop raw-inject ENTIRELY** → spt-hosted idle = translation-binary-only; declared-but-failed OR absent binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject. doyle authored the **ADR-0022 amendment** (docs/adr/0022...). The raw-inject REMOVAL is a SEPARATE build assignment doyle dispatches AFTER F-019 lands (F-019 ships first as the immediate CC unblock).

**GATES GREEN (local Win):** clippy `--workspace --all-targets` EXIT0 no-warn; `cargo test -p spt-daemon --lib` (new unit + notif 19 + harnesshost) green; `cargo test -p spt-runtime --lib resolve_program` 3 green; traceable EXIT0 (REQ-INSTALL-11 [OK] +doc+impl+unit, no stage change — extends coverage). unit = `translation_binary_resolves_against_install_dir`. HITL = perri real claude-spt: shipped RELATIVE-path manifest, fresh endpoint, `spt send` → CC SUBMITS (she reverts her interim absolute-path workaround on this shipping).

**DOYLE GATE-PASS @4fd028d 2026-06-23** (re-ran: clippy --workspace EXIT0; spt-daemon --lib translation unit + notif 18 green; spt-runtime --lib resolve_program 3 green; traceable EXIT0; diff design-faithful, all 4 sites + uniformity + fallback-untouched, notif 3rd-class catch credited).

**v0.14.2 CUT carries TWO commits** (deployah): F-019 fix @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab) **+ ADR-0022 amendment @1eaeef1** (raw-inject removal DESIGN + F-019 record, on design/endpoint-creation-flow — a tracked ADR that must ride v0.14.2). deployah cherry-picks 1eaeef1 (+ design doc 1941eb8 if carrying design docs) alongside 4fd028d.

**NEXT:** v0.14.2 cuts (perri verifies real CC at publish) → THEN raw-inject REMOVAL build = todlando's next SEPARATE assignment, OPERATOR-TIMED (doyle sends scope when operator rules timing). Removal = declared-but-failed OR absent translation binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject (per ADR-0022 amendment). GOTCHA reaffirmed: `spt` has NO lib target (`--bin spt`); spt-daemon + spt-runtime DO (`--lib`).

-**NEXT:** v0.14.2 cuts (perri verifies real CC at publish) → THEN raw-inject REMOVAL build = todlando's next SEPARATE assignment, OPERATOR-TIMED (doyle sends scope when operator rules timing). Removal = declared-but-failed OR absent translation binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject (per ADR-0022 amendment). GOTCHA reaffirmed: `spt` has NO lib target (`--bin spt`); spt-daemon + spt-runtime DO (`--lib`).

+**PUBLISHED ✅ counter 32, Latest (deployah 2026-06-23).** Bump-in-PR clean: PR#35 green BOTH runners (Win held — netstream #4 fix in base), merged @365fb0c. hashes linux 98714384… / win 08e8a267…. Cut carried F-019 @4fd028d + ADR-0022 amendment @1eaeef1 + design doc. doyle releasing perri for real-CC validation (idle-submit choreography on real Windows CC = THE #1 blocker close-out criterion).

+**NEXT:** perri real-CC validation pending → THEN raw-inject REMOVAL build = todlando's next SEPARATE assignment, OPERATOR-TIMED (doyle sends scope when operator rules timing). Removal = declared-but-failed OR absent translation binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject (per ADR-0022 amendment). GOTCHA reaffirmed: `spt` has NO lib target (`--bin spt`); spt-daemon + spt-runtime DO (`--lib`).


Update ledger (counters) + MEMORY.md index hook.


<system-reminder>This memory is 4 days old. Memories are point-in-time observations, not live state — claims about code behavior or file:line citations may be outdated. Verify against current code before asserting as fact.</system-reminder>
1	---
2	name: v0121-published
3	description: "v0.12.1 published 2026-06-18 (counter 26, PATCH); real-harness lifecycle fixes + CLI polish"
4	metadata:
5	  node_type: memory
6	  type: project
7	  originSessionId: 291b3f47-b265-4a38-867f-ac3d798281c0
8	---
9
10	v0.12.1 PUBLIC 2026-06-18 (counter 26); PATCH 0.12.0→0.12.1; real-harness lifecycle fixes (v0.12.0 lifecycle fixes were green-on-mocks but broken in the real claude-spt harness — see [[v0121-realharness-reopen]]): attach output, tab-close survival (viewer-close-detach), broker attach wedge/deadlock; + CLI polish (endpoint list always-merges-local / `--local` removed, picker Attach-for-online + fresh-shows-under-project, `spt --help` renders markdown). main @86f20ac.
11
12	DIVISION OF LABOR (differs from prior releases): **doyle drove changelog→bump (0.12.0→0.12.1)→merge-to-main→green CI both runners→tag**; deployah leg = SIGN + PUBLISH ONLY (RELEASE-RUNBOOK step 4). todlando cross-checked changelog scope; 2 trailing commits (185eaee/86f20ac) = test/CI-hygiene, no bullet (correct per [[changelog-scope-vs-commit-range]]). sign+publish: update-set v26. Hashes: linux `fa6a3cdfdd7555d0…` / win `2c5ca121ed14c20b…`. Publisher leg 20× clean (counter 7-26).
13
14	COUNTER: v0.12.0=25 → v0.12.1=26 (confirmed vs my publish logs; release-publish monotonic rollback-floor accepted 26). hfenduleam disk held (~322G free, recovered from the mid-session 100%-full event). EIGHT releases this revive session: v0.8.3→v0.8.4→v0.9.0→v0.9.1→v0.10.0→v0.11.0→v0.12.0→v0.12.1. See [[v0120-published]].
15

---
name: v0121-published
description: "v0.12.1 published 2026-06-18 (counter 26, PATCH); real-harness lifecycle fixes + CLI polish"
metadata:
  node_type: memory
  type: project
  originSessionId: 291b3f47-b265-4a38-867f-ac3d798281c0
---

v0.12.1 PUBLIC 2026-06-18 (counter 26); PATCH 0.12.0→0.12.1; real-harness lifecycle fixes (v0.12.0 lifecycle fixes were green-on-mocks but broken in the real claude-spt harness — see [[v0121-realharness-reopen]]): attach output, tab-close survival (viewer-close-detach), broker attach wedge/deadlock; + CLI polish (endpoint list always-merges-local / `--local` removed, picker Attach-for-online + fresh-shows-under-project, `spt --help` renders markdown). main @86f20ac.

DIVISION OF LABOR (differs from prior releases): **doyle drove changelog→bump (0.12.0→0.12.1)→merge-to-main→green CI both runners→tag**; deployah leg = SIGN + PUBLISH ONLY (RELEASE-RUNBOOK step 4). todlando cross-checked changelog scope; 2 trailing commits (185eaee/86f20ac) = test/CI-hygiene, no bullet (correct per [[changelog-scope-vs-commit-range]]). sign+publish: update-set v26. Hashes: linux `fa6a3cdfdd7555d0…` / win `2c5ca121ed14c20b…`. Publisher leg 20× clean (counter 7-26).

COUNTER: v0.12.0=25 → v0.12.1=26 (confirmed vs my publish logs; release-publish monotonic rollback-floor accepted 26). hfenduleam disk held (~322G free, recovered from the mid-session 100%-full event). EIGHT releases this revive session: v0.8.3→v0.8.4→v0.9.0→v0.9.1→v0.10.0→v0.11.0→v0.12.0→v0.12.1. See [[v0120-published]].


1	- [v0.14.0 endpoint-creation-flow](v0140-endpoint-creation-flow.md) — PUBLISHED 2026-06-23 counter 30, Latest. Multi-subnet home-at-creation + UNBOUND pre-bind attach. Tag @6ba875e (last old-flow separate-bump-push cut). hashes linux 72889c07… / win 641561d9…. CI attempt-1 RED = Win netstream flake → rerun green. signed rel-primary-2026, docs-publish green. SPT_RELEASE_SEED present in env (len64) this session — no manual fetch needed. ACCEPTANCE-PROVEN: perri real claude-spt repro ALL GREEN (0.058s MULTI_SUBNET_HOME refuse vs old 25s hang, --subnet homes+binds UNBOUND→online, hollow UNBOUND row), seed flipped fix-confirmed @24c620a, no spt-core gap
2	- [v0.14.1 builds (F-018 + picker-home + label + netstream)](f018-adapter-add-nondestructive.md) — v0.14.1 = ALL FOUR on design/endpoint-creation-flow (NOT pushed, await release cut). 3 doyle GATE-PASS 2026-06-23: F-018/REQ-INSTALL-13 @6920ea8, REQ-RUN-PICKER-HOME @1ecdc1c (int-deferral ratified), label-clarity #3 @6acdef5 (ADAPTER_INSTALLED vs ADAPTER_INSTALL_PENDING; REQ-INSTALL-9). #4 netstream flake @a0fc440 doyle GATE-PASS 2026-06-23 (netstream int 15× deterministic on Win box = ~5% flake DEAD + StreamLog --lib unit + clippy --workspace + traceable ALL EXIT0): ROOT = StreamLog.next_seq counts TRANSPORT read_chunk appends NOT logical chunks; QUIC coalesces under Win timing → fewer seqs same bytes → eof 19v20. PRODUCTION CORRECT (byte-exact+exactly-once); TEST conflated 1:1 chunk:seq. Fix test-only: read_until drains by BYTES (bytes_for(count)), dropped next_seq==until + cursor==KILL_AT asserts, KEPT byte-exact+exactly-once + real net_cursor into resume, +StreamLog unit (2 appends→next_seq==2). SUPERSEDES [[win-netstream-redrive-flake]] (was "NOT-a-blocker"; now FIXED). **ALL FOUR GATE-PASS. v0.14.1 SHIPPED: PR#34 green BOTH runners (netstream #4 fix HELD in CI — no flake, gate validated) → merged (no-squash, per-commit traceable tags) → main @46289ab → tagged+pushed v0.14.1, counter 31. doyle CHANGELOG-vet PASS (3 surfaces, #4 omitted as test-only). First bump-in-PR cut clean end-to-end. PUBLISHED counter 31, Latest: hashes linux 1e64d63a… / win 2fbbfe03…, signed rel-primary-2026, docs-publish green.** GOTCHA: `spt` has NO lib target → `--bin spt` not `--lib` (spt-daemon DOES have lib → `--lib` ok there)
3	- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — v0.14.2, REQ-INSTALL-11 ext. THE #1 CC-on-Windows blocker: idle msgs typed but never SUBMITTED because `[message-idle-translation-binary]` bare path spawned via Command::new (no install_dir resolve) → fail → silent raw-inject fallback → choreography never ran. @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab, NOT pushed) — already doyle GATE-PASS (clippy/spt-daemon+spt-runtime --lib/traceable + diff verified). PUBLISHED 2026-06-23 v0.14.2 counter 32, Latest: hashes linux 98714384… / win 08e8a267…. 3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c). CHANGELOG = 1 Fixed bullet (idle delivery submits); ADR/design/notif×2 OMITTED (internal, doyle-ratified). Raw-inject-removal = todlando separate follow-up NEXT (operator-timed). perri 3-step real-CC validation pending (doyle-released). Fix 4 sites via resolve_program_in_dir/with_install_dir (translation initial+W3d-respawn, notif×2) + session-program uniformity; digest/lifecycle/psyche already-resolved. KH diagnosis note + MANIFEST contract note. Fallback FLOW UNTOUCHED — raw-inject REMOVAL (spool+poll) = SEPARATE assignment per doyle's ADR-0022 amendment, ships after. Gates green. unit translation_binary_resolves_against_install_dir
4	- [stale-broker attach wedge](stale-broker-attach-wedge.md) — attach "brain IPC read deadline" while list/dial work = stale daemon broker from old rev; fix = full daemon restart. Confirmed 2026-06-23
5	- [Win netstream redrive flake](win-netstream-redrive-flake.md) — RECURRING Win-only CI flake: sender/receiver_brain_restart redrive exactly-once (netstream.rs:99 chunk-gap, 19v20). Linux-green-same-code. Hit 2× this session, clears on `gh run rerun --failed`; verify per-attempt. NOT a blocker; post-v0.14.0 fix (F-018). Kin [[v013-forkpty-groundtruth]]

- [v0.14.0 endpoint-creation-flow](v0140-endpoint-creation-flow.md) — PUBLISHED 2026-06-23 counter 30, Latest. Multi-subnet home-at-creation + UNBOUND pre-bind attach. Tag @6ba875e (last old-flow separate-bump-push cut). hashes linux 72889c07… / win 641561d9…. CI attempt-1 RED = Win netstream flake → rerun green. signed rel-primary-2026, docs-publish green. SPT_RELEASE_SEED present in env (len64) this session — no manual fetch needed. ACCEPTANCE-PROVEN: perri real claude-spt repro ALL GREEN (0.058s MULTI_SUBNET_HOME refuse vs old 25s hang, --subnet homes+binds UNBOUND→online, hollow UNBOUND row), seed flipped fix-confirmed @24c620a, no spt-core gap
- [v0.14.1 builds (F-018 + picker-home + label + netstream)](f018-adapter-add-nondestructive.md) — v0.14.1 = ALL FOUR on design/endpoint-creation-flow (NOT pushed, await release cut). 3 doyle GATE-PASS 2026-06-23: F-018/REQ-INSTALL-13 @6920ea8, REQ-RUN-PICKER-HOME @1ecdc1c (int-deferral ratified), label-clarity #3 @6acdef5 (ADAPTER_INSTALLED vs ADAPTER_INSTALL_PENDING; REQ-INSTALL-9). #4 netstream flake @a0fc440 doyle GATE-PASS 2026-06-23 (netstream int 15× deterministic on Win box = ~5% flake DEAD + StreamLog --lib unit + clippy --workspace + traceable ALL EXIT0): ROOT = StreamLog.next_seq counts TRANSPORT read_chunk appends NOT logical chunks; QUIC coalesces under Win timing → fewer seqs same bytes → eof 19v20. PRODUCTION CORRECT (byte-exact+exactly-once); TEST conflated 1:1 chunk:seq. Fix test-only: read_until drains by BYTES (bytes_for(count)), dropped next_seq==until + cursor==KILL_AT asserts, KEPT byte-exact+exactly-once + real net_cursor into resume, +StreamLog unit (2 appends→next_seq==2). SUPERSEDES [[win-netstream-redrive-flake]] (was "NOT-a-blocker"; now FIXED). **ALL FOUR GATE-PASS. v0.14.1 SHIPPED: PR#34 green BOTH runners (netstream #4 fix HELD in CI — no flake, gate validated) → merged (no-squash, per-commit traceable tags) → main @46289ab → tagged+pushed v0.14.1, counter 31. doyle CHANGELOG-vet PASS (3 surfaces, #4 omitted as test-only). First bump-in-PR cut clean end-to-end. PUBLISHED counter 31, Latest: hashes linux 1e64d63a… / win 2fbbfe03…, signed rel-primary-2026, docs-publish green.** GOTCHA: `spt` has NO lib target → `--bin spt` not `--lib` (spt-daemon DOES have lib → `--lib` ok there)
- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — v0.14.2, REQ-INSTALL-11 ext. THE #1 CC-on-Windows blocker: idle msgs typed but never SUBMITTED because `[message-idle-translation-binary]` bare path spawned via Command::new (no install_dir resolve) → fail → silent raw-inject fallback → choreography never ran. @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab, NOT pushed) — already doyle GATE-PASS (clippy/spt-daemon+spt-runtime --lib/traceable + diff verified). PUBLISHED 2026-06-23 v0.14.2 counter 32, Latest: hashes linux 98714384… / win 08e8a267…. 3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c). CHANGELOG = 1 Fixed bullet (idle delivery submits); ADR/design/notif×2 OMITTED (internal, doyle-ratified). Raw-inject-removal = todlando separate follow-up NEXT (operator-timed). perri 3-step real-CC validation pending (doyle-released). Fix 4 sites via resolve_program_in_dir/with_install_dir (translation initial+W3d-respawn, notif×2) + session-program uniformity; digest/lifecycle/psyche already-resolved. KH diagnosis note + MANIFEST contract note. Fallback FLOW UNTOUCHED — raw-inject REMOVAL (spool+poll) = SEPARATE assignment per doyle's ADR-0022 amendment, ships after. Gates green. unit translation_binary_resolves_against_install_dir
- [stale-broker attach wedge](stale-broker-attach-wedge.md) — attach "brain IPC read deadline" while list/dial work = stale daemon broker from old rev; fix = full daemon restart. Confirmed 2026-06-23
- [Win netstream redrive flake](win-netstream-redrive-flake.md) — RECURRING Win-only CI flake: sender/receiver_brain_restart redrive exactly-once (netstream.rs:99 chunk-gap, 19v20). Linux-green-same-code. Hit 2× this session, clears on `gh run rerun --failed`; verify per-attempt. NOT a blocker; post-v0.14.0 fix (F-018). Kin [[v013-forkpty-groundtruth]]


MEMORY.md F-019 line already PUBLISHED (prior session updated). Just bump the ledger line counter.


84:- [Published releases ledger](v0121-published.md) — counters: v0.4.0=7 … v0.12.0=25, v0.12.1=26, v0.13.0=27, v0.13.2=29, v0.14.0=30, v0.14.1=31, v0.14.2=32. bump-in-PR standard (v0.14.1+) proven 2×. Publisher leg proven 20×+. Each vX.Y.Z-published.md holds that release's hashes+gotcha


Memory already current — prior session logged v0.14.2=32 in ledger. One nit: F-019 hook line says "3rd bump-in-PR cut" but ledger says proven 2× (v0.14.1=1st, v0.14.2=2nd). Fix off-by-one.


Edit

3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c)

2nd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c)


<tool_use_error>File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.</tool_use_error>

Error: File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.


3	- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — v0.14.2, REQ-INSTALL-11 ext. THE #1 CC-on-Windows blocker: idle msgs typed but never SUBMITTED because `[message-idle-translation-binary]` bare path spawned via Command::new (no install_dir resolve) → fail → silent raw-inject fallback → choreography never ran. @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab, NOT pushed) — already doyle GATE-PASS (clippy/spt-daemon+spt-runtime --lib/traceable + diff verified). PUBLISHED 2026-06-23 v0.14.2 counter 32, Latest: hashes linux 98714384… / win 08e8a267…. 3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c). CHANGELOG = 1 Fixed bullet (idle delivery submits); ADR/design/notif×2 OMITTED (internal, doyle-ratified). Raw-inject-removal = todlando separate follow-up NEXT (operator-timed). perri 3-step real-CC validation pending (doyle-released). Fix 4 sites via resolve_program_in_dir/with_install_dir (translation initial+W3d-respawn, notif×2) + session-program uniformity; digest/lifecycle/psyche already-resolved. KH diagnosis note + MANIFEST contract note. Fallback FLOW UNTOUCHED — raw-inject REMOVAL (spool+poll) = SEPARATE assignment per doyle's ADR-0022 amendment, ships after. Gates green. unit translation_binary_resolves_against_install_dir


3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c)

2nd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c)


The file C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\MEMORY.md has been updated successfully. (file state is current in your context — no need to Read it back)

- [v0.14.0 endpoint-creation-flow](v0140-endpoint-creation-flow.md) — PUBLISHED counter 30 @6ba875e (last old-flow separate-bump cut). Multi-subnet home-at-creation + UNBOUND pre-bind attach. hashes linux 72889c07… / win 641561d9…. ACCEPTANCE-PROVEN: perri real claude-spt repro ALL GREEN (0.058s refuse vs old 25s hang). SPT_RELEASE_SEED in env (len64) — no manual fetch

- [v0.14.1 builds (F-018+picker-home+label+netstream)](f018-adapter-add-nondestructive.md) — PUBLISHED counter 31 @46289ab (1st bump-in-PR cut, PR#34). F-018 adapter-add non-destructive (REQ-INSTALL-13), picker home-subnet (REQ-RUN-PICKER-HOME), installed-vs-pending labels, #4 netstream flake FIX (root=StreamLog.next_seq counts transport read_chunks not logical chunks; QUIC Win-coalesce → eof 19v20; test-only byte-based fix, SUPERSEDES [[win-netstream-redrive-flake]]). hashes 1e64d63a… / 2fbbfe03…. GOTCHA: `spt` NO lib target → `--bin spt` (spt-daemon HAS lib)

-- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — v0.14.2, REQ-INSTALL-11 ext. THE #1 CC-on-Windows blocker: idle msgs typed but never SUBMITTED because `[message-idle-translation-binary]` bare path spawned via Command::new (no install_dir resolve) → fail → silent raw-inject fallback → choreography never ran. @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab, NOT pushed) — already doyle GATE-PASS (clippy/spt-daemon+spt-runtime --lib/traceable + diff verified). PUBLISHED 2026-06-23 v0.14.2 counter 32, Latest: hashes linux 98714384… / win 08e8a267…. 3rd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c). CHANGELOG = 1 Fixed bullet (idle delivery submits); ADR/design/notif×2 OMITTED (internal, doyle-ratified). Raw-inject-removal = todlando separate follow-up NEXT (operator-timed). perri 3-step real-CC validation pending (doyle-released). Fix 4 sites via resolve_program_in_dir/with_install_dir (translation initial+W3d-respawn, notif×2) + session-program uniformity; digest/lifecycle/psyche already-resolved. KH diagnosis note + MANIFEST contract note. Fallback FLOW UNTOUCHED — raw-inject REMOVAL (spool+poll) = SEPARATE assignment per doyle's ADR-0022 amendment, ships after. Gates green. unit translation_binary_resolves_against_install_dir

+- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — v0.14.2, REQ-INSTALL-11 ext. THE #1 CC-on-Windows blocker: idle msgs typed but never SUBMITTED because `[message-idle-translation-binary]` bare path spawned via Command::new (no install_dir resolve) → fail → silent raw-inject fallback → choreography never ran. @4fd028d (branch fix/f019-translation-install-dir-resolve off main @46289ab, NOT pushed) — already doyle GATE-PASS (clippy/spt-daemon+spt-runtime --lib/traceable + diff verified). PUBLISHED 2026-06-23 v0.14.2 counter 32, Latest: hashes linux 98714384… / win 08e8a267…. 2nd bump-in-PR cut (PR#35 off main 46289ab, cherry-picked 3 commits + bump → merged @365fb0c). CHANGELOG = 1 Fixed bullet (idle delivery submits); ADR/design/notif×2 OMITTED (internal, doyle-ratified). Raw-inject-removal = todlando separate follow-up NEXT (operator-timed). perri 3-step real-CC validation pending (doyle-released). Fix 4 sites via resolve_program_in_dir/with_install_dir (translation initial+W3d-respawn, notif×2) + session-program uniformity; digest/lifecycle/psyche already-resolved. KH diagnosis note + MANIFEST contract note. Fallback FLOW UNTOUCHED — raw-inject REMOVAL (spool+poll) = SEPARATE assignment per doyle's ADR-0022 amendment, ships after. Gates green. unit translation_binary_resolves_against_install_dir

- [stale-broker attach wedge](stale-broker-attach-wedge.md) — attach "brain IPC read deadline" while list/dial work = stale daemon broker from old rev; fix = full daemon restart. Confirmed 2026-06-23

- [Win netstream redrive flake](win-netstream-redrive-flake.md) — RECURRING Win-only CI flake: sender/receiver_brain_restart redrive exactly-once (netstream.rs:99 chunk-gap, 19v20). Linux-green-same-code. Hit 2× this session, clears on `gh run rerun --failed`; verify per-attempt. NOT a blocker; post-v0.14.0 fix (F-018). Kin [[v013-forkpty-groundtruth]]

- [release standard: bump-in-PR](release-standard-bump-in-pr.md) — v0.14.1 ONWARD: bump rides IN release PR (Cargo ver+lock first-party+CHANGELOG+xtask gen) → PR CI validates tagged commit → tag on merge → push:[main] CI = non-blocking backstop. Kills serial 2nd-CI wait


Done. Status:

**v0.14.2 PUBLISHED** counter 32, Latest @365fb0c — F-019 idle-submit fix LIVE.
- Cut = my @4fd028d + ADR-0022 amendment @1eaeef1 + design doc
- PR#35 green both runners (Win held, netstream #4 in base)
- hashes linux 98714384… / win 08e8a267…

Memory synced (f019 file + MEMORY.md hook + ledger already at 32). Fixed one nit: hook said "3rd bump-in-PR" → corrected to 2nd (v0.14.1=1st, v0.14.2=2nd).

**Pending:**
1. perri real-CC validation (doyle-released) — closes THE #1 blocker if idle choreography fires on real Windows CC
2. raw-inject-removal build = my next assignment, operator-timed

deployah unreachable (NO_PERCH, no spool) — ack not sent. Standing by.


<task-notification>
<task-id>br1kp3y1l</task-id>
Monitor event: "« spt event »"
<event><EVENT-PART seq="1/17" id="111225b4" type="msg" from="doyle">ASSIGNMENT — v0.14.3: raw-inject REMOVAL (ADR-0022 amendment @1eaeef1). Operator-GO'd. You build, I gate, deployah cuts. Branch off main @365fb0c (v0.14.2, where F-019 lives).

CONTRACT (ADR-0022 amended): spt-hosted idle delivery = translation-binary-ONLY. A translation binary that is ABSENT (none declared), SP</EVENT-PART>
<EVENT-PART seq="2/17" id="111225b4">AWN-FAILED, FAULTED, or whose worker channel is gone → the inbound message stays SPOOLED (not lost), NEVER raw PTY-injected. Failure is LOUD. Raw `payload+\r` was a non-submitting pseudo-delivery on a modern TUI (the silent degrade that MASKED F-019).

I grounded the seam — the removal is BOUNDED because the spool machinery already e</EVENT-PART>
<EVENT-PART seq="3/17" id="111225b4">xists: dispatch_endpoint_input replies endpoint_injected_envelope(ep, delivered:bool); inject_endpoint returns it; try_broker_inject (cli.rs:3510) → false → caller SPOOLS (&quot;never lost&quot;). Today the no-working-binary case raw-injects (input.enqueue) + replies delivered=TRUE. Flip it to delivered=FALSE (spool). That's the spine.
</EVENT-PART>
<EVENT-PART seq="4/17" id="111225b4">
CHANGES:
1. broker.rs dispatch_endpoint_input (~1875-1932): KEEP the working-binary path (translation Some + !faulted + event_tx.send ok → delivered=true, choreography). REMOVE the raw-inject fallback at ~1922 (input.enqueue(bytes) + delivered=true). In its place reply endpoint_injected_envelope(ep, FALSE) so the caller spools. Loud l</EVENT-PART>
<EVENT-PART seq="5/17" id="111225b4">og: &quot;&lt;ep&gt;: no working translation binary (absent/faulted/worker-gone) -&gt; SPOOLED, not injected&quot;. The worker-channel-dropped fall-through (~1911) also goes to spool, not raw inject.
2. broker.rs fault_translation (~1172): log &quot;reverting to raw inject&quot; -&gt; &quot;messages spool until a working binary&quot;. fault</EVENT-PART>
<EVENT-PART seq="6/17" id="111225b4">ed flag still gates to the spool path.
3. broker.rs build_translation (~1077): spawn-fail log &quot;degrading to raw inject&quot; -&gt; &quot;no idle PTY delivery; inbound spools (declare/repair the binary)&quot;. Still returns None; None now MEANS spool, not raw inject.
4. Reword every broker.rs comment that frames raw-inject as the deg</EVENT-PART>
<EVENT-PART seq="7/17" id="111225b4">enerate/fallback delivery path (I saw ~154, 829, 837, 848, 872, 1027, 1037, 1170, 1882-1897, 1914-1916) to the spool contract. translation.rs spawn doc (~238 &quot;falls back to the degenerate raw inject&quot;) too.
5. cli.rs try_broker_inject / cmd_send: VERIFY delivered=false → spool fires AND the user-facing report is honest (spooled, </EVENT-PART>
<EVENT-PART seq="8/17" id="111225b4">NOT &quot;Sent online&quot;). The no-hosted-session path already returned false; confirm the no-binary case now rides the same honest path. Adjust messaging only if it conflated.

TESTS — [[behavior-
...(truncated)</event>
</task-notification>


1	- [v0.14.0 endpoint-creation-flow](v0140-endpoint-creation-flow.md) — PUBLISHED counter 30 @6ba875e (last old-flow separate-bump cut). Multi-subnet home-at-creation + UNBOUND pre-bind attach. hashes linux 72889c07… / win 641561d9…. ACCEPTANCE-PROVEN: perri real claude-spt repro ALL GREEN (0.058s refuse vs old 25s hang). SPT_RELEASE_SEED in env (len64) — no manual fetch
2	- [v0.14.1 builds (F-018+picker-home+label+netstream)](f018-adapter-add-nondestructive.md) — PUBLISHED counter 31 @46289ab (1st bump-in-PR cut, PR#34). F-018 adapter-add non-destructive (REQ-INSTALL-13), picker home-subnet (REQ-RUN-PICKER-HOME), installed-vs-pending labels, #4 netstream flake FIX (root=StreamLog.next_seq counts transport read_chunks not logical chunks; QUIC Win-coalesce → eof 19v20; test-only byte-based fix, SUPERSEDES [[win-netstream-redrive-flake]]). hashes 1e64d63a… / 2fbbfe03…. GOTCHA: `spt` NO lib target → `--bin spt` (spt-daemon HAS lib)
3	- [F-019 translation install_dir resolve](f019-translation-install-dir-resolve.md) — PUBLISHED v0.14.2 counter 32 @365fb0c (2nd bump-in-PR, PR#35). THE #1 CC-on-Windows blocker: idle msgs typed-not-SUBMITTED — `[message-idle-translation-binary]` bare path Command::new'd w/o install_dir resolve → fail → silent raw-inject fallback. Fix=resolve_program_in_dir at 4 sites (translation initial+W3d-respawn, notif×2). hashes 98714384… / 08e8a267…. CHANGELOG=1 Fixed bullet (ADR/design/notif×2 OMITTED, doyle-ratified). NEXT: todlando raw-inject-REMOVAL (spool+poll, ADR-0022 amendment) operator-timed; perri 3-step real-CC validation pending (doyle-released)
4	- [stale-broker attach wedge](stale-broker-attach-wedge.md) — attach "brain IPC read deadline" while list/dial work = stale daemon broker from old rev; fix = full daemon restart. Confirmed 2026-06-23
5	- [Win netstream redrive flake](win-netstream-redrive-flake.md) — FIXED in v0.14.1 (#4, see [[f018-adapter-add-nondestructive]]): was Win-only CI flake (netstream.rs:99 chunk-gap 19v20, Linux-green-same-code, clear on rerun); root=StreamLog seq counts transport read_chunks. Historic; verify-per-attempt lesson stands. Kin [[v013-forkpty-groundtruth]]
6	- [release standard: bump-in-PR](release-standard-bump-in-pr.md) — v0.14.1 ONWARD: bump rides IN release PR (Cargo ver+lock first-party+CHANGELOG+xtask gen) → PR CI validates tagged commit → tag on merge → push:[main] CI = non-blocking backstop. Kills serial 2nd-CI wait
7	- [v0.14.0 W6 int structure](v0140-w6-int-structure.md) — mirror perri regression: >=2-subnet gate (single HIDES gap), Case1 endpoint-run E2E behind acceptance-env, Cases2/3 fast bind HOME_REFUSED/--subnet probes
8	- [v0.13.2 build drive](v0132-build-drive.md) — PUBLISHED counter 29; adapter-packaging. New W6 docs-token gate (public --help no internal codes)
9	- [v0.13.0 forkpty ground truth](v013-forkpty-groundtruth.md) — SHIPPED counter 27. LIVE attach forward-gap on ring-roll-behind; green-units≠green-int. Win attach flake = per-IPC io_timeout (SPT_ATTACH_IPC_DEADLINE_MS). gh run rerun attaches STALE attempt — verify per-attempt
10	- [v0.13.0 W1b effect-journal wedge](v013-w1b-effect-journal-wedge.md) — apply_once holds 1 mutex across 2 fsync + blocking PtyWrite → stutter + blocked-write kills attaches. REQ-HAZARD-EFFECT-JOURNAL-PTY-WEDGE. Fix=no-lock-across-effect + drop per-keystroke fsync
11	- [v0.13.0 milestone](v0130-milestone.md) — msg-delivery redesign (ADR-0022): translation binary = pure stdin→stdout filter, spt-core owns PTY writes ATOMICALLY. Trace in ~/.ccs NOT .claude
12	- [v0.12.1 real-harness reopen](v0121-realharness-reopen.md) — v0.12.0 lifecycle broke in REAL harness (green-on-mocks). BINDING: gate lifecycle vs REAL dummy-harness, NO mocks
13	- [v0.12.1 L0 attach-deadlock](v0121-l0-attach-deadlock-root.md) — KEYSTONE: serve_attach forwards on SAME broker IPC conn; become_controller inline ring replay blocks → backpressure deadlock → rc 0 bytes. Only non-empty ring
14	- [v0.12.1 L2 attach-wedge](v0121-l2-attach-wedge-proven.md) — L2/L3/L4 @e883f45 PROVE-DON'T-CHANGE: stale root debunked (send_stream bounded). int attach_wedge_e2e GREEN
15	- [v0.12.1 help-md render](v0121-help-md.md) — `spt --help` leaked literal MD; helpfmt::render (bold→ANSI/code→cyan, strip on pipe/NO_COLOR). REQ-CLI-HELP-MARKDOWN @d4241f9
16	- [changelog scope vs commit range](changelog-scope-vs-commit-range.md) — release CHANGELOG must COVER every user-facing SURFACE in vPREV..vNEW (log=checklist NOT quota) + bullet SCOPE not broader than delta. Post-publish fix=docs-only no retag
17	- [pre-flight clippy --workspace](ci-clippy-preflight-workspace.md) — CI denies warnings workspace-wide; `-p <crate>` misses sibling lints. CI fires on PR (push=main/dev-freeform)
18	- [behavior-change → grep tests](behavior-change-grep-tests-not-comments.md) — rename/behavior/token change: grep tests/+ci/ for OLD behavior as ASSERTIONS; comment-only hit = RED FLAG, read body. Run heavy e2e locally. green-units≠green-int
19	- [shared-seam → run ALL seam tests](shared-seam-change-run-all-seam-tests.md) — SHARED runtime-seam change breaks SIBLING tests; grep+run ALL seam tests not just new ones
20	- [ccs Windows PTY-spawn fix](ccs-win-pty-program-resolve.md) — bare program → portable-pty picks extensionless shim → CreateProcessW 193. Fix: spt_term::winprog PATHEXT resolver. REQ-HAZARD-WIN-PTY-PROGRAM-RESOLVE
21	- [harness adapter-agnostic resolution](harness-adapter-agnostic-resolution.md) — ADR-0021: seed adapter-AGNOSTIC (pid+session_id), --adapter OPTIONAL; resolve at bind by pid→exe→host_binaries→profiles
22	- [broker-QUIC-deadline](v083-broker-quic-deadline.md) — REQ-HAZARD-BROKER-QUIC-DEADLINE: NetHost::bounded_block_on (10s<30s brain) wraps dial/open/send → dead peer = ORDINARY error, pump redials
23	- [peer-pump stall = deferred B-half](peer-pump-stall-bhalf-confirmed.md) — pump STALL = broker-side unbounded QUIC op to DEAD roster peer. Interim=restart daemon; real fix=broker-side QUIC bound
24	- [v0.8.2 templating+residency](v082-templating-residency.md) — F-009 TEMPLATE-ARGV-FILL (tokenize THEN fill, no injection); F-010 LIVEHOST-NONRESIDENT (child dead in N s → psyche_host_error)
25	- [v0.8.0 merge reconciliation](v080-merge-reconciliation.md) — unified merge non-clean: live psyche diverged (M11 daemon-host vs main Feature B install-dir); naive merge DROPS Feature B (reapply livehost.rs with_config_in)
26	- [F-007 live-relay acceptance](f007-live-relay-acceptance.md) — live bringup = persistent `api listen` via Monitor (NOT --once/ready); psyche-spawn gated on --manifest + install-dir fix. Ground in CONTEXT.md before ruling
27	- [delegate-build preflight hang](delegate-build-preflight-hang.md) — bg build agents hang silently on full int suite; instruct targeted units (--lib+named); check liveness via transcript mtime, TaskStop stalled, take partial work
28	- [proceed autonomously](dont-wait-proceed-autonomously.md) — operator: don't stop to ask permission between steps; chain next action
29	- [alarm port deferred](alarm-port-deferred-arrangement.md) — /spt:new-alarm durable scheduler = ACCEPTED parity gap, DEFERRED; superseding "arrangement" system coming. Don't port or stopgap
30	- [broker is daemon state anchor](broker-is-daemon-state-anchor.md) — post-ADR-0018 BROKER (not restartable brain) = always-up CLI-reachable daemon-lifetime anchor; place ephemeral in-mem state there
31	- [adapter add --release archive](adapter-add-release-archive.md) — `spt adapter add --release <user/repo>` (REQ-INSTALL-9): fetch .spt tar from GH release, extract, register root. Acquisition only, not [update] route
32	- [adapter tips → published docs](adapter-tips-published-docs.md) — perri tips → harness-agnostic docs-site harness-contract/patterns.md; publish via `gh workflow run docs-publish.yml --ref main` (tags/dispatch). Pre-flight xtask check+site
33	- [how-to subnet → W5 scope](howto-subnet-w5-scope.md) — `spt how-to subnet` dead-ended (HOW_TO_TOPICS locked); REQ-DOCS-6 gap, landed M11-W5
34	- [M11 COMPLETE](m11-complete.md) — shell-substrate (consent/drive/tunnel/gateway/rig+docs) all GATE PASS. Cross-node tunnel DEFERRED

... [46 lines truncated] ...


<owl_reachability_notice>
You have an active owl perch. When spawning subagents or doing work, use run_in_background: true so you stay reachable for incoming messages.
</owl_reachability_notice>


CAVEMAN MODE ACTIVE (full). Drop articles/filler/pleasantries/hedging. Fragments OK. Code/commits/security: write normal.


doyle assigned **v0.14.3: raw-inject REMOVAL** (my build). 17-part msg, truncated at part 8 (TESTS section cut). Need full text before I build.


ToolSearch

Question: select:Monitor


Question: select:Monitor


Monitor = new-events stream, won't recover the truncated body. Need parts 8-17 (TESTS/gates). Check roster + try doyle.


Bash

List reachable endpoints


SUBNET SPT_DEV
  call-a  HFENDULEAM (14efb80c…)  Active
  wall-a  HFENDULEAM (14efb80c…)  Dormant
SUBNET BIGNET
  call-a  HFENDULEAM (14efb80c…)  Active
  wall-a  HFENDULEAM (14efb80c…)  Dormant
ENDPOINTS:4
LOCAL (this node)
  call-a                       live_agent     -                      ready=true alive=true
  f019badpath                  live_agent     -                      ready=false alive=true
  f019verify                   live_agent     -                      ready=false alive=true
  wall-a                       live_agent     -                      ready=false alive=false


doyle not in roster (cross-node agent). Truncated msg — find full text on disk via the part id `111225b4`.


echo "SPT_HOME=$SPT_HOME"; echo "---"; grep -rl "111225b4" "$SPT_HOME" 2>/dev/null | head; echo "--- fallback search common dirs ---"; grep -rl "raw-inject REMOVAL" "$HOME/.spt" "$SPT_HOME" 2>/dev/null | head

Locate spooled message by part id


SPT_HOME=
---
--- fallback search common dirs ---


for d in "$HOME/.spt" "$HOME/AppData/Local/spt" "$HOME/AppData/Roaming/spt" "$LOCALAPPDATA/spt" "$APPDATA/spt"; do [ -d "$d" ] && echo "FOUND: $d"; done; echo "---grep---"; grep -rl "111225b4\|no working translation binary" "$HOME/AppData/Local/spt" "$HOME/AppData/Roaming/spt" 2>/dev/null | head

Find spt data dir and message


FOUND: /c/Users/decid/AppData/Local/spt
FOUND: C:\Users\decid\AppData\Local/spt
---grep---


cd "$HOME/AppData/Local/spt" && ls -la; echo "=== recursive grep for doyle msg ==="; grep -rl "raw-inject\|raw inject\|dispatch_endpoint_input\|111225b4" . 2>/dev/null | head

Inspect spt local data dir, grep for message


total 99
drwxr-xr-x 1 decid 197609   0 Jun  6 00:13 .
drwxr-xr-x 1 decid 197609   0 Jun 16 09:45 ..
-rw-r--r-- 1 decid 197609  21 Jun  2 14:33 last-seen-version.json
drwxr-xr-x 1 decid 197609   0 Jun 13 22:06 logs_latest
drwxr-xr-x 1 decid 197609   0 Jun 23 16:15 owlery
drwxr-xr-x 1 decid 197609   0 Apr  8 02:38 psyches
drwxr-xr-x 1 decid 197609   0 Jun 23 15:26 pulses
-rw-r--r-- 1 decid 197609 512 Jun 23 16:14 settings.json
-rw-r--r-- 1 decid 197609 527 May 26 23:33 settings.json.bak-20260526233508
-rw-r--r-- 1 decid 197609 366 May 27 01:24 settings.json.bak-syncclean-20260527030355
drwxr-xr-x 1 decid 197609   0 Jun 22 22:39 status
=== recursive grep for doyle msg ===
./logs_latest/doyle.log
./logs_latest/perri.log
./logs_latest/todlando.log
./owlery/deployah/spool.db
./owlery/doyle/spool.db
./owlery/perri/spool.db
./owlery/todlando/spool.db
./psyches/tracked/agents/doyle/live_context.md
./psyches/tracked/agents/perri/daemon.log
./psyches/tracked/projects/spt-core/todlando.md
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Message landed live to my perch. Full text should be in logs. Grep for the contract body.


cd "$HOME/AppData/Local/spt/logs_latest" && ls -la; echo "=== grep ASSIGNMENT in logs ==="; grep -rl "ASSIGNMENT\|TESTS\|behavior-change-grep\|traceab" . 2>/dev/null

List logs, find assignment text


total 2708
drwxr-xr-x 1 decid 197609       0 Apr  8 03:10 ,old
drwxr-xr-x 1 decid 197609       0 Jun 13 22:06 .
drwxr-xr-x 1 decid 197609       0 Jun  6 00:13 ..
-rw-r--r-- 1 decid 197609   84765 Jun 23 16:15 deployah.log
-rw-r--r-- 1 decid 197609 1250343 Jun 23 16:14 doyle.log
-rw-r--r-- 1 decid 197609  290433 May 22 16:41 dunsen.log
-rw-r--r-- 1 decid 197609    1108 May 10 19:04 executor.log
-rw-r--r-- 1 decid 197609    1255 Jun  6 23:07 ling.log
-rw-r--r-- 1 decid 197609   82465 May 12 12:55 mica.log
-rw-r--r-- 1 decid 197609  105661 Jun 23 16:10 perri.log
-rw-r--r-- 1 decid 197609   19089 May 23 23:21 probetest.log
-rw-r--r-- 1 decid 197609  214169 Jun 10 05:31 rebbie.log
-rw-r--r-- 1 decid 197609  495306 Jun 16 18:34 solar.log
-rw-r--r-- 1 decid 197609  111945 Jun 23 16:13 todlando.log
-rw-r--r-- 1 decid 197609    1229 May 22 03:31 webber.log
-rw-r--r-- 1 decid 197609   76179 Apr 23 00:14 witty.log
=== grep ASSIGNMENT in logs ===
./deployah.log
./doyle.log
./dunsen.log
./perri.log
./rebbie.log
./todlando.log
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


grep -n "111225b4\|no working translation\|dispatch_endpoint_input\|TESTS\|raw-inject REMOVAL\|fault_translation" "$HOME/AppData/Local/spt/logs_latest/todlando.log" | tail -30

Find assignment message in todlando log


1438:>>>  **ADR-0022 amendment @1eaeef1 (doyle, on design/endpoint-creation-flow):** operator RULED drop raw-inject ENTIRELY → spt-hosted idle = translation-binary-only; declared-but-failed OR absent binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject. Binary-less adapter gets no idle PTY delivery until it declares one. The raw-inject REMOVAL build is a SEPARATE todlando assignment AFTER v0.14.2 cuts (operator-timed); doyle sends scope. This ADR commit must RIDE v0.14.2 alongside F-019.
1503:>>>  **ADR-0022 amendment @1eaeef1 (doyle, on design/endpoint-creation-flow):** operator RULED drop raw-inject ENTIRELY → spt-hosted idle = translation-binary-only; declared-but-failed OR absent binary → message stays SPOOLED (poll-fed) + loud, NEVER raw PTY inject. Binary-less adapter gets no idle PTY delivery until it declares one. The raw-inject REMOVAL build is a SEPARATE todlando assignment AFTER v0.14.2 cuts (operator-timed); doyle sends scope. This ADR commit must RIDE v0.14.2 alongside F-019.


Tail my log for newest received message


[15:35:44] poll iteration 146 starting
[15:35:44] [ECHO] gate idle: no sentinel present (awaiting next Stop)
[15:35:44] ready file exists: true
[15:43:44] poll exited code=0 stderr=
[15:43:44] poll returned 40 bytes
[15:43:44] [PULSE] pulse-psyche=off — skipping resume; echo gate fires next iteration
[15:43:44] poll iteration 147 starting
[15:43:44] [ECHO] gate rejected (sentinel fresh, 154s old); scheduling short pulse in 745s
[15:43:44] ready file exists: true
[15:56:10] poll exited code=0 stderr=
[15:56:10] poll returned 40 bytes
[15:56:10] [PULSE] pulse-psyche=off — skipping resume; echo gate fires next iteration
[15:56:10] poll iteration 148 starting
[15:56:10] [ECHO] gate rejected (sentinel fresh, 899s old); scheduling short pulse in 60s
[15:56:10] ready file exists: true
[15:57:10] poll exited code=0 stderr=
[15:57:10] poll returned 40 bytes
[15:57:10] [PULSE] pulse-psyche=off — skipping resume; echo gate fires next iteration
[15:57:10] poll iteration 149 starting
[15:57:10] [ECHO] gate open: sentinel stale (or metadata unavailable) — firing echo commune
[15:57:10] [ECHO] spawned pid=171780
[15:57:10] ready file exists: true
--- ECHO_COMMUNE 2026-06-23T15:57:31-07:00 pid=187580 self_session=34b6e19b-97c5-41c1-b0df-d79dbfd01fd7 fresh_session=51eede0e-1ede-4f96-ac9f-66f5cbc3bd12 exit=0 stdout_bytes=1959 excerpt_bytes=25545 excerpt_lines=14 excerpt_dropped_errors=0 excerpt_source_error=ok ---

--- /ECHO_COMMUNE ---
[15:57:34] poll exited code=0 stderr=
[15:57:34] poll returned 1073 bytes
[15:57:34] [MSG] from=<EVENT type="echo_commune" from="todland: ""
[15:57:34] [STDIN] 931 bytes to resume:
>>>  [Current time: 2026-06-23T15:57:34-07:00]
>>>  Inbound echo_commune envelope at 2026-06-23T15:57:34-07:00:
>>>    machine: HFENDULEAM
>>>    project: spt-core
>>>    branch: design/endpoint-creation-flow
>>>    head_sha: 1941eb823b36cc6ecc95dcbffe49b5a2047335fd
>>>
>>>  <project-context>
>>>  **v0.14.2 PUBLISHED** counter 32 @ 365fb0c (2026-06-23): F-019 idle-submit fix LIVE. Cut = todlando @4fd028d install_dir resolve + doyle ADR-0022 amendment @1eaeef1 + design doc 1941eb8. PR#35 green both runners (netstream #4 fix in base). Hashes linux 98714384… / win 08e8a267…. perri released for real-CC validation (idle choreography on real Windows CC = closes THE #1 blocker if confirmed working).
>>>
>>>  **raw-inject-removal build** — todlando next assignment, operator-timed. (ADR-0022 rule: drop raw-inject entirely → spt-hosted idle translation-binary-only; binary-less adapter idles poll-fed until declared; separate build after v0.14.2 ships.)
>>>  </project-context>
[15:57:48] [PSYCHE] resume (exit=0):
>>>  Holding for operator timing on raw-inject-removal build.
[15:57:48] auto-commit: git_commit_context after resume_session_with_exit
[15:57:48] [LIVE-CONTEXT-POST-WRITE] skip no-project-slice self_id=todlando project_resolves=true prompt_had_project_ctx=false
[15:57:49] poll iteration 150 starting
[15:57:49] [ECHO] gate idle: no sentinel present (awaiting next Stop)
[15:57:49] ready file exists: true
[16:05:50] poll exited code=0 stderr=
[16:05:50] poll returned 40 bytes
[16:05:50] [PULSE] pulse-psyche=off — skipping resume; echo gate fires next iteration
[16:05:50] poll iteration 151 starting
[16:05:50] [ECHO] gate idle: no sentinel present (awaiting next Stop)
[16:05:50] ready file exists: true
[16:13:50] poll exited code=0 stderr=
[16:13:50] poll returned 40 bytes
[16:13:50] [PULSE] pulse-psyche=off — skipping resume; echo gate fires next iteration
[16:13:50] poll iteration 152 starting
[16:13:50] [ECHO] gate idle: no sentinel present (awaiting next Stop)
[16:13:50] ready file exists: true


This session's todlando poll log doesn't carry the full inbound. I have contract + changes 1-5; missing parts 9-17 (TESTS/traceability/gates). Ask doyle for the tail — doyle.log is fresh (active).


printf '%s' "Ack v0.14.3 raw-inject-REMOVAL assignment — operator-GO'd, branch off main @365fb0c. Contract clear: spt-hosted idle = translation-binary-ONLY; absent/SPAWN-FAILED/FAULTED/worker-gone → message stays SPOOLED + LOUD, never raw PTY-inject. The spine = flip the no-working-binary case in dispatch_endpoint_input from input.enqueue+delivered=true to endpoint_injected_envelope(ep,FALSE) so try_broker_inject(cli.rs:3510) spools. I have your CHANGES 1-5 (broker.rs dispatch ~1875-1932 remove raw fallback ~1922; fault_translation ~1172 log reword; build_translation ~1077 log reword + None=spool; comment sweep ~154/829/837/848/872/1027/1037/1170/1882-1897/1914-1916 + translation.rs ~238; cli.rs try_broker_inject/cmd_send honest-report verify). BUT your msg truncated at part 8 mid-TESTS. Resend parts 8-17 (TESTS + traceability/REQ + gate criteria) before I start — don't want to guess the test contract." | spt send doyle 2>&1

Ack doyle, request truncated parts 8-17


Error: Exit code 1
NO_PERCH:doyle is not listening


doyle NO_PERCH (hard fail, not spooled). doyle is sender-side — full assignment body doyle composed is likely in doyle's own log/context. Grep there.


grep -n "TESTS\|dispatch_endpoint_input\|behavior-change-grep\|traceab\|REQ-\|GATE\|delivered=false\|delivered=FALSE" "$HOME/AppData/Local/spt/logs_latest/doyle.log" | tail -40

Grep doyle log for full assignment body


15725:>>>  - **REQ-ADAPTER-VERSION-CMD** (base, 679315a6): `spt adapter version <name>` → `AdapterCmd::Version{option}` → `resolve_option` → print `manifest.adapter.version` (EXISTING mandatory `[adapter]` field, NOT `[strings].version`). Unit-only. Corrected form only per operator's earlier guidance.
15726:>>>  - **REQ-DOCS-NO-INTERNAL-CODES**: sweep 14 reference.md leak sites (REQ-KICK-1, REQ-TERM-4×2, REQ-EP-1/6, REQ-MSG-5, ADR-0019/0022/0020/0008×2/0021) → plain language scrub; + xtask forbidden-token gate banning REQ-*/F-###/M#-W#/ADR-#### in GENERATED reference.md. New adapter-version help written clean from start.
15728:>>>  todlando ACKed both REQs (corrected scope locked), building now. Minting both in traceable first. Will ping when combined W6 green → deployah cuts v0.13.2 (counter 29, last scope before release).
15779:>>>  **REQ-ADAPTER-VERSION-CMD**: `spt adapter version <name>` → `resolve_option` → prints `manifest.adapter.version` (existing `[adapter]` field). Unit 2/2 pass (parses + surfaces v3.1.4 for "cc" adapter).
15781:>>>  **REQ-DOCS-NO-INTERNAL-CODES**: Swept all 14 reference.md leak sites (REQ-MSG-5, REQ-KICK-1, ADR-0019/0022/0020, etc.) to plain language. Planted `forbidden_codes_in()` scanner in `xtask check`, runs after drift-check. Left-boundary guards UTF-8/hyphenated prose. Full reference.md grep = ZERO codes (down from 14). Unit: planted tokens FAIL (non-vacuous); clean text PASS (UTF-8 case tested).
15783:>>>  All gates green: traceable both REQs +doc +impl +unit; xtask check drift==0 + scan clean; clippy OK.
15797:>>>  3. No false-positive on hyphenated prose (`ADR-justified`, `REQ-uired`)
15839:>>>  W6 final gate + CHANGELOG vet complete @ 2026-06-23 02:23. REQ-ADAPTER-VERSION-CMD + REQ-DOCS-NO-INTERNAL-CODES both verified; v0.13.2 bump (counter 29) drafted 2bb9c8f on rel/v0.13.2 atop PR#29 a2667de. CHANGELOG body vetted: surface coverage full (v0.13.1..rel/v0.13.2 = 11 feat/fix + ADR-0023 unbuilt/correctly omitted), zero internal codes, headlines honest. Cargo correct (0.13.2, 11 first-party spt-* only). **PASS — GO sent to deployah for push → CI green both → tag v0.13.2 → sign+publish.**
15845:>>>  W6 GATE-PASS confirmed. Deployah has GO. Monitoring for publish confirmation.
15879:>>>  W6 final gate + CHANGELOG vet COMPLETE @ 2026-06-23 02:23. REQ-ADAPTER-VERSION-CMD + REQ-DOCS-NO-INTERNAL-CODES verified; v0.13.2 (counter 29) drafted 2bb9c8f. **NOW: v0.13.2 PUBLISHED** by deployah — CI green both runners, signed, public; perri notified. CHANGELOG shipped verbatim (full surface coverage v0.13.1..rel/v0.13.2, 11 feat/fix + ADR-0023 correctly omitted, zero internal codes).
15939:>>>  v0.13.2 release arc CLOSED @ counter 29. **v0.14.0 W1 GATED PASS** @0e30143 (REQ-ENDPOINT-UNBOUND-ATTACH, ADR-0027). Rebase prerequisite verified (built on v0.13.2 @2bb9c8f sessions map). PR #30 = milestone PR (lands wave-by-wave).
15946:>>>  v0.14.0 endpoint-creation-flow W1 gated PASS (STATUS_UNBOUND primitive @0e30143, PR#30). W2 in flight (home resolve + skeleton-with-home). REQ-ENDPOINT-UNBOUND-ATTACH activated +impl+unit. v0.13.2 binding prerequisite (ADR-0025 W3a sessions map) confirmed satisfied.
15949:>>>  W1 GATE-PASS logged. W2 in flight — home resolve is load-bearing (resolution matrix + immutable prior-branch home inheritance). Monitoring for W2 gate ping.
16096:>>>  **v0.14.0 W1 = GATE PASS** (STATUS_UNBOUND @0e30143, prior-branch logic). **v0.14.0 W2 = GATE PASS** (@4a23dec; REQ-RUN-MULTISUBNET-HOME implemented, CI both runners green, live_adapt_* E2Es pass, traceable, the create_dir_all fix validates the skeleton→bind design pattern). **W3 in flight** (two-level MRU lists: per-project + node-global fallback, default = project-head ?? node-global-head, both lists move-to-front on every home choice; todlando building now, CI-green ping expected).
16101:>>>  W2 GATE-PASS logged. W3 in flight. Two operator GO items pending (perri release steps + PR #31) — not doyle's gate. Monitoring for W3 ping.
16143:>>>  v0.14.0 endpoint-creation-flow: **W1/W2 GATED PASS (@4a23dec; REQ-RUN-MULTISUBNET-HOME, create_dir_all fix validates skeleton→bind pattern, live_adapt_* E2Es pass both runners).** **W3 (two-level MRU lists: per-project + node-global fallback) pushed @a035512, awaiting todlando's explicit gate ping.** W4 (attach-on-session) → W5 (Unbound display) → W6 (int + perri's multi-subnet regression) queued. Holding.
16146:>>>  **v0.14.0 W1/W2 = GATE PASS.** W1: STATUS_UNBOUND @0e30143 (prior-branch logic + test coverage). W2: REQ-RUN-MULTISUBNET-HOME @4a23dec (decide_run_home matrix + recent_home.rs node-global MRU default + resolve_home_and_write_skeleton pre-launch; skeleton carries home, bind inherits via prior-branch). CI escape fixed (create_dir_all before write_info); both runners + live_adapt_* E2Es green, traceable, xtask check EXIT=0, clippy clean. **W3 (two-level MRU home lists) PUSHED @a035512.** Awaiting todlando's W3 gate ping. W6 assertion load-bearing claim logged (skeleton home=S → bind stays home=S, no re-resolve, no double-seed on sync scope) — W6 int will assert both explicitly (live_adapt_* E2Es only prove sole-subnet path, W6 proves multi-subnet hold).
16215:>>>  v0.14.0 endpoint-creation-flow: **W1/W2/W3 GATED PASS** (@4a23dec, @a035512). W4 design ruling **APPROVED** (todlando's conservative rc.rs failfast strategy verified in code: path-(a) gates on `status == STATUS_OFFLINE` specifically, so UNBOUND falls through → resolve_session → attaches; path-(b) bounded backstop + (c) BrokerGone already guard the session-death races; only change is `cmd_endpoint_run`'s `await_endpoint_online → await_endpoint_session`; W6 must-prove the multi-subnet home hold). W4 **implementation basically done** (compiles, clippy clean, xtask check EXIT=0; boundary comment (resume-window-OFFLINE case) adding, then commit+push for CI). W5 (Unbound display) → W6 (int + perri's multi-subnet regression) queued. Holding for W4 gate ping post-CI green.
16218:>>>  **v0.14.0 W3 = GATE PASS @a035512.** Store 6/6 + cli 2/2 units, traceable green, no reference drift, clippy clean, CI both runners. Verified: two-level precedence + move-to-front-both-levels + CAP + legacy back-compat all correct. ADR-0026 §3 already specified two-level MRU (no doc delta).
16223:>>>  W3 GATE-PASS logged. W4 design sound — UNBOUND falls through STATUS_OFFLINE failfast correctly, (b)+(c) chain intact. Awaiting CI green + gate ping.
16277:>>>  v0.14.0 endpoint-creation-flow: **W1/W2/W3/W4 GATED PASS** (@4a23dec/@a035512/@21cdfba). W4 gate @21cdfba CI GREEN both runners (run 28009013867: Linux 11m13s + Windows 10m24s pass, n1-gate both pass, traceability pass). **Notable: CI caught a gap in the prior ruling** — rc.rs shares the offline failfast, so `endpoint run --attach` on a resuming-offline perch hit it. todlando's fix (`run_attach_session_confirmed` skips only (a) when session proved; (b)+(c) backstop intact = no B1 regression) refined the boundary correctly. Poll 1/1 + standalone-failfast 1/1 units verified; traceable + clippy. W5 (Unbound display) → W6 (fresh UNBOUND attach-before-bind + multi-subnet regression) queued. Holding for W5 gate ping.
16280:>>>  **v0.14.0 W4 = GATE PASS @21cdfba** — attach-on-session-exists. CI GREEN both runners (28009013867). Notable boundary refinement: CI caught that rc.rs (a) offline-failfast is shared with run_attach; a resuming-offline perch invoking `endpoint run --attach` hit it pre-bind. todlando's fix splits `run_attach_session_confirmed(session_confirmed=true)` to skip only (a) when caller proved session; (b) bounded first-event backstop + (c) BrokerGone EOF intact → no B1 regression. cli.rs correct: awaits SESSION (not STATUS_ONLINE) via poll_until_ready (fast/timeout/later units), then attaches session-confirmed. Dummy_harness_e2e (no mocks) proves resume-offline attach + CI validation. Poll + standalone tests all green; traceable + clippy.
16285:>>>  W4 GATE-PASS logged. Notable lesson: CI caught that `rc.rs` offline failfast is shared — design ruling had a gap that impl+CI surfaced. `run_attach_session_confirmed` split was the right fix. W5 in flight. Monitoring.
16377:>>>  v0.14.0 W5 **GATE PASS** @6b75cc7 — picker Unbound display fixed. data.rs implements `row_status(alive||unbound→Online)` pure helper; real-derivation catch test `row_status(false, true)==Online→display Unbound` guards the seam. Impossible-combo assertion removed. Text-list path already correct. Ripple: confirm_options→Attach (not Start), confirm_terminal→Attach{Control}, start_headless no-op, resume_rows none, status_word="unbound". CI both runners + clippy/xtask/traceable green, picker 33/33.
16387:>>>  W5 GATE-PASS logged. W6 capstone in flight — full 5-item checklist must close. FRESH-UNBOUND timing race is the open design question; monitoring for todlando's approach + gate ping.
16433:>>>  v0.14.0 W6 **GATE PASS** @6b75cc7 (final) — all 5 checklist items verified non-vacuous by direct read:
16451:>>>  v0.14.0 milestone: **SHIPPED GATE-COMPLETE** — all 6 waves W1–W6 gated, both ADRs-0026/0027 accepted, release PR #30 ready. Awaiting doyle's release GO. perri's latent multi-subnet bringup gap closed in code. Next: release cut, PR #31 merge, F-018 follow-up.
16538:>>>  v0.14.0 RELEASE PIPELINE ADVANCING — THREE GATES CLEARED:
16542:>>>  **Gate 2 (PR #32 on main):** ✅ MERGED @5eea750. All CI checks passed (both runners, n1-gate, traceability; twohost skipped).
16588:>>>  **v0.14.0 release pipeline:** Three gates cleared + PR #33 (runbook) authored. deployah's v0.14.0 bump CI (attempt-1) hit known Windows ConPTY netstream ring-redrive flake (sender_brain_restart_redrive_is_exactly_once + receiver_brain_restart_is_gapless_and_exactly_once, netstream.rs:99 chunk-count gap). Code byte-identical to PR #30 green, Linux + n1-gates + traceability all green. Rerun scheduled (attempt-2 in progress). **2nd flake hit this session** (todlando's W2 also caught this family). Not a blocker — flake logged + batched with F-018 for post-release investigation. Tag held @6ba875e until attempt-2 green both runners.
16917:>>>  **v0.14.1 gates FULLY PASSED** (both F-018 @6920ea8 & picker-home @1ecdc1c). Doyle manually re-verified all gates (not trusting initial report): clippy exit 0, cargo test 242/242, 8 new tests all ✓, traceable-reqs clean (REQ-INSTALL-13 + REQ-RUN-PICKER-HOME both "+doc+impl+unit"). Diffs design-faithful. Int deferred (correct, ratified — matches INSTALL-4/9 pattern). Notified todlando GATE-PASS; release scope to operator.
17492:>>>  # doyle gen-21 — F-019 GATE-PASS @4fd028d; v0.14.2 ready to cut
17497:>>>  **Fix (GATE-PASS @4fd028d):** todlando resolved all adapter-shipped programs via `resolve_program_in_dir` (4 sites: translation initial spawn + W3d respawn, notif command ×2). New unit `translation_binary_resolves_against_install_dir` + 3 `resolve_program` tests + 18 notif tests all pass. Clippy `--workspace` exit 0, traceable exit 0. All gates verified by doyle on detached F-019 commit.
17539:>>>  **Session WRAP (2026-06-23). Resuming next session — not a fresh drive.** Delta since gen-21 (which already had F-019 GATE-PASS + v0.14.2 scoped):
17552:>>>  **v0.14.1 SHIPPED + PUBLISHED (counter 31, 2026-06-23).** Four fixes: (1) `spt adapter add` non-destructive (refuse re-add + stage-then-swap, REQ-INSTALL-13/F-018); (2) `spt endpoint run` interactive picker gains a home-subnet selection layer on multi-subnet nodes (REQ-RUN-PICKER-HOME — the deferred half of v0.14.0's ADR-0026 design); (3) clearer adapter-add installed-vs-pending messages; (4) Win netstream CI flake fixed (test conflated transport-seq with logical-chunk count under QUIC coalescing; production was correct).
17554:>>>  **v0.14.2 READY (F-019 — the #1 CC-on-Windows blocker):** spt-hosted idle message delivery to Claude Code typed the envelope but NEVER submitted. Root: the `[message-idle-translation-binary]` ships a bare relative path; spt-core spawned it via `Command::new` WITHOUT resolving against `install_dir` (the daemon diverged from ADR-0022's own translate-proof contract) → spawn fail → silent raw-inject fallback → the choreography never ran. Fix @4fd028d routes ALL adapter-shipped programs through `resolve_program_in_dir` (REQ-INSTALL-11) at 4 sites (translation initial+W3d-respawn, notif×2). ADR-0022 amended @1eaeef1: idle delivery = relay-poll OR translation-binary, raw-inject removed as a path (declared-but-failed → spooled, loud). v0.14.3 = the raw-inject removal build.
17590:>>>  **Session WRAP (2026-06-23). Resuming next session — not a fresh drive.** Delta since gen-21 (which already had F-019 GATE-PASS + v0.14.2 scoped):
17603:>>>  **v0.14.1 SHIPPED + PUBLISHED (counter 31, 2026-06-23).** Four fixes: (1) `spt adapter add` non-destructive (refuse re-add + stage-then-swap, REQ-INSTALL-13/F-018); (2) `spt endpoint run` interactive picker gains a home-subnet selection layer on multi-subnet nodes (REQ-RUN-PICKER-HOME — the deferred half of v0.14.0's ADR-0026 design); (3) clearer adapter-add installed-vs-pending messages; (4) Win netstream CI flake fixed (test conflated transport-seq with logical-chunk count under QUIC coalescing; production was correct).
17605:>>>  **v0.14.2 READY (F-019 — the #1 CC-on-Windows blocker):** spt-hosted idle message delivery to Claude Code typed the envelope but NEVER submitted. Root: the `[message-idle-translation-binary]` ships a bare relative path; spt-core spawned it via `Command::new` WITHOUT resolving against `install_dir` (the daemon diverged from ADR-0022's own translate-proof contract) → spawn fail → silent raw-inject fallback → the choreography never ran. Fix @4fd028d routes ALL adapter-shipped programs through `resolve_program_in_dir` (REQ-INSTALL-11) at 4 sites (translation initial+W3d-respawn, notif×2). ADR-0022 amended @1eaeef1: idle delivery = relay-poll OR translation-binary, raw-inject removed as a path (declared-but-failed → spooled, loud). v0.14.3 = the raw-inject removal build.
17641:>>>  **v0.14.2 GATE CLEARED → EXECUTE:** Base corrected (46289ab vs stale d7738be). CHANGELOG: 1 bullet (idle-submit fix), notif×2 correctly omitted as sibling-audit hardening, ADR/design internal. Counter 32 from metadata. cherry-picks clean. PR#35 on CI, both runners. On green → merge → tag → sign → publish → docs → perri validates. Next: v0.14.3 raw-inject removal (todlando, separate assignment, when operator times).


doyle.log = sender's commune, lacks the new assignment tail. The full 17-part payload reached the daemon — search the session task-output/spool stores for the TESTS tail.


grep -rl "endpoint_injected_envelope\|no working translation binary\|reverting to raw inject" "$HOME/AppData/Local/spt" "$HOME/.ccs" "/c/Users/decid/AppData/Local/Temp/claude" 2>/dev/null | grep -v "logs_latest" | head

Search broad for full assignment payload


Those are repo file-history snapshots, not the message. Recovery of the tail is low-yield. Per [[dont-wait-proceed-autonomously]] + doyle NO_PERCH: start the build now (changes 1-5 fully specified), recover TESTS/REQ tail when doyle perches. One last check for the tail, then ground in actual code.


ls -t "C:/Users/decid/.ccs/instances/bigscreen/projects/C--Users-decid-Documents-projects-spt-core/34b6e19b-97c5-41c1-b0df-d79dbfd01fd7/tool-results" 2>/dev/null | head; echo "=== grep tail markers ==="; grep -rl "9/17\|10/17\|TESTS\|REQ-MSG\|REQ-HAZARD" "C:/Users/decid/.ccs/instances/bigscreen/projects/C--Users-decid-Documents-projects-spt-core/34b6e19b-97c5-41c1-b0df-d79dbfd01fd7" 2>/dev/null | head

Check session tool-results for full payload tail


hook-353248cd-bd99-4a2b-9cd1-09400f77434d-5-additionalContext.txt
=== grep tail markers ===
C:/Users/decid/.ccs/instances/bigscreen/projects/C--Users-decid-Documents-projects-spt-core/34b6e19b-97c5-41c1-b0df-d79dbfd01fd7/tool-results/hook-353248cd-bd99-4a2b-9cd1-09400f77434d-5-additionalContext.txt


Tail unrecoverable. Proceeding. Ground in code + set up branch.


git fetch origin --quiet 2>&1 | tail -3; echo "=== main ==="; git log origin/main -1 --oneline; echo "=== local main ==="; git log main -1 --oneline 2>&1; echo "=== status ==="; git status -sb | head -5

Fetch and verify main at 365fb0c


=== main ===
365fb0c Merge pull request #35 from SaberMage/release/v0.14.2
=== local main ===
365fb0c Merge pull request #35 from SaberMage/release/v0.14.2
=== status ===
## design/endpoint-creation-flow...origin/design/endpoint-creation-flow [ahead 7]


main @365fb0c confirmed (v0.14.2). Branch off it + read the cited code in parallel.


git checkout -b fix/v0143-raw-inject-removal main 2>&1 | tail -3; git log -1 --oneline

Create v0.14.3 branch off main


Switched to a new branch 'fix/v0143-raw-inject-removal'
365fb0c Merge pull request #35 from SaberMage/release/v0.14.2


grep -rn "fn dispatch_endpoint_input\|fn fault_translation\|fn build_translation\|fn read_translation_path" --include=*.rs . | head

Locate target functions in source


./crates/spt-daemon/src/broker.rs:1045:fn build_translation(
./crates/spt-daemon/src/broker.rs:1089:fn read_translation_path(install_dir: &std::path::Path) -> Option<String> {
./crates/spt-daemon/src/broker.rs:1177:fn fault_translation(faulted: &AtomicBool, child: &TranslationChild, why: &str) {
./crates/spt-daemon/src/broker.rs:1880:    fn dispatch_endpoint_input(&self, env: Envelope, send: &SharedSend) -> Result<(), String> {
./crates/spt-daemon/src/broker.rs:3182:    fn read_translation_path_reads_declared_path() {
./crates/spt-daemon/src/broker.rs:3206:    fn read_translation_path_none_when_absent() {


On branch `fix/v0143-raw-inject-removal`. Read the spine: dispatch_endpoint_input + the three log sites.


1880	    fn dispatch_endpoint_input(&self, env: Envelope, send: &SharedSend) -> Result<(), String> {
1881	        let req: EndpointInputReq = serde_json::from_value(env.payload)
1882	            .map_err(|e| format!("bad endpoint-input payload: {e}"))?;
1883	        let bytes =
1884	            decode_bytes(&req.data_b64).map_err(|e| format!("bad endpoint-input base64: {e}"))?;
1885	        // Resolve endpoint → (input-writer, translation) under the lock, cloning the
1886	        // Arcs out so the ENQUEUE happens without holding the table lock
1887	        // (dispatch_input rule). The raw-inject path now enqueues to the lone
1888	        // writer too, so it can never park the dispatch thread (P0).
1889	        let resolved = {
1890	            let sessions = self.sessions.lock().unwrap();
1891	            sessions
1892	                .values()
1893	                .find(|h| h.endpoint == req.endpoint)
1894	                .map(|h| (Arc::clone(&h.input), h.translation.clone()))
1895	        };
1896	        match resolved {
1897	            Some((input, translation)) => {
1898	                // Layer E: a live (non-faulted) translation binary OWNS the
1899	                // choreography — queue the whole `<EVENT>` envelope to the inject
1900	                // worker, which drives it through the binary and applies the
1901	                // resulting keystrokes atomically w.r.t. the controller. Raw inject
1902	                // is the DEGENERATE fallback when no binary is attached, it has
1903	                // faulted, or the worker channel is gone.
1904	                if let Some(tr) = &translation {
1905	                    if !tr.faulted.load(Ordering::Relaxed) {
1906	                        let envelope = String::from_utf8_lossy(&bytes).into_owned();
1907	                        if tr.event_tx.send(envelope).is_ok() {
1908	                            eprintln!(
1909	                                "ENDPOINT_INJECT:{} ({} bytes → translation binary)",
1910	                                req.endpoint,
1911	                                bytes.len()
1912	                            );
1913	                            send_frame(send, &endpoint_injected_envelope(&req.endpoint, true));
1914	                            return Ok(());
1915	                        }
1916	                        // worker receiver dropped → fall through to raw inject.
1917	                    }
1918	                }
1919	                // IDLE/direct raw inject. Logged (REQ-SEND-SPT-HOSTED MVP): activity
1920	                // is not yet gated, so note the raw write — never a silent mid-turn
1921	                // interleave passed off as done.
1922	                eprintln!(
1923	                    "ENDPOINT_INJECT:{} ({} bytes, idle-direct — activity not yet gated)",
1924	                    req.endpoint,
1925	                    bytes.len()
1926	                );
1927	                input.enqueue(bytes);
1928	                send_frame(send, &endpoint_injected_envelope(&req.endpoint, true));
1929	                Ok(())
1930	            }
1931	            // No hosted session for this endpoint — tell the caller to spool.
1932	            None => {
1933	                send_frame(send, &endpoint_injected_envelope(&req.endpoint, false));
1934	                Ok(())
1935	            }
1936	        }
1937	    }
1938
1939	    /// Resize a session's PTY — CONTROLLER-EXCLUSIVE (REQ-RCVIEW-1). The broker
1940	    /// rejects a resize arriving on any stream that is not the session's current
1941	    /// controller (a viewer's resize is refused), then updates the stored size
1942	    /// and pushes a `size` frame to every viewer (the letterbox feed).
1943	    fn dispatch_resize(&self, env: Envelope, send: &SharedSend) -> Result<(), String> {
1944	        let req: ResizeReq =
1945	            serde_json::from_value(env.payload).map_err(|e| format!("bad resize payload: {e}"))?;
1946	        let (session, log) = {
1947	            let sessions = self.sessions.lock().unwrap();
1948	            let h = sessions
1949	                .get(&req.session_id)
1950	                .ok_or_else(|| format!("no such session {}", req.session_id))?;
1951	            (Arc::clone(&h.session), Arc::clone(&h.log))
1952	        };
1953	        if !log.lock().unwrap().is_controller(send) {
1954	            return Err(
1955	                "resize is controller-exclusive: only the interactive controller may resize"
1956	                    .to_string(),
1957	            );
1958	        }
1959	        session
1960	            .resize(SurfaceSize::new(req.rows, req.cols))
1961	            .map_err(|e| format!("resize failed: {e}"))?;
1962	        log.lock().unwrap().set_size_and_notify(req.rows, req.cols);
1963	        Ok(())
1964	    }
1965
1966	    /// Report the broker-owned net endpoint's status (D4a). Answered even when
1967	    /// the broker has no network host (`enabled: false`) so a brain can probe
1968	    /// capability without treating absence as an error.
1969	    // [impl->REQ-DAEMON-2]
1970	    fn dispatch_net_status(&self, send: &SharedSend) {
1971	        let reply = match self.net.get() {
1972	            Some(host) => NetStatusReply {
1973	                enabled: true,
1974	                node_id_hex: Some(host.node_id_hex()),
1975	                addr: host.addr_json(),
1976	                conn_count: host.conn_count(),
1977	            },
1978	            None => NetStatusReply {
1979	                enabled: false,
1980	                node_id_hex: None,
1981	                addr: serde_json::Value::Null,
1982	                conn_count: 0,
1983	            },
1984	        };
1985	        let frame = Envelope::new(
1986	            KIND_NET_STATUS_REPLY,
1987	            serde_json::to_value(reply).expect("NetStatusReply serializes"),
1988	        );
1989	        send_frame(send, &frame);
1990	    }
1991
1992	    /// Handle a planned brain-restart request (ADR-0018 D3-3, Q3): raise the
1993	    /// supervisor's restart signal so it cycles the brain child onto the swapped
1994	    /// binary with `start-reason=update`, then ack. `honored` reflects whether a
1995	    /// supervisor is wired (a bare test broker has none → accepted-but-unhonored).
1996	    /// The broker — which observes every respawn — stamps the `update` reason,
1997	    /// keeping planned-vs-crash authoritative on this side (V2).
1998	    // [impl->REQ-HAZARD-BROKER-PROCESS-ISOLATION]
1999	    // [impl->REQ-UPD-3]

    fn dispatch_endpoint_input(&self, env: Envelope, send: &SharedSend) -> Result<(), String> {
        let req: EndpointInputReq = serde_json::from_value(env.payload)
            .map_err(|e| format!("bad endpoint-input payload: {e}"))?;
        let bytes =
            decode_bytes(&req.data_b64).map_err(|e| format!("bad endpoint-input base64: {e}"))?;
        // Resolve endpoint → (input-writer, translation) under the lock, cloning the
        // Arcs out so the ENQUEUE happens without holding the table lock
        // (dispatch_input rule). The raw-inject path now enqueues to the lone
        // writer too, so it can never park the dispatch thread (P0).
        let resolved = {
            let sessions = self.sessions.lock().unwrap();
            sessions
                .values()
                .find(|h| h.endpoint == req.endpoint)
                .map(|h| (Arc::clone(&h.input), h.translation.clone()))
        };
        match resolved {
            Some((input, translation)) => {
                // Layer E: a live (non-faulted) translation binary OWNS the
                // choreography — queue the whole `<EVENT>` envelope to the inject
                // worker, which drives it through the binary and applies the
                // resulting keystrokes atomically w.r.t. the controller. Raw inject
                // is the DEGENERATE fallback when no binary is attached, it has
                // faulted, or the worker channel is gone.
                if let Some(tr) = &translation {
                    if !tr.faulted.load(Ordering::Relaxed) {
                        let envelope = String::from_utf8_lossy(&bytes).into_owned();
                        if tr.event_tx.send(envelope).is_ok() {
                            eprintln!(
                                "ENDPOINT_INJECT:{} ({} bytes → translation binary)",
                                req.endpoint,
                                bytes.len()
                            );
                            send_frame(send, &endpoint_injected_envelope(&req.endpoint, true));
                            return Ok(());
                        }
                        // worker receiver dropped → fall through to raw inject.
                    }
                }
                // IDLE/direct raw inject. Logged (REQ-SEND-SPT-HOSTED MVP): activity
                // is not yet gated, so note the raw write — never a silent mid-turn
                // interleave passed off as done.
                eprintln!(
                    "ENDPOINT_INJECT:{} ({} bytes, idle-direct — activity not yet gated)",
                    req.endpoint,
                    bytes.len()
                );
                input.enqueue(bytes);
                send_frame(send, &endpoint_injected_envelope(&req.endpoint, true));
                Ok(())
            }
            // No hosted session for this endpoint — tell the caller to spool.
            None => {
                send_frame(send, &endpoint_injected_envelope(&req.endpoint, false));
                Ok(())
            }
        }
    }

    /// Resize a session's PTY — CONTROLLER-EXCLUSIVE (REQ-RCVIEW-1). The broker
    /// rejects a resize arriving on any stream that is not the session's current
    /// controller (a viewer's resize is refused), then updates the stored size
    /// and pushes a `size` frame to every viewer (the letterbox feed).
    fn dispatch_resize(&self, env: Envelope, send: &SharedSend) -> Result<(), String> {
        let req: ResizeReq =
            serde_json::from_value(env.payload).map_err(|e| format!("bad resize payload: {e}"))?;
        let (session, log) = {
            let sessions = self.sessions.lock().unwrap();
            let h = sessions
                .get(&req.session_id)
                .ok_or_else(|| format!("no such session {}", req.session_id))?;
            (Arc::clone(&h.session), Arc::clone(&h.log))
        };
        if !log.lock().unwrap().is_controller(send) {
            return Err(
                "resize is controller-exclusive: only the interactive controller may resize"
                    .to_string(),
            );
        }
        session
            .resize(SurfaceSize::new(req.rows, req.cols))
            .map_err(|e| format!("resize failed: {e}"))?;
        log.lock().unwrap().set_size_and_notify(req.rows, req.cols);
        Ok(())
    }

    /// Report the broker-owned net endpoint's status (D4a). Answered even when
    /// the broker has no network host (`enabled: false`) so a brain can probe
    /// capability without treating absence as an error.
    // [impl->REQ-DAEMON-2]
    fn dispatch_net_status(&self, send: &SharedSend) {
        let reply = match self.net.get() {
            Some(host) => NetStatusReply {
                enabled: true,
                node_id_hex: Some(host.node_id_hex()),
                addr: host.addr_json(),
                conn_count: host.conn_count(),
            },
            None => NetStatusReply {
                enabled: false,
                node_id_hex: None,
                addr: serde_json::Value::Null,
                conn_count: 0,
            },
        };
        let frame = Envelope::new(
            KIND_NET_STATUS_REPLY,
            serde_json::to_value(reply).expect("NetStatusReply serializes"),
        );
        send_frame(send, &frame);
    }

    /// Handle a planned brain-restart request (ADR-0018 D3-3, Q3): raise the
    /// supervisor's restart signal so it cycles the brain child onto the swapped
    /// binary with `start-reason=update`, then ack. `honored` reflects whether a
    /// supervisor is wired (a bare test broker has none → accepted-but-unhonored).
    /// The broker — which observes every respawn — stamps the `update` reason,
    /// keeping planned-vs-crash authoritative on this side (V2).
    // [impl->REQ-HAZARD-BROKER-PROCESS-ISOLATION]
    // [impl->REQ-UPD-3]


Spine confirmed — matches doyle's CHANGE 1 exactly (lines 1919-1929 raw-inject fallback = remove; 1916 worker-dropped fall-through → spool). Note `input` Arc becomes unused after removal → must drop from resolved tuple (clippy --workspace denies warnings). Read the other sites + check for an existing REQ before editing.