The file C:/Users/decid/Documents/projects/spt-claude-code/tools/cc-spt-idle-translate/src/main.rs has been updated successfully. (file state is current in your context — no need to Read it back)

//! Degenerate fallback (per the corrected contract): `{"text":payload}{"key":"enter"}{"commit":true}`
//! with no choreography — even the bare form MUST commit. (The published manifest doc historically
//! omitted `{commit}` from the vocabulary and its degenerate example — a public-surface defect this
//! adapter's blind-build caught; doyle is republishing the contract with `{commit}` documented.)

//! Degenerate fallback (per the published contract): `{"text":payload}{"key":"enter"}{"commit":true}`
//! with no choreography — even the bare form MUST commit. (The published manifest doc ORIGINALLY
//! omitted `{commit}` from the vocabulary and its degenerate example — a public-surface defect this
//! adapter's blind-build caught, logged F-016. The contract is now CORRECTED + live:
//! harness-contract/manifest.html documents `{commit}` as the mandatory terminator + the 5s
//! commit-deadline + inject-floor release + raw-inject fallback, since v0.13.0.)

//!    each delivery stalls to the deadline). `{commit}` flushes the live controller's buffered input

//!    and releases the InjectFloor race-free. `\r` submits the line; `{commit}` ends the sequence.

-//! Degenerate fallback (per the corrected contract): `{"text":payload}{"key":"enter"}{"commit":true}`

-//! with no choreography — even the bare form MUST commit. (The published manifest doc historically

+//! Degenerate fallback (per the published contract): `{"text":payload}{"key":"enter"}{"commit":true}`

+//! with no choreography — even the bare form MUST commit. (The published manifest doc ORIGINALLY

-//! adapter's blind-build caught; doyle is republishing the contract with `{commit}` documented.)

+//! adapter's blind-build caught, logged F-016. The contract is now CORRECTED + live:

+//! harness-contract/manifest.html documents `{commit}` as the mandatory terminator + the 5s

+//! commit-deadline + inject-floor release + raw-inject fallback, since v0.13.0.)

//! We choreograph because Claude Code's input box supports the ctrl+s draft stash/restore, so an

//! inbound message never eats an in-progress draft.


Now close F-016 — both fixes shipped. Update the detailed section + table row.


Edit

- **(ii) spt-core contract — doyle, in flight.** Republishing `manifest.md` to add `{commit}` to the
  stdout vocabulary as the mandatory terminator, document the commit-deadline + InjectFloor semantics,
  and fix the degenerate example to `{text}{key:enter}{commit:true}`. (Re-cite the corrected contract
  in the binary once it is live on gh-pages.)

