8855	            parse(&["spt", "adapter", "translate-proof", "claude-spt"]).is_err(),
8856	            "--event is required"
8857	        );
8858	    }
8859
8860	    /// The test-only `xlate_choreo_fixture` bin (declared as a `[[bin]]` in this
8861	    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
8862	    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
8863	    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`).
8864	    #[cfg(test)]
8865	    fn xlate_fixture_path() -> std::path::PathBuf {
8866	        let exe = std::env::current_exe().expect("test exe path");
8867	        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
8868	        let profile_dir = exe
8869	            .parent()
8870	            .and_then(|deps| deps.parent())
8871	            .expect("target profile dir");
8872	        profile_dir.join(format!("xlate_choreo_fixture{}", std::env::consts::EXE_SUFFIX))
8873	    }
8874
8875	    // [unit->REQ-ADAPTER-TRANSLATE-PROOF] translate-proof drives the REAL
8876	    // translation driver over the declared binary and GATES on the emitted stream:
8877	    // a binary that emits a committed choreography passes (0); the same binary in
8878	    // `nocommit` mode emits commands but no terminating `{commit}` → fails (1); an
8879	    // adapter with no `[message-idle-translation-binary]` section → exit 2. Never a
8880	    // silent success.
8881	    #[test]
8882	    fn adapter_translate_proof_gates_on_commit() {
8883	        let fixture = xlate_fixture_path();
8884	        if !fixture.exists() {
8885	            // The fixture bin must be built for this gate. `cargo test -p spt`
8886	            // builds it; a bare `cargo test --lib` without the bin would not.
8887	            panic!(
8888	                "xlate_choreo_fixture must be built: {} (run via `cargo test -p spt`)",
8889	                fixture.display()
8890	            );
8891	        }
8892
8893	        let _h = crate::testutil::isolated_home();
8894	        let adapters = spt_store::perch::adapters_dir();
8895
8896	        // A harness adapter declaring `[message-idle-translation-binary]` whose

            parse(&["spt", "adapter", "translate-proof", "claude-spt"]).is_err(),
            "--event is required"
        );
    }

    /// The test-only `xlate_choreo_fixture` bin (declared as a `[[bin]]` in this
    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`).
    #[cfg(test)]
    fn xlate_fixture_path() -> std::path::PathBuf {
        let exe = std::env::current_exe().expect("test exe path");
        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
        let profile_dir = exe
            .parent()
            .and_then(|deps| deps.parent())
            .expect("target profile dir");
        profile_dir.join(format!("xlate_choreo_fixture{}", std::env::consts::EXE_SUFFIX))
    }

    // [unit->REQ-ADAPTER-TRANSLATE-PROOF] translate-proof drives the REAL
    // translation driver over the declared binary and GATES on the emitted stream:
    // a binary that emits a committed choreography passes (0); the same binary in
    // `nocommit` mode emits commands but no terminating `{commit}` → fails (1); an
    // adapter with no `[message-idle-translation-binary]` section → exit 2. Never a
    // silent success.
    #[test]
    fn adapter_translate_proof_gates_on_commit() {
        let fixture = xlate_fixture_path();
        if !fixture.exists() {
            // The fixture bin must be built for this gate. `cargo test -p spt`
            // builds it; a bare `cargo test --lib` without the bin would not.
            panic!(
                "xlate_choreo_fixture must be built: {} (run via `cargo test -p spt`)",
                fixture.display()
            );
        }

        let _h = crate::testutil::isolated_home();
        let adapters = spt_store::perch::adapters_dir();

        // A harness adapter declaring `[message-idle-translation-binary]` whose


All refs mapped. Executing the rename to `translate_proof_fixture` — `git mv` the source, then update Cargo.toml, the int test, the unit test, and the fixture header (documenting the collision reason):


Bash

cd /c/Users/decid/Documents/projects/spt-core-translate-proof && git mv crates/spt/tests/fixtures/xlate_choreo_fixture.rs crates/spt/tests/fixtures/translate_proof_fixture.rs && echo "moved:" && ls crates/spt/tests/fixtures/

git mv fixture to unique name


moved:
translate_proof_fixture.rs
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Edit

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same
# cross-crate fixture-bin pattern as `mock-session`).
[[bin]]
name = "xlate_choreo_fixture"
path = "tests/fixtures/xlate_choreo_fixture.rs"

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_translate_proof_fixture` to the integration test (the same
# cross-crate fixture-bin pattern as `mock-session`). The name MUST stay distinct
# from spt-daemon's `xlate_choreo_fixture` bin: an identical bin name collides on
# the shared `target/<profile>/` output filename and the two clobber each other —
# the daemon's `g3_content_free_ping` then resolves `CARGO_BIN_EXE_xlate_choreo_fixture`
# to the wrong fixture and fails (the PR#28 Windows gate-escape).
[[bin]]
name = "translate_proof_fixture"
path = "tests/fixtures/translate_proof_fixture.rs"


<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>

Error: File has not been read yet. Read it first before writing to it.


11
12	# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
13	# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
14	# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
15	# excludes it. `cargo test -p spt` builds it and exposes
16	# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same
17	# cross-crate fixture-bin pattern as `mock-session`).
18	[[bin]]
19	name = "xlate_choreo_fixture"
20	path = "tests/fixtures/xlate_choreo_fixture.rs"
21

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same
# cross-crate fixture-bin pattern as `mock-session`).
[[bin]]
name = "xlate_choreo_fixture"
path = "tests/fixtures/xlate_choreo_fixture.rs"


# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same
# cross-crate fixture-bin pattern as `mock-session`).
[[bin]]
name = "xlate_choreo_fixture"
path = "tests/fixtures/xlate_choreo_fixture.rs"

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_translate_proof_fixture` to the integration test (the same
# cross-crate fixture-bin pattern as `mock-session`). The name MUST stay distinct
# from spt-daemon's `xlate_choreo_fixture` bin: an identical bin name collides on
# the shared `target/<profile>/` output filename and the two clobber each other —
# the daemon's `g3_content_free_ping` then resolves `CARGO_BIN_EXE_xlate_choreo_fixture`
# to the wrong fixture and fails (the PR#28 Windows gate-escape).
[[bin]]
name = "translate_proof_fixture"
path = "tests/fixtures/translate_proof_fixture.rs"


The file C:/Users/decid/Documents/projects/spt-core-translate-proof/crates/spt/Cargo.toml has been updated successfully. (file state is current in your context — no need to Read it back)

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_translate_proof_fixture` to the integration test (the same
# cross-crate fixture-bin pattern as `mock-session`). The name MUST stay distinct
# from spt-daemon's `xlate_choreo_fixture` bin: an identical bin name collides on
# the shared `target/<profile>/` output filename and the two clobber each other —
# the daemon's `g3_content_free_ping` then resolves `CARGO_BIN_EXE_xlate_choreo_fixture`
# to the wrong fixture and fails (the PR#28 Windows gate-escape).
[[bin]]
name = "translate_proof_fixture"
path = "tests/fixtures/translate_proof_fixture.rs"

[package]
name = "spt"
version.workspace = true
edition = "2021"
publish = false
description = "spt-core CLI: the single `spt` binary. Thin command layer over spt-msg (send/ring/ready/list/stop/whoami) + the harness-contract `api` surface (spt-runtime)."

[[bin]]
name = "spt"
path = "src/main.rs"

# Test-only ADR-0022 translation-binary fixture for `tests/translate_proof.rs`
# (REQ-ADAPTER-TRANSLATE-PROOF). Its source lives under `tests/` so it never
# ships from `src/`; CI's release build is `cargo build -p spt --bin spt`, which
# excludes it. `cargo test -p spt` builds it and exposes
# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same
# cross-crate fixture-bin pattern as `mock-session`).
[[bin]]
name = "xlate_choreo_fixture"
path = "tests/fixtures/xlate_choreo_fixture.rs"

[dependencies]
spt-proto = { path = "../spt-proto" }
spt-store = { path = "../spt-store" }
spt-msg = { path = "../spt-msg" }
spt-runtime = { path = "../spt-runtime" }
spt-live = { path = "../spt-live" }
spt-daemon = { path = "../spt-daemon" }
# The `api digest-entry` push door validates the inbound record against the
# published digest-record contract (`spt_term::record_to_tagged`) — REQ-TERM-4.
spt-term = { path = "../spt-term" }
# The reference binary ships the WAN transport on by default (ADR-0002). D2g reuses its
# RFC-6238 TotpSeed (spt_net::net::pairing::totp) to render a subnet's local pairing
# code — reused, not reimplemented, so the CLI code matches the ceremony's exactly.
spt-net = { path = "../spt-net" }
# `wrap_help`: wrap long help text to the terminal width with a hanging indent
# (without it clap emits unwrapped lines and the terminal hard-wraps to col 0).
clap = { version = "4", features = ["derive", "wrap_help"] }
# `spt rc` raw terminal mode for the attach pump (M12-W1): enter/leave raw mode
# so keystrokes pass through to the broker-held PTY unbuffered + unechoed. The
# same crate W2's ratatui picker builds on, so it lands once for the milestone.
crossterm = "0.28"
# `spt endpoint run` interactive picker (M12-W2, REQ-RUN-PICKER). ratatui's
# double-buffered renderer removes the manual erase/redraw + wrapped-row-counting
# hazard; it renders to a testable `Buffer` (buffer + state-model unit asserts,
# no live terminal). 0.29 pairs with crossterm 0.28. nucleo-matcher = the `/`
# type-to-filter fuzzy match (the searchMultiselect feel, lifted from
# vercel-labs/skills).
ratatui = "0.29"
nucleo-matcher = "0.3"
# The WAN send leg (D9-1-4) serializes the dial address + reads registry
# snapshots - same pinned shape as spt-daemon's.
serde_json = { version = "1", features = ["preserve_order"] }
# Terminal QR render for `spt subnet create` (M7 plan decision 11): the
# otpauth:// URI as unicode half-blocks. default-features off drops the
# image/svg renderers — the unicode renderer is all the CLI needs.
qrcode = { version = "0.14", default-features = false }
# Local-timezone rendering of the pairing code's expiry instant (std has no
# local tz). Clock feature only — no serde, no wasm.
chrono = { version = "0.4", default-features = false, features = ["clock"] }
# `spt update fetch` (REQ-UPD-7): HTTPS GET of the signed release from the
# GitHub origin. Blocking client + rustls (no OpenSSL); already in the tree
# transitively (iroh), so no new vendor. The fetch runs in the CLI, NOT the
# daemon — the daemon keeps zero HTTP surface (iroh QUIC only).
reqwest = { version = "0.13", default-features = false, features = ["blocking", "rustls"] }

# OS privilege-elevation probe for the node-bound code fetch (REQ-PAIR-6). Only the
# binary pulls the OS deps; the core stays dep-minimal. Matches the workspace's existing
# libc/windows-sys usage (spt-msg, spt-store) rather than the heavyweight `windows`.
[target.'cfg(unix)'.dependencies]
libc = "0.2"

[target.'cfg(windows)'.dependencies]
# REQ-RC-WIN-PASTE (v0.13.0 P1): `spt rc` reads the operator's LOCAL clipboard on a
# ctrl+V / right-click gesture and injects a bracketed paste (CC runs daemon-side, no
# access to the local clipboard — remote paste is client-originated). clipboard-win is
# the minimal Windows-only reader (a thin wrapper over the same Win32 clipboard calls,
# no X11 baggage); cfg(windows) only — Unix pastes natively through the byte pump.
clipboard-win = "5"
windows-sys = { version = "0.59", features = [
    "Win32_Foundation",
    "Win32_Security",
    "Win32_System_Threading",
    # REQ-ELEVATE-1: ShellExecuteW("runas") launches the UAC-elevated console;
    # GetConsoleProcessList lets the elevated child detect a fresh (sole-owner)
    # console so it pauses before exit instead of vanishing.
    "Win32_UI_Shell",
    "Win32_UI_WindowsAndMessaging",
    "Win32_System_Console",
] }

[dev-dependencies]
tempfile = "3"
toml = "0.8"
# install_e2e stages the built binary as a release asset (SHA256SUMS) for the
# D2 installer-script rung — same sha2 the workspace already carries.
sha2 = "0.10"
# The D7-1 process-level survival int-test (brain_survive.rs) drives the
# production supervisor + an in-process broker/NetHost while spawning the REAL
# `spt daemon brain` child (CARGO_BIN_EXE_spt). Integration tests don't inherit
# the lib's normal deps, so the daemon/net/identity surfaces it touches directly
# are re-declared here (the spt-daemon dev-dep pattern).
spt-daemon = { path = "../spt-daemon" }
spt-net = { path = "../spt-net" }
spt-proto = { path = "../spt-proto" }

-# `CARGO_BIN_EXE_xlate_choreo_fixture` to the integration tests (the same

-# cross-crate fixture-bin pattern as `mock-session`).

+# `CARGO_BIN_EXE_translate_proof_fixture` to the integration test (the same

+# cross-crate fixture-bin pattern as `mock-session`). The name MUST stay distinct

+# from spt-daemon's `xlate_choreo_fixture` bin: an identical bin name collides on

+# the shared `target/<profile>/` output filename and the two clobber each other —

+# the daemon's `g3_content_free_ping` then resolves `CARGO_BIN_EXE_xlate_choreo_fixture`

+# to the wrong fixture and fails (the PR#28 Windows gate-escape).


Now the unit test (cli.rs) + int test (translate_proof.rs):


    /// The test-only `xlate_choreo_fixture` bin (declared as a `[[bin]]` in this
    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`).
    #[cfg(test)]
    fn xlate_fixture_path() -> std::path::PathBuf {
        let exe = std::env::current_exe().expect("test exe path");
        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
        let profile_dir = exe
            .parent()
            .and_then(|deps| deps.parent())
            .expect("target profile dir");
        profile_dir.join(format!("xlate_choreo_fixture{}", std::env::consts::EXE_SUFFIX))
    }

    /// The test-only `translate_proof_fixture` bin (declared as a `[[bin]]` in this
    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`). NAME is distinct from
    /// spt-daemon's `xlate_choreo_fixture` so the two bins don't clobber a shared
    /// output filename (the PR#28 Windows collision).
    #[cfg(test)]
    fn xlate_fixture_path() -> std::path::PathBuf {
        let exe = std::env::current_exe().expect("test exe path");
        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
        let profile_dir = exe
            .parent()
            .and_then(|deps| deps.parent())
            .expect("target profile dir");
        profile_dir.join(format!("translate_proof_fixture{}", std::env::consts::EXE_SUFFIX))
    }


The file C:/Users/decid/Documents/projects/spt-core-translate-proof/crates/spt/src/cli.rs has been updated successfully. (file state is current in your context — no need to Read it back)

    /// The test-only `xlate_choreo_fixture` bin (declared as a `[[bin]]` in this
    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`).
    #[cfg(test)]
    fn xlate_fixture_path() -> std::path::PathBuf {
        let exe = std::env::current_exe().expect("test exe path");
        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
        let profile_dir = exe
            .parent()
            .and_then(|deps| deps.parent())
            .expect("target profile dir");
        profile_dir.join(format!("xlate_choreo_fixture{}", std::env::consts::EXE_SUFFIX))
    }

    /// The test-only `translate_proof_fixture` bin (declared as a `[[bin]]` in this
    /// crate, source under `tests/fixtures/`) sits in the workspace target profile
    /// dir alongside the unit-test exe's `deps/` dir. Resolve it from
    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`). NAME is distinct from
    /// spt-daemon's `xlate_choreo_fixture` so the two bins don't clobber a shared
    /// output filename (the PR#28 Windows collision).
    #[cfg(test)]
    fn xlate_fixture_path() -> std::path::PathBuf {
        let exe = std::env::current_exe().expect("test exe path");
        // .../target/<profile>/deps/<unit-test-exe>  →  .../target/<profile>/
        let profile_dir = exe
            .parent()
            .and_then(|deps| deps.parent())
            .expect("target profile dir");
        profile_dir.join(format!("translate_proof_fixture{}", std::env::consts::EXE_SUFFIX))
    }

-    /// The test-only `xlate_choreo_fixture` bin (declared as a `[[bin]]` in this

+    /// The test-only `translate_proof_fixture` bin (declared as a `[[bin]]` in this

-    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`).

