{
  "summary": "Read-only source map completed for releases#302, #49, and #267 in .worktrees/304-product. Local and remote rc use the same attach protocol/serve loop, but recurring hitches, refresh freezes, and composite-update freezes remain separate investigations. Prior v0.41.0 freeze fix and its explicitly documented mutation-green integration-coverage gap located. No runtime reproduction, validation, edits, or present-day root-cause claim.",
  "files": [
    {
      "path": ".worktrees/304-product/crates/spt/src/rc.rs:1405-1519,2292-2500,2645-2673,2877-3150",
      "description": "Stdin producers, local/remote establishment, reconnect queue handling, single-threaded input/output pump and rendered-output dedup."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/attach.rs:228-300,449-580,582-739,815-852,893-935,989-1000",
      "description": "Controller gap resume; target serve loop; role-pending input; two IPC carriers; output forwarding; attach/input wire construction."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/broker.rs:3073-3192,3910-4010,4234-4278,8746-8843,9227-9240",
      "description": "Subscribe lease/idempotence decisions, controller writer boundary, bounded PTY input writer, input authority/journal/translation buffering, planned brain-restart signal."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/dispatch.rs:694-810,922-953,1158-1228",
      "description": "Fresh dispatcher claim loop, durable-opener lookup, classification and real serve_attach invocation."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/applyhost.rs:126-298,303-369",
      "description": "Signed staged-candidate preparation, binary swap followed by restart request, and refresh's same restart request without swap."
    },
    {
      "path": ".worktrees/304-product/crates/spt/src/cli.rs:8150-8185,9392-9434,9500-9557,9705-9708,10824-10827",
      "description": "Refresh CLI, apply live/daemonless branch, composite fetch/apply/adapters/finish dispatch, and separate full-cycle finish entry."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/brainproc.rs:141-169,270-278,396-409,629-638,935-1085",
      "description": "Restart signal and supervision; cursor-only restoration; readiness heartbeat and drained promotion boundary."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/tests/attach_idempotent_replay.rs:1-55,238-338",
      "description": "Prior fix's real-broker integration test explicitly reports that removing the discriminator still passes; reads broker events directly rather than real viewport serve path."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/src/broker.rs:12321-12442",
      "description": "Prior fix's structural unit matrix and distinct-floor gap-resume coverage."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/tests/attach.rs:830-998",
      "description": "Short-stream manual target-brain handoff test with dead-window input, bypassing production rediscovery."
    },
    {
      "path": ".worktrees/304-product/crates/spt-daemon/tests/redispatch.rs:1-24,219-350,579-686,689-740",
      "description": "Actual dispatcher-generation fixtures for historical attach retirement, opener eviction and transient start retry; not full supervised daemon/real CLI refresh."
    },
    {
      "path": ".worktrees/304-product/crates/spt/tests/daemon_refresh_e2e.rs:1-302",
      "description": "Real CLI refresh test preserves broker/harness process and online status; no attached rc client or queued viewport input."
    },
    {
      "path": ".worktrees/304-product/docs/adr/0047-daemon-lifecycle-custody-authority.md:32-41,107-146",
      "description": "Historical 15ms same-connection repeat subscribe evidence and idempotence decision, including different-floor requirement and unresolved double-serve origin."
    },
    {
      "path": ".worktrees/304-product/docs/REDISPATCH-TRUTH-TRIAGE.md:10-48,65-105",
      "description": "Earlier refresh-failure history, measured 4/5 endpoints freezing, and explicit original test bypass."
    },
    {
      "path": ".worktrees/304-product/CHANGELOG.md:1668-1694",
      "description": "v0.41.0 claimed update/refresh freeze fix, subsequently refuted as a complete field fix by issue #49."
    },
    {
      "path": ".worktrees/304-product/docs/DEBUG-ROLLOUT.md",
      "description": "Required signed debug rollout, channel/key/platform constraints, consent and broker-touching refusal."
    }
  ],
  "architecture": "rc stdin reader → mpsc → rc main pump → AttachRecord over local loopback or remote QUIC → broker-held stream → restartable dispatcher/serve_attach → broker controller fence/effect journal/optional inject-floor → bounded InputWriter → PTY. Output reverses through broker OutputLog/controller writer → serve_attach's separate wire IPC → stream → rc cursor dedup/stdout. Refresh and routine core apply both signal the stable broker to replace its supervised brain; composite update additionally runs adapter updates.",
  "report": "## Scope and evidence discipline\nAll paths below are relative to `.worktrees/304-product`. Read actual issue bodies at https://github.com/BigscreenVR/spt-bs-releases/issues/302, https://github.com/BigscreenVR/spt-bs-releases/issues/49 and https://github.com/BigscreenVR/spt-bs-releases/issues/267. Read AGENTS.md, diagnosis skill, relevant CONTEXT terminal/update vocabulary, DEBUG-ROLLOUT.md and ADR-0016 before update research. No processes, fixtures, builds, tests, production probes or edits were run. This is preparation for reproduction, not reproduced diagnosis. Historical measurements below are attributed to their records, not re-measured now. The direct GitHub comments API returned 404; issue bodies were available through issue://, and in-tree ADR/test/history records supplied the prior-fix evidence. Issue #49's linked raw attachment was not obtained here; raw incident logs and complete discussion history remain evidence gaps.\n\n## Shared present-day boundaries — not evidence of a shared cause\n- `crates/spt/src/rc.rs:1-21` explicitly defines one pump: local attach uses broker loopback and the same target dispatcher/serve path as remote QUIC. Establishment is `establish_attach` at 2292 onward; transport explanation is 2261-2275. A local hitch therefore does not eliminate broker stream/dispatcher/serve participation, but does eliminate dependence on an actual inter-host QUIC path for that local occurrence.\n- Input: rc readers at 1405-1519 produce `StdinMsg`; main pump at 2970-3097 drains it and calls `send_attach_input`. `attach.rs:989-1000` encodes op-id-bearing Input and sends unjournaled transport bytes. `serve_attach` subscribes at 449-460, creates a separate outbound wire Brain at 478, receives/decode-dispatches at 582-660. Confirmed controller input uses `send_effect_no_ack`; pre-confirmation input enters `pending_input` and is flushed via `send_effect` after Subscribed at 696-720. Viewer/refused input is discarded. These are distinct queue/ack states; no evidence here identifies one as the freeze owner.\n- Broker input `broker.rs:8746-8843`: clone session handles; check rc's active-controller connection; emit optional translation-binary input ping; optionally buffer behind the translation inject floor; apply the minter/session/op journal; otherwise enqueue. `InputWriter::enqueue` at 4234-4256 uses try_send and drops on full with backpressure stamping; sole PTY writer at 4274-4278 calls blocking write_input. Thus 'all queued input eventually drains' cannot be assumed from this code: queue location and counts must be measured, and overflow has an explicit drop contract.\n- Output: controller seat/writer creation is `broker.rs:2593-2694`; writer entry 3910; target forwards Output at `attach.rs:832-841` on its second wire carrier. rc renders sequence-deduplicated Output at 3123-3150. `attach.rs:242-300` handles controller gaps by resubscribing from delivered_through; repeated non-progress returns ControllerIrrecoverablyBehind. These boundaries require timestamps/cursors to distinguish no producer progress from no delivery or no rendering.\n- rc `read_event_until` polls in 40ms slices (rc.rs:43-46,3100-3118). Its first-event stall check is not an ongoing established-view heartbeat: after `seen_any=true`, silence does not on its own request reconnection. Only BrokerGone/Severed enter reconnect (`2730-2745`). While reconnecting, `2645-2673` drains stdin messages solely to recognize Detach; ordinary Bytes are consumed without forwarding. Preserve a distinction between input during a still-open stalled stream and input during explicit reconnect. This source behavior is not proof that either issue enters reconnect.\n\n## #302 — recurring local/remote hitches\n**Field evidence:** issue body reports v0.69.0, output and input freezing every 10–20 seconds for roughly 5–10 seconds; input queues and drains at the end. Occurs enlyzeam→gravity-nvidia-temp, enlyzeam-local and gravity-nvidia-temp-local. No refresh/update trigger is stated. No timestamped trace or stack sample was supplied by the retrieved body.\n\n**Exact trace:** rc `1405-1519 → 2970-3150`; request/input helpers `attach.rs:893-935,989-1000`; target `449-739,832-852`; broker `8746-8843 → 4234-4278`; output `2593-2694 → 3910`, then target wire forwarding and rc stdout. Production admission is dispatcher `694-810,922-953,1158-1228`. Existing established streams should be observed before modifying reconstruction scenarios.\n\n**Smallest executable reproduction design:** after allocation, run one isolated supervised broker/brain, one sustained instrumented echo/heartbeat PTY and one *actual persistent rc viewport* over local loopback. Keep the same rc process, stdin producer and endpoint session alive for at least 180 seconds; send numbered input at a modest fixed cadence throughout, including every apparent pause. Emit independently numbered PTY heartbeats. Retain source timestamps, input acceptance order, rendered bytes and broker/brain/stream identities. Do not refresh or update in this cell. First report long inter-heartbeat gaps and input-to-echo latency versus baseline; match reported repeated 5–10s freezes rather than interpreting any small scheduling delay as reproduction. Add a read-only persistent viewer to distinguish controller-only output loss from shared session delivery loss. Then repeat the same protocol on two isolated lab nodes; keep local-on-each-host controls independent. If the minimal cell is non-reproducing, retain it as such and add only separately recorded workload/history/adapter conditions from the field.\n\n**Missing discriminators:** simultaneous PTY source/output/rc timing, exact running broker versus brain versus CLI builds, CPU/thread/IPC wait samples during a hitch, stream/lease IDs, whether multiple views stall together, translation presence and inject-floor state, actual queue occupancy/drop count, and whether any unreported brain generation change occurred. Old 15s/30s hazards are not causal evidence for this 5–10s specimen. `docs/REDISPATCH-STALL-TRIAGE.md:15-18` records older v0.34 20–30s freezes, 17–62s dispatch tails, and 15,000–15,154ms poison windows: historical contrast, not a match established here.\n\n## #49 — refresh / staged core-swap freezes\n**Field evidence:** current issue states every active rc freezes when the brain restarts; explicit daemon refresh and staged core update reproduce; multiple historical fix claims failed in the field. Treat the latest issue as refuting blanket closure, not as proof the old measured defect never existed.\n\n**Trigger trace:** `cli.rs:8150-8185 cmd_daemon_refresh` → `applyhost.rs:364-369 refresh_brain` → `brain.rs:2237` request_brain_restart → broker command arm `6321` and handler `9227` → `brainproc.rs:141-169 BrainRestart` → supervisor `1079-1085` kills/waits current brain and respawns. Broker/PTYS and transport rows stay with the broker; replacement brain's dispatcher starts its own claim map (`dispatch.rs:694-810`), looks up pinned opener (`922-953`), resolves endpoint/session, seeds `serve_attach` (`1158-1228`). This serves an already existing operator stream, with queued/replayed input reaching the role-pending and confirmed branches described above. Readiness at `brainproc.rs:396-409` plus outgoing local-controller drained predicate `629-638` is not an end-to-end old-viewport/input observation.\n\n**Prior fixes and actual coverage gaps:**\n1. Earlier redispatch history: `docs/REDISPATCH-TRUTH-TRIAGE.md:10-48` records 4/5 remote endpoints freezing across two July 16 refreshes, low/historical DISPATCH failures, stale historical attach replay and missing opener classification. It explicitly states the old `attach_survives_target_brain_restart_exactly_once` manually re-served a known short stream, bypassing production discovery and opener rollover. Current `tests/attach.rs:830-998` still hand-steps life1, drops that Brain, queues MARKER_TWO in the dead window, then manually calls serve_attach for life2. It does exercise replay and dead-window input on the held stream. It does not exercise full supervisor/real refresh, production rediscovery or actual rc frontend. Its final marker-in-screen assertions are not independent input-effect multiplicity counters.\n2. Later v0.41.0 claim: CHANGELOG `1668-1694`; ADR-0047 `32-41,107-146`. Historical OBS evidence recorded same connection, identity and generation subscribed twice 15ms apart, contradicting an earlier presumed gen+1 mechanism. Fix's current decision in `broker.rs:3147-3192` preserves an identical nonzero-generation same-conn same-from_seq seat; a different carrier or changed from_seq still installs a successor. Why dispatcher produced the double serve remained explicitly open in that ADR. The accepted zero-progress gap collision remains stated in ADR lines 133-142; it was not proved to explain current freezes.\n3. Crucial actual gap: `tests/attach_idempotent_replay.rs:32-55` explicitly says **removing the fix discriminator leaves its real-IPC integration test green**. Brain cursor hides replayed bytes, and replacement writer on the same connection keeps raw broker events flowing. Test bypasses the serve worker/viewport composition. `238-338` also injects through a separate Shell-minter spawner, not rc's controller-exclusive input route. Its 'original writer still live' commentary overstates what the observed echo proves; its own header correctly records that limitation. Discriminating historical proof was structural unit assertions over sink/epoch at `broker.rs:12321-12391`, plus changed-floor test `12396-12442`; these pin the mechanism but do not demonstrate the user's refresh scenario fails before and passes after.\n4. Existing production-dispatch suite is stronger than manual handoff: `tests/redispatch.rs:1-24,219-350,579-686,689 onward` uses a killable dispatch_fixture child and real QUIC brokers, tests historical row retirement, pinned opener after ring roll and injected transient setup failure. It is not equivalent to actual supervised brain/CLI refresh with persistent rc windows and timed queued input. Its ring-roll cell shrinks the ring rather than requiring production 4096 capacity. Do not claim all prior tests bypass dispatch.\n5. Real refresh CLI test `spt/tests/daemon_refresh_e2e.rs` starts a NET-LESS daemon with intentionally invalid node seed, creates an endpoint and calls daemon refresh; it checks new brain pid/generation, unchanged running broker, surviving harness and online perch. It creates no rc viewport and sends no input through one. Endpoint survival is genuine coverage, but it cannot observe viewport continuity.\n\n**Smallest executable reproduction design:** reuse the real daemon-refresh fixture's isolated supervised daemon, but with valid isolated node identity and actual attach transport. Before trigger, open one long-lived controller rc plus one long-lived read-only view on an already-producing numbered echo/heartbeat PTY. Keep frontend processes, stdin streams, decoder state, stream identities, endpoint/session and numbered workload alive. Invoke real `spt daemon refresh` externally while input continues before/during/after brain death. Require same broker and PTY identity, observed brain generation transition, old view resumed output and every accepted input delivered once/in order, without detach or replacement viewport. Record failures before trying manual detach; only then use a separately labelled recovery action to test issue's contrast. Add historical finished attach and rolled-opener cells separately after the minimal trigger cell. Remote version uses two isolated hosts and refreshes target first; source-node refresh is an independent cell.\n\n## #267 — refresh stalls, also after spt update\n**Field evidence:** the actual title is '`spt daemon refresh` stalls session PTYs'; body adds 'also happens after `spt update`' and says intentional detach followed by rc/go back to the SAME session recovers. Do not silently relabel this as update-only. Its overlap with #49 is reported symptom/trigger overlap, not established causal identity. Body gives no core/adapters versions, exact update flags, signed candidate or freeze timing.\n\n**Refresh arm:** source boundaries and reproduction design are the #49 refresh arm, but preserve this issue's same-session manual detach/re-attach recovery observation independently.\n\n**Routine update arm:** `cli.rs:9519-9557 cmd_update_composite` dispatches FetchApply then Adapters for plain update (CONTEXT.md:688); live apply at `9392-9434` calls `applyhost.rs:303-350`. `prepare_apply:126-298` re-verifies/classifies before `swap_and_record`; restart signal follows binary swap, then shared supervision/reconstruction path above. Adapters are a separate composite leg and must have their timing captured. `--restart`/Finish is a different full-daemon lifecycle branch at `cli.rs:9705` and must not be substituted for routine update; stopped-daemon apply is likewise not the existing-view scenario.\n\n**Smallest executable reproduction design:** baseline old live views and numbered input exactly as #49, then in a dedicated test home stage one verified, monotonic, platform-correct **brain-compatible** signed candidate using the normal debug rollout substrate. Trigger explicit apply first to isolate core-swap handoff; keep views/input alive throughout and assert old broker/PTY continuity separately from activated brain version. Run real plain composite `spt update` as an additional independent cell with pinned candidate and controlled adapter update state. Compare core-already-current/adapters-noop and core-apply cases; add actual adapter-change case only with its own fixture/artifact. Capture phase markers before assigning the freeze to handoff versus adapters. Do not quiesce endpoints to make this routine-update cell pass: that destroys the acceptance scenario. Broker-breaking candidates are refused while live resources exist and cannot stand in for the brain-compatible test.\n\n## Allocation and artifact prerequisites — nothing authorized or executed here\nA separately sized Rust/rig allocation is required before any build, fixture or runtime use. Minimum requested topology: one exclusive source revision and pool-owner-approved target directory; one Windows local test host with an isolated home/identity and ephemeral advisory ports; sequential execution of one supervised broker+brain, one child PTY, controller rc, observer rc and timestamp/input driver. Two-host remote cells additionally need a second isolated lab home/host, isolated trust/addresses and an explicitly allocated transport path. Do not use production homes, endpoints, keys, resident daemon or fleet release distribution. Exact memory, disk, child-process and wall-time caps must be allocated by the owner from host/pool capacity; no Rust allocation currently exists, so no resource numbers have been pretended measured.\n\nRequired runtime artifacts: v0.69.0 baseline CLI/broker/brain provenance and candidate source revision; compatible mock/echo harness and real rc frontend; durable externally observed sequence ledger rather than only ScreenGrid; supervisor generation and attach/dispatch/cursor telemetry; controlled cleanup scoped to owned processes. Update additionally needs custodied debug signing seed, explicit test-home release-key overlay/channel pin, monotonic debug counter, correct platform artifacts and normal consent/apply policy (DEBUG-ROLLOUT.md; ADR-0016), plus before/after running broker/brain version records. Any runtime instrumentation or fixture edits require Main's product authority and Hertz's regression ownership; this scout supplies only the source and reproduction map.\n\n**Handoff conclusion:** the most useful proven historical finding is not a new culprit: a prior freeze fix's integration test was explicitly mutation-green because it observed below the failing composition, while the true refresh CLI test observed process/perch survival without a viewport. Preserve existing views and input at the real frontend across each independent trigger to close that observational gap. Current root causes remain unproven."
}