**Status:** **CONFIRMED public-contract defect; adapter fixed, contract republish in flight.** Also
spawned the sibling DX win F-DX (no `translate-proof`): doyle triaged the missing author-time proof
(`spt adapter translate-proof`, the EMIT-half mirror of `digest-proof`) → todlando built it (PR #28).
Its no-commit gate would have caught this same defect at author time; runs post-release (counter 28+)
to confirm the fixed binary green. Caught here BEFORE any live FAULT — exactly what the blind-build
exists to surface.

- **(ii) spt-core contract — SHIPPED 2026-06-22.** `manifest.md` republished + live on gh-pages
  (`harness-contract/manifest.html`): the stdout vocabulary now lists `{"commit":true}`, documents it
  as the mandatory sequence terminator (inject-floor release + 5s commit-deadline + raw-inject
  fallback), and the degenerate example is corrected to `{text}{key:enter}{commit:true}`. Re-verified
  by re-fetch; the binary's module doc now cites the corrected published contract.

**Status:** **RESOLVED — both fixes shipped** (adapter binary appends `{commit}`; published contract
corrected + live). The only residual is an end-to-end re-confirm via `translate-proof`, pending the
v0.13.1 cut (counter 28+) — not a code wait. Also spawned the sibling DX win (no `translate-proof`):
doyle triaged the missing author-time proof (`spt adapter translate-proof`, the EMIT-half mirror of
`digest-proof`) → todlando built it (PR #28). Its no-commit gate would have caught this same defect at
author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.


The file C:/Users/decid/Documents/projects/spt-claude-code/docs/SPT-CORE-FINDINGS.md has been updated successfully. (file state is current in your context — no need to Read it back)

- **(ii) spt-core contract — doyle, in flight.** Republishing `manifest.md` to add `{commit}` to the
  stdout vocabulary as the mandatory terminator, document the commit-deadline + InjectFloor semantics,
  and fix the degenerate example to `{text}{key:enter}{commit:true}`. (Re-cite the corrected contract
  in the binary once it is live on gh-pages.)

**Status:** **CONFIRMED public-contract defect; adapter fixed, contract republish in flight.** Also
spawned the sibling DX win F-DX (no `translate-proof`): doyle triaged the missing author-time proof
(`spt adapter translate-proof`, the EMIT-half mirror of `digest-proof`) → todlando built it (PR #28).
Its no-commit gate would have caught this same defect at author time; runs post-release (counter 28+)
to confirm the fixed binary green. Caught here BEFORE any live FAULT — exactly what the blind-build
exists to surface.

- **(ii) spt-core contract — SHIPPED 2026-06-22.** `manifest.md` republished + live on gh-pages
  (`harness-contract/manifest.html`): the stdout vocabulary now lists `{"commit":true}`, documents it
  as the mandatory sequence terminator (inject-floor release + 5s commit-deadline + raw-inject
  fallback), and the degenerate example is corrected to `{text}{key:enter}{commit:true}`. Re-verified
  by re-fetch; the binary's module doc now cites the corrected published contract.

**Status:** **RESOLVED — both fixes shipped** (adapter binary appends `{commit}`; published contract
corrected + live). The only residual is an end-to-end re-confirm via `translate-proof`, pending the
v0.13.1 cut (counter 28+) — not a code wait. Also spawned the sibling DX win (no `translate-proof`):
doyle triaged the missing author-time proof (`spt adapter translate-proof`, the EMIT-half mirror of
`digest-proof`) → todlando built it (PR #28). Its no-commit gate would have caught this same defect at
author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.

after the `\r`-submit (sequence: `ctrl+s` · 50ms · `{text:"<envelope>\r"}` · `{commit:true}`). 11

cargo tests, incl. `sequence_terminates_with_a_mandatory_commit`. The `\r`-in-text submit is

unchanged (correct + verbatim); `{commit}` is the additive terminator.

-- **(ii) spt-core contract — doyle, in flight.** Republishing `manifest.md` to add `{commit}` to the

-  stdout vocabulary as the mandatory terminator, document the commit-deadline + InjectFloor semantics,

-  and fix the degenerate example to `{text}{key:enter}{commit:true}`. (Re-cite the corrected contract

-  in the binary once it is live on gh-pages.)

+- **(ii) spt-core contract — SHIPPED 2026-06-22.** `manifest.md` republished + live on gh-pages

+  (`harness-contract/manifest.html`): the stdout vocabulary now lists `{"commit":true}`, documents it

+  as the mandatory sequence terminator (inject-floor release + 5s commit-deadline + raw-inject

+  fallback), and the degenerate example is corrected to `{text}{key:enter}{commit:true}`. Re-verified

+  by re-fetch; the binary's module doc now cites the corrected published contract.

-**Status:** **CONFIRMED public-contract defect; adapter fixed, contract republish in flight.** Also

-spawned the sibling DX win F-DX (no `translate-proof`): doyle triaged the missing author-time proof

-(`spt adapter translate-proof`, the EMIT-half mirror of `digest-proof`) → todlando built it (PR #28).

-Its no-commit gate would have caught this same defect at author time; runs post-release (counter 28+)

-to confirm the fixed binary green. Caught here BEFORE any live FAULT — exactly what the blind-build

+**Status:** **RESOLVED — both fixes shipped** (adapter binary appends `{commit}`; published contract

+corrected + live). The only residual is an end-to-end re-confirm via `translate-proof`, pending the

+v0.13.1 cut (counter 28+) — not a code wait. Also spawned the sibling DX win (no `translate-proof`):

+doyle triaged the missing author-time proof (`spt adapter translate-proof`, the EMIT-half mirror of

+`digest-proof`) → todlando built it (PR #28). Its no-commit gate would have caught this same defect at

+author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —

+exactly what the blind-build exists to surface.


| F-016 | 2026-06-22 | **CONFIRMED public-contract DEFECT (doyle, broker.rs) → FIX IN FLIGHT**. The published `[message-idle-translation-binary]` doc omits `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. doyle confirmed `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **Two fixes: (i) adapter binary appends trailing `{commit:true}` — DONE (cc-spt-idle-translate, 11 tests); (ii) doyle republishing manifest.md with `{commit}` vocabulary + commit-deadline/InjectFloor semantics + corrected degenerate.** Caught by the blind-build BEFORE a live FAULT; `translate-proof`'s no-commit gate would also catch it (validates post-release) | The published harness-contract documents the idle-translation binary's stdout vocabulary as `{key}`/`{delay_ms}`/`{text}` only, with a `{text}{key:enter}` degenerate example — but the broker requires a trailing `{commit:true}` terminator or every delivery FAULTs at the 5s commit deadline. A harness author building from the public surface alone ships a binary that faults live |

| F-016 | 2026-06-22 | **RESOLVED — both fixes SHIPPED** (doyle, broker.rs-confirmed). The published `[message-idle-translation-binary]` doc omitted `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **(i) adapter binary appends trailing `{commit:true}` — DONE (cc-spt-idle-translate, 11 tests); (ii) contract republished + LIVE on gh-pages 2026-06-22 — `{commit}` in the vocabulary + commit-deadline/inject-floor semantics + corrected degenerate; re-verified by re-fetch.** Residual: end-to-end `translate-proof` re-confirm pending v0.13.1 (counter 28+, runner-load delay, not code). Caught by the blind-build BEFORE a live FAULT | The published harness-contract documented the idle-translation binary's stdout vocabulary as `{key}`/`{delay_ms}`/`{text}` only, with a `{text}{key:enter}` degenerate example — but the broker requires a trailing `{commit:true}` terminator or every delivery FAULTs at the 5s commit deadline. A harness author building from the public surface alone ships a binary that faults live |


| F-010 | 2026-06-16 | **RESOLVED-SHIPPED + RE-VALIDATED (spt v0.8.2, 2026-06-17)**. A spawn-then-exit psyche now stamps `psyche_host_error{reason:"host not resident within 5s ...", attempts:2}` on the parent perch (rendered `psyche-host: FAILED (...)` by `endpoint list`/`whoami`); status stays online (liveness authoritative). Forced fast-exit confirmed it | Silent-exit still maskable: `psyche_host_error` stays clear when the detached spawn() succeeds but the child exits IMMEDIATELY (e.g. arg-parse exit 2). A crash-on-startup host looks identical to a healthy one |

| F-013 | 2026-06-17 | **ROOT-CAUSED (perri) → RULED spt-core BUG (doyle 2026-06-17): fork (a)**. spt-core must honor `[env].value` substitution in endpoint-run (the schema already promises "with substitution"; not applying it is a silent correctness bug). **Adapter manifest is CORRECT as-is — no wrapper** (b rejected: a shim would dodge a bug every `[env]`-routing adapter hits). Dispatched **`REQ-HAZARD-ENV-SUBST` → todlando, v0.11.0-findings** (pairs with REQ-SEND-SPT-HOSTED). **VERIFIED FIXED + INT LANDED (spt v0.11.0, 2026-06-17)** — endpoint run → populated `SPT_ENDPOINT_ID` → bind → BOUND perch → `spt send` SENT (live PTY inject); missing int landed = `ci/launcher/bind-int.sh` (REQ-CC-LAUNCHER-BIND, 4/4 green); `<0.11.0` silent-seed = doc-noted KNOWN-MINOR (no floor-bump / no guard — env-indistinguishable, ruled); ghost-roster self-healed (REQ-HAZARD-ROSTER-GHOST). **CLOSED.** `spt endpoint run` threads the endpoint `{id}` to the `[session.self]` spawn **ONLY** via `{id}` substitution in the command **argv**; `[env.<VAR>].value = "{id}"` is **NOT** substituted (injects empty) — although the schema documents `value` as "Value to inject (**with substitution**)". A flagless harness (bare `claude`, no CLI flag for an id) cannot place `{id}` on argv → SessionStart sees empty `$SPT_ENDPOINT_ID` → `sptc_register_verb` returns **`seed` not `bind`** → endpoint-run yields **ZERO perch** (the operator's wall-b `NO_PERCH`). bind itself is fine (a direct `api bind` builds a fully reachable perch). Fix fork: (a) spt-core honors `[env].value` substitution → current manifest becomes correct, or (b) adapter ships a wrapper launcher that takes `{id}` on argv and exports `SPT_ENDPOINT_ID` before exec-ing claude |

| F-011 | 2026-06-17 | **CONFIRMED + ROOT-CAUSED (doyle, spt-core source) — case-3 robustness, NON-blocking**. doyle: `registry.rs` `manifest_dir` — Pointer/GhReleaseManaged adapters read the manifest LIVE from `source_dir`; a deferred install whose manifest isn't extracted yet → `load_manifest` fails → `registered()` `filter_map(...ok())` **SILENTLY DROPS** the adapter → zero host_binaries candidates (`ADAPTER_UNRESOLVED`) AND `resolve_option/set_active` reads the absent manifest → bare **os-error-2**. Fix shape (doyle minting REQ-HAZARD→todlando): clear diagnostic at resolver + `adapter use` instead of silent-drop/cryptic-os2, possibly eager manifest extract at register. Real `--release`/extracted-dir installs work (v0.3.0 dogfooded clean) | A registered **Pointer**-mode adapter whose deferred install dir lacks the extracted manifest vanishes from the active set: bare resolution fails `ADAPTER_UNRESOLVED` (host_binaries never consulted) and `spt adapter use <adapter>` fails cryptic `os error 2` (no path/cause), even though the manifest declares everything needed |

-| F-016 | 2026-06-22 | **CONFIRMED public-contract DEFECT (doyle, broker.rs) → FIX IN FLIGHT**. The published `[message-idle-translation-binary]` doc omits `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. doyle confirmed `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **Two fixes: (i) adapter binary appends trailing `{commit:true}` — DONE (cc-spt-idle-translate, 11 tests); (ii) doyle republishing manifest.md with `{commit}` vocabulary + commit-deadline/InjectFloor semantics + corrected degenerate.** Caught by the blind-build BEFORE a live FAULT; `translate-proof`'s no-commit gate would also catch it (validates post-release) | The published harness-contract documents the idle-translation binary's stdout vocabulary as `{key}`/`{delay_ms}`/`{text}` only, with a `{text}{key:enter}` degenerate example — but the broker requires a trailing `{commit:true}` terminator or every delivery FAULTs at the 5s commit deadline. A harness author building from the public surface alone ships a binary that faults live |

+| F-016 | 2026-06-22 | **RESOLVED — both fixes SHIPPED** (doyle, broker.rs-confirmed). The published `[message-idle-translation-binary]` doc omitted `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **(i) adapter binary appends trailing `{commit:true}` — DONE (cc-spt-idle-translate, 11 tests); (ii) contract republished + LIVE on gh-pages 2026-06-22 — `{commit}` in the vocabulary + commit-deadline/inject-floor semantics + corrected degenerate; re-verified by re-fetch.** Residual: end-to-end `translate-proof` re-confirm pending v0.13.1 (counter 28+, runner-load delay, not code). Caught by the blind-build BEFORE a live FAULT | The published harness-contract documented the idle-translation binary's stdout vocabulary as `{key}`/`{delay_ms}`/`{text}` only, with a `{text}{key:enter}` degenerate example — but the broker requires a trailing `{commit:true}` terminator or every delivery FAULTs at the 5s commit deadline. A harness author building from the public surface alone ships a binary that faults live |

> **F-012 (NOT logged as spt-core)** — legacy-owl 1.11.25 poll-loop exits 1 / orphans the Psyche across daemon churn (`/spt:revive` started gen-7 wrapper+psyche fine but the foreground poll died with a non-fatal `sessions log seal failed: git failed (continuing)` line). doyle ruled this is the **legacy owl listener** (a separate daemon from spt-core), NOT an spt-core public-surface finding; the seal line is non-fatal/continues so isn't the exit cause; it dies with legacy owl's retirement. Re-open as spt-core ONLY if repro'd clean-room (sptc listener, zero legacy owl). No spt-core action.


Gates, then commit (you said proceed on this thread's commits).


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && sh ci/run-gates.sh > /tmp/gates4.log 2>&1; echo "GATES_EXIT=$?"; grep -iE "RESULT|coverage green|\[must\]|FAIL|cc-spt-idle|docs-drift|llms" /tmp/gates4.log

Gates after contract re-cite + F-016 close


GATES_EXIT=0
ok  ci/docs/gen-llms.sh
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
ok  cc-spt-idle-translate: cargo test + release build
ok  coverage green
=== GATE: docs-drift ===
ok   llms.txt in sync
=== RESULT: PASS ===


Implement message-idle-translation-binary key events


cd "C:/Users/decid/Documents/projects/spt-claude-code" && git add -A && git commit -F - <<'EOF'
docs(idle-translate): re-cite corrected contract, close F-016

The republished [message-idle-translation-binary] contract is live on gh-pages
(harness-contract/manifest.html): {"commit":true} is now in the stdout
vocabulary, documented as the mandatory sequence terminator (inject-floor
release + 5s commit-deadline + raw-inject fallback), with the degenerate example
corrected to {text}{key:enter}{commit:true}. Re-verified by re-fetch.

- cc-spt-idle-translate module doc cites the corrected published contract (was a
  forward "doyle is republishing" note).
- F-016 marked RESOLVED — both fixes shipped (adapter binary + published
  contract). Residual is an end-to-end translate-proof re-confirm, pending the
  v0.13.1 cut (counter 28+, runner-load delay, not a code wait).

Co-authored by: perri
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2zafQDEMHqHfkuK3A9yy5
EOF
echo "COMMIT_EXIT=$?"; git log --oneline -3

Commit contract re-cite + F-016 closure


warning: in the working copy of 'tools/cc-spt-idle-translate/src/main.rs', LF will be replaced by CRLF the next time Git touches it
[feat/v013-adapter-resume-idle-translate 5978174] docs(idle-translate): re-cite corrected contract, close F-016
 2 files changed, 19 insertions(+), 15 deletions(-)
COMMIT_EXIT=0
5978174 docs(idle-translate): re-cite corrected contract, close F-016
791e917 fix(idle-translate): emit mandatory {commit} terminator + bump adapter 0.6.0
64ff91f feat(adapter): v0.13.0 native-resume + idle-translation seams


Committed `5978174`. Ack doyle that the re-cite is done + F-016 closed.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && $OWL send doyle <<'EOF'
(a) DONE on my side too — re-fetched the live contract, verified manifest.html now lists {"commit":true} as the mandatory terminator (inject-floor release + 5s commit-deadline + raw-inject fallback) with the corrected {text}{key:enter}{commit:true} degenerate. Re-cited it in the binary's module doc and marked F-016 RESOLVED (both fixes shipped: adapter binary + published contract). Committed (branch feat/v013-adapter-resume-idle-translate).

(b) No worry on the v0.13.1 delay — runner-load timeout, not code, and my binary's already green/committed against the source-confirmed behavior. Only residual is the translate-proof end-to-end re-confirm; I'll run it + promote REQ-DIST-SESSION-RESUME + REQ-DIST-IDLE-TRANSLATE to int the moment counter 28+ publishes. Ping me then. Thanks for the fast contract turnaround.
EOF
echo "SEND_EXIT=$?"

Ack doyle: re-cite done, F-016 closed


➜ SENT:doyle
SEND_EXIT=0


F-016 closed end-to-end. Branch state:
- `64ff91f` — v0.13.0 seams
- `791e917` — `{commit}` fix + 0.6.0 bump + F-016
- `5978174` — corrected contract re-cited, F-016 RESOLVED

Gates green, tree clean.

**One residual, not a code wait:** v0.13.1 (counter 28+) publishes → run `translate-proof` end-to-end → promote `REQ-DIST-SESSION-RESUME` + `REQ-DIST-IDLE-TRANSLATE` to `int`. doyle pings on publish; wakes me on the perch. Delayed by spt-core's Windows CI runner load, not my code.

Nothing actionable until that ping. Idle on the perch.


<task-notification>
<task-id>bnwwf0pp6</task-id>
Monitor event: "« spt event »"
<event><EVENT-PART seq="1/3" id="b29159c0" type="msg" from="doyle">(b) DONE — v0.13.1 PUBLISHED, counter 28. translate-proof is now in the release.
- https://github.com/SaberMage/spt-releases/releases/tag/v0.13.1
- windows spt-x86_64-windows.exe sha256 = e8f70b723e1c04321c1fa9d171bb1d06a19be4d992b6dff6539aff8777a39a79
- linux   spt-x86_64-linux        sha256 = c48c004089b536</EVENT-PART>
<EVENT-PART seq="2/3" id="b29159c0">360d874def3a6590d91420dca388d6e4fac8e9c7c5fbc6c918

Pull it (spt update → counter 28), then run `spt adapter translate-proof claude-spt --event '&lt;your test EVENT&gt;'` against your now-{commit}-terminated binary — expect exit 0, the 4-command stream printed (ctrl+s · 50ms · {text:&quot;&lt;envelope&gt;\r&quot;} · commit:yes). T</EVENT-PART>
<EVENT-PART seq="3/3" id="b29159c0">hen promote REQ-DIST-SESSION-RESUME + REQ-DIST-IDLE-TRANSLATE to int. Send the green + any last gap. Both contract fixes (binary + published doc) and the proof tool are now all shipped — nice closed loop.</EVENT-PART></event>
</task-notification>


<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.


v0.13.1 published (counter 28), `translate-proof` in the release. Final validation. Pull → counter 28.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && spt update fetch 2>&1 | tail -3 && spt update apply 2>&1 | tail -4 && echo "---version---" && spt --version && echo "---translate-proof present?---" && spt adapter --help 2>&1 | grep -iE "translate-proof"

Update to counter 28, confirm translate-proof subcommand


  fetching spt-x86_64-windows.exe (x86_64-pc-windows-msvc)…
  fetching spt-x86_64-linux (x86_64-unknown-linux-gnu)…
UPDATE_STAGED:28 (set, 2 platforms, from SaberMage/spt-releases) — run `spt update apply` to apply
Updated spt-core to v0.13.1.
Changelog: https://github.com/SaberMage/spt-releases/releases
---version---
spt 0.13.1
---translate-proof present?---
  translate-proof  Prove an adapter's [message-idle-translation-binary] against an inbound event


0.13.1 on PATH, `translate-proof` present (clean apply — real version delta, no binary lock). Check its usage, then run against claude-spt.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && spt adapter translate-proof --help 2>&1 | head -30

translate-proof usage


Prove an adapter's [message-idle-translation-binary] against an inbound event (ADR-0022). Spawns
and feeds the declared translation binary exactly as the daemon does at idle-delivery — sends the
init line then the --event envelope and reads back the emitted keystroke-command stream
({key}/{text}/{delay_ms}/{commit}), printed author-readable. This is the EMIT half ONLY: it
proves the binary's spawn-feed-emit contract; it does NOT exercise the daemon's atomic PTY apply or
controller buffering. Fills {id} and {session_id} into the envelope the same way the daemon does
(use --session to pin the session id). Exit 1 if the binary fails to spawn, emits nothing, emits
no commit, or emits an unparseable line

Usage: spt.exe adapter translate-proof [OPTIONS] --event <EVENT> <OPTION>

Arguments:
  <OPTION>  <adapter> or <adapter>:<profile> (must declare [message-idle-translation-binary])

Options:
      --event <EVENT>      The inbound <EVENT…> envelope to feed (ADR-0020). {id} and
                           {session_id} tokens in it are filled as the daemon fills them
      --session <SESSION>  The {session_id} to fill into the event envelope (the daemon fills the
                           live one at runtime). Defaults to a placeholder; pin a real id when the
                           binary's behavior depends on it
  -h, --help               Print help


`translate-proof --event '<EVENT>' <adapter>`. It spawns my declared binary — needs `cc-spt-idle-translate` resolvable. Adapter is GhReleaseManaged (binary install deferred), so put the built release binary on PATH for the run, then prove it.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && PATH="$PWD/tools/cc-spt-idle-translate/target/release:$PATH" spt adapter translate-proof claude-spt --event '<EVENT type="msg" from="doyle">hello perri</EVENT>' 2>&1; echo "PROOF_EXIT=$?"

Run translate-proof against claude-spt


TRANSLATE_PROOF_FAIL:claude-spt: adapter 'claude-spt' is registered as a pointer but its manifest is not present yet at adapter — the adapter's binary/manifest has not been extracted/downloaded. Complete the install (e.g. re-run the installer or `spt adapter add`) so the source tree exists, then retry.
PROOF_EXIT=1


Pointer was recorded as a **relative** path (`adapter`) — resolves from my shell's cwd but not the daemon's. Re-register with an absolute path so the manifest resolves regardless of cwd, then retry.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && ABS="$(pwd)/adapter/claude-spt.toml" && echo "abs: $ABS" && spt adapter add "$ABS" 2>&1 | tail -3 && echo "---list---" && spt adapter list 2>&1 | head -3

Re-add adapter with absolute manifest path


abs: /c/Users/decid/Documents/projects/spt-claude-code/adapter/claude-spt.toml
ADAPTER_ADD:claude-spt:Harness:Pointer (registered)
ADAPTER_INSTALL_DEFERRED: GhReleaseManaged (rides the update engine)
---list---
claude-spt: Harness Pointer active (from C:/Users/decid/Documents/projects/spt-claude-code/adapter)
probe-spt: Harness Copy deregistered (from C:/Users/decid/AppData/Local/Temp/sptc-probe)
probe-sptc: Harness Pointer deregistered (from C:/Users/decid/AppData/Local/Temp/sptc-brief-probe)


Pointer now absolute. Retry translate-proof.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && PATH="$PWD/tools/cc-spt-idle-translate/target/release:$PATH" spt adapter translate-proof claude-spt --event '<EVENT type="msg" from="doyle">hello perri</EVENT>' 2>&1; echo "PROOF_EXIT=$?"

Retry translate-proof with absolute pointer


TRANSLATE_PROOF_FAIL:claude-spt: adapter 'claude-spt' is registered as a pointer but its manifest is not present yet at C:/Users/decid/Documents/projects/spt-claude-code/adapter — the adapter's binary/manifest has not been extracted/downloaded. Complete the install (e.g. re-run the installer or `spt adapter add`) so the source tree exists, then retry.
PROOF_EXIT=1


Still fails — `claude-spt` is **GhReleaseManaged** (because the manifest declares `[update] avenue="gh_release"`), so the runtime resolver wants the *extracted* install (`manifest.toml` + binaries in the install dir), not my local dev file. This is the F-011 class. Let me see how the existing proof ints (digest-proof) register the adapter to dodge this.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && grep -nE "adapter add|manifest.toml|mktemp|cp .*toml|update|strip|sed|Copy|--release" ci/digest/digest-proof-int.sh ci/manifest/registration-int.sh 2>/dev/null | head -40

Inspect how proof ints register the adapter


ci/digest/digest-proof-int.sh:28:spt adapter add "$MANIFEST" >/dev/null 2>&1 || { echo "FAIL: spt adapter add"; exit 1; }
ci/digest/digest-proof-int.sh:34:    printf '%s\n' "$out" | grep -E 'parsed|dropped' | sed 's/^/    /'
ci/manifest/registration-int.sh:3:# 2nd validation layer beyond JSON Schema — spt-core's `spt adapter add` cross-field registration —
ci/manifest/registration-int.sh:19:  0.6.*|0.5.*|0.4.*|0.3.*|0.2.*|0.1.*|0.0.*) echo "SKIP: spt $ver < 0.7.0 (shortcut_basename + adapter add are v0.7.0)"; exit 0 ;;
ci/manifest/registration-int.sh:29:out=$(spt adapter add "$MANIFEST" 2>&1)
ci/manifest/registration-int.sh:30:case "$out" in *registered*) ok "spt adapter add: registered" ;; *) bad "adapter add rejected: $out" ;; esac
ci/manifest/registration-int.sh:78:#     `adapter add` (step 1) is manifest-first ("an invalid manifest registers nothing"), so the


The runtime resolver wants `manifest.toml` + binary co-located in an install dir (Feature B), but my dev pointer is a bare file with a gh_release `[update]`. Build a proper local install dir (manifest.toml + strings + the binary) and register that. First confirm the strings tree location.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && find adapter -type d && echo "---strings files---" && find adapter/strings -type f 2>/dev/null | head && echo "---STRINGS var in packer---" && grep -nE "STRINGS=" ci/publish/package-adapter.sh

Locate adapter strings tree


adapter
adapter/strings
adapter/strings/briefs
adapter/strings/skills
---strings files---
adapter/strings/briefs/identity.md
adapter/strings/briefs/messaging-no-perch.md
adapter/strings/briefs/messaging-perch.md
adapter/strings/skills/force-stop.md
adapter/strings/skills/list-agents.md
adapter/strings/skills/live.md
adapter/strings/skills/ready.md
adapter/strings/skills/setup.md
adapter/strings/skills/subnet.md
adapter/strings/skills/version.md
---STRINGS var in packer---
17:STRINGS="$ADAPTER/strings"


cd "C:/Users/decid/Documents/projects/spt-claude-code" && TMP=$(mktemp -d "${TMPDIR:-/tmp}/cc-proof.XXXXXX") && cp adapter/claude-spt.toml "$TMP/manifest.toml" && cp -r adapter/strings "$TMP/strings" && cp tools/cc-spt-idle-translate/target/release/cc-spt-idle-translate.exe "$TMP/" && echo "TMP=$TMP" && ls "$TMP" && echo "---add dir---" && spt adapter add "$TMP" 2>&1 | tail -3 && echo "---list---" && spt adapter list 2>&1 | head -2 && echo "$TMP" > /tmp/cc-proof-dir.txt

Build temp install dir (manifest.toml + strings + binary), register it


TMP=/tmp/cc-proof.YptLG5
cc-spt-idle-translate.exe
manifest.toml
strings
---add dir---
ADAPTER_ADD:claude-spt:Harness:Pointer (registered)
ADAPTER_INSTALL_DEFERRED: GhReleaseManaged (rides the update engine)
---list---
claude-spt: Harness Pointer active (from C:/Users/decid/AppData/Local/Temp/cc-proof.YptLG5)
  claude-spt:ccs (shipped)


Pointer now at the temp dir with `manifest.toml` + binary present. Run translate-proof.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && spt adapter translate-proof claude-spt --event '<EVENT type="msg" from="doyle">hello perri</EVENT>' 2>&1; echo "PROOF_EXIT=$?"

Run translate-proof against the local install dir


=== translate-proof: claude-spt ===
emitted 4 command(s), commit: yes

--- emitted keystroke commands ---
  key   ctrl+s -> [13]
  delay 50ms
  text  "<EVENT type=\"msg\" from=\"doyle\">hello perri</EVENT>\r"
  commit true
TRANSLATE_PROOF_OK:claude-spt
PROOF_EXIT=0


**`TRANSLATE_PROOF_OK`, exit 0, commit: yes.** The emitted stream is exactly right:
```
key   ctrl+s -> [13]      (0x13 = ctrl+s)
delay 50ms
text  "<EVENT …>hello perri</EVENT>\r"
commit true
```
End-to-end EMIT-half validation **green** — my `{commit}`-terminated binary passes against the daemon-identical spawn-feed-emit.

Important precision: translate-proof validates **idle-translate EMIT only** — it does *not* touch native-resume, nor the APPLY half. So `REQ-DIST-IDLE-TRANSLATE` earns its int (EMIT); `REQ-DIST-SESSION-RESUME` int still needs a real-claude `endpoint run --resume` bringup (no translate-proof analog). Let me read the digest-proof int pattern, then write a committed int script.


1	#!/bin/sh
2	# Integration proof: `spt adapter digest-proof` runs the claude-spt [digest] extractor and renders a
3	# non-empty digest from a real CC-shaped sample (the M10 acceptance criterion carried
4	# forward for spt-claude-code). [int->REQ-DIST-DIGEST-EXTRACTOR]
5	#
6	# Gated behind SPTC_ACCEPTANCE=1 (mutates the node-local adapter registry: add + soft-remove) and a
7	# present spt>=0.7 + a built extractor. Idempotent. Run: SPTC_ACCEPTANCE=1 sh ci/digest/digest-proof-int.sh
8	#
9	# GREEN since spt v0.7.2 (doyle's F-004 fix, release counter 14): `digest-proof --sample` now fills
10	# the runtime substitution keys ({id}+{session_id}, + an optional --session) matching the daemon, so
11	# the published-shape extractor command (`--session {session_id} --in {source}`) proofs instead of
12	# hard-failing {session_id}. Was F-004-blocked on <=0.7.1 (empty key map, cli.rs:5135) — the legacy
13	# SKIP branch below stays as a guard so an OLD binary announces the version gap rather than failing.
14	set -u
15	ROOT=$(CDPATH= cd "$(dirname "$0")/../.." && pwd)
16	MANIFEST="$ROOT/adapter/claude-spt.toml"
17	SAMPLE="$ROOT/ci/digest/sample.jsonl"
18	RELDIR="$ROOT/tools/claude-spt-digest/target/release"
19
20	[ "${SPTC_ACCEPTANCE:-0}" = "1" ] || { echo "SKIP: set SPTC_ACCEPTANCE=1 to run (mutates the adapter registry)"; exit 0; }
21	command -v spt >/dev/null 2>&1 || { echo "SKIP: no spt on PATH"; exit 0; }
22	[ -x "$RELDIR/claude-spt-digest" ] || [ -x "$RELDIR/claude-spt-digest.exe" ] || { echo "SKIP: extractor not built (run sh ci/digest/build.sh)"; exit 0; }
23
24	trap 'spt adapter remove claude-spt >/dev/null 2>&1 || true' EXIT INT TERM
25	# Make the manifest's bare `claude-spt-digest` resolvable (the release dir holds the built binary).
26	PATH="$RELDIR:$PATH"; export PATH
27
28	spt adapter add "$MANIFEST" >/dev/null 2>&1 || { echo "FAIL: spt adapter add"; exit 1; }
29
30	out=$(spt adapter digest-proof claude-spt --sample "$SAMPLE" 2>&1)
31	case "$out" in
32	  *DIGEST_PROOF_OK*)
33	    echo "ok  digest-proof: DIGEST_PROOF_OK"
34	    printf '%s\n' "$out" | grep -E 'parsed|dropped' | sed 's/^/    /'
35	    echo "DIGEST-PROOF-INT OK"; exit 0 ;;
36	  *"no value for substitution key {session_id}"*)
37	    echo "SKIP: spt < v0.7.2 — digest-proof --sample doesn't fill {session_id} (pre-F-004-fix binary)."
38	    echo "      upgrade to spt >= 0.7.2 (release counter 14) to run this int. Extractor itself: cargo tests green."
39	    exit 0 ;;
40	  *)
41	    echo "FAIL: unexpected digest-proof output:"; printf '%s\n' "$out"; exit 1 ;;
42	esac
43

#!/bin/sh
# Integration proof: `spt adapter digest-proof` runs the claude-spt [digest] extractor and renders a
# non-empty digest from a real CC-shaped sample (the M10 acceptance criterion carried
# forward for spt-claude-code). [int->REQ-DIST-DIGEST-EXTRACTOR]
#
# Gated behind SPTC_ACCEPTANCE=1 (mutates the node-local adapter registry: add + soft-remove) and a
# present spt>=0.7 + a built extractor. Idempotent. Run: SPTC_ACCEPTANCE=1 sh ci/digest/digest-proof-int.sh
#
# GREEN since spt v0.7.2 (doyle's F-004 fix, release counter 14): `digest-proof --sample` now fills
# the runtime substitution keys ({id}+{session_id}, + an optional --session) matching the daemon, so
# the published-shape extractor command (`--session {session_id} --in {source}`) proofs instead of
# hard-failing {session_id}. Was F-004-blocked on <=0.7.1 (empty key map, cli.rs:5135) — the legacy
# SKIP branch below stays as a guard so an OLD binary announces the version gap rather than failing.
set -u
ROOT=$(CDPATH= cd "$(dirname "$0")/../.." && pwd)
MANIFEST="$ROOT/adapter/claude-spt.toml"
SAMPLE="$ROOT/ci/digest/sample.jsonl"
RELDIR="$ROOT/tools/claude-spt-digest/target/release"

[ "${SPTC_ACCEPTANCE:-0}" = "1" ] || { echo "SKIP: set SPTC_ACCEPTANCE=1 to run (mutates the adapter registry)"; exit 0; }
command -v spt >/dev/null 2>&1 || { echo "SKIP: no spt on PATH"; exit 0; }
[ -x "$RELDIR/claude-spt-digest" ] || [ -x "$RELDIR/claude-spt-digest.exe" ] || { echo "SKIP: extractor not built (run sh ci/digest/build.sh)"; exit 0; }

trap 'spt adapter remove claude-spt >/dev/null 2>&1 || true' EXIT INT TERM
# Make the manifest's bare `claude-spt-digest` resolvable (the release dir holds the built binary).
PATH="$RELDIR:$PATH"; export PATH

spt adapter add "$MANIFEST" >/dev/null 2>&1 || { echo "FAIL: spt adapter add"; exit 1; }

out=$(spt adapter digest-proof claude-spt --sample "$SAMPLE" 2>&1)
case "$out" in
  *DIGEST_PROOF_OK*)
    echo "ok  digest-proof: DIGEST_PROOF_OK"
    printf '%s\n' "$out" | grep -E 'parsed|dropped' | sed 's/^/    /'
    echo "DIGEST-PROOF-INT OK"; exit 0 ;;
  *"no value for substitution key {session_id}"*)
    echo "SKIP: spt < v0.7.2 — digest-proof --sample doesn't fill {session_id} (pre-F-004-fix binary)."
    echo "      upgrade to spt >= 0.7.2 (release counter 14) to run this int. Extractor itself: cargo tests green."
    exit 0 ;;
  *)
    echo "FAIL: unexpected digest-proof output:"; printf '%s\n' "$out"; exit 1 ;;