+    /// `current_exe()` (unit tests get no `CARGO_BIN_EXE_*`). NAME is distinct from

+    /// spt-daemon's `xlate_choreo_fixture` so the two bins don't clobber a shared

+    /// output filename (the PR#28 Windows collision).

-        profile_dir.join(format!("xlate_choreo_fixture{}", std::env::consts::EXE_SUFFIX))

+        profile_dir.join(format!("translate_proof_fixture{}", std::env::consts::EXE_SUFFIX))

// [unit->REQ-ADAPTER-TRANSLATE-PROOF] translate-proof drives the REAL


"xlate_choreo_fixture must be built: {} (run via `cargo test -p spt`)",

"translate_proof_fixture must be built: {} (run via `cargo test -p spt`)",


// The fixture bin must be built for this gate. `cargo test -p spt`

// builds it; a bare `cargo test --lib` without the bin would not.

-                "xlate_choreo_fixture must be built: {} (run via `cargo test -p spt`)",

+                "translate_proof_fixture must be built: {} (run via `cargo test -p spt`)",


//! external translation binary (`xlate_choreo_fixture`, a sibling `[[bin]]` in

//! external translation binary (`translate_proof_fixture`, a sibling `[[bin]]` in


The file C:/Users/decid/Documents/projects/spt-core-translate-proof/crates/spt/tests/translate_proof.rs has been updated successfully. (file state is current in your context — no need to Read it back)

//! End-to-end int gate for `spt adapter translate-proof` (ADR-0022,
//! REQ-ADAPTER-TRANSLATE-PROOF): the author-time EMIT-half proof for
//! `[message-idle-translation-binary]`.
//!
//! This drives the REAL `spt` binary through the REAL command, against a REAL
//! external translation binary (`xlate_choreo_fixture`, a sibling `[[bin]]` in
//! this crate). No mocks: `translate-proof` spawns and feeds the fixture exactly
//! as the daemon does (the `init` line then the `--event` envelope), reads back
//! its emitted keystroke-command stream, prints it, and gates on the result. The
//! fixture's choreography (`ctrl+s` / delay / `text:XLATE_OK` / enter / delay /
//! `ctrl+s` / `ctrl+q` / `commit`) is the EMIT half of the W2 idle-delivery seam.

use std::path::PathBuf;
use std::process::Command;
use std::time::Duration;

mod common;
use common::CommandNoWindowExt;

use spt_store::perch;

/// Absolute path to a sibling binary in the same target dir as the `spt` test bin.
fn sibling_bin(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_BIN_EXE_spt"))
        .with_file_name(format!("{name}{}", std::env::consts::EXE_SUFFIX))
}

/// Run `spt <args...>` under an isolated `SPT_HOME`, bounded, capturing output.
fn run_spt(
    spt_bin: &std::path::Path,
    home: &std::path::Path,
    args: &[&str],
    fixture_mode: Option<&str>,
) -> std::process::Output {
    let mut cmd = Command::new(spt_bin);
    cmd.no_window().args(args).env("SPT_HOME", home);
    if let Some(mode) = fixture_mode {
        cmd.env("XLATE_FIXTURE_MODE", mode);
    } else {
        cmd.env_remove("XLATE_FIXTURE_MODE");
    }
    cmd.output().expect("spawn spt adapter translate-proof")
}

// [int->REQ-ADAPTER-TRANSLATE-PROOF] the real command drives the real external
// translation binary end-to-end: the committed choreography proofs (exit 0 + the
// emitted stream printed), the `nocommit` variant of the SAME binary fails (exit
// 1, NO_COMMIT), and an adapter declaring no section exits 2.
#[test]
fn translate_proof_drives_the_real_translation_binary() {
    let spt_bin = PathBuf::from(env!("CARGO_BIN_EXE_spt"));
    let fixture = sibling_bin("xlate_choreo_fixture");
    assert!(
        fixture.exists(),
        "the translation-binary fixture must be built: {} \
         (cargo test -p spt builds it)",
        fixture.display()
    );

    let home = tempfile::tempdir().unwrap();

    // Register a harness adapter declaring [message-idle-translation-binary] with
    // the absolute fixture path. Register via the lib API into this home's adapter
    // registry (the child `spt` reads the same SPT_HOME).
    std::env::set_var("SPT_HOME", home.path());
    let adapters = perch::adapters_dir();
    let fixture_for_toml = fixture.to_string_lossy().replace('\\', "/");
    let manifest = format!(
        "[adapter]\nname = \"cc\"\nkind = \"harness\"\nversion = \"1\"\n\
         min_spt_core_version = \"0\"\n\n\
         [message-idle-translation-binary]\npath = '{fixture_for_toml}'\n"
    );
    let src = perch::spt_home().join("srcs").join("cc");
    std::fs::create_dir_all(&src).unwrap();
    std::fs::write(src.join("manifest.toml"), &manifest).unwrap();
    spt_runtime::registry::register(&adapters, &src, 1).unwrap();

    // A second adapter with NO translation-binary section (for the exit-2 case).
    let plain = "[adapter]\nname = \"plain\"\nkind = \"harness\"\nversion = \"1\"\n\
                 min_spt_core_version = \"0\"\n";
    let psrc = perch::spt_home().join("srcs").join("plain");
    std::fs::create_dir_all(&psrc).unwrap();
    std::fs::write(psrc.join("manifest.toml"), plain).unwrap();
    spt_runtime::registry::register(&adapters, &psrc, 1).unwrap();
    std::env::remove_var("SPT_HOME");

    let event = "<EVENT type=\"msg\" to=\"{id}\" sid=\"{session_id}\"/>";

    // ── Happy path: committed choreography → exit 0, stream printed. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "cc", "--event", event],
        None,
    );
    let stdout = String::from_utf8_lossy(&out.stdout);
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert!(
        out.status.success(),
        "committed choreography must proof (exit 0).\nstdout:\n{stdout}\nstderr:\n{stderr}"
    );
    // The EMIT half is visible: the payload text and the commit are reported.
    assert!(
        stdout.contains("XLATE_OK"),
        "the emitted payload text must be surfaced.\nstdout:\n{stdout}"
    );
    assert!(
        stdout.contains("commit: yes"),
        "a committed sequence reports commit: yes.\nstdout:\n{stdout}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_OK:cc"),
        "the OK marker is emitted on stderr.\nstderr:\n{stderr}"
    );

    // ── No-commit variant of the SAME binary → exit 1, NO_COMMIT. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "cc", "--event", event, "--session", "sessA"],
        Some("nocommit"),
    );
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert_eq!(
        out.status.code(),
        Some(1),
        "a sequence with no terminating commit fails (exit 1).\nstderr:\n{stderr}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_NO_COMMIT:cc"),
        "the no-commit gate marker is emitted.\nstderr:\n{stderr}"
    );

    // ── No section → exit 2. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "plain", "--event", event],
        None,
    );
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert_eq!(
        out.status.code(),
        Some(2),
        "no [message-idle-translation-binary] section → exit 2.\nstderr:\n{stderr}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_NO_SECTION:plain"),
        "the no-section marker is emitted.\nstderr:\n{stderr}"
    );

    // Sanity: drain budget keeps the whole gate well under any wedge timeout.
    let _ = Duration::from_secs(5);
}

-//! external translation binary (`xlate_choreo_fixture`, a sibling `[[bin]]` in

+//! external translation binary (`translate_proof_fixture`, a sibling `[[bin]]` in


let fixture = sibling_bin("xlate_choreo_fixture");

let fixture = sibling_bin("translate_proof_fixture");


