{
  "summary": "Reuse the real CLI launch/adapter fixtures, but replace their one-hit/unlabelled-output oracle with a persistent numbered-input/independent-heartbeat child and continuous capture. Piped Windows rc input exercises the actual byte-reader path; an outer ConPTY is needed separately for the interactive crossterm path. attach_idempotent_replay explicitly remains mutation-green and cannot establish real-rc continuity. Production daemon transport and elevated firewall auto-repair prevent treating a temporary SPT_HOME as network isolation.",
  "files": [
    {
      "path": ".worktrees/hertz-304/crates/spt/tests/rc_attach_truth.rs",
      "description": "Lines 87–175: adapter registration, real daemon spawn, scoped teardown; 224–280: single-heartbeat rc capture that must be replaced for continuity."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt/tests/twohost_cli.rs",
      "description": "DaemonGuard/start/stop/drop around 247–345; spawn_ticker 552–583; final B-3 rung around 1340–1457 supplies persistent real-rc stdout capture but only proves unnumbered tick/banner/tick."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-daemon/tests/attach_idempotent_replay.rs",
      "description": "Header explicitly documents mutation-green status; test 242–339 drives raw Brain subscriptions/effects, not rc or serve_attach."
    },
    {
      "path": ".worktrees/hertz-304/adapters/mock/src/main.rs",
      "description": "Dummy/hold-unbound modes 118–235 bind optionally and emit numbered heartbeats, but never read interactive stdin or journal effects."
    },
    {
      "path": ".worktrees/hertz-304/adapters/mock/src/console_mode_probe.rs",
      "description": "Lines 69–129 demonstrate byte-based CR/LF input framing under Windows raw console; optional raw mode and intentional echo re-enabling provide apparatus precedent."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt/src/rc.rs",
      "description": "1398–1445 choose interactive Windows events versus piped raw bytes; 2874–3200 pump input, deduplicate attach output, render bytes, and detach on input-channel disconnect."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-term/src/pty.rs",
      "description": "PtySession native ConPTY wrapper with spawn_program_in_env, take_reader, try_wait, kill and SessionSurface input APIs."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt/tests/common/mod.rs",
      "description": "output_bounded 195–250; sibling_bin/fixture_package 253–273; no_window 276–290. Useful launch conventions, not a complete hard-bounded persistent supervisor."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt/tests/common/reap.rs",
      "description": "observe, authenticated_kill, target_gone and population_sweep implement identity/image/ancestry-aware cleanup."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-test-support/src/lib.rs",
      "description": "TestHome owns/restores SPT_HOME under the shared environment lock; converge_within reports elapsed time/sample count/last observed state."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-daemon/src/daemon.rs",
      "description": "try_start_net 528–568 always assembles production All-interface + mDNS transport and invokes firewall verification."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-daemon/src/firewall.rs",
      "description": "Install reconcile obeys SPT_INSTALL_NO_FIREWALL at 273; daemon verify 614–627 does not check that gate and may repair the product rule when elevated."
    },
    {
      "path": ".worktrees/hertz-304/crates/spt-daemon/src/attach.rs",
      "description": "serve_attach 449 onward is the missing real stream worker layer; request_attach_endpoint and send_attach_input provide protocol-level supplementary rig APIs."
    }
  ],
  "architecture": "Real endpoint start → manifest harness command → broker-hosted child PTY → serve_attach → actual persistent spt rc → captured terminal bytes. Input must traverse the same rc in reverse. The child-owned effects journal is an independent authority; numbered PTY messages measure delivery/progress, not exactly-once execution. A separate outer ConPTY around rc adds the Windows interactive-input/rendering layer.",
  "report": "## Implementation recipe (proposal, not executed)\n\nAll references are under `.worktrees/hertz-304`. No edits, builds, tests, fixtures, process launches, or issue research were performed. Prior source-map index was read. Nothing here proves a root cause for #302/#49/#267.\n\n### 1. Reuse the fixture shell, replace the observation core\n\nReuse `rc_attach_truth.rs::register_raw_harness`/`register_harness`, `run_start`, and the real `spt daemon run` readiness pattern; reuse the `twohost_cli.rs::DaemonGuard` ownership shape rather than its entire multi-rung two-host suite. Prefer `spt_test_support::TestHome` over copying the fixtures' file-local environment locks/manual `set_var`: it restores the prior home and coordinates the shared process-global lease. Set TEMP/TMP/TMPDIR in the externally owned sandbox; TestHome deliberately does not set them.\n\nReplace `rc_attach_capture`: its reader stops at the first `DUMMY_HARNESS_TICK`, returns one observation, and kills rc. This cannot measure continuity. Borrow B-3's continuous stdout reader, but retain one rc child and one writable stdin handle for the entire baseline/trigger/recovery sequence. Capture raw bytes continuously to a rig-owned file plus a bounded parser buffer; timestamp progress and byte offsets. Drain stderr continuously or use a file, never B-3's undrained `stderr(Stdio::piped())`. Keep daemon stderr as files and collect `common::daemon_stderr_panel`, which knows about post-redirect daemon evidence.\n\n### 2. Actual Windows rc stdin: two distinct coverage cells\n\n* **Piped primary cell:** `Command::new(spt).args([\"rc\", target])`, temp SPT_HOME, piped stdin/stdout, file stderr, `CommandNoWindowExt::no_window()`. Write and flush framed ASCII input ending in CR. Retain stdin until intentional detach. `rc.rs:1405–1445` dispatches non-terminal Windows stdin to `spawn_stdin_reader_bytes`; `3086–3094` forwards it through `send_attach_input` and detaches when the reader channel disconnects. Therefore the B-3 comment saying EOF is not detach is not a safe contract.\n* **Interactive Windows cell:** launch the same real rc under `spt_term::PtySession::spawn_program_in_env`, sized `SurfaceSize`, and use `SessionSurface::write_input`, `take_reader`, `try_wait`, `kill`. `spt-term` publicly reexports these plus `CommandBuilder`. This exercises Windows console/crossterm input (`rc.rs:1408–1411`, `1456+`), not the piped byte fallback. No existing outer-ConPTY rc fixture was found in spt/tests; the reusable mechanism is in spt-term. The extra pseudoconsole adds a second renderer and must have its own vehicle control. Do not describe piped success as interactive-console success.\n\n### 3. Supply a real bidirectional child, not cat/findstr/tick\n\nMinimum fixture extension belongs in the existing `mock-adapter` / `mock-session` facilities in the separately allocated W3 tree. Existing `dummy`/`hold-unbound` code (`main.rs:118–235`) already handles the manifest bind, ready marker, optional resume marker, and numbered heartbeat. It does not consume stdin. Preserve that launch/bind contract and add a fixture-only continuity mode with:\n\n* a fresh run/child-incarnation identifier;\n* input frames such as `IN <run> <n> <nonce>\\r`;\n* transformed child replies such as `ACK <run> <incarnation> <n> <digest(nonce)>`, never the literal input text;\n* independent timer-driven `HB <run> <incarnation> <h>` messages, not advanced by input;\n* one child-owned append-only effects journal recording every accepted complete input occurrence, including duplicates, before emitting ACK; flush each entry;\n* a child birth/readiness record and explicit shutdown record where possible.\n\nUse byte accumulation and CR/LF framing from `console_mode_probe.rs:86–120`, not `read_line` under raw Windows console mode. Serialize heartbeat/ACK writes so records cannot interleave, keep records narrow enough to avoid deliberate wrapping, and flush them. No shell is needed. Do not deduplicate commands inside the fixture: that would conceal product double application.\n\n### 4. Separate execution, delivery, and repaint oracles\n\nThe journal count of `(run, input_n)` is the exactly-once child-effect oracle. Count occurrences, not just unique keys. ACK occurrences in terminal capture are a different metric: multiple appearances with one journal entry mean output replay/repaint duplication, not duplicate execution. Missing journal entries mean input did not reach/complete at the child; one journal entry but missing fresh ACK means an output-path failure. Fresh increasing HB values with stalled ACKs distinguish one-way progress from total output loss.\n\nRetain raw bytes, but parse a stateful terminal presentation stream when ConPTY cursor movement fragments records. Merely stripping ANSI or counting substrings is insufficient: `spt-term/src/lib.rs:18–24` explicitly documents screen-buffer repaint/reordering/duplication on Windows. `rc.rs:2915–2918,3128–3144` also deduplicates attach Output sequence numbers; visible bytes are not raw broker replay evidence. A ScreenGrid presentation view can supplement capture, but a final screen alone can lose scrolled evidence and is not the effects authority.\n\nSend newly minted numbered probes before, throughout, and after the trigger, using the same rc. Record input submission time, child receipt, first fresh ACK visibility, and independent HB high-watermark. After the trigger require multiple new ACK/HB advances beyond the pre-trigger watermarks. Never accept process survival, byte growth, an old tick, or a reconnect banner as continuity. If a stop/start intentionally creates another child, classify it as restoration with a new incarnation, not same-child survival. B-3 explicitly respawns its ticker and its unnumbered `tick` after a banner can be historical replay.\n\n### 5. Mutation-green replacement boundary\n\n`attach_idempotent_replay.rs:32–57` explicitly says disabling the same-conn discriminator still passes: Brain filters resynthesized history and the replacement writer remains usable to this raw broker client. Its input uses another Brain's `send_effect`, not rc stdin. The post-replay assertion naming the ORIGINAL writer is stronger than its observation.\n\nRetain it only as the documented low-level non-regression guard. Do not promote it by adding longer waits or more cat echoes. The replacement integration boundary must include the production dispatcher/`serve_attach` worker plus actual rc and transformed child input, with continuous output. `attach.rs::serve_attach` subscribes the receiving connection and creates a separate forwarding `wire` connection (`449–479`); its seeded opener and subsequent wire Request can both run the subscribe path (`436–442`, `505+`). A supplementary deterministic worker-level rig can use `request_attach_endpoint`/`send_attach_input`; it is not a substitute for the actual CLI cell. A fresh independent Brain repeating a subscribe is not necessarily the same serve-worker connection. Require breadcrumbs naming the exercised connection/session/generation/floor and trigger, rather than assuming a refresh exercised the same-connection discriminator. Keep the existing broker unit identity/epoch matrix as the source's stated mutation-discriminating evidence; a new real-rc mutation result remains to be earned in W3.\n\n### 6. Discriminating apparatus control\n\nUse a fixture-only negative-control interval in which the child remains alive and continues emitting fresh numbered heartbeats but deliberately stops consuming input. Send fresh numbered rc commands during that interval. The harness must fail the ACK/effect-progress budget even though PID, stdout bytes, and HB high-watermark continue advancing. This directly rejects the old ticker/process-survival false positive. Separately, replay an already emitted ACK without adding a journal entry: report a delivery duplicate, not a duplicate effect. These controls concern the apparatus, not product/root-cause mutation claims.\n\n### 7. Supervision, budgets, dependencies, and isolation\n\nEvery proposed stage needs an absolute wall deadline plus last-progress evidence: startup (existing fixtures use 30/60s), each ACK window (existing raw attach uses 10s), trigger/recovery (explicit trigger-derived budget), and teardown. Log elapsed time, last input/ACK/HB, child incarnation, rc exit state, stderr tail, and journal tail on failure. `converge_within` is the reusable reporting shape. Continuous HB means `drain_quiet` is inapplicable; sequence barriers replace global silence.\n\nExisting cleanup is incomplete for reuse unchanged: rc_attach_truth has manual teardown, B-3's rc is not a drop guard, replay's `kill_session` is only reached after assertions, and simple kill_pid trusts numeric PIDs. Wrap all children/readers in owned teardown and use `common::reap::{observe, authenticated_kill, target_gone, population_sweep}` with staged-image/ancestry/creation-time evidence. `output_bounded` bounds its polling but calls blocking wait/reader joins afterwards; inherited pipe handles can defeat the advertised overall hard wall. It is appropriate for bounded short CLI calls, not as the persistent-rc supervisor. PTY read EOF is particularly unsafe as a teardown condition on Windows; use lifecycle plus bounded drain completion and explicit failure evidence.\n\n**Binary minimum:** real `spt.exe` (`CARGO_BIN_EXE_spt` convention), `mock-session.exe` from package `mock-adapter`, and the rig executable. Adapter setup stages another spt image as `psychebin.exe`; it is not another build target. `common::sibling_bin` resolves fixtures beside spt and fails loudly when absent. Optional `console-mode-probe.exe` supports console vehicle qualification; `capture-player.exe` is for prerecorded-output tests and cannot supply bidirectional continuity. No Python/PowerShell/cat/findstr/ping dependency is needed for the proposed child. Libraries already available include spt-daemon, spt-term, spt-test-support, spt-store, tempfile; mock-adapter already depends on sha2.\n\n**Process estimate [INFERENCE]:** minimal direct-session local apparatus: rig + daemon broker + supervised brain + child + rc = about five long-lived logical processes. Manifest harness bringup can add a hosted psyche process and its pseudoconsole. Windows adds roughly one console host per pseudoconsole, plus another for outer-ConPTY rc. Budget approximately 6–9 OS processes for one local manifest cell, plus short-lived start/bind/trigger/stop commands; do not treat this as a measured count. A second real daemon adds broker+brain and its console/CLI overhead; avoid importing all the unrelated twohost suite rungs.\n\n**Blocking isolation facts:** temp SPT_HOME isolates stores/IPC naming, not transport. `daemon.rs:528–562` uses `BindScope::All`, `LocalDiscovery::Mdns`, configurable relay policy, then firewall verification. `twohost_cli.rs:35–58` intentionally relies on production relay/discovery and has no daemon bind-port knob. `TEST_EPHEMERAL_ADVISORY_PORTS_ENV` affects advisory ports, not QUIC/mDNS/UPnP. Library `NetEndpoint::bind_scoped` offers Loopback and disables portmapper there (`endpoint.rs:319–406`), but replacing real production daemon assembly with that mechanism changes the acceptance boundary. Relay disabled alone does not remove mDNS/all-interface binds; Port scope is also all-interface. Failed net startup retries rather than staying safely offline.\n\nMost importantly, `firewall.rs:614–627` may invoke Windows delete/add repair when elevated. `SPT_INSTALL_NO_FIREWALL` is checked in install reconciliation, not this daemon verification path. Thus it is not sufficient protection for this rig. Under the stated no-production-network/firewall-mutation constraint, real-daemon execution requires an already authorized disposable isolated environment with constrained egress/non-elevated posture; do not launch it on the workstation merely because its home is temporary, and do not solve this by adding product test knobs or mutating host firewall rules."
}