esac


translate-proof int green by hand. Note: `digest-proof-int.sh` uses the bare-file `adapter add` form that the newer GhReleaseManaged behavior now breaks (manifest-not-present) — my temp-install-dir pattern is the current-correct one. Writing the committed int script with that pattern.


Write

#!/bin/sh
# Integration proof: `spt adapter translate-proof` spawns + feeds the claude-spt
# [message-idle-translation-binary] (cc-spt-idle-translate) EXACTLY as the daemon does at idle
# delivery (init line then the --event envelope), reads back the emitted keystroke-command stream,
# and gates it. This is the EMIT half of REQ-DIST-IDLE-TRANSLATE — the cross-process author-time proof
# (ADR-0022, the EMIT-half mirror of digest-proof). It does NOT exercise the daemon's atomic PTY APPLY
# or controller buffering — that half stays the real-claude bringup int (deferred). [int->REQ-DIST-IDLE-TRANSLATE]
#
# Gated behind SPTC_ACCEPTANCE=1 (mutates the node-local adapter registry: add + soft-remove) + a
# present spt >= 0.13.1 (translate-proof landed in v0.13.1 / counter 28) + a built binary. Idempotent.
# Run: SPTC_ACCEPTANCE=1 sh ci/idle-translate/translate-proof-int.sh
#
# GREEN since spt v0.13.1 (counter 28) against the {commit}-terminated binary: emits the 4-command
# choreography ctrl+s · 50ms · {text:"<envelope>\r"} · {commit:true}, exit 0 / TRANSLATE_PROOF_OK /
# "commit: yes". The no-{commit} form FAULTs (the F-016 defect the proof's no-commit gate catches).
#
# INSTALL-DIR NOTE: claude-spt declares [update] avenue="gh_release", so a bare-file `adapter add`
# registers it GhReleaseManaged and the runtime resolver wants the EXTRACTED install (manifest.toml +
# the binary co-located), not the dev source file. So this int stages a real install DIR — manifest.toml
# (the renamed manifest) + strings/ + the built binary — exactly the shape `adapter add --release`
# extracts, and points the adapter at it. (The sibling ci/digest/digest-proof-int.sh predates this
# GhReleaseManaged behavior and uses the now-stale bare-file form.)
set -u
ROOT=$(CDPATH= cd "$(dirname "$0")/../.." && pwd)
MANIFEST="$ROOT/adapter/claude-spt.toml"
STRINGS="$ROOT/adapter/strings"
RELDIR="$ROOT/tools/cc-spt-idle-translate/target/release"
EVENT='<EVENT type="msg" from="ci">translate-proof int probe</EVENT>'