//! End-to-end int gate for `spt adapter translate-proof` (ADR-0022,
//! REQ-ADAPTER-TRANSLATE-PROOF): the author-time EMIT-half proof for
//! `[message-idle-translation-binary]`.
//!
//! This drives the REAL `spt` binary through the REAL command, against a REAL
//! external translation binary (`translate_proof_fixture`, a sibling `[[bin]]` in
//! this crate). No mocks: `translate-proof` spawns and feeds the fixture exactly
//! as the daemon does (the `init` line then the `--event` envelope), reads back
//! its emitted keystroke-command stream, prints it, and gates on the result. The
//! fixture's choreography (`ctrl+s` / delay / `text:XLATE_OK` / enter / delay /
//! `ctrl+s` / `ctrl+q` / `commit`) is the EMIT half of the W2 idle-delivery seam.

use std::path::PathBuf;
use std::process::Command;
use std::time::Duration;

mod common;
use common::CommandNoWindowExt;

use spt_store::perch;

/// Absolute path to a sibling binary in the same target dir as the `spt` test bin.
fn sibling_bin(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_BIN_EXE_spt"))
        .with_file_name(format!("{name}{}", std::env::consts::EXE_SUFFIX))
}

/// Run `spt <args...>` under an isolated `SPT_HOME`, bounded, capturing output.
fn run_spt(
    spt_bin: &std::path::Path,
    home: &std::path::Path,
    args: &[&str],
    fixture_mode: Option<&str>,
) -> std::process::Output {
    let mut cmd = Command::new(spt_bin);
    cmd.no_window().args(args).env("SPT_HOME", home);
    if let Some(mode) = fixture_mode {
        cmd.env("XLATE_FIXTURE_MODE", mode);
    } else {
        cmd.env_remove("XLATE_FIXTURE_MODE");
    }
    cmd.output().expect("spawn spt adapter translate-proof")
}

// [int->REQ-ADAPTER-TRANSLATE-PROOF] the real command drives the real external
// translation binary end-to-end: the committed choreography proofs (exit 0 + the
// emitted stream printed), the `nocommit` variant of the SAME binary fails (exit
// 1, NO_COMMIT), and an adapter declaring no section exits 2.
#[test]
fn translate_proof_drives_the_real_translation_binary() {
    let spt_bin = PathBuf::from(env!("CARGO_BIN_EXE_spt"));
    let fixture = sibling_bin("xlate_choreo_fixture");
    assert!(
        fixture.exists(),
        "the translation-binary fixture must be built: {} \
         (cargo test -p spt builds it)",
        fixture.display()
    );

    let home = tempfile::tempdir().unwrap();

    // Register a harness adapter declaring [message-idle-translation-binary] with
    // the absolute fixture path. Register via the lib API into this home's adapter
    // registry (the child `spt` reads the same SPT_HOME).
    std::env::set_var("SPT_HOME", home.path());
    let adapters = perch::adapters_dir();
    let fixture_for_toml = fixture.to_string_lossy().replace('\\', "/");
    let manifest = format!(
        "[adapter]\nname = \"cc\"\nkind = \"harness\"\nversion = \"1\"\n\
         min_spt_core_version = \"0\"\n\n\
         [message-idle-translation-binary]\npath = '{fixture_for_toml}'\n"
    );
    let src = perch::spt_home().join("srcs").join("cc");
    std::fs::create_dir_all(&src).unwrap();
    std::fs::write(src.join("manifest.toml"), &manifest).unwrap();
    spt_runtime::registry::register(&adapters, &src, 1).unwrap();

    // A second adapter with NO translation-binary section (for the exit-2 case).
    let plain = "[adapter]\nname = \"plain\"\nkind = \"harness\"\nversion = \"1\"\n\
                 min_spt_core_version = \"0\"\n";
    let psrc = perch::spt_home().join("srcs").join("plain");
    std::fs::create_dir_all(&psrc).unwrap();
    std::fs::write(psrc.join("manifest.toml"), plain).unwrap();
    spt_runtime::registry::register(&adapters, &psrc, 1).unwrap();
    std::env::remove_var("SPT_HOME");

    let event = "<EVENT type=\"msg\" to=\"{id}\" sid=\"{session_id}\"/>";

    // ── Happy path: committed choreography → exit 0, stream printed. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "cc", "--event", event],
        None,
    );
    let stdout = String::from_utf8_lossy(&out.stdout);
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert!(
        out.status.success(),
        "committed choreography must proof (exit 0).\nstdout:\n{stdout}\nstderr:\n{stderr}"
    );
    // The EMIT half is visible: the payload text and the commit are reported.
    assert!(
        stdout.contains("XLATE_OK"),
        "the emitted payload text must be surfaced.\nstdout:\n{stdout}"
    );
    assert!(
        stdout.contains("commit: yes"),
        "a committed sequence reports commit: yes.\nstdout:\n{stdout}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_OK:cc"),
        "the OK marker is emitted on stderr.\nstderr:\n{stderr}"
    );

    // ── No-commit variant of the SAME binary → exit 1, NO_COMMIT. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "cc", "--event", event, "--session", "sessA"],
        Some("nocommit"),
    );
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert_eq!(
        out.status.code(),
        Some(1),
        "a sequence with no terminating commit fails (exit 1).\nstderr:\n{stderr}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_NO_COMMIT:cc"),
        "the no-commit gate marker is emitted.\nstderr:\n{stderr}"
    );

    // ── No section → exit 2. ──
    let out = run_spt(
        &spt_bin,
        home.path(),
        &["adapter", "translate-proof", "plain", "--event", event],
        None,
    );
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert_eq!(
        out.status.code(),
        Some(2),
        "no [message-idle-translation-binary] section → exit 2.\nstderr:\n{stderr}"
    );
    assert!(
        stderr.contains("TRANSLATE_PROOF_NO_SECTION:plain"),
        "the no-section marker is emitted.\nstderr:\n{stderr}"
    );

    // Sanity: drain budget keeps the whole gate well under any wedge timeout.
    let _ = Duration::from_secs(5);
}

-    let fixture = sibling_bin("xlate_choreo_fixture");

+    let fixture = sibling_bin("translate_proof_fixture");


Update the fixture's own header (the env-var ref + the must-be-distinct-name rationale):


1	//! Test-only ADR-0022 translation-binary fixture for the `spt` crate's
2	//! `translate-proof` tests — an EMIT-focused sibling of
3	//! `crates/spt-daemon/src/bin/xlate_choreo_fixture.rs` (the W2 Layer G fixture).
4	//! It emits the SAME ADR-0022 choreography on `{type:"event"}`, but drops the
5	//! daemon copy's PTY-echo / `XLATE_FIXTURE_STDIN_LOG` machinery (that exists for
6	//! the W1 inject-control coexistence test, which has a live PTY) — irrelevant to
7	//! this EMIT-half proof, which has no PTY. Re-homed here because
8	//! `CARGO_BIN_EXE_xlate_choreo_fixture` is only set for the crate that DECLARES
9	//! the bin: the daemon's copy serves `spt-daemon`'s `inject_control_wedge.rs`,
10	//! this copy serves the `spt` crate's `tests/translate_proof.rs` so the int drives
11	//! a REAL external binary through the real `spt adapter translate-proof` command.
12	//! Declared as a `[[bin]]` whose source lives under `tests/` so it never ships
13	//! from `src/` (CI's release build is `cargo build -p spt --bin spt`, so it is
14	//! excluded there). NOT a production binary.
15	//!
16	//! Protocol (spt-core → here, one JSON object per line on stdin):

//! Test-only ADR-0022 translation-binary fixture for the `spt` crate's
//! `translate-proof` tests — an EMIT-focused sibling of
//! `crates/spt-daemon/src/bin/xlate_choreo_fixture.rs` (the W2 Layer G fixture).
//! It emits the SAME ADR-0022 choreography on `{type:"event"}`, but drops the
//! daemon copy's PTY-echo / `XLATE_FIXTURE_STDIN_LOG` machinery (that exists for
//! the W1 inject-control coexistence test, which has a live PTY) — irrelevant to
//! this EMIT-half proof, which has no PTY. Re-homed here because
//! `CARGO_BIN_EXE_xlate_choreo_fixture` is only set for the crate that DECLARES
//! the bin: the daemon's copy serves `spt-daemon`'s `inject_control_wedge.rs`,
//! this copy serves the `spt` crate's `tests/translate_proof.rs` so the int drives
//! a REAL external binary through the real `spt adapter translate-proof` command.
//! Declared as a `[[bin]]` whose source lives under `tests/` so it never ships
//! from `src/` (CI's release build is `cargo build -p spt --bin spt`, so it is
//! excluded there). NOT a production binary.
//!
//! Protocol (spt-core → here, one JSON object per line on stdin):


//! this EMIT-half proof, which has no PTY. Re-homed here because
//! `CARGO_BIN_EXE_xlate_choreo_fixture` is only set for the crate that DECLARES
//! the bin: the daemon's copy serves `spt-daemon`'s `inject_control_wedge.rs`,
//! this copy serves the `spt` crate's `tests/translate_proof.rs` so the int drives
//! a REAL external binary through the real `spt adapter translate-proof` command.
//! Declared as a `[[bin]]` whose source lives under `tests/` so it never ships
//! from `src/` (CI's release build is `cargo build -p spt --bin spt`, so it is
//! excluded there). NOT a production binary.

//! this EMIT-half proof, which has no PTY. Re-homed here because
//! `CARGO_BIN_EXE_translate_proof_fixture` is only set for the crate that DECLARES
//! the bin: the daemon's `xlate_choreo_fixture` serves `spt-daemon`'s
//! `inject_control_wedge.rs`, this fixture serves the `spt` crate's
//! `tests/translate_proof.rs` so the int drives a REAL external binary through the
//! real `spt adapter translate-proof` command. The bin is NAMED
//! `translate_proof_fixture`, distinct from the daemon's `xlate_choreo_fixture` —
//! an identical bin name collides on the shared `target/<profile>/` output
//! filename and the two clobber each other (the daemon's `g3_content_free_ping`
//! then resolves `CARGO_BIN_EXE_xlate_choreo_fixture` to THIS emit-only fixture,
//! whose ping/stdin-log machinery is stripped, and fails — the PR#28 Windows
//! gate-escape). Declared as a `[[bin]]` whose source lives under `tests/` so it
//! never ships from `src/` (CI's release build is `cargo build -p spt --bin spt`,
//! so it is excluded there). NOT a production binary.


The file C:/Users/decid/Documents/projects/spt-core-translate-proof/crates/spt/tests/fixtures/translate_proof_fixture.rs has been updated successfully. (file state is current in your context — no need to Read it back)

//! this EMIT-half proof, which has no PTY. Re-homed here because
//! `CARGO_BIN_EXE_translate_proof_fixture` is only set for the crate that DECLARES
//! the bin: the daemon's `xlate_choreo_fixture` serves `spt-daemon`'s
//! `inject_control_wedge.rs`, this fixture serves the `spt` crate's
//! `tests/translate_proof.rs` so the int drives a REAL external binary through the
//! real `spt adapter translate-proof` command. The bin is NAMED
//! `translate_proof_fixture`, distinct from the daemon's `xlate_choreo_fixture` —
//! an identical bin name collides on the shared `target/<profile>/` output
//! filename and the two clobber each other (the daemon's `g3_content_free_ping`
//! then resolves `CARGO_BIN_EXE_xlate_choreo_fixture` to THIS emit-only fixture,
//! whose ping/stdin-log machinery is stripped, and fails — the PR#28 Windows
//! gate-escape). Declared as a `[[bin]]` whose source lives under `tests/` so it
//! never ships from `src/` (CI's release build is `cargo build -p spt --bin spt`,
//! so it is excluded there). NOT a production binary.