[ "${SPTC_ACCEPTANCE:-0}" = "1" ] || { echo "SKIP: set SPTC_ACCEPTANCE=1 to run (mutates the adapter registry)"; exit 0; }
command -v spt >/dev/null 2>&1 || { echo "SKIP: no spt on PATH"; exit 0; }

# translate-proof is a v0.13.1+ subcommand — announce the version gap rather than fail on an old binary.
if ! spt adapter --help 2>&1 | grep -q 'translate-proof'; then
  echo "SKIP: spt has no 'adapter translate-proof' (needs v0.13.1 / counter 28+). Binary itself: cargo tests green."
  exit 0
fi

BIN="$RELDIR/cc-spt-idle-translate"
[ -x "$BIN" ] || BIN="$RELDIR/cc-spt-idle-translate.exe"
[ -x "$BIN" ] || { echo "SKIP: binary not built (run sh ci/idle-translate/build.sh)"; exit 0; }

# Stage the install dir the resolver expects (manifest.toml + strings/ + the binary co-located).
STAGE=$(mktemp -d "${TMPDIR:-/tmp}/cc-xlate-int.XXXXXX") || { echo "FAIL: mktemp"; exit 1; }
trap 'spt adapter remove claude-spt >/dev/null 2>&1 || true; rm -rf "$STAGE"' EXIT INT TERM
cp "$MANIFEST" "$STAGE/manifest.toml" || { echo "FAIL: stage manifest"; exit 1; }
cp -r "$STRINGS" "$STAGE/strings"     || { echo "FAIL: stage strings"; exit 1; }
cp "$BIN" "$STAGE/"                    || { echo "FAIL: stage binary"; exit 1; }

spt adapter add "$STAGE" >/dev/null 2>&1 || { echo "FAIL: spt adapter add (install dir)"; exit 1; }

out=$(spt adapter translate-proof claude-spt --event "$EVENT" 2>&1)
rc=0
case "$out" in
  *TRANSLATE_PROOF_OK*) echo "ok  translate-proof: TRANSLATE_PROOF_OK" ;;
  *) echo "FAIL: translate-proof did not pass:"; printf '%s\n' "$out"; exit 1 ;;
esac
# The {commit} terminator is the F-016 fix — assert the proof saw it (no-commit would FAULT live).
case "$out" in
  *"commit: yes"*) echo "ok  emitted the mandatory {commit} terminator (commit: yes)" ;;
  *) echo "FAIL: proof reports no commit terminator (the F-016 fault condition):"; printf '%s\n' "$out"; rc=1 ;;
esac
# And the verbatim \r submit rides inside the text command (not a separate enter key).
case "$out" in
  *'\r"'*) echo "ok  text command carries the trailing \\r submit" ;;
  *) echo "FAIL: no trailing \\r in the text command:"; printf '%s\n' "$out"; rc=1 ;;
esac

[ "$rc" -eq 0 ] && { echo "TRANSLATE-PROOF-INT OK"; exit 0; } || { echo "TRANSLATE-PROOF-INT FAIL"; exit 1; }


File created successfully at: C:/Users/decid/Documents/projects/spt-claude-code/ci/idle-translate/translate-proof-int.sh (file state is current in your context — no need to Read it back)

#!/bin/sh
# Integration proof: `spt adapter translate-proof` spawns + feeds the claude-spt
# [message-idle-translation-binary] (cc-spt-idle-translate) EXACTLY as the daemon does at idle
# delivery (init line then the --event envelope), reads back the emitted keystroke-command stream,
# and gates it. This is the EMIT half of REQ-DIST-IDLE-TRANSLATE — the cross-process author-time proof
# (ADR-0022, the EMIT-half mirror of digest-proof). It does NOT exercise the daemon's atomic PTY APPLY
# or controller buffering — that half stays the real-claude bringup int (deferred). [int->REQ-DIST-IDLE-TRANSLATE]
#
# Gated behind SPTC_ACCEPTANCE=1 (mutates the node-local adapter registry: add + soft-remove) + a
# present spt >= 0.13.1 (translate-proof landed in v0.13.1 / counter 28) + a built binary. Idempotent.
# Run: SPTC_ACCEPTANCE=1 sh ci/idle-translate/translate-proof-int.sh
#
# GREEN since spt v0.13.1 (counter 28) against the {commit}-terminated binary: emits the 4-command
# choreography ctrl+s · 50ms · {text:"<envelope>\r"} · {commit:true}, exit 0 / TRANSLATE_PROOF_OK /
# "commit: yes". The no-{commit} form FAULTs (the F-016 defect the proof's no-commit gate catches).
#
# INSTALL-DIR NOTE: claude-spt declares [update] avenue="gh_release", so a bare-file `adapter add`
# registers it GhReleaseManaged and the runtime resolver wants the EXTRACTED install (manifest.toml +
# the binary co-located), not the dev source file. So this int stages a real install DIR — manifest.toml
# (the renamed manifest) + strings/ + the built binary — exactly the shape `adapter add --release`
# extracts, and points the adapter at it. (The sibling ci/digest/digest-proof-int.sh predates this
# GhReleaseManaged behavior and uses the now-stale bare-file form.)
set -u
ROOT=$(CDPATH= cd "$(dirname "$0")/../.." && pwd)
MANIFEST="$ROOT/adapter/claude-spt.toml"
STRINGS="$ROOT/adapter/strings"
RELDIR="$ROOT/tools/cc-spt-idle-translate/target/release"
EVENT='<EVENT type="msg" from="ci">translate-proof int probe</EVENT>'

[ "${SPTC_ACCEPTANCE:-0}" = "1" ] || { echo "SKIP: set SPTC_ACCEPTANCE=1 to run (mutates the adapter registry)"; exit 0; }
command -v spt >/dev/null 2>&1 || { echo "SKIP: no spt on PATH"; exit 0; }

# translate-proof is a v0.13.1+ subcommand — announce the version gap rather than fail on an old binary.
if ! spt adapter --help 2>&1 | grep -q 'translate-proof'; then
  echo "SKIP: spt has no 'adapter translate-proof' (needs v0.13.1 / counter 28+). Binary itself: cargo tests green."
  exit 0
fi

BIN="$RELDIR/cc-spt-idle-translate"
[ -x "$BIN" ] || BIN="$RELDIR/cc-spt-idle-translate.exe"
[ -x "$BIN" ] || { echo "SKIP: binary not built (run sh ci/idle-translate/build.sh)"; exit 0; }

# Stage the install dir the resolver expects (manifest.toml + strings/ + the binary co-located).
STAGE=$(mktemp -d "${TMPDIR:-/tmp}/cc-xlate-int.XXXXXX") || { echo "FAIL: mktemp"; exit 1; }
trap 'spt adapter remove claude-spt >/dev/null 2>&1 || true; rm -rf "$STAGE"' EXIT INT TERM
cp "$MANIFEST" "$STAGE/manifest.toml" || { echo "FAIL: stage manifest"; exit 1; }
cp -r "$STRINGS" "$STAGE/strings"     || { echo "FAIL: stage strings"; exit 1; }
cp "$BIN" "$STAGE/"                    || { echo "FAIL: stage binary"; exit 1; }

spt adapter add "$STAGE" >/dev/null 2>&1 || { echo "FAIL: spt adapter add (install dir)"; exit 1; }

out=$(spt adapter translate-proof claude-spt --event "$EVENT" 2>&1)
rc=0
case "$out" in
  *TRANSLATE_PROOF_OK*) echo "ok  translate-proof: TRANSLATE_PROOF_OK" ;;
  *) echo "FAIL: translate-proof did not pass:"; printf '%s\n' "$out"; exit 1 ;;
esac
# The {commit} terminator is the F-016 fix — assert the proof saw it (no-commit would FAULT live).
case "$out" in
  *"commit: yes"*) echo "ok  emitted the mandatory {commit} terminator (commit: yes)" ;;
  *) echo "FAIL: proof reports no commit terminator (the F-016 fault condition):"; printf '%s\n' "$out"; rc=1 ;;
esac
# And the verbatim \r submit rides inside the text command (not a separate enter key).
case "$out" in
  *'\r"'*) echo "ok  text command carries the trailing \\r submit" ;;
  *) echo "FAIL: no trailing \\r in the text command:"; printf '%s\n' "$out"; rc=1 ;;
esac

[ "$rc" -eq 0 ] && { echo "TRANSLATE-PROOF-INT OK"; exit 0; } || { echo "TRANSLATE-PROOF-INT FAIL"; exit 1; }


Run it for real (SPTC_ACCEPTANCE=1) to confirm the committed int is green.


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && SPTC_ACCEPTANCE=1 sh ci/idle-translate/translate-proof-int.sh; echo "INT_EXIT=$?"

Run the translate-proof int script


ok  translate-proof: TRANSLATE_PROOF_OK
ok  emitted the mandatory {commit} terminator (commit: yes)
ok  text command carries the trailing \r submit
TRANSLATE-PROOF-INT OK
INT_EXIT=0


Int green: `TRANSLATE_PROOF_OK` · commit: yes · `\r` present. Now promote `REQ-DIST-IDLE-TRANSLATE` to int. The int tag lives in `ci/idle-translate/` — not a scan root (same shallow-scan gotcha as the build.sh impl tag), so I must add it to `[scan].roots`.


Edit

roots = ["plugin", "ci", "ci/acceptance", "ci/publish", "ci/docs", "ci/manifest", "ci/digest", "adapter", "tools", "tests", "docs", "docs-site", "CONTEXT.md", "SCOPE.md", "AGENTS.md", "HANDOFF.md"]

roots = ["plugin", "ci", "ci/acceptance", "ci/publish", "ci/docs", "ci/manifest", "ci/digest", "ci/idle-translate", "adapter", "tools", "tests", "docs", "docs-site", "CONTEXT.md", "SCOPE.md", "AGENTS.md", "HANDOFF.md"]


The file C:/Users/decid/Documents/projects/spt-claude-code/traceable-reqs.toml has been updated successfully. (file state is current in your context — no need to Read it back)

# audit this whenever a new evidence dir appears. ADD `plugin`, `skills`, `hooks`, `tests`

# the moment those dirs are created (skeleton milestone, body #2) — until they exist a

# nonexistent root is a hard manifest_error, so only list what is on disk now.

-roots = ["plugin", "ci", "ci/acceptance", "ci/publish", "ci/docs", "ci/manifest", "ci/digest", "adapter", "tools", "tests", "docs", "docs-site", "CONTEXT.md", "SCOPE.md", "AGENTS.md", "HANDOFF.md"]

+roots = ["plugin", "ci", "ci/acceptance", "ci/publish", "ci/docs", "ci/manifest", "ci/digest", "ci/idle-translate", "adapter", "tools", "tests", "docs", "docs-site", "CONTEXT.md", "SCOPE.md", "AGENTS.md", "HANDOFF.md"]

# Default policy applied at activation: doc + impl + unit. Networking/lifecycle/cross-node


required_stages = ["impl", "unit"]  # impl: tools/cc-spt-idle-translate (Rust JSON-lines filter — event→4-step choreography [stash · 50ms · <envelope>\r submit · {commit:true} terminator; CC auto-restores the draft so NO trailing restore keystroke], init/input/unknown-type emit nothing, CR/LF in the envelope neutralized so only the trailing submit \r fires, forward-compat unknown fields ignored) + [message-idle-translation-binary] path="cc-spt-idle-translate" in adapter/claude-spt.toml + ci/idle-translate/build.sh gate (wired into ci/run-gates.sh) + packed into adapter.spt (ci/publish/package-adapter.sh, the 3rd binary). unit: the crate's 11 cargo tests (run by ci/idle-translate/build.sh: the choreography order, text+\r submit-not-enter-key, mandatory terminating commit, stash-precedes-submit, single-ctrl+s no-trailing-restore, CR/LF neutralization, dispatch, no-output types, envelope-less event, unknown fields, single-field command shape) + tests/{manifest-shortcut.sh (manifest path), adapter-archive.sh (binary packs at root)}. int DEFERRED: the spawn-on-up/reap-on-down lifecycle + atomic PTY apply need the v0.13.0 daemon — add "int" when doyle ships it.

required_stages = ["impl", "unit", "int"]  # impl: tools/cc-spt-idle-translate (Rust JSON-lines filter — event→4-step choreography [stash · 50ms · <envelope>\r submit · {commit:true} terminator; CC auto-restores the draft so NO trailing restore keystroke], init/input/unknown-type emit nothing, CR/LF in the envelope neutralized so only the trailing submit \r fires, forward-compat unknown fields ignored) + [message-idle-translation-binary] path="cc-spt-idle-translate" in adapter/claude-spt.toml + ci/idle-translate/build.sh gate (wired into ci/run-gates.sh) + packed into adapter.spt (ci/publish/package-adapter.sh, the 3rd binary). unit: the crate's 11 cargo tests (run by ci/idle-translate/build.sh: the choreography order, text+\r submit-not-enter-key, mandatory terminating commit, stash-precedes-submit, single-ctrl+s no-trailing-restore, CR/LF neutralization, dispatch, no-output types, envelope-less event, unknown fields, single-field command shape) + tests/{manifest-shortcut.sh (manifest path), adapter-archive.sh (binary packs at root)}. int: ci/idle-translate/translate-proof-int.sh — `spt adapter translate-proof claude-spt --event …` on real spt >=0.13.1 (counter 28) spawns+feeds the binary daemon-identically and asserts TRANSLATE_PROOF_OK + "commit: yes" + the trailing \r in the text command. GREEN 2026-06-22 (disposable install-dir staged manifest.toml+strings+binary — the GhReleaseManaged resolver wants the extracted shape; soft-removed on teardown). This is the EMIT half ONLY; the daemon's atomic PTY APPLY + spawn-on-up/reap-on-down lifecycle stay covered by a real-claude bringup int (heavier tier, still deferred) — translate-proof explicitly does not exercise apply (ADR-0022). The no-{commit} FAULT (F-016) is exactly what the proof's no-commit gate catches.


title = "The adapter ships the [message-idle-translation-binary] (path=\"cc-spt-idle-translate\") — a lifecycle-managed stdin→stdout JSON-lines filter that turns each idle inbound <EVENT> envelope into the keystroke choreography spt-core applies ATOMICALLY to the broker PTY: ctrl+s (stash any draft) · 50ms · <envelope>\\r (the CR submits the PTY line) · {commit:true} (terminate the inject sequence) — so an inbound message never clobbers a half-typed operator draft (CC auto-restores the stashed draft after submit; no trailing restore keystroke). The trailing {commit} is MANDATORY: spt-core's run_inject_worker (broker.rs:1075-1090) ends a sequence only on {commit}; without it the broker FAULTs at the 5s INJECT_COMMIT_DEADLINE on every delivery (the \r submits the line, {commit} releases the InjectFloor — two distinct signals, doyle-confirmed 2026-06-22). Idle delivery ONLY (the spt-hosted complement to the busy/mid-turn [inject] hook path); coexists with a live `spt rc` controller."

-required_stages = ["impl", "unit"]  # impl: tools/cc-spt-idle-translate (Rust JSON-lines filter — event→4-step choreography [stash · 50ms · <envelope>\r submit · {commit:true} terminator; CC auto-restores the draft so NO trailing restore keystroke], init/input/unknown-type emit nothing, CR/LF in the envelope neutralized so only the trailing submit \r fires, forward-compat unknown fields ignored) + [message-idle-translation-binary] path="cc-spt-idle-translate" in adapter/claude-spt.toml + ci/idle-translate/build.sh gate (wired into ci/run-gates.sh) + packed into adapter.spt (ci/publish/package-adapter.sh, the 3rd binary). unit: the crate's 11 cargo tests (run by ci/idle-translate/build.sh: the choreography order, text+\r submit-not-enter-key, mandatory terminating commit, stash-precedes-submit, single-ctrl+s no-trailing-restore, CR/LF neutralization, dispatch, no-output types, envelope-less event, unknown fields, single-field command shape) + tests/{manifest-shortcut.sh (manifest path), adapter-archive.sh (binary packs at root)}. int DEFERRED: the spawn-on-up/reap-on-down lifecycle + atomic PTY apply need the v0.13.0 daemon — add "int" when doyle ships it. doc DEFERRED to the docs-site harness-contract RUN-group slice (documented in the manifest + module comment meanwhile). Public-surface-complete: the contract page (harness-contract/manifest.html, message-idle-translation-binary since v0.13.0) is the authority; the operator-specified ctrl+s choreography is the adapter's own UX layer atop the generic key/text/delay_ms protocol. SOURCE-CONFIRMED (doyle 2026-06-20): spt-core applies a {text} command VERBATIM (broker.rs:1016-1017, no control-char strip), so the trailing \r submits (== {key:enter}, key_to_bytes("enter")->b"\r") AND the envelope-internal CR/LF neutralization is required (an un-neutralized \n/\r would reach the PTY) — doyle is republishing the manifest to state text-is-verbatim authoritatively (a doc gap, the contract example showed {text}{key:enter} but never stated verbatim).

+required_stages = ["impl", "unit", "int"]  # impl: tools/cc-spt-idle-translate (Rust JSON-lines filter — event→4-step choreography [stash · 50ms · <envelope>\r submit · {commit:true} terminator; CC auto-restores the draft so NO trailing restore keystroke], init/input/unknown-type emit nothing, CR/LF in the envelope neutralized so only the trailing submit \r fires, forward-compat unknown fields ignored) + [message-idle-translation-binary] path="cc-spt-idle-translate" in adapter/claude-spt.toml + ci/idle-translate/build.sh gate (wired into ci/run-gates.sh) + packed into adapter.spt (ci/publish/package-adapter.sh, the 3rd binary). unit: the crate's 11 cargo tests (run by ci/idle-translate/build.sh: the choreography order, text+\r submit-not-enter-key, mandatory terminating commit, stash-precedes-submit, single-ctrl+s no-trailing-restore, CR/LF neutralization, dispatch, no-output types, envelope-less event, unknown fields, single-field command shape) + tests/{manifest-shortcut.sh (manifest path), adapter-archive.sh (binary packs at root)}. int: ci/idle-translate/translate-proof-int.sh — `spt adapter translate-proof claude-spt --event …` on real spt >=0.13.1 (counter 28) spawns+feeds the binary daemon-identically and asserts TRANSLATE_PROOF_OK + "commit: yes" + the trailing \r in the text command. GREEN 2026-06-22 (disposable install-dir staged manifest.toml+strings+binary — the GhReleaseManaged resolver wants the extracted shape; soft-removed on teardown). This is the EMIT half ONLY; the daemon's atomic PTY APPLY + spawn-on-up/reap-on-down lifecycle stay covered by a real-claude bringup int (heavier tier, still deferred) — translate-proof explicitly does not exercise apply (ADR-0022). The no-{commit} FAULT (F-016) is exactly what the proof's no-commit gate catches. doc DEFERRED to the docs-site harness-contract RUN-group slice (documented in the manifest + module comment meanwhile). Public-surface-complete: the contract page (harness-contract/manifest.html, message-idle-translation-binary since v0.13.0) is the authority; the operator-specified ctrl+s choreography is the adapter's own UX layer atop the generic key/text/delay_ms protocol. SOURCE-CONFIRMED (doyle 2026-06-20): spt-core applies a {text} command VERBATIM (broker.rs:1016-1017, no control-char strip), so the trailing \r submits (== {key:enter}, key_to_bytes("enter")->b"\r") AND the envelope-internal CR/LF neutralization is required (an un-neutralized \n/\r would reach the PTY) — doyle is republishing the manifest to state text-is-verbatim authoritatively (a doc gap, the contract example showed {text}{key:enter} but never stated verbatim).


Clarify on the resume req that translate-proof doesn't cover it (its int stays the real-claude bringup), and record the 0.13.1 static signals.