//! Test-only ADR-0022 translation-binary fixture for the `spt` crate's
//! `translate-proof` tests — an EMIT-focused sibling of
//! `crates/spt-daemon/src/bin/xlate_choreo_fixture.rs` (the W2 Layer G fixture).
//! It emits the SAME ADR-0022 choreography on `{type:"event"}`, but drops the
//! daemon copy's PTY-echo / `XLATE_FIXTURE_STDIN_LOG` machinery (that exists for
//! the W1 inject-control coexistence test, which has a live PTY) — irrelevant to
//! this EMIT-half proof, which has no PTY. Re-homed here because
//! `CARGO_BIN_EXE_xlate_choreo_fixture` is only set for the crate that DECLARES
//! the bin: the daemon's copy serves `spt-daemon`'s `inject_control_wedge.rs`,
//! this copy serves the `spt` crate's `tests/translate_proof.rs` so the int drives
//! a REAL external binary through the real `spt adapter translate-proof` command.
//! Declared as a `[[bin]]` whose source lives under `tests/` so it never ships
//! from `src/` (CI's release build is `cargo build -p spt --bin spt`, so it is
//! excluded there). NOT a production binary.
//!
//! Protocol (spt-core → here, one JSON object per line on stdin):
//!   `{"type":"init",…}`  — identity; noted, never drives output.
//!   `{"type":"input"}`   — a CONTENT-FREE operator-activity ping; ignored.
//!   `{"type":"event","envelope":"…"}` — an inbound `<EVENT>`; we respond with
//!                          the CC stash/restore choreography.
//!
//! On an `event` we emit (here → spt-core, one JSON object per line on stdout,
//! flushing each so the reader sees them promptly):
//!   `{"key":"ctrl+s"}` `{"delay_ms":50}` `{"text":"XLATE_OK"}` `{"key":"enter"}`
//!   `{"delay_ms":50}` `{"key":"ctrl+s"}` then `{"commit":true}`.
//!
//! Modes (env `XLATE_FIXTURE_MODE`, read ONCE at start; default `choreo`):
//!   - `choreo`   — the full sequence ENDING in `{"commit":true}` (happy path).
//!   - `nocommit` — emit the payload text + a key but NEVER `{"commit":true}`, so
//!     the commit-deadline / no-commit gate is exercised.

use std::io::{self, BufRead, Write};

/// The fixed, recognizable payload token the choreography types into the PTY.
const PAYLOAD: &str = "XLATE_OK";