Public-surface-complete: the contract page (harness-contract/manifest.html#session.resume, since v0.13.0) is the authority; no spt-core internals.

Public-surface-complete: the contract page (harness-contract/manifest.html#session.resume, since v0.13.0) is the authority; no spt-core internals. STATIC signals green on spt 0.13.1 (counter 28): registration accepts the [session.resume] role + `spt endpoint run --resume <RESUME>` flag present (conflicts --create). NB the v0.13.1 `translate-proof` tool validates the IDLE-TRANSLATION binary ONLY — it does NOT cover [session.resume]; the resume int stays a real-claude `endpoint run --resume` bringup (reattach the transcript + RC drive), the heavier tier, still deferred — so this REQ stays unit (not promoted by translate-proof).


title = "The adapter manifest declares [session.resume] — Claude Code's NATIVE-RESUME verb (`claude -r {session_id} --remote-control {id} --dangerously-skip-permissions`, keys=[\"session_id\",\"id\"]) — so a spt-hosted resume (`spt endpoint run --resume` / picker Resume-from-history) reloads the REAL transcript by id instead of silently re-running [session.self] = a fresh blank session. {session_id} reloads the transcript (-r); {id} threads the endpoint as the remote-control session name (the RC channel native-resume drives, the same one `spt rc` / the idle-translation-binary use); skip-permissions for the non-interactive broker PTY (REQ-HAZARD-PSYCHE-PERMS-DEADLOCK). The PTY lands in the resumed session's recorded project cwd; CC resolves the transcript by {session_id}+cwd."

-required_stages = ["unit"]  # [session.resume] is a DECLARATION-ONLY seam: the in-repo deliverable is the manifest table adapter/claude-spt.toml (validated against CC's real `-r`/`--remote-control` flags — both exist in `claude --help`), and the traceable-reqs scanner does NOT read .toml, so there is no scannable impl artifact in-repo (the code that ACTS on the declaration is the spt-core daemon — out of repo, exercised at int). Same convention as REQ-DIST-SHORTCUT-BASENAME/REQ-DIST-SESSIONSTART-BRIEF (manifest tables documented in notes, evidence anchored on the acting code / asserting test). unit: tests/manifest-shortcut.sh — [session.resume] present, the `-r {session_id}` reload-fill + `--remote-control {id}` id-fill, and the 3rd skip-perms CC spawn (REQ-HAZARD-PSYCHE-PERMS-DEADLOCK). int DEFERRED (the impl-in-action): a real native-resume launch (resumed-transcript reload + RC drive) needs the v0.13.0 daemon (docs lead the binary, still v0.12.x on spt-releases) — add "int" when doyle ships it. doc DEFERRED to the docs-site harness-contract RUN-group slice (the seam is fully documented in the manifest [session.resume] comment meanwhile; mirrors REQ-DIST-DIGEST-EXTRACTOR's doc-deferred precedent). Public-surface-complete: the contract page (harness-contract/manifest.html#session.resume, since v0.13.0) is the authority; no spt-core internals.

+required_stages = ["unit"]  # [session.resume] is a DECLARATION-ONLY seam: the in-repo deliverable is the manifest table adapter/claude-spt.toml (validated against CC's real `-r`/`--remote-control` flags — both exist in `claude --help`), and the traceable-reqs scanner does NOT read .toml, so there is no scannable impl artifact in-repo (the code that ACTS on the declaration is the spt-core daemon — out of repo, exercised at int). Same convention as REQ-DIST-SHORTCUT-BASENAME/REQ-DIST-SESSIONSTART-BRIEF (manifest tables documented in notes, evidence anchored on the acting code / asserting test). unit: tests/manifest-shortcut.sh — [session.resume] present, the `-r {session_id}` reload-fill + `--remote-control {id}` id-fill, and the 3rd skip-perms CC spawn (REQ-HAZARD-PSYCHE-PERMS-DEADLOCK). int DEFERRED (the impl-in-action): a real native-resume launch (resumed-transcript reload + RC drive) needs the v0.13.0 daemon (docs lead the binary, still v0.12.x on spt-releases) — add "int" when doyle ships it. doc DEFERRED to the docs-site harness-contract RUN-group slice (the seam is fully documented in the manifest [session.resume] comment meanwhile; mirrors REQ-DIST-DIGEST-EXTRACTOR's doc-deferred precedent). Public-surface-complete: the contract page (harness-contract/manifest.html#session.resume, since v0.13.0) is the authority; no spt-core internals. STATIC signals green on spt 0.13.1 (counter 28): registration accepts the [session.resume] role + `spt endpoint run --resume <RESUME>` flag present (conflicts --create). NB the v0.13.1 `translate-proof` tool validates the IDLE-TRANSLATION binary ONLY — it does NOT cover [session.resume]; the resume int stays a real-claude `endpoint run --resume` bringup (reattach the transcript + RC drive), the heavier tier, still deferred — so this REQ stays unit (not promoted by translate-proof).


Update the plan's status, then re-add the adapter (the int soft-removed it) and run gates so `traceable-reqs check` confirms the int evidence resolves.


## Deferred — `int` (GATED on v0.13.0 daemon — doyle pings on ship)
- Native-resume launch: real `--resume` reloads the transcript + RC drive → add `int` to REQ-DIST-SESSION-RESUME.
- Idle-translation lifecycle: spawn-on-up / reap-on-down + atomic PTY apply → add `int` to REQ-DIST-IDLE-TRANSLATE.
- `doc` for both: docs-site harness-contract RUN-group slice (documented in manifest/module comments meanwhile).

## Int status (spt 0.13.1 / counter 28)
- ✅ **REQ-DIST-IDLE-TRANSLATE → int** (EMIT half): `ci/idle-translate/translate-proof-int.sh` — real
  `spt adapter translate-proof` spawns+feeds the binary daemon-identically, asserts `TRANSLATE_PROOF_OK`
  + `commit: yes` + the trailing `\r`. GREEN 2026-06-22. The `{commit}` fix (F-016) is exactly what
  the proof's no-commit gate guards.
- ⏳ **REQ-DIST-IDLE-TRANSLATE APPLY half** (atomic PTY + spawn-on-up/reap-on-down lifecycle): deferred —
  needs a real-claude bringup (translate-proof is EMIT-only, ADR-0022).
- ⏳ **REQ-DIST-SESSION-RESUME → int**: deferred — real-claude `endpoint run --resume` bringup
  (transcript reattach + RC drive). translate-proof does NOT cover resume. Static signals green on
  0.13.1 (role accepted, `--resume` flag present). Stays `unit`.
- `doc` for both: docs-site harness-contract RUN-group slice (documented in manifest/module comments meanwhile).


The file C:/Users/decid/Documents/projects/spt-claude-code/V13-ADAPTER-PLAN.md has been updated successfully. (file state is current in your context — no need to Read it back)

## Int status (spt 0.13.1 / counter 28)
- ✅ **REQ-DIST-IDLE-TRANSLATE → int** (EMIT half): `ci/idle-translate/translate-proof-int.sh` — real
  `spt adapter translate-proof` spawns+feeds the binary daemon-identically, asserts `TRANSLATE_PROOF_OK`
  + `commit: yes` + the trailing `\r`. GREEN 2026-06-22. The `{commit}` fix (F-016) is exactly what
  the proof's no-commit gate guards.
- ⏳ **REQ-DIST-IDLE-TRANSLATE APPLY half** (atomic PTY + spawn-on-up/reap-on-down lifecycle): deferred —
  needs a real-claude bringup (translate-proof is EMIT-only, ADR-0022).
- ⏳ **REQ-DIST-SESSION-RESUME → int**: deferred — real-claude `endpoint run --resume` bringup
  (transcript reattach + RC drive). translate-proof does NOT cover resume. Static signals green on
  0.13.1 (role accepted, `--resume` flag present). Stays `unit`.
- `doc` for both: docs-site harness-contract RUN-group slice (documented in manifest/module comments meanwhile).

# V13-ADAPTER-PLAN — build the two v0.13.0 harness-contract seams ahead of the binary

> **Scope.** spt-core's v0.13.0 harness contract is PUBLISHED (sabermage.github.io/spt-releases/
> harness-contract) ahead of the v0.13.0 binary (still v0.12.x on spt-releases). Build + structure
> the two new RUN-group adapter seams against the contract NOW; defer the runtime dogfood (`int`) to
> the v0.13.0 daemon. Public-surface-only (AGENTS.md): the contract pages are the authority.

## Seams

### 1. `[session.resume]` — native-resume (REQ-DIST-SESSION-RESUME)
- CC verb: `claude -r {session_id} --remote-control {id} --dangerously-skip-permissions`,
  keys `["session_id","id"]`. Both flags verified real (`claude --help`: `-r/--resume`,
  `--remote-control [name]`).
- `{session_id}` reloads the real transcript; `{id}` = the remote-control session name (RC is the
  channel native-resume drives — same channel `spt rc` + the idle-translation-binary use). Omitting
  the role → silent fallback to `[session.self]` = blank fresh session (the documented footgun).
- PTY lands in the resumed session's recorded project cwd.

### 2. `[message-idle-translation-binary]` — idle PTY delivery (REQ-DIST-IDLE-TRANSLATE)
- `path = "cc-spt-idle-translate"` — Rust stdin→stdout JSON-lines filter (`tools/cc-spt-idle-translate`).
- Input: `{"type":"init",…}` (no output) · `{"type":"event","envelope":"<EVENT…>"}` · `{"type":"input"}` (no output).
- Output per event = the **choreography**:
  `{"key":"ctrl+s"}` · `{"delay_ms":50}` · `{"text":"<envelope>\r"}` · `{"commit":true}`
  (stash draft → submit line → terminate the inject sequence; CC auto-restores the draft after
  submit, so no trailing restore keystroke). The `\r` submits the line; `{"commit":true}` is the
  MANDATORY terminator — spt-core's `run_inject_worker` FAULTs at a 5s `INJECT_COMMIT_DEADLINE`
  without it (broker.rs:1075-1090, doyle-confirmed). The published contract had **dropped `{commit}`**
  from the vocabulary + degenerate example — a public-surface defect this blind-build caught; doyle
  is republishing manifest.md with `{commit}` documented.
- Idle-only; busy/mid-turn delivery stays the `[inject]` hook path. spt-core spawns on endpoint-up,
  reaps on down, applies keystrokes atomically (coexists with a live `spt rc` controller).

## Status — DONE (impl + unit)
- ✅ `tools/cc-spt-idle-translate` (Rust, 9 cargo tests green)
- ✅ `[session.resume]` + `[message-idle-translation-binary]` in `adapter/claude-spt.toml`
- ✅ `tests/manifest-shortcut.sh` (resume shape + 3rd skip-perms + idle path); `tests/adapter-archive.sh` (3rd binary at root)
- ✅ `ci/idle-translate/build.sh` wired into `ci/run-gates.sh`; packer packs the 3rd binary
- ✅ traceable-reqs: REQ-DIST-SESSION-RESUME + REQ-DIST-IDLE-TRANSLATE (`["impl","unit"]`); REQ-HAZARD-PSYCHE-PERMS-DEADLOCK extended to resume

## Deferred — `int` (GATED on v0.13.0 daemon — doyle pings on ship)
- Native-resume launch: real `--resume` reloads the transcript + RC drive → add `int` to REQ-DIST-SESSION-RESUME.
- Idle-translation lifecycle: spawn-on-up / reap-on-down + atomic PTY apply → add `int` to REQ-DIST-IDLE-TRANSLATE.
- `doc` for both: docs-site harness-contract RUN-group slice (documented in manifest/module comments meanwhile).

## Gate
`sh ci/run-gates.sh` green + `traceable-reqs check` green.

-## Deferred — `int` (GATED on v0.13.0 daemon — doyle pings on ship)

-- Native-resume launch: real `--resume` reloads the transcript + RC drive → add `int` to REQ-DIST-SESSION-RESUME.

-- Idle-translation lifecycle: spawn-on-up / reap-on-down + atomic PTY apply → add `int` to REQ-DIST-IDLE-TRANSLATE.

+## Int status (spt 0.13.1 / counter 28)

+- ✅ **REQ-DIST-IDLE-TRANSLATE → int** (EMIT half): `ci/idle-translate/translate-proof-int.sh` — real

+  `spt adapter translate-proof` spawns+feeds the binary daemon-identically, asserts `TRANSLATE_PROOF_OK`

+  + `commit: yes` + the trailing `\r`. GREEN 2026-06-22. The `{commit}` fix (F-016) is exactly what

+- ⏳ **REQ-DIST-IDLE-TRANSLATE APPLY half** (atomic PTY + spawn-on-up/reap-on-down lifecycle): deferred —

+  needs a real-claude bringup (translate-proof is EMIT-only, ADR-0022).

+- ⏳ **REQ-DIST-SESSION-RESUME → int**: deferred — real-claude `endpoint run --resume` bringup

+  (transcript reattach + RC drive). translate-proof does NOT cover resume. Static signals green on

+  0.13.1 (role accepted, `--resume` flag present). Stays `unit`.


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && spt adapter add "$(pwd)/adapter/claude-spt.toml" >/dev/null 2>&1 && echo "re-added claude-spt" && echo "---trace idle-translate int---" && traceable-reqs trace REQ-DIST-IDLE-TRANSLATE 2>&1 | grep -E "int|\[OK\]|\[--\]" | head && echo "---full gates---" && sh ci/run-gates.sh > /tmp/gates5.log 2>&1; echo "GATES_EXIT=$?"; grep -iE "RESULT|coverage green|\[must\]|FAIL|missing_stage" /tmp/gates5.log

Re-add adapter, verify int evidence resolves, full gates


re-added claude-spt
---trace idle-translate int---
REQ-DIST-IDLE-TRANSLATE — The adapter ships the [message-idle-translation-binary] (path="cc-spt-idle-translate") — a lifecycle-managed stdin→stdout JSON-lines filter that turns each idle inbound <EVENT> envelope into the keystroke choreography spt-core applies ATOMICALLY to the broker PTY: ctrl+s (stash any draft) · 50ms · <envelope>\r (the CR submits the PTY line) · {commit:true} (terminate the inject sequence) — so an inbound message never clobbers a half-typed operator draft (CC auto-restores the stashed draft after submit; no trailing restore keystroke). The trailing {commit} is MANDATORY: spt-core's run_inject_worker (broker.rs:1075-1090) ends a sequence only on {commit}; without it the broker FAULTs at the 5s INJECT_COMMIT_DEADLINE on every delivery (the
 submits the line, {commit} releases the InjectFloor — two distinct signals, doyle-confirmed 2026-06-22). Idle delivery ONLY (the spt-hosted complement to the busy/mid-turn [inject] hook path); coexists with a live `spt rc` controller.
  required stages: [impl, unit, int]
  [--] doc (not required)
  [OK] impl
  [OK] unit
  [OK] int
        ci/idle-translate/translate-proof-int.sh:7
---full gates---
GATES_EXIT=0
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
ok  coverage green
=== RESULT: PASS ===


All green — `REQ-DIST-IDLE-TRANSLATE` now `[impl, unit, int]`, int evidence resolves. Commit, then report.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && git add -A && git status --short && (git diff --cached --name-only | grep -i "target/" && echo WARN || echo "clean: no artifacts")

Stage int promotion, verify


M  V13-ADAPTER-PLAN.md
A  ci/idle-translate/translate-proof-int.sh
M  traceable-reqs.toml
clean: no artifacts


cd "C:/Users/decid/Documents/projects/spt-claude-code" && git commit -F - <<'EOF'
test(idle-translate): promote REQ-DIST-IDLE-TRANSLATE to int (translate-proof green)

`spt adapter translate-proof claude-spt --event '<EVENT>'` on real spt 0.13.1
(counter 28) spawns + feeds cc-spt-idle-translate exactly as the daemon does at
idle delivery and reads back the emitted stream — the EMIT-half mirror of
digest-proof (ADR-0022). Against the {commit}-terminated binary it returns
exit 0 / TRANSLATE_PROOF_OK with the 4-command choreography:
  key ctrl+s · delay 50ms · text "<envelope>\r" · commit true

- ci/idle-translate/translate-proof-int.sh: the committed int (SPTC_ACCEPTANCE-
  gated, spt>=0.13.1). Asserts TRANSLATE_PROOF_OK + "commit: yes" + the trailing
  \r in the text command. GREEN 2026-06-22.
- REQ-DIST-IDLE-TRANSLATE promoted to [impl, unit, int]; added ci/idle-translate
  to the traceable-reqs [scan] roots so the int tag resolves.

Scope precision: translate-proof is EMIT-only. The daemon's atomic PTY APPLY +
spawn-on-up/reap-on-down lifecycle stay a deferred real-claude bringup int.
REQ-DIST-SESSION-RESUME is NOT covered by translate-proof (not a translation
binary) — its int stays the real `endpoint run --resume` bringup; stays unit.

Dev-rig note: claude-spt is GhReleaseManaged ([update] gh_release), so the proof
resolver wants the extracted install shape (manifest.toml + binary co-located),
not the bare dev source file — the int stages a disposable install dir. (The
sibling ci/digest/digest-proof-int.sh predates this and uses the now-stale
bare-file form.)

Co-authored by: perri
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2zafQDEMHqHfkuK3A9yy5
EOF
echo "COMMIT_EXIT=$?"; git log --oneline -4

Commit int promotion


[feat/v013-adapter-resume-idle-translate 4f72183] test(idle-translate): promote REQ-DIST-IDLE-TRANSLATE to int (translate-proof green)
 3 files changed, 82 insertions(+), 6 deletions(-)
 create mode 100644 ci/idle-translate/translate-proof-int.sh
COMMIT_EXIT=0
4f72183 test(idle-translate): promote REQ-DIST-IDLE-TRANSLATE to int (translate-proof green)
5978174 docs(idle-translate): re-cite corrected contract, close F-016
791e917 fix(idle-translate): emit mandatory {commit} terminator + bump adapter 0.6.0
64ff91f feat(adapter): v0.13.0 native-resume + idle-translation seams


Committed. Report the green + the precision + a dev-ergonomics finding to doyle.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && $OWL send doyle <<'EOF'
TRANSLATE-PROOF GREEN. Pulled v0.13.1 (counter 28, clean apply), ran `spt adapter translate-proof claude-spt --event '<EVENT…>'` against the {commit}-terminated binary:

  === translate-proof: claude-spt ===
  emitted 4 command(s), commit: yes
    key   ctrl+s -> [13]
    delay 50ms
    text  "<EVENT …>hello perri</EVENT>\r"
    commit true
  TRANSLATE_PROOF_OK   (exit 0)

The F-016 fix is confirmed end-to-end — the proof's no-commit gate would have caught the old form; the new form passes with commit:yes. Committed a self-gated int (ci/idle-translate/translate-proof-int.sh) and promoted REQ-DIST-IDLE-TRANSLATE to int.

ONE PRECISION on your "promote both": translate-proof validates the IDLE-TRANSLATION binary EMIT half only. [session.resume] is NOT a translation binary, so translate-proof doesn't touch it — REQ-DIST-SESSION-RESUME's int stays the real-claude `endpoint run --resume` bringup (transcript reattach + RC drive), heavier tier, still deferred. So only IDLE-TRANSLATE got promoted; resume stays unit with green static signals (role accepted + --resume flag present). Flag if you want me to stand up the resume bringup int next (real claude session, costlier).