fn main() {
    let mode = std::env::var("XLATE_FIXTURE_MODE").unwrap_or_else(|_| "choreo".to_string());

    let stdin = io::stdin();
    let mut out = io::stdout();

    for line in stdin.lock().lines() {
        let Ok(line) = line else { break }; // stdin closed (EOF) → exit (no-zombie).
        let trimmed = line.trim();
        if trimmed.is_empty() {
            continue;
        }

        // Only `{"type":"event",…}` drives a response. `init` and the
        // content-free `input` ping are noted and ignored.
        let v: serde_json::Value = match serde_json::from_str(trimmed) {
            Ok(v) => v,
            Err(_) => continue,
        };
        if v.get("type").and_then(|t| t.as_str()) != Some("event") {
            continue;
        }

        // Emit the choreography, flushing each line so the reader applies it
        // promptly (the delays are part of the sequence, not a wall-clock).
        emit(&mut out, r#"{"key":"ctrl+s"}"#);
        emit(&mut out, r#"{"delay_ms":50}"#);
        emit(&mut out, &format!(r#"{{"text":"{PAYLOAD}"}}"#));
        emit(&mut out, r#"{"key":"enter"}"#);

        if mode == "nocommit" {
            // No-commit path: the payload + a key landed, but we deliberately
            // NEVER emit `{"commit":true}` — translate-proof must surface this as
            // a NO_COMMIT failure (exit 1), and the live broker would FAULT on its
            // commit deadline.
            emit(&mut out, r#"{"key":"ctrl+q"}"#);
            continue;
        }

        emit(&mut out, r#"{"delay_ms":50}"#);
        emit(&mut out, r#"{"key":"ctrl+s"}"#);
        // XON (`ctrl+q` = 0x11): resume the terminal output flow the `ctrl+s`
        // (XOFF) chord paused — a real stash/restore adapter restores flow at the
        // end of its sequence just the same.
        emit(&mut out, r#"{"key":"ctrl+q"}"#);
        emit(&mut out, r#"{"commit":true}"#);
    }
}

/// Write one JSON-lines command and flush so the reader sees it immediately.
fn emit(out: &mut io::Stdout, line: &str) {
    let _ = writeln!(out, "{line}");
    let _ = out.flush();
}

-//! `CARGO_BIN_EXE_xlate_choreo_fixture` is only set for the crate that DECLARES

-//! the bin: the daemon's copy serves `spt-daemon`'s `inject_control_wedge.rs`,

-//! this copy serves the `spt` crate's `tests/translate_proof.rs` so the int drives

-//! a REAL external binary through the real `spt adapter translate-proof` command.

-//! Declared as a `[[bin]]` whose source lives under `tests/` so it never ships

-//! from `src/` (CI's release build is `cargo build -p spt --bin spt`, so it is

-//! excluded there). NOT a production binary.

+//! `CARGO_BIN_EXE_translate_proof_fixture` is only set for the crate that DECLARES

+//! the bin: the daemon's `xlate_choreo_fixture` serves `spt-daemon`'s

+//! `inject_control_wedge.rs`, this fixture serves the `spt` crate's

+//! `tests/translate_proof.rs` so the int drives a REAL external binary through the

+//! real `spt adapter translate-proof` command. The bin is NAMED

+//! `translate_proof_fixture`, distinct from the daemon's `xlate_choreo_fixture` —

+//! an identical bin name collides on the shared `target/<profile>/` output

+//! filename and the two clobber each other (the daemon's `g3_content_free_ping`

+//! then resolves `CARGO_BIN_EXE_xlate_choreo_fixture` to THIS emit-only fixture,

+//! whose ping/stdin-log machinery is stripped, and fails — the PR#28 Windows

+//! gate-escape). Declared as a `[[bin]]` whose source lives under `tests/` so it

+//! never ships from `src/` (CI's release build is `cargo build -p spt --bin spt`,

+//! so it is excluded there). NOT a production binary.


All renames applied. Verify no stray `xlate_choreo_fixture` self-refs remain (only legit daemon references allowed), then run doyle's full cross-crate matrix:


C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\Cargo.toml:16:# `CARGO_BIN_EXE_translate_proof_fixture` to the integration test (the same
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\Cargo.toml:18:# from spt-daemon's `xlate_choreo_fixture` bin: an identical bin name collides on
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\Cargo.toml:20:# the daemon's `g3_content_free_ping` then resolves `CARGO_BIN_EXE_xlate_choreo_fixture`
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\Cargo.toml:23:name = "translate_proof_fixture"
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\Cargo.toml:24:path = "tests/fixtures/translate_proof_fixture.rs"
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\fixtures\translate_proof_fixture.rs:3://! `crates/spt-daemon/src/bin/xlate_choreo_fixture.rs` (the W2 Layer G fixture).
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\fixtures\translate_proof_fixture.rs:8://! `CARGO_BIN_EXE_translate_proof_fixture` is only set for the crate that DECLARES
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\fixtures\translate_proof_fixture.rs:9://! the bin: the daemon's `xlate_choreo_fixture` serves `spt-daemon`'s
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\fixtures\translate_proof_fixture.rs:13://! `translate_proof_fixture`, distinct from the daemon's `xlate_choreo_fixture` —
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\fixtures\translate_proof_fixture.rs:16://! then resolves `CARGO_BIN_EXE_xlate_choreo_fixture` to THIS emit-only fixture,
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\translate_proof.rs:6://! external translation binary (`translate_proof_fixture`, a sibling `[[bin]]` in
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\tests\translate_proof.rs:52:    let fixture = sibling_bin("translate_proof_fixture");
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\src\cli.rs:8860:    /// The test-only `translate_proof_fixture` bin (declared as a `[[bin]]` in this
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\src\cli.rs:8864:    /// spt-daemon's `xlate_choreo_fixture` so the two bins don't clobber a shared
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\src\cli.rs:8874:        profile_dir.join(format!("translate_proof_fixture{}", std::env::consts::EXE_SUFFIX))
C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt\src\cli.rs:8890:                "translate_proof_fixture must be built: {} (run via `cargo test -p spt`)",


Clean — all functional refs now `translate_proof_fixture`; remaining `xlate_choreo_fixture` strings are doc references to the daemon's bin (correct). Now doyle's full cross-crate matrix: collision-check build + the daemon's g-tests (the collision victims, esp g3) + spt's translate_proof + gates:


Bash

cd /c/Users/decid/Documents/projects/spt-core-translate-proof
echo "===== COLLISION CHECK: build both crates' tests ====="
cargo build -p spt -p spt-daemon --tests 2>&1 | grep -iE "collision|output filename" && echo "!!! COLLISION STILL PRESENT !!!" || echo "NO COLLISION WARNING"
echo "===== both fixture exes present + DISTINCT? ====="
ls target/debug/xlate_choreo_fixture* target/debug/translate_proof_fixture* 2>&1 | grep -iE "xlate_choreo_fixture|translate_proof_fixture"
echo "===== spt-daemon g-tests (collision victims, esp g3) ====="
cargo nextest run -p spt-daemon --test inject_control_wedge g1_ g2_ g3_ g4_ 2>&1 | tail -14
echo "===== spt translate_proof int ====="
cargo nextest run -p spt translate_proof 2>&1 | tail -6
echo "===== spt units ====="
cargo test -p spt --bin spt adapter_translate_proof 2>&1 | tail -5
echo "===== clippy both crates ====="
cargo clippy -p spt -p spt-daemon --all-targets -- -D warnings 2>&1 | tail -3
echo "===== traceable + xtask ====="
traceable-reqs check >/dev/null 2>&1; echo "traceable exit=$?"
cargo run -p xtask -- check 2>&1 | tail -2

Full cross-crate matrix: collision check + g-tests + translate_proof + gates


Command running in background with ID: bhkex92ee. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bhkex92ee.output. You will be notified when it completes. To check interim output, use Read on that file path.


Matrix running. Brief ack to doyle while it verifies (no "fixed" claim until the full matrix is green — that discipline is exactly what the gate-escape lacked):


cat <<'EOF' | "$OWL" send doyle 2>&1
On it — root confirmed, my gate-escape: I ran `cargo test -p spt` only, never the daemon suite, so the shared-target output-filename collision (+ the g3 fixture-resolution clobber) was invisible to me. The collision warning was build-time; -p spt alone never linked the daemon's g3.

FIX in progress on feat/translate-proof: renamed the spt-crate fixture bin xlate_choreo_fixture -> translate_proof_fixture (git mv'd the source, updated the [[bin]] name+path, the int test's sibling_bin(), the unit test's path-join + panic msg, and both headers — documented the must-stay-distinct reason inline so this can't regress). Functional refs all renamed; remaining xlate_choreo_fixture strings are doc references to the DAEMON's bin.

Now running the FULL cross-crate matrix (the thing I should have run): collision-check build of BOTH crates' tests, spt-daemon g1-g4 (esp g3_content_free_ping, the victim), spt translate_proof int + units, clippy both crates, traceable, xtask drift. Will push + send you the evidence ONLY once g3 + the g-suite are green again — not on translate-proof's units alone this time. Hold for that.
EOF
echo sent

Ack doyle: root + fix-in-progress, awaiting full matrix


➜ SENT:doyle
sent


Acked. Awaiting the full cross-crate matrix (collision-check + daemon g1–g4 + spt translate_proof + gates) before pushing. Will push + send doyle evidence only once g3 and the g-suite are green again — no "fixed" claim on units alone this time.


<task-notification>
<task-id>bsp4y8a8u</task-id>
<summary>Monitor event: "« spt event »"</summary>
<event><EVENT-PART seq="1/2" id="718929dc" type="msg" from="doyle">Holding. Rename + the inline must-stay-distinct note is the right fix, and running the FULL cross-crate matrix (g3 the victim + g-suite + both crates' clippy + traceable + drift) is exactly the verification this class needs — same lesson as the shared-seam rule. Push when g3 + the g-suite are green again; I'll re-gate</EVENT-PART>
<EVENT-PART seq="2/2" id="718929dc"> (full read of the rename diff + grep that no other xlate_choreo_fixture consumer is touched), then we go to the v0.13.1 cut on green-both-runners. No rush over correctness.</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: holding, approves the approach, will re-gate (rename diff + grep no other consumer touched) → v0.13.1 cut on green-both-runners. Correctness over speed.

Awaiting the matrix result before push. Nothing else to do.


<task-notification>
<task-id>bhkex92ee</task-id>
<tool-use-id>toolu_01CoyVhffCwLFQS1C1JyDq8S</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bhkex92ee.output</output-file>
<status>completed</status>
<summary>Background command "Full cross-crate matrix: collision check + g-tests + translate_proof + gates" completed (exit code 0)</summary>
</task-notification>


1	===== COLLISION CHECK: build both crates' tests =====
2	NO COLLISION WARNING
3	===== both fixture exes present + DISTINCT? =====
4	target/debug/translate_proof_fixture.exe
5	target/debug/translate_proof_fixture.pdb
6	target/debug/xlate_choreo_fixture.exe
7	target/debug/xlate_choreo_fixture.pdb
8	===== spt-daemon g-tests (collision victims, esp g3) =====
9	   Compiling portmapper v0.16.0
10	   Compiling iroh v0.98.2
11	   Compiling spt-net v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-net)
12	   Compiling spt-daemon v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-daemon)
13	    Finished `test` profile [unoptimized + debuginfo] target(s) in 47.54s
14	────────────
15	 Nextest run ID 5c363bb6-1be3-4b09-b51b-798083613f72 with nextest profile: default
16	    Starting 4 tests across 1 binary (6 tests skipped)
17	        PASS [  12.661s] (1/4) spt-daemon::inject_control_wedge g1_choreography_happy_path_payload_reaches_pty_and_controller_keeps_control
18	        PASS [   0.841s] (2/4) spt-daemon::inject_control_wedge g2_no_commit_deadline_faults_binary_and_does_not_wedge_controller_input
19	        PASS [   0.873s] (3/4) spt-daemon::inject_control_wedge g3_content_free_ping_never_duplicates_operator_keystrokes_into_binary
20	        PASS [   0.749s] (4/4) spt-daemon::inject_control_wedge g4_translation_child_is_reaped_no_zombie_after_session_down
21	────────────
22	     Summary [  15.126s] 4 tests run: 4 passed, 6 skipped
23	===== spt translate_proof int =====
24	    Starting 3 tests across 36 binaries (248 tests skipped)
25	        PASS [   0.016s] (1/3) spt::bin/spt cli::tests::adapter_translate_proof_parses
26	        PASS [   5.135s] (2/3) spt::bin/spt cli::tests::adapter_translate_proof_gates_on_commit
27	        PASS [   5.871s] (3/3) spt::translate_proof translate_proof_drives_the_real_translation_binary
28	────────────
29	     Summary [   5.872s] 3 tests run: 3 passed, 248 skipped
30	===== spt units =====
31	test cli::tests::adapter_translate_proof_parses ... ok
32	test cli::tests::adapter_translate_proof_gates_on_commit ... ok
33
34	test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 208 filtered out; finished in 5.09s
35
36	===== clippy both crates =====
37	    Checking spt-daemon v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-daemon)
38	    Checking spt v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt)
39	    Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.92s
40	===== traceable + xtask =====
41	traceable exit=0
42	     Running `target\debug\xtask.exe check`
43	xtask check: OK
44

===== COLLISION CHECK: build both crates' tests =====
NO COLLISION WARNING
===== both fixture exes present + DISTINCT? =====
target/debug/translate_proof_fixture.exe
target/debug/translate_proof_fixture.pdb
target/debug/xlate_choreo_fixture.exe
target/debug/xlate_choreo_fixture.pdb
===== spt-daemon g-tests (collision victims, esp g3) =====
   Compiling portmapper v0.16.0
   Compiling iroh v0.98.2
   Compiling spt-net v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-net)
   Compiling spt-daemon v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-daemon)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 47.54s
────────────
 Nextest run ID 5c363bb6-1be3-4b09-b51b-798083613f72 with nextest profile: default
    Starting 4 tests across 1 binary (6 tests skipped)
        PASS [  12.661s] (1/4) spt-daemon::inject_control_wedge g1_choreography_happy_path_payload_reaches_pty_and_controller_keeps_control
        PASS [   0.841s] (2/4) spt-daemon::inject_control_wedge g2_no_commit_deadline_faults_binary_and_does_not_wedge_controller_input
        PASS [   0.873s] (3/4) spt-daemon::inject_control_wedge g3_content_free_ping_never_duplicates_operator_keystrokes_into_binary
        PASS [   0.749s] (4/4) spt-daemon::inject_control_wedge g4_translation_child_is_reaped_no_zombie_after_session_down
────────────
     Summary [  15.126s] 4 tests run: 4 passed, 6 skipped
===== spt translate_proof int =====
    Starting 3 tests across 36 binaries (248 tests skipped)
        PASS [   0.016s] (1/3) spt::bin/spt cli::tests::adapter_translate_proof_parses
        PASS [   5.135s] (2/3) spt::bin/spt cli::tests::adapter_translate_proof_gates_on_commit
        PASS [   5.871s] (3/3) spt::translate_proof translate_proof_drives_the_real_translation_binary
────────────
     Summary [   5.872s] 3 tests run: 3 passed, 248 skipped
===== spt units =====
test cli::tests::adapter_translate_proof_parses ... ok
test cli::tests::adapter_translate_proof_gates_on_commit ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 208 filtered out; finished in 5.09s

===== clippy both crates =====
    Checking spt-daemon v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt-daemon)
    Checking spt v0.13.0 (C:\Users\decid\Documents\projects\spt-core-translate-proof\crates\spt)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.92s
===== traceable + xtask =====
traceable exit=0
     Running `target\debug\xtask.exe check`
xtask check: OK


**Full matrix GREEN** — collision-class verified fixed:
- NO COLLISION WARNING ✓ · both exes coexist distinctly (`xlate_choreo_fixture.exe` + `translate_proof_fixture.exe`) ✓
- spt-daemon **g1–g4 all PASS** — including **g3_content_free_ping** (the victim) ✓
- spt translate_proof int + 2 units PASS ✓ · clippy both crates clean ✓ · traceable exit 0 ✓ · xtask drift OK ✓

Verified on the full cross-crate matrix doyle demanded, not units alone. Commit + push:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
git add crates/spt/Cargo.toml crates/spt/src/cli.rs crates/spt/tests/translate_proof.rs crates/spt/tests/fixtures/translate_proof_fixture.rs crates/spt/tests/fixtures/xlate_choreo_fixture.rs
echo "=== staged ==="; git status --short
git commit -F - <<'EOF'
fix(test): rename spt-crate fixture bin to dodge an output-filename collision with spt-daemon

PR#28 Windows CI RED (gate-escape, caught only by the full cross-crate matrix):
the re-homed `spt`-crate translation fixture was named `xlate_choreo_fixture` —
the SAME bin name as spt-daemon's existing `src/bin/xlate_choreo_fixture.rs`.
Both target the same `target/<profile>/xlate_choreo_fixture.exe` output filename
and clobber each other (cargo's "output filename collision" warning). The build
order on the Windows runner left the `spt` crate's EMIT-only copy (whose
`XLATE_FIXTURE_STDIN_LOG` / content-free-ping machinery is deliberately stripped)
as the winner, so spt-daemon's `g3_content_free_ping_never_duplicates_operator_keystrokes_into_binary`
resolved `CARGO_BIN_EXE_xlate_choreo_fixture` to the WRONG fixture — no ping
logged → FAILED (inject_control_wedge.rs). translate-proof's own tests passed
(they target the fixture by a sibling path, not the colliding env var), which is
exactly why a `-p spt`-only run never surfaced it.

Fix: rename the `spt`-crate fixture bin to `translate_proof_fixture` (unique).
`git mv` the source, update the `[[bin]]` name+path, the int test's
`sibling_bin(..)`, the unit test's path-join + panic message, and both headers —
with an inline must-stay-distinct note in the Cargo.toml `[[bin]]` comment + both
fixture/test headers so the collision can't silently regress. The two fixtures
now build to distinct output filenames and coexist.

Verified on the FULL cross-crate matrix (the verification the gate-escape lacked):
no collision warning; both `xlate_choreo_fixture.exe` + `translate_proof_fixture.exe`
present; spt-daemon g1-g4 green (g3 the victim back to PASS); spt translate_proof
int + units green; clippy -p spt -p spt-daemon --all-targets -D warnings clean;
traceable-reqs check exit 0; xtask doc-drift OK.

[int->REQ-ADAPTER-TRANSLATE-PROOF]

Co-authored by: todlando
EOF
echo "=== commit exit $? ==="; git log --oneline -2
git push origin feat/translate-proof 2>&1 | tail -4; echo "=== push exit ${PIPESTATUS[0]} ==="

Commit + push fixture rename fix


fatal: pathspec 'crates/spt/tests/fixtures/xlate_choreo_fixture.rs' did not match any files
=== staged ===
 M crates/spt/Cargo.toml
 M crates/spt/src/cli.rs
RM crates/spt/tests/fixtures/xlate_choreo_fixture.rs -> crates/spt/tests/fixtures/translate_proof_fixture.rs
 M crates/spt/tests/translate_proof.rs
?? TRANSLATE-PROOF-JIT-PLAN.md
[feat/translate-proof bf6b3b7] fix(test): rename spt-crate fixture bin to dodge an output-filename collision with spt-daemon
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename crates/spt/tests/fixtures/{xlate_choreo_fixture.rs => translate_proof_fixture.rs} (100%)
=== commit exit 0 ===
bf6b3b7 fix(test): rename spt-crate fixture bin to dodge an output-filename collision with spt-daemon
a05ef2c feat(cli): `spt adapter translate-proof` — author-time EMIT-half proof for the translation binary
To https://github.com/SaberMage/spt-core.git
   a05ef2c..bf6b3b7  feat/translate-proof -> feat/translate-proof
=== push exit 0 ===
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Problem — the `git add` **fatal'd on the now-nonexistent old path and staged nothing**, so commit bf6b3b7 captured ONLY the rename (0 content changes). My reference edits (Cargo.toml, cli.rs, translate_proof.rs, fixture header) are unstaged — meaning the pushed bf6b3b7 is **broken** (Cargo.toml still points `[[bin]] path` at the renamed-away file). Must fix immediately. Checking exact state:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
echo "=== status ==="; git status --short
echo "=== is the committed bf6b3b7 broken? (Cargo.toml [[bin]] in HEAD) ==="; git show HEAD:crates/spt/Cargo.toml | sed -n '18,24p'
echo "=== working-tree Cargo.toml (my edit, unstaged) ==="; sed -n '22,24p' crates/spt/Cargo.toml

Diagnose broken commit + unstaged edits


=== status ===
 M crates/spt/Cargo.toml
 M crates/spt/src/cli.rs
 M crates/spt/tests/fixtures/translate_proof_fixture.rs
 M crates/spt/tests/translate_proof.rs
?? TRANSLATE-PROOF-JIT-PLAN.md
=== is the committed bf6b3b7 broken? (Cargo.toml [[bin]] in HEAD) ===
[[bin]]
name = "xlate_choreo_fixture"
path = "tests/fixtures/xlate_choreo_fixture.rs"

[dependencies]
spt-proto = { path = "../spt-proto" }
spt-store = { path = "../spt-store" }
=== working-tree Cargo.toml (my edit, unstaged) ===
[[bin]]
name = "translate_proof_fixture"
path = "tests/fixtures/translate_proof_fixture.rs"
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Confirmed: bf6b3b7 committed the rename but HEAD's Cargo.toml still points `[[bin]]` at the renamed-away file → broken. All 4 content edits sit unstaged in the working tree (the same tree the matrix validated green). Amend bf6b3b7 to fold them in (makes it complete + buildable, no broken commit in history), then force-push (bf6b3b7 was just pushed, not yet gated):


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
git add crates/spt/Cargo.toml crates/spt/src/cli.rs crates/spt/tests/translate_proof.rs crates/spt/tests/fixtures/translate_proof_fixture.rs
echo "=== staged now ==="; git status --short
git commit --amend --no-edit 2>&1 | tail -3
echo "=== amended HEAD Cargo.toml [[bin]] (must be translate_proof_fixture) ==="; git show HEAD:crates/spt/Cargo.toml | sed -n '22,24p'
echo "=== amended commit diffstat ==="; git show --stat HEAD --oneline | head -12
git push --force-with-lease origin feat/translate-proof 2>&1 | tail -4; echo "=== push exit ${PIPESTATUS[0]} ==="

Stage content edits, amend, force-push complete fix


warning: in the working copy of 'crates/spt/tests/fixtures/translate_proof_fixture.rs', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'crates/spt/tests/translate_proof.rs', LF will be replaced by CRLF the next time Git touches it
=== staged now ===
M  crates/spt/Cargo.toml
M  crates/spt/src/cli.rs
M  crates/spt/tests/fixtures/translate_proof_fixture.rs
M  crates/spt/tests/translate_proof.rs
?? TRANSLATE-PROOF-JIT-PLAN.md
 Date: Mon Jun 22 01:13:22 2026 -0700
 4 files changed, 29 insertions(+), 17 deletions(-)
 rename crates/spt/tests/fixtures/{xlate_choreo_fixture.rs => translate_proof_fixture.rs} (79%)
=== amended HEAD Cargo.toml [[bin]] (must be translate_proof_fixture) ===
[[bin]]
name = "translate_proof_fixture"
path = "tests/fixtures/translate_proof_fixture.rs"
=== amended commit diffstat ===
aa5fa2a fix(test): rename spt-crate fixture bin to dodge an output-filename collision with spt-daemon
 crates/spt/Cargo.toml                                | 12 ++++++++----
 crates/spt/src/cli.rs                                | 10 ++++++----
 ..._choreo_fixture.rs => translate_proof_fixture.rs} | 20 +++++++++++++-------
 crates/spt/tests/translate_proof.rs                  |  4 ++--
 4 files changed, 29 insertions(+), 17 deletions(-)
To https://github.com/SaberMage/spt-core.git
 + bf6b3b7...aa5fa2a feat/translate-proof -> feat/translate-proof (forced update)
=== push exit 0 ===
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Amended `aa5fa2a` now complete (Cargo.toml→`translate_proof_fixture`, all 4 files, +29/-17), force-pushed `bf6b3b7...aa5fa2a`. HEAD == the matrix-validated working tree. Confirming clean state + that no daemon consumer was touched, then evidence to doyle:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
echo "=== working tree clean (only untracked JIT plan)? ==="; git status --short
echo "=== did my fix touch ANY spt-daemon file? (should be none) ==="; git show --stat aa5fa2a --format="" | grep -i "spt-daemon" && echo "!!! TOUCHED DAEMON !!!" || echo "NO spt-daemon files touched — daemon's xlate_choreo_fixture + consumers untouched"
echo "=== full branch diff vs main: files ==="; git diff --stat origin/main...feat/translate-proof | tail -12

Confirm clean + daemon untouched + branch scope


=== working tree clean (only untracked JIT plan)? ===
?? TRANSLATE-PROOF-JIT-PLAN.md
=== did my fix touch ANY spt-daemon file? (should be none) ===
NO spt-daemon files touched — daemon's xlate_choreo_fixture + consumers untouched
=== full branch diff vs main: files ===
 crates/spt/Cargo.toml                              |  14 +
 crates/spt/src/cli.rs                              | 335 +++++++++++++++++++++
 .../spt/tests/fixtures/translate_proof_fixture.rs  |  96 ++++++
 crates/spt/tests/translate_proof.rs                | 154 ++++++++++
 docs-site/src/cli/reference.md                     | 120 +++++---
 ...-spt-hosted-idle-delivery-translation-binary.md |  34 +++
 traceable-reqs.toml                                |   6 +
 7 files changed, 717 insertions(+), 42 deletions(-)
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Confirmed: working tree clean (only the untracked JIT plan), **no spt-daemon file touched** (daemon's `xlate_choreo_fixture` + consumers untouched — g1–g4 PASS proves they resolve the daemon's fixture correctly), branch scope is spt-crate + docs only. Evidence to doyle:


cat <<'EOF' | "$OWL" send doyle 2>&1
PUSHED — collision fix on feat/translate-proof @ aa5fa2a. Ready for your re-gate. FULL cross-crate matrix GREEN.

PROCESS HONESTY: my first push was a botched commit (bf6b3b7) — a `git add` listing the pre-rename path fatal'd and staged nothing but the `git mv`, so it captured the rename with NONE of the reference updates (a broken, unbuildable commit: Cargo.toml [[bin]] still pointed at the renamed-away file). Caught it immediately on the diffstat (1 file, 0 insertions), staged the 4 content edits, amended into aa5fa2a (complete + buildable), and force-pushed (--force-with-lease; bf6b3b7 was seconds old and never gated). HEAD now == the matrix-validated tree.

THE FIX (aa5fa2a): spt-crate fixture bin xlate_choreo_fixture -> translate_proof_fixture. git mv source; [[bin]] name+path; int sibling_bin(); unit path-join + panic msg; both headers — inline must-stay-distinct note in the Cargo.toml [[bin]] comment + fixture header so it can't silently regress.

RE-GATE ANSWERS (pre-confirmed for your grep):
- NO spt-daemon file touched. `git show --stat aa5fa2a` has zero spt-daemon paths — the daemon's own xlate_choreo_fixture (src/bin + inject_control_wedge.rs CARGO_BIN_EXE consumers) is UNTOUCHED. The remaining `xlate_choreo_fixture` strings in my diff are doc/comment references TO the daemon's bin, not functional.
- Distinct output filenames now: target/debug/xlate_choreo_fixture.exe (daemon) + target/debug/translate_proof_fixture.exe (spt) both present, no clobber.

FULL MATRIX (Windows, the verification the escape lacked):
- collision-check build of BOTH crates' tests: NO "output filename collision" warning.
- spt-daemon inject_control_wedge g1-g4: ALL PASS — g3_content_free_ping (the victim) back to PASS (resolves the daemon's full fixture again, ping logged).
- spt translate_proof int + 2 units: PASS.
- clippy -p spt -p spt-daemon --all-targets -D warnings: clean.
- traceable-reqs check: exit 0. xtask doc-drift: OK.

Branch: 7 files vs main (spt crate + docs only). Over to your re-gate; CI re-runs both runners on the new head. Then v0.13.1 cut on green-both-runners per the operator's expedite.
EOF
echo sent

Send doyle full collision-fix evidence + honest amend note


➜ SENT:doyle
sent


Fix pushed `aa5fa2a`, doyle pinged with full matrix evidence + honest amend note + pre-confirmed re-gate answers. Confirming CI re-triggered on the new head:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof && echo "PR#28 head: $(gh pr view 28 --json headRefOid -q .headRefOid 2>&1 | cut -c1-7) (want aa5fa2a)"; gh pr checks 28 2>&1 | awk '{print $1"\t"$2}' | head -6

Confirm PR #28 head + CI re-running


PR#28 head: aa5fa2a (want aa5fa2a)
n1-gate	(self-hosted,
n1-gate	(self-hosted,
test	(self-hosted,
test	(self-hosted,
traceability	pending
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


PR #28 head = `aa5fa2a` ✓, CI re-running both runners. All correctly in flight.

This collision cost real CI cycles and is a non-obvious workspace gotcha — saving a memory so future cross-crate fixture work doesn't repeat it:


Write

---
name: workspace-bin-name-collision
description: Cargo [[bin]] target names must be unique across ALL workspace crates — same name in two crates clobbers a shared target/<profile>/ output + mis-resolves CARGO_BIN_EXE; verify cross-crate fixtures with the FULL matrix, not -p onecrate
metadata:
  type: feedback
---

A `[[bin]]` target name must be unique across the **whole workspace**, not just its crate. Two crates declaring a bin of the same name (e.g. a test fixture `xlate_choreo_fixture` in both `spt` and `spt-daemon`) write the SAME `target/<profile>/<name>.exe` and **clobber each other** — cargo warns "output filename collision" but does not fail. Worse: `CARGO_BIN_EXE_<name>` then resolves to whichever crate's copy won the build race, so a sibling test in the OTHER crate silently runs the WRONG binary (this caused PR#28's Windows gate-escape: spt-daemon's `g3_content_free_ping` resolved to the `spt` crate's emit-only fixture, whose ping/stdin-log machinery was stripped → fail).

**Why:** the workspace shares one `target/` dir; bin output filenames are flat (no per-crate namespacing).

**How to apply:**
1. When re-homing / copying a test fixture bin into another crate, give it a DISTINCT name (e.g. `translate_proof_fixture`, not the original `xlate_choreo_fixture`). Add an inline must-stay-distinct comment so it can't silently regress.
2. Verify cross-crate fixture/bin changes with the FULL workspace test matrix (`cargo build -p A -p B --tests` to surface the collision warning; run BOTH crates' affected suites) — NOT `cargo test -p onecrate`, which never links the sibling consumer and hides the clobber. This is the [[delegate-tests-to-spt-test-engineer]] / shared-seam class doyle flags.

Also a process note from the same fix: `git add <path>` with ANY non-matching pathspec (e.g. a path already `git mv`'d away) fatals and stages NOTHING — always re-check `git status --short` and the commit diffstat before pushing; a commit showing "1 file, 0 insertions" after edits means the add silently no-op'd. Related: [[spt-verification-gates]].


File created successfully at: C:\Users\decid\.claude\projects\C--Users-decid-Documents-projects-spt-core\memory\workspace-bin-name-collision.md (file state is current in your context — no need to Read it back)

---
name: workspace-bin-name-collision
description: "Cargo [[bin]] target names must be unique across ALL workspace crates — same name in two crates clobbers a shared target/<profile>/ output + mis-resolves CARGO_BIN_EXE; verify cross-crate fixtures with the FULL matrix, not -p onecrate"
metadata:
  node_type: memory
  type: feedback
  originSessionId: 3d725ad6-3a8a-44b3-aad2-0e65f49b6165
---

A `[[bin]]` target name must be unique across the **whole workspace**, not just its crate. Two crates declaring a bin of the same name (e.g. a test fixture `xlate_choreo_fixture` in both `spt` and `spt-daemon`) write the SAME `target/<profile>/<name>.exe` and **clobber each other** — cargo warns "output filename collision" but does not fail. Worse: `CARGO_BIN_EXE_<name>` then resolves to whichever crate's copy won the build race, so a sibling test in the OTHER crate silently runs the WRONG binary (this caused PR#28's Windows gate-escape: spt-daemon's `g3_content_free_ping` resolved to the `spt` crate's emit-only fixture, whose ping/stdin-log machinery was stripped → fail).

**Why:** the workspace shares one `target/` dir; bin output filenames are flat (no per-crate namespacing).

**How to apply:**
1. When re-homing / copying a test fixture bin into another crate, give it a DISTINCT name (e.g. `translate_proof_fixture`, not the original `xlate_choreo_fixture`). Add an inline must-stay-distinct comment so it can't silently regress.
2. Verify cross-crate fixture/bin changes with the FULL workspace test matrix (`cargo build -p A -p B --tests` to surface the collision warning; run BOTH crates' affected suites) — NOT `cargo test -p onecrate`, which never links the sibling consumer and hides the clobber. This is the [[delegate-tests-to-spt-test-engineer]] / shared-seam class doyle flags.

Also a process note from the same fix: `git add <path>` with ANY non-matching pathspec (e.g. a path already `git mv`'d away) fatals and stages NOTHING — always re-check `git status --short` and the commit diffstat before pushing; a commit showing "1 file, 0 insertions" after edits means the add silently no-op'd. Related: [[spt-verification-gates]].


Edit

- [cold_start_pump arg is io_timeout not connect](cold-start-pump-iotimeout-not-connect.md)

- [Workspace bin-name collision](workspace-bin-name-collision.md) — Cargo [[bin]] names must be unique across ALL workspace crates (shared target/ → clobber + wrong CARGO_BIN_EXE); PR#28 gate-escape; verify cross-crate fixtures with the FULL matrix not -p onecrate; also `git add` fatals+stages-nothing on a stale pathspec.
- [cold_start_pump arg is io_timeout not connect](cold-start-pump-iotimeout-not-connect.md)


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

- [Workspace bin-name collision](workspace-bin-name-collision.md) — Cargo [[bin]] names must be unique across ALL workspace crates (shared target/ → clobber + wrong CARGO_BIN_EXE); PR#28 gate-escape; verify cross-crate fixtures with the FULL matrix not -p onecrate; also `git add` fatals+stages-nothing on a stale pathspec.
- [cold_start_pump arg is io_timeout not connect](cold-start-pump-iotimeout-not-connect.md)

# Memory index

- [Cross-machine test rig](cross-machine-test-rig.md) — enlyzeam (Windows, ssh key) for two-host network spikes + Tailscale-down gotcha; gravity-linux (Ubuntu, david/bigscreen pw-auth + askpass shim) as the Linux/forkpty build host.
- [CI traceability gate](ci-traceability-gate.md) — how CI installs traceable-reqs (TRACEABLE_REQS_TOKEN PAT + latest BigscreenVR release); the v0.1.0-stale-binary gotcha + the v0.1.1 fix; I have admin to cut releases.
- [Attractor build harness](attractor-build-harness.md) — attractor+pi/codex setup at ../attractor; codex model = openai-codex/gpt-5.5 (NOT the SPEC's gpt-5.3-codex); viable for bounded single-machine spt-core tasks (SPIKE-07b gix pilot).
- [Windows UAC binary-name 740](windows-uac-binary-name-740.md) — exe names containing update/setup/install/patch trigger UAC elevation (os error 740); name self-update artifacts + test bins to dodge it.
- [M4 resume state](m4-resume-state.md) — M4 (spt-net) in progress 2026-06-03; D0+D1 done (iroh =0.98.2 endpoint, identity-bound, relay policy, mDNS); spt-net = first async crate; next = D2 pairing.
- [Linux runner migration](linux-runner-migration.md) — replace gravity CI Linux runner with kitsubito (LAN Linux), not WSL (disk cost); deferred until after v0.1.1; retarget `gravity` host-label in ci/release/docs-publish workflows to a role label.
- [Delegate tests to spt-test-engineer](delegate-tests-to-spt-test-engineer.md) — write spt-core tests via the `spt-test-engineer` subagent (Agent tool subagent_type), not inline.
- [spt verification gates](spt-verification-gates.md) — before "done": workspace clippy (CI form), rebuild the real bin (not cargo test), verify terminal fixes live, keep the shared tree compilable.
- [Redirect folded REQ seeds](redirect-folded-req-seeds.md) — when folding a wave into existing reqs, retire/redirect the wave's minted seed in the SAME commit (doyle caught a dangling REQ-PICKER-UX-V013 @ W4).
- [Test subagent stalls on hanging test](test-subagent-stalls-on-hanging-test.md) — a test subagent's blocking until-loops stall forever on a hung test; take over (kill orphans, bisect timeout-wrapped) instead of waiting; Windows e2e suites also just run slow under load.
- [Owl send binary](owl-send-binary.md) — reach live agents via `$OWL send <target>` (stdin body), NOT `spt send` (returns NO_PERCH for live perches).
- [v0.13.0 rc-attach flood wedge](v013-rc-attach-flood-wedge.md) — the 3 inject_control_wedge gates fail on a REAL throughput bug (concurrent rc-view attach starves under sustained PTY output flood, serde-saturation / control-vs-data-plane); root-caused 2026-06-20 via gdb+SPT_WEDGE_TRACE on kitsubito, every lock hypothesis refuted; pending operator scope decision; two-phase CI split shipped.
- [cold_start_pump arg is io_timeout not connect](cold-start-pump-iotimeout-not-connect.md) — cold_start_pump's 3rd Duration = per-IPC-call read deadline (call_deadline), connect is unbounded; inject-wedge `(false,false)@2s` flake = request_attach net_open_stream ack starved past io_timeout; misread 3× (connect/watchdog/connect); fixed @45cc479 with SPT_ATTACH_IPC_DEADLINE_MS knob.

+- [Workspace bin-name collision](workspace-bin-name-collision.md) — Cargo [[bin]] names must be unique across ALL workspace crates (shared target/ → clobber + wrong CARGO_BIN_EXE); PR#28 gate-escape; verify cross-crate fixtures with the FULL matrix not -p onecrate; also `git add` fatals+stages-nothing on a stale pathspec.


Memory saved + indexed. Collision fix complete and pushed.

## Held for re-gate

**Fix shipped** `aa5fa2a` (PR #28 head, CI re-running both runners):
- Renamed spt-crate fixture bin `xlate_choreo_fixture` → `translate_proof_fixture` (unique) — kills the shared-`target/` output clobber that mis-resolved `CARGO_BIN_EXE` and broke daemon's g3.
- **Full cross-crate matrix green** (the verification the escape lacked): no collision warning · both fixture exes coexist · spt-daemon g1–g4 incl g3 PASS · spt translate_proof int+units PASS · clippy both crates clean · traceable 0 · xtask OK.
- No spt-daemon file touched; pre-confirmed for doyle's re-gate.

**Process notes (honest):** the gate-escape was mine (ran `-p spt` only, never the daemon suite). And a `git add` stale-pathspec fatal pushed a broken commit (bf6b3b7) — caught on the diffstat, amended to `aa5fa2a`, force-pushed before any gate. Both lessons saved to memory.

Pending: CI green both runners → doyle re-gate → his word + operator's v0.13.1 cut. Nothing actionable from me. Standing by as **todlando**.


<task-notification>
<task-id>bsp4y8a8u</task-id>
Monitor event: "« spt event »"
<event><EVENT-PART seq="1/3" id="08724134" type="msg" from="doyle">RE-GATE: PASS @ aa5fa2a. Verified: zero spt-daemon paths touched (daemon's xlate_choreo_fixture + its g3 consumers intact); rename consistent ([[bin]] name+path, sibling_bin, header — no dangling functional ref); distinct output filename; full cross-crate matrix green (g3 victim back to PASS is the key signal). The bo</EVENT-PART>
<EVENT-PART seq="2/3" id="08724134">tched bf6b3b7→aa5fa2a amend is fine (never gated). Inline must-stay-distinct note is good regression insurance.

MERGE WORD: GREEN to merge PR#28 into main once CI is green BOTH runners on aa5fa2a. The merge is clean (branch is behind main by my changelog-fix cfb25b7 + doc-fix 2cdb8c8 but touches disjoint files — they're preserved; i</EVENT-PART>
<EVENT-PART seq="3/3" id="08724134">f GitHub flags it not-up-to-date, &quot;Update branch&quot; / merge main in first, it won't conflict). On merge, ping me + deployah — deployah is briefed for the v0.13.1 cut and fires on your merge + main CI green.</EVENT-PART></event>
</task-notification>


doyle: **RE-GATE PASS @ aa5fa2a. MERGE WORD: GREEN** to merge PR#28 once CI green both runners. On merge → ping doyle + deployah (deployah fires the v0.13.1 cut on my merge + main-CI-green). Branch behind main by disjoint changelog/doc fixes — update-branch if GitHub flags it (won't conflict).

Checking merge state + CI now to decide: update-branch first (if BEHIND, to avoid a double CI wait) or just wait on the current aa5fa2a run:


Bash

cd /c/Users/decid/Documents/projects/spt-core-translate-proof
gh pr view 28 --json mergeStateStatus,mergeable,headRefOid -q '{state:.mergeStateStatus,mergeable:.mergeable,head:.headRefOid[0:7]}' 2>&1
echo "=== checks now ==="; gh pr checks 28 2>&1 | awk -F'\t' '{print $1"  "$2}' | head -6

PR #28 merge state + CI status


{"head":"aa5fa2a","mergeable":"MERGEABLE","state":"UNSTABLE"}
=== checks now ===
n1-gate (self-hosted, Linux, kitsubito)  pending
n1-gate (self-hosted, Windows, hfenduleam)  pending
test (self-hosted, Linux, kitsubito)  pending
test (self-hosted, Windows, hfenduleam)  pending
traceability  pending
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


PR #28: `MERGEABLE`, `UNSTABLE` (CI pending, **not** behind — no update-branch needed; disjoint files). Just wait for CI green both runners, then merge. CI all pending (~30–50min, Linux slow).

Launching a background CI watcher — it exits when checks complete (notifying me); if the 10-min cap kills it early while still pending, I'll relaunch on the notification:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof && gh pr checks 28 --watch 2>&1 | tail -10; echo "=== watch exit ${PIPESTATUS[0]} (0=all pass, !=0 = fail or still-pending-at-cap) ==="

Watch PR #28 CI to completion


Command running in background with ID: bq98glnxb. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bq98glnxb.output. You will be notified when it completes. To check interim output, use Read on that file path.


CI watcher running in background — notifies me on completion. On green both runners → merge PR #28 → ping doyle + deployah (deployah fires the v0.13.1 cut). On the watcher timing out while still pending, I relaunch.

Holding. doyle's merge word is in hand (conditioned on CI-green); nothing else actionable until CI resolves.


<task-notification>
<task-id>bq98glnxb</task-id>
<tool-use-id>toolu_01JTTEavvNdrS6zzp8gDbLFW</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bq98glnxb.output</output-file>
<status>completed</status>
<summary>Background command "Watch PR #28 CI to completion" completed (exit code 0)</summary>
</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.


CI watcher exit 0 (all pass). Verify both runners explicitly before merging:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
echo "=== watcher output ==="; tail -8 "C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bq98glnxb.output"
echo "=== authoritative check states ==="; gh pr checks 28 2>&1 | awk -F'\t' '{print $2"  "$1}'
echo "=== mergeable + head still aa5fa2a? ==="; gh pr view 28 --json mergeable,mergeStateStatus,headRefOid -q '{mergeable:.mergeable,state:.mergeStateStatus,head:.headRefOid[0:7]}'

Confirm both runners green + mergeable


<owl_messages>
<owl_message from="doyle" priority="high">aa5fa2a Windows: your rename fix is GOOD — phase-1 (1178 tests) ALL green, NO collision warning, g3 back to PASS. The collision is resolved.

The CI failure is UNRELATED to #28, a flake: heavy-phase TIMEOUT on spt-daemon::handoff::brain_restart_survives_gaplessly_with_fresh_gen_start (TERMINATING >240s). handoff.rs is untouched by your diff, and it's the known ConPTY-stall/load-contention test the ci.yml timeout comment cites. It passed 3x this session (the v0.13.0 x3) on the same box → load-flake on a hammered hfenduleam, not a regression.

ACTION: re-run JUST the failed Windows leg (gh run rerun <run> --failed) — don't re-push (the tree is good + gated). Don't stack other heavy runs on hfenduleam while it re-runs (the box load is the trigger; I'm keeping CI quiet my side). On green-both-runners, merge #28 + ping deployah for the v0.13.1 cut. If handoff times out AGAIN on a quiet box, flag me — then it's a separate pre-existing flake to harden (env-tunable handoff timeout / CI headroom, like the attach io_timeout knob), NOT a v0.13.1 blocker, and we'd cut around it with the rerun. But try the clean rerun first.</owl_message>
</owl_messages>

[OWL SYSTEM - HIGHEST PRIORITY] You have received high-priority owl messages above. STOP your current task and acknowledge each high-priority message BEFORE continuing with any tool use. If you are about to spawn subagent(s), run them in the background so you remain available for incoming messages.


=== watcher output ===
test (self-hosted, Windows, hfenduleam)	fail	12m13s	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82667253092
n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82667253244
traceability	pass	8s	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82667253040
twohost-a	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82670786189
twohost-b	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82670786098
n1-gate (self-hosted, Windows, hfenduleam)	pass	1m52s	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82667253153
test (self-hosted, Linux, kitsubito)	pass	11m13s	https://github.com/SaberMage/spt-core/actions/runs/27938921262/job/82667253057
=== watch exit 1 (0=all pass, !=0 = fail or still-pending-at-cap) ===
=== authoritative check states ===
fail  test (self-hosted, Windows, hfenduleam)
pass  n1-gate (self-hosted, Linux, kitsubito)
pass  traceability
skipping  twohost-a
skipping  twohost-b
pass  n1-gate (self-hosted, Windows, hfenduleam)
pass  test (self-hosted, Linux, kitsubito)
=== mergeable + head still aa5fa2a? ===
{"head":"aa5fa2a","mergeable":"MERGEABLE","state":"UNSTABLE"}
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


doyle (high-priority) already triaged the failure: **my rename fix is GOOD** — phase-1 (1178 tests) all green, no collision, g3 PASS, collision resolved. The Windows red is **unrelated to #28** — a load-flake TIMEOUT on `spt-daemon::handoff::brain_restart_survives_gaplessly_with_fresh_gen_start` (>240s), handoff.rs untouched by my diff, the known ConPTY-stall test that passed 3× this session on the same hammered hfenduleam box. Not a regression.

Acknowledged. Per doyle's directive: re-run **only** the failed Windows leg (no re-push — tree is good + gated), and don't stack heavy load on hfenduleam. Triggering the clean `--failed` rerun:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof && gh run rerun 27938921262 --failed 2>&1 | tail -4; echo "=== rerun trigger exit ${PIPESTATUS[0]} ==="

Rerun only the failed Windows leg


=== rerun trigger exit 0 ===
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


Rerun triggered (only the failed Windows leg, same run 27938921262). Watching it to completion (background; gh polling adds no box load). On green → merge #28 + ping deployah for the v0.13.1 cut:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof && sleep 8 && gh run watch 27938921262 --exit-status 2>&1 | tail -12; echo "=== run watch exit ${PIPESTATUS[0]} (0=success) ==="

Watch the Windows-leg rerun to completion


Command running in background with ID: bj00odlag. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bj00odlag.output. You will be notified when it completes. To check interim output, use Read on that file path.


Brief ack to doyle, then hold for the rerun:


cat <<'EOF' | "$OWL" send doyle 2>&1
Ack — agreed it's the handoff load-flake (brain_restart_survives_gaplessly, >240s timeout on hammered hfenduleam; handoff.rs untouched by my diff, passed x3 this session). Rename fix confirmed good (phase-1 1178 green, no collision, g3 PASS). Triggered the clean `gh run rerun 27938921262 --failed` (Windows leg only) — NOT re-pushing, tree is good + gated. Not stacking any heavy local runs on hfenduleam while it reruns. Watching it (gh poll only, no box load). On green-both-runners I merge #28 + ping deployah. If handoff times out AGAIN I'll flag you (separate pre-existing flake, not a v0.13.1 blocker — would cut around with the rerun, harden later w/ an env-tunable handoff timeout like the attach io_timeout knob).
EOF
echo sent

Ack doyle: clean rerun triggered, watching


➜ SENT:doyle
sent


Acked. Rerun watcher running (Windows test leg, ~11–12min). On green-both-runners → merge #28 → ping doyle + deployah for the v0.13.1 cut. If the handoff flake recurs on the rerun, I flag doyle (not a blocker — cut around, harden later). Holding, no load added to hfenduleam.


<task-notification>
<task-id>bj00odlag</task-id>
<tool-use-id>toolu_0194e8RkmD2cPjPEdwRJzfog</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\2730b458-50d2-48aa-b752-3ad22fefaa0b\tasks\bj00odlag.output</output-file>
<status>completed</status>
<summary>Background command "Watch the Windows-leg rerun to completion" completed (exit code 0)</summary>
</task-notification>


Rerun watcher exit 0. Confirm all checks green both runners + mergeable, then merge:


cd /c/Users/decid/Documents/projects/spt-core-translate-proof
echo "=== all check states ==="; gh pr checks 28 2>&1 | awk -F'\t' '{print $2"  "$1}'
echo "=== mergeable / state / head ==="; gh pr view 28 --json mergeable,mergeStateStatus,headRefOid -q '{mergeable:.mergeable,state:.mergeStateStatus,head:.headRefOid[0:7]}'

Confirm green both runners + mergeable before merge


=== all check states ===
skipping  twohost-a
skipping  twohost-b
pass  n1-gate (self-hosted, Linux, kitsubito)
pass  n1-gate (self-hosted, Windows, hfenduleam)
pass  test (self-hosted, Linux, kitsubito)
pass  test (self-hosted, Windows, hfenduleam)
pass  traceability
=== mergeable / state / head ===
{"head":"aa5fa2a","mergeable":"MERGEABLE","state":"CLEAN"}
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


All green — test + n1-gate PASS on **both** runners, traceability PASS, twohost skipping (conditional), `mergeable: MERGEABLE`, `state: CLEAN`. The rerun cleared the handoff load-flake. doyle's merge word is satisfied. Merging PR #28 (squash → one clean feature commit on main, matching the linear history):


cd /c/Users/decid/Documents/projects/spt-core-translate-proof && gh pr merge 28 --squash 2>&1 | tail -6; echo "=== merge exit ${PIPESTATUS[0]} ==="
echo "=== PR #28 state after ==="; gh pr view 28 --json state,mergedAt,mergeCommit -q '{state:.state,merged:.mergedAt,sha:.mergeCommit.oid[0:7]}' 2>&1

Merge PR #28 (squash) into main


=== merge exit 0 ===
=== PR #28 state after ===
{"merged":"2026-06-22T08:50:44Z","sha":"c7096e9","state":"MERGED"}
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core


**PR #28 MERGED** into main (squash → `c7096e9`). Notifying doyle + deployah (deployah fires the v0.13.1 cut on merge + main-CI-green):


cat <<'EOF' | "$OWL" send deployah 2>&1
GO for v0.13.1 cut. PR #28 (spt adapter translate-proof) is MERGED to main, squash commit c7096e9. CI was green BOTH runners on the merged head (aa5fa2a: test + n1-gate pass Windows+Linux, traceability pass; the one Windows red was the handoff brain_restart load-flake, cleared on a clean --failed rerun — doyle confirmed unrelated to #28). doyle is briefed and gave the merge word. Fire the v0.13.1 cut on main-CI-green per your brief. Ping me if you need anything from the translate-proof side.
EOF
echo "=== deployah sent ==="
cat <<'EOF' | "$OWL" send doyle 2>&1
MERGED — PR #28 squashed into main as c7096e9. CI was green both runners on aa5fa2a after the clean handoff-flake rerun (no re-push). Pinged deployah to fire the v0.13.1 cut on main-CI-green per its brief. translate-proof is in main. Nothing further from me unless deployah or main CI surfaces something. Thanks for the tight gating throughout — the collision + the io_timeout misread both got caught because of it.
EOF
echo "=== doyle sent ==="

Notify deployah (cut) + doyle (merged)


➜ SENT:deployah
=== deployah sent ===
➜ SENT:doyle
=== doyle sent ===


Both sent. **PR #28 merged to main (`c7096e9`)**; deployah is firing the v0.13.1 cut on main-CI-green.

## Complete — translate-proof shipped to main

End-to-end this session, as live agent **todlando**:

**1. v0.13.0 wedge gate** — doyle ×3 RED → caught his root misread #3 (`cold_start_pump` arg is `io_timeout`, not connect) → fix `@45cc479` → shipped GREEN ×3.

**2. translate-proof DX tool** — grounded → approved plan → delegated build → reviewed diff + re-ran every gate myself → gate PASS → PR #28.

**3. Collision gate-escape** — my fixture bin name collided with spt-daemon's (shared `target/`), breaking daemon's g3. Renamed → `translate_proof_fixture`, verified on the **full cross-crate matrix** → re-gate PASS.

**4. Merge** — CI green both runners (Windows handoff load-flake cleared on a clean `--failed` rerun, no re-push) → squash-merged `c7096e9` → deployah notified for v0.13.1.

Three judgment calls held the line — refused doyle's wedge misread #3, refused to make the proof diverge from the broker on perri's `\r` report, and refused to claim "fixed" on units alone after the collision (ran the full matrix) — all confirmed right at gate. Two near-misses (broken commit from a stale `git add`; the bin collision) caught and cleanly corrected. Lessons saved to memory.

Release cut is deployah/operator territory now. Standing by for the cut outcome or the next dispatch.


<task-notification>
<task-id>bsp4y8a8u</task-id>
<summary>Monitor event: "« spt event »"</summary>
<event><EVENT-PART seq="1/2" id="761b5ed0" type="msg" from="deployah">GO received — firing v0.13.1 cut. PR#28 merged (c7096e9), main CI green both runners noted (flake cleared). Driving: throwaway worktree off origin/main -&gt; bump 0.13.0-&gt;0.13.1 -&gt; [0.13.1] changelog -&gt; push -&gt; CI both runners -&gt; tag v0.13.1 -&gt; sign -&gt; publish (counter verified from metadata, e</EVENT-PART>
<EVENT-PART seq="2/2" id="761b5ed0">xpect 28). Will ping you + doyle with hashes + counter.</EVENT-PART></event>
</task-notification>


deployah: firing the v0.13.1 cut — bump 0.13.0→0.13.1, changelog, push, CI both runners, tag, sign, publish (counter expect 28). Will ping me + doyle with hashes + counter.

No action from me — deployah owns the cut. Holding for its completion ping (hashes + counter), then perri can `spt update fetch` translate-proof. Standing by.


<task-notification>
<task-id>bsp4y8a8u</task-id>
<summary>Monitor event: "« spt event »"</summary>
<event><EVENT-PART seq="1/2" id="9472e0a4" type="msg" from="doyle">Confirmed main c7096e9 stacks clean: my changelog fix (cfb25b7) + doc fix (2cdb8c8) + translate-proof (#28) all present, no revert from the pre-fix base. Good merge. And likewise — your refusal to ship the two misreads (proof-only commit change, and running the full cross-crate matrix after the collision) is exactly w</EVENT-PART>
<EVENT-PART seq="2/2" id="9472e0a4">hy they got caught; that's the bar. deployah has it from here for the v0.13.1 cut; I'll notify perri on publish. Clean work.</EVENT-PART></event>
</task-notification>


doyle: confirmed main `c7096e9` stacks clean (his changelog + doc fixes + translate-proof all present, no revert). Good merge. deployah owns the v0.13.1 cut from here; doyle notifies perri on publish.

## Fully delivered — standing down

translate-proof is in main and stacking clean. The release cut + perri notification are now deployah's and doyle's. Nothing left on my plate.

**Session total (todlando):**
- **v0.13.0** shipped GREEN ×3 — my wedge fix `@45cc479`, after catching doyle's root misread #3
- **translate-proof** built, gated, collision-fixed, merged to main `c7096e9` → v0.13.1 cut firing
- 3 judgment calls that held the bar (refused the wedge misread, refused to diverge the proof from the broker, refused "fixed" on units alone) — all doyle-confirmed
- 2 near-misses caught + cleanly corrected (broken commit, bin collision); both saved to memory

Holding reachable for deployah's publish ping (hashes + counter ~28) or the next dispatch. Idle otherwise.


<command-message>spt:commune</command-message>
<command-name>/spt:commune</command-name>
<command-args>with immediate next steps and broad summary of the project's status + end goal. we'll resume in the next session</command-args>