TWO dev-ergonomics findings (minor, FYI — not blocking):
1. translate-proof/digest-proof can't resolve a GhReleaseManaged adapter ([update] gh_release) added via the bare-file `adapter add` form: the resolver wants the EXTRACTED install (manifest.toml + binary co-located) and errors "manifest is not present yet at <dir>" even with the dev manifest right there as claude-spt.toml. F-011 class. Worked around by staging a disposable install dir (manifest.toml + strings + binary). Knock-on: ci/digest/digest-proof-int.sh (bare-file form) is now stale on 0.13.x — would hit the same.
2. Suggestion: a `--manifest <file>` / `--dir <path>` override on the *-proof commands (mirroring digest-proof's --sample pointing straight at a file) would let an author proof a DEV binary without staging a full install dir. Tiny DX win for the author-time loop.

Clean closed loop on the {commit} thread regardless — binary + contract + proof all shipped + green.
EOF
echo "SEND_EXIT=$?"

Report translate-proof green + precision + DX findings to doyle


➜ SENT:doyle
SEND_EXIT=0


## translate-proof GREEN — idle-translate promoted to int

```
emitted 4 command(s), commit: yes
  key ctrl+s · delay 50ms · text "<EVENT …>\r" · commit true
TRANSLATE_PROOF_OK  (exit 0)
```

F-016 fix confirmed end-to-end on real spt 0.13.1. Committed a self-gated int (`translate-proof-int.sh`) + promoted `REQ-DIST-IDLE-TRANSLATE` → `[impl, unit, int]`. Gates + coverage green.

**Branch `feat/v013-adapter-resume-idle-translate` (4 commits):**
- seams → `{commit}` fix + 0.6.0 → contract re-cite/F-016 closed → int promotion

**Corrected a conflation for doyle:** translate-proof is idle-translate EMIT-only. `[session.resume]` isn't a translation binary — its int stays a real `endpoint run --resume` bringup, **still deferred**. So only idle-translate promoted; resume stays `unit` (static signals green).

**Flagged 2 dev-ergonomics findings:** GhReleaseManaged adapters can't be proofed via bare-file `adapter add` (must stage an install dir; F-011 class; makes `digest-proof-int.sh` stale on 0.13.x) + suggested a `--manifest/--dir` override on the proof commands.

**Remaining deferrals:**
- `REQ-DIST-SESSION-RESUME` int — real-claude `endpoint run --resume` bringup (costlier: spawns a real claude PTY session)
- idle-translate **APPLY** half (atomic PTY) — same real-bringup tier
- `doc` stage for both — docs-site slice

The `{commit}` thread is a fully closed loop (binary + contract + proof all shipped + green).

**Your call:** stand up the resume bringup int now (spawns a real claude session), or call this body of work done and leave resume int + the doc slice as the next deliberate session? My lean: **done for now** — the headline idle-translate seam is int-validated end-to-end; resume is registration-validated with a clean deferred int, and a real-claude bringup is a heavier, separate tier better run deliberately.


<task-notification>
<task-id>bnwwf0pp6</task-id>
Monitor event: "« spt event »"
<event><EVENT-PART seq="1/6" id="acd41aac" type="msg" from="doyle">translate-proof GREEN confirmed — clean closed loop on the whole {commit} thread (binary + published contract + proof tool, all shipped + green). Nicely done.

Your precision is RIGHT and my &quot;promote both&quot; was sloppy — translate-proof is the idle-translation EMIT-half only; [session.resume] is not a </EVENT-PART>
<EVENT-PART seq="2/6" id="acd41aac">translation binary, so it's untouched. Correct split: REQ-DIST-IDLE-TRANSLATE -&gt; int (done), REQ-DIST-SESSION-RESUME stays unit on the static signals (role accepted + --resume present). RESUME bringup int: DEFER for now — it's the costly real-claude reattach+RC-drive tier, not blocking, and the static signals + your binary actually exerci</EVENT-PART>
<EVENT-PART seq="3/6" id="acd41aac">sing --resume cover it short-term. Tracking it as a deferred int; stand it up later (or I'll flag if the operator wants the real gate sooner). Don't spin it now.

Both DX findings are real and I'm batching them — note the timing: I'm mid-grill with the operator on v0.13.2 ADAPTER + update changes right now, so these land squarely in th</EVENT-PART>
<EVENT-PART seq="4/6" id="acd41aac">at batch:
1. GhReleaseManaged bare-file adapter can't be resolved by the *-proof commands (wants a fully-extracted install dir) = F-011 class, genuine author-time-loop friction.
2. Your fix is the right one: a `--dir &lt;path&gt;` / `--manifest &lt;file&gt;` override on the *-proof family (mirrors digest-proof's --sample-at-a-file) so an</EVENT-PART>
<EVENT-PART seq="5/6" id="acd41aac"> author proofs a DEV binary without staging a full install. Tiny, clean, un-stales your digest-proof-int.sh too.
I'll fold &quot;(--dir/--manifest override on *-proof)&quot; into the v0.13.x adapter-DX scope and gate it with the rest. Short-term: keep staging the disposable install dir (as you did) for digest-proof-int.sh. Log it as F-011 w</EVENT-PART>
<EVENT-PART seq="6/6" id="acd41aac">ith the repro; I've got it tracked on my side. Thanks — clean report.</EVENT-PART></event>
</task-notification>


<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 aligns: **defer the resume int** (don't spin it now — tracked deferred), both DX findings are real and he's batching them into v0.13.2 adapter-DX scope (the `--dir/--manifest` override on `*-proof`). He asked me to **log it as F-011 with the repro**. Doing that, then this body of work is done.


895	makes **no mention** of `{"commit":true}`, an `InjectFloor`, or a commit deadline. But the broker
896	requires a trailing `{commit}` to terminate an inject sequence — so a binary built faithfully from the
897	published vocabulary (including the doc's own degenerate example) emits no terminator and **faults on
898	every delivery**.
899
900	**Confirmed from source (doyle, 2026-06-22).** `run_inject_worker` (broker.rs:1075-1090) ends an
901	inject sequence ONLY on an explicit `{commit}`; `Text`/`Key`/`Delay` just enqueue. With no `{commit}`,
902	the sequence hits `INJECT_COMMIT_DEADLINE` (5s, broker.rs:151-169) and FAULTs (broker.rs:832-846;
903	Layer-G "no-commit FAULT test"). On the fault the broker flushes + releases anyway (1015-1022) so
904	input is not lost, but every delivery faults and stalls to the 5s deadline. The reference response IS
905	`{text:payload}{key:enter}{commit:true}` (translation.rs:74-78) — `{commit}` is separate from, and
906	after, the submit. Two distinct signals: the trailing `\r` (or `{key:enter}`) submits the PTY *line*
907	(verbatim — broker.rs:1066); `{commit}` terminates the *sequence* and releases the InjectFloor that
908	buffers the live controller's input during emission.
909

makes **no mention** of `{"commit":true}`, an `InjectFloor`, or a commit deadline. But the broker
requires a trailing `{commit}` to terminate an inject sequence — so a binary built faithfully from the
published vocabulary (including the doc's own degenerate example) emits no terminator and **faults on
every delivery**.

**Confirmed from source (doyle, 2026-06-22).** `run_inject_worker` (broker.rs:1075-1090) ends an
inject sequence ONLY on an explicit `{commit}`; `Text`/`Key`/`Delay` just enqueue. With no `{commit}`,
the sequence hits `INJECT_COMMIT_DEADLINE` (5s, broker.rs:151-169) and FAULTs (broker.rs:832-846;
Layer-G "no-commit FAULT test"). On the fault the broker flushes + releases anyway (1015-1022) so
input is not lost, but every delivery faults and stalls to the 5s deadline. The reference response IS
`{text:payload}{key:enter}{commit:true}` (translation.rs:74-78) — `{commit}` is separate from, and
after, the submit. Two distinct signals: the trailing `\r` (or `{key:enter}`) submits the PTY *line*
(verbatim — broker.rs:1066); `{commit}` terminates the *sequence* and releases the InjectFloor that
buffers the live controller's input during emission.


cd "C:/Users/decid/Documents/projects/spt-claude-code" && tail -5 docs/SPT-CORE-FINDINGS.md

Read findings EOF


v0.13.1 cut (counter 28+) — not a code wait. Also spawned the sibling DX win (no `translate-proof`):
doyle triaged the missing author-time proof (`spt adapter translate-proof`, the EMIT-half mirror of
`digest-proof`) → todlando built it (PR #28). Its no-commit gate would have caught this same defect at
author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.


Edit

author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.

author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.

---

## F-011 (cont.) — the `*-proof` commands can't resolve a GhReleaseManaged dev adapter (author-time-loop friction)

**Surfaced:** 2026-06-22, running `spt adapter translate-proof` (v0.13.1) against `claude-spt` in
local dev. Same root class as F-011 (a Pointer/GhReleaseManaged adapter whose manifest isn't at the
resolver's expected install path → resolution fails), now hit via the author-time proof commands.
doyle acked it 2026-06-22 and is folding the fix into the v0.13.x adapter-DX batch.

**The friction.** `claude-spt` declares `[update] avenue = "gh_release"`, so `spt adapter add
<dev-manifest-file>` registers it **GhReleaseManaged**. The `*-proof` resolvers (`translate-proof`,
and the same path `digest-proof` uses) then want the **extracted install shape** — `manifest.toml`
plus the binary **co-located** in the install dir — not the dev source file. With a bare-file add the
proof fails:

```
$ spt adapter add "$PWD/adapter/claude-spt.toml"          # registers a GhReleaseManaged pointer
$ spt adapter translate-proof claude-spt --event '<EVENT…>'
TRANSLATE_PROOF_FAIL:claude-spt: adapter 'claude-spt' is registered as a pointer but its manifest is
not present yet at <dir> — the adapter's binary/manifest has not been extracted/downloaded …
```

…even though the dev manifest is right there (just named `claude-spt.toml`, not `manifest.toml`, and
the binary lives under `tools/…/target/release/`, not co-located).

**Workaround (in `ci/idle-translate/translate-proof-int.sh`).** Stage a disposable install dir that
mirrors the extracted shape — `manifest.toml` (the renamed manifest) + `strings/` + the built binary
co-located — and `adapter add` *that dir*. Then the proof resolves and passes (TRANSLATE_PROOF_OK,
commit: yes). **Knock-on:** the older `ci/digest/digest-proof-int.sh` uses the bare-file form and so is
now **stale on 0.13.x** (would hit the same error); it needs the same install-dir staging.

**Suggested fix (doyle agreed, batched into v0.13.x adapter-DX).** Add a `--dir <path>` / `--manifest
<file>` override to the `*-proof` family — mirroring `digest-proof`'s `--sample` pointing straight at a
file — so an author can proof a DEV binary against a DEV manifest without staging a full extracted
install. Tiny, and it un-stales `digest-proof-int.sh` too.

**Status:** **acked + tracked by doyle (2026-06-22), batched into the v0.13.x adapter-DX scope.**
Non-blocking — the disposable-install-dir staging is a clean workaround and the int is GREEN with it.


The file C:/Users/decid/Documents/projects/spt-claude-code/docs/SPT-CORE-FINDINGS.md has been updated successfully. (file state is current in your context — no need to Read it back)

author time; runs post-release to confirm the fixed binary green. Caught here BEFORE any live FAULT —
exactly what the blind-build exists to surface.

---

## F-011 (cont.) — the `*-proof` commands can't resolve a GhReleaseManaged dev adapter (author-time-loop friction)

**Surfaced:** 2026-06-22, running `spt adapter translate-proof` (v0.13.1) against `claude-spt` in
local dev. Same root class as F-011 (a Pointer/GhReleaseManaged adapter whose manifest isn't at the
resolver's expected install path → resolution fails), now hit via the author-time proof commands.
doyle acked it 2026-06-22 and is folding the fix into the v0.13.x adapter-DX batch.

**The friction.** `claude-spt` declares `[update] avenue = "gh_release"`, so `spt adapter add
<dev-manifest-file>` registers it **GhReleaseManaged**. The `*-proof` resolvers (`translate-proof`,
and the same path `digest-proof` uses) then want the **extracted install shape** — `manifest.toml`
plus the binary **co-located** in the install dir — not the dev source file. With a bare-file add the
proof fails:

```
$ spt adapter add "$PWD/adapter/claude-spt.toml"          # registers a GhReleaseManaged pointer
$ spt adapter translate-proof claude-spt --event '<EVENT…>'
TRANSLATE_PROOF_FAIL:claude-spt: adapter 'claude-spt' is registered as a pointer but its manifest is
not present yet at <dir> — the adapter's binary/manifest has not been extracted/downloaded …
```

…even though the dev manifest is right there (just named `claude-spt.toml`, not `manifest.toml`, and
the binary lives under `tools/…/target/release/`, not co-located).

**Workaround (in `ci/idle-translate/translate-proof-int.sh`).** Stage a disposable install dir that
mirrors the extracted shape — `manifest.toml` (the renamed manifest) + `strings/` + the built binary
co-located — and `adapter add` *that dir*. Then the proof resolves and passes (TRANSLATE_PROOF_OK,
commit: yes). **Knock-on:** the older `ci/digest/digest-proof-int.sh` uses the bare-file form and so is
now **stale on 0.13.x** (would hit the same error); it needs the same install-dir staging.

**Suggested fix (doyle agreed, batched into v0.13.x adapter-DX).** Add a `--dir <path>` / `--manifest
<file>` override to the `*-proof` family — mirroring `digest-proof`'s `--sample` pointing straight at a
file — so an author can proof a DEV binary against a DEV manifest without staging a full extracted
install. Tiny, and it un-stales `digest-proof-int.sh` too.

**Status:** **acked + tracked by doyle (2026-06-22), batched into the v0.13.x adapter-DX scope.**
Non-blocking — the disposable-install-dir staging is a clean workaround and the int is GREEN with it.

`digest-proof`) → todlando built it (PR #28). Its no-commit gate would have caught this same defect at

+## F-011 (cont.) — the `*-proof` commands can't resolve a GhReleaseManaged dev adapter (author-time-loop friction)

+**Surfaced:** 2026-06-22, running `spt adapter translate-proof` (v0.13.1) against `claude-spt` in

+local dev. Same root class as F-011 (a Pointer/GhReleaseManaged adapter whose manifest isn't at the

+resolver's expected install path → resolution fails), now hit via the author-time proof commands.

+doyle acked it 2026-06-22 and is folding the fix into the v0.13.x adapter-DX batch.

+**The friction.** `claude-spt` declares `[update] avenue = "gh_release"`, so `spt adapter add

+<dev-manifest-file>` registers it **GhReleaseManaged**. The `*-proof` resolvers (`translate-proof`,

+and the same path `digest-proof` uses) then want the **extracted install shape** — `manifest.toml`

+plus the binary **co-located** in the install dir — not the dev source file. With a bare-file add the

+$ spt adapter add "$PWD/adapter/claude-spt.toml"          # registers a GhReleaseManaged pointer

+$ spt adapter translate-proof claude-spt --event '<EVENT…>'

+TRANSLATE_PROOF_FAIL:claude-spt: adapter 'claude-spt' is registered as a pointer but its manifest is

+not present yet at <dir> — the adapter's binary/manifest has not been extracted/downloaded …

+…even though the dev manifest is right there (just named `claude-spt.toml`, not `manifest.toml`, and

+the binary lives under `tools/…/target/release/`, not co-located).

+**Workaround (in `ci/idle-translate/translate-proof-int.sh`).** Stage a disposable install dir that

+mirrors the extracted shape — `manifest.toml` (the renamed manifest) + `strings/` + the built binary

+co-located — and `adapter add` *that dir*. Then the proof resolves and passes (TRANSLATE_PROOF_OK,

+commit: yes). **Knock-on:** the older `ci/digest/digest-proof-int.sh` uses the bare-file form and so is

+now **stale on 0.13.x** (would hit the same error); it needs the same install-dir staging.

+**Suggested fix (doyle agreed, batched into v0.13.x adapter-DX).** Add a `--dir <path>` / `--manifest

+<file>` override to the `*-proof` family — mirroring `digest-proof`'s `--sample` pointing straight at a

+file — so an author can proof a DEV binary against a DEV manifest without staging a full extracted

+install. Tiny, and it un-stales `digest-proof-int.sh` too.

+**Status:** **acked + tracked by doyle (2026-06-22), batched into the v0.13.x adapter-DX scope.**

+Non-blocking — the disposable-install-dir staging is a clean workaround and the int is GREEN with it.


Update the F-011 table-row status to flag the recurrence + point at the cont. section.


Real `--release`/extracted-dir installs work (v0.3.0 dogfooded clean) | A registered **Pointer**-mode adapter whose deferred install dir lacks the extracted manifest vanishes from the active set:

Real `--release`/extracted-dir installs work (v0.3.0 dogfooded clean). **RECURRED 2026-06-22 via the `*-proof` commands (translate-proof/digest-proof) on a GhReleaseManaged dev adapter — acked + batched by doyle into v0.13.x adapter-DX (a `--dir`/`--manifest` override); see "F-011 (cont.)" below.** | A registered **Pointer**-mode adapter whose deferred install dir lacks the extracted manifest vanishes from the active set: