{
  "summary": "Read-only source investigation completed. A fresh rig can genuinely apply the exact same repaired bytes using a positive debug release counter without an older binary baseline. Plain daemonless apply must be followed by an explicitly owned, unelevated foreground daemon run for trial promotion. Historical r4 cannot recognize the real lowercase applied-state encoding and does not start the daemon needed to promote. --finish/node start have job-escape/service seams and are unsuitable for the accepted containment route.",
  "files": [
    {
      "path": ".worktrees/304-w2-repr/docs/DEBUG-ROLLOUT.md",
      "description": "Required rollout guidance, read first; generic guidance does not override actual pinned apply implementation."
    },
    {
      "path": ".worktrees/304-w2-repr/docs/adr/0016-platform-targeted-update-sets.md",
      "description": "Required ADR, read first: signed platform sets, exclusive debug channel, monotonic counter, node-local keys."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt-daemon/src/applyhost.rs",
      "description": "115-245 prepare gates; 255-291 actual swap and pending record; 302-350 live restart handoff; 382-426 daemonless apply and no-op classifier."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt/src/cli.rs",
      "description": "8691-8788 no-autostart daemon status; 9260-9416 observable apply outputs; 9434-9487 apply dispatch/finish guard; 9741-9828 finish restart escape seam."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt-daemon/src/brainproc.rs",
      "description": "690-742 promotion writes and drained gate; 866-900 readiness gate; 997-1044 promotion and rejection; 1172-1185 unverified hash fallback; 1213-1255 canonical child spawning; 1297-1318 canonical capture."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt-daemon/src/relcache.rs",
      "description": "83-114 exact phase-tagged lowercase JSON; 470-490 record write/read."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt-daemon/src/daemon.rs",
      "description": "55-117 direct elevated daemon de-elevation seam; 602-605 liveness; 781-812 service-aware start; 873-919 detached spawning; 1973-1988 WMI/scheduler/breakaway ladder."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt-daemon/src/lanhost.rs",
      "description": "74-78 refusal tokens; 184-222 set gate; 239-268 production-policy runtime reads; 665-679 gate before listener construction."
    },
    {
      "path": ".worktrees/304-w2-repr/crates/spt/src/serveverb.rs",
      "description": "182-201 every serve command, including status/stop, ensures daemon; 233-261 LAN success/refusal and firewall admission ordering."
    },
    {
      "path": ".spt/preserved/hertz-fp-driver-review/d2/fp-driver-d2-r5.sh",
      "description": "881-929 accepted run-job helpers; 2053-2100 consumed provenance contract; 2536-2538 readiness before autostart-capable setup."
    },
    {
      "path": ".spt/preserved/hertz-fp-driver-review/d2/launch-v2.cs",
      "description": "250-294 environment/guard protection; 311-328 exact job flags; 375-377 suspended creation; 521-562 assign/verify/resume and run-scope lifetime; 659-705 fresh image/creation/parent/job proof."
    },
    {
      "path": ".spt/preserved/hertz-fp-driver-review/d2/run-daemon-ready.ps1",
      "description": "Fresh retained-handle membership request/response, supervisor and brain checks; despite read-only custody label, writes request files and must not execute during PREP."
    },
    {
      "path": ".spt/preserved/hertz-fp-driver-review/d2/run-daemon-control.py",
      "description": "Environment helper exclusively creates a JSON file containing SPT_HOME and SPT_INSTALL_NO_FIREWALL=1; no session-guard overrides."
    },
    {
      "path": ".spt/preserved/hertz-fp-driver-review/d2/provision-rig-r4.sh",
      "description": "301-343 historical apply/promotion; 345-387 process-path observations; 389-406 provenance/residue; historical ungranted guidance, not executable plan."
    }
  ],
  "architecture": "Production stages a signed platform set, applies through authenticity/class gates and a real executable swap, records applied-pending, and lets the supervisor promote after generation readiness plus drained old control plane. LAN bootstrap separately requires authenticated set, matching running-path digest, and exact promoted version. The safe rig seam is daemonless plain apply followed by accepted run-owned foreground daemon run, not daemon auto-start or --finish.",
  "report": "SCOPE AND EVIDENCE\nAll product ranges below refer to .worktrees/304-w2-repr unless explicitly marked current main. No binaries, validation commands, builds, tests, mutation helpers, fleet-home reads, or runtime observations were performed. The source describes expected behavior of the pinned subject; this investigation does not independently attest compilation provenance. Subject remains target/release/spt.exe SHA256 72d309011415b419aabfdb0b4065df1183bfd0069a9f95b5779da62e43349b10; never rebuild/substitute. Accepted r5 remains fp-driver-d2-r5.sh SHA256 df6cca2d987e8eb2a6e9ccba6e9532d278c08bb4f873674836653e5a8e419c59.\n\nORDERED FUTURE APPLY/PROMOTION PLAN — AFTER ONE EXPLICIT MUTATION GRANT\nLet E be the absolute RIG_ROOT/bin/spt.exe, H the exclusively created RIG_ROOT/home, N the pinned positive u64 debug set version. Signing/staging is another scout's scope. Do not invoke any command below during PREP.\n1. Finish isolated placement/trust/staging with daemon absent. Require exact subject bytes at E and as the signed Windows x86_64-pc-windows-msvc artifact, channel debug, intended key, and no older/pending/applied/quarantine records in fresh H. There is no required older executable or older product-semver baseline. Absence of an applied record is the honest initial state, not a synthetic version-0 record. Choose N>0 (e.g. 1 if the isolated signing sequence and all relevant floors are truly fresh). release.rs:526-530,564-568 rejects candidate <= floor; apply and LAN verification use floor 0. If any previous applied/pending record exists, this is not the fresh rig and must be refused, not repaired.\n2. In an accepted bounded STEP job, with SPT_HOME=H and no signing seed inherited, invoke argv [E, 'update', 'apply'] (no --finish). Plain apply uses current_exe as swap destination and chooses daemonless if the seed socket is down: cli.rs:9434-9487; daemon.rs:602-605. Require native exit 0 AND the daemonless installed message, real before/after byte evidence, and product-produced pending JSON. Do not accept NO_UPDATE or 'already up to date' as a new transition. With no product_version stamped, expected stdout begins 'Installed spt-core release N on disk. The daemon is offline, so nothing is running the new version yet …' (cli.rs:9316-9335). This output itself recommends --finish/node start, but the rig must NOT follow that generic advice because those paths escape accepted job ownership.\n3. Before any daemon launch, capture H/releases/applied-state.json as parsed JSON: phase='applied-pending', numeric version=N, rollback_binary=RIG_ROOT/bin/spt.exe.old-N, candidate_started_ms, prior_version=null on first-ever apply. Capture the actual aside and E digests. applyhost.rs:255-291 performs the rename, lands exact staged bytes and writes this record best-effort; absence is a failure, not permission to fabricate it. Daemonless ordering makes the pending state observable before a supervisor can immediately promote it.\n4. Launch the promotion daemon directly and UNELEVATED using the accepted v2 launcher as a sibling to, never descendant of, a bounded step launcher: pwsh -NoProfile -File <launch-v2.ps1> -Label run-daemon -Seconds <remaining bounded run allowance> -Scope run -Admission process-tree -RecordFile <run-daemon.json> -ArgsFile <JSON argv ['daemon','run']> -EnvironmentFile <JSON {'SPT_HOME':H,'SPT_INSTALL_NO_FIREWALL':'1'}> -StopFile <run-daemon.stop> -Exe E -OutFile <run-daemon.out> -ErrFile <run-daemon.err>. This is the accepted helper shape at r5:881-899. The 'daemon' spelling is a supported visible alias of primary 'node' (cli.rs:423-426); direct foreground run is documented at 1042-1054. No separate public 'promote' command exists: the normal supervisor performs it.\n5. Use accepted run-daemon-ready.ps1 -RecordFile <run-daemon.json> -Home H -Seconds 20 as the future custody readiness check. Require RUN_DAEMON_READY=YES and its matching request-id evidence, exact image E, anchored creation times, supervisor/brain live and in the retained run job, and brain parent equal supervisor. It is not a pure read-only PREP command: it writes membership request files. Poll the product state to the bounded deadline, parsing exact phase='applied', numeric version=N. Capture 'BRAIN_PROMOTED: candidate vN signalled ready (generation G) — swap accepted' from run-daemon stderr, H/brain.ready, and legacy promotion records. Require ready.exe_hash equals the subject/staged/post-apply digest, ready.pid belongs to the measured brain, and generation consistency.\n6. Supported no-autostart status query: SPT_HOME=H E --json node status (equivalently E --json daemon status). cli.rs:8691-8788 connects with Brain::cold_start_pump and does not call ensure/start. This reports live supervisor PID and broker/coordinator versions, not the release trial phase. It is therefore liveness/identity corroboration, NOT a substitute for parsed applied-state.json. No 'spt update status' exists in the pinned UpdateCmd enum (1833-1870). The status code later reads local state and can load_or_create node identity if subnets are present (8789-8811), so call it only in the future granted rig, not as a blanket claim of zero filesystem side effects.\n7. Before handing the provisioned home to unmodified accepted r5, close only the provisioning run job through its StopFile and require CONFIRMED_GONE plus fresh residual attribution. r5's run_daemon_start explicitly refuses H/daemon.pid preexistence (881-885), and expects to start its own run job during its experimental phase (2536-2538). Do not simply leave the provisioning daemon up, and do not delete a lingering daemon.pid breadcrumb to make admission pass: an unexpected remaining breadcrumb is a refusal requiring a future decision. No daemon stop guard bypass.\n8. The later field invocation stays exactly SPT_HOME=H E serve lan --bootstrap --port <authorized port>, with SPT_INSTALL_NO_FIREWALL absent ONLY in the authorized elevated setup leg. Owned daemon readiness must be freshly established first; this is not part of provisioning's read-only preparation. Every serve variant uses ensure_running, including 'serve lan' with no flags and '--stop' (serveverb.rs:182-201), so neither is a no-autostart status probe.\n\nVERSION / SAME-BYTES ANSWER\napplyhost.rs:412-426 checks versions, not executable byte equality: pending.version>=staged or legacy applied_version>=staged yields AlreadyApplied. Same version already pending/applied is an exit-0 no-op even before re-verification. Same product semver or same artifact bytes with an unrecorded/newer release counter still reaches genuine rename + land + trial. N=0 is invalid against the floor-0 verification path. A genuine initial baseline does not require an older binary: running and staged copies may both be the exact repaired subject. On first-ever failure, prior_version=null means rollback reporting falls back to N-1 (applyhost.rs:284-290; brainproc.rs:1123-1145); this fallback must not be misrepresented as a genuinely previously applied release. A quarantined same N is refused before the no-op check (applyhost.rs:134-148).\n\nQUIESCENCE / PROMOTION CONDITIONS\nGeneric DEBUG-ROLLOUT guidance says broker-touching candidates should be quiesced first. Actual pinned apply prepare is stricter: every class other than BrainOnly returns RefusedClass unconditionally (applyhost.rs:230-237). Quiescing does not enable a supported broker-breaking/full-swap implementation in this executable. Require the signed set to classify BrainOnly; on UPDATE_APPLY_REFUSED:<class>, native exit=3, stop rather than invent a full-swap route. The fresh home should have no hosted endpoints, registered resident services or broker-held control state. Plain live BrainOnly apply preserves the broker/endpoints and asks the supervisor to restart only the brain (302-350), but initial daemonless-then-direct-start is simpler and makes the pending record observable.\nPromotion is not synonymous with startup or apply exit 0. The trial uses generation-matched readiness AND old_gen_drained (brainproc.rs:866-900). Windows trial window defaults to the common 30-second healthy interval, with three pre-ready exits allowed (44-55). Supervisor clears stale readiness before a pending trial (958-979). After readiness/drain, wrong hashes cause BRAIN_PROMOTE_REJECTED and rollback (997-1025). IMPORTANT: missing either hash yields PROMOTE_BYTES_UNVERIFIED and still permits promotion, because only BytesGate::Mismatch refuses (1172-1185 and 1013). The rig therefore requires actual matching ready hash; absence/unverified must fail its evidence gate. The durable promotion writes are best-effort at 700-707: log alone is insufficient, and legacy applied.json alone is insufficient for LAN gate.\n\nPARENT / JOB / PATH RISKS\nThe v2 launcher creates suspended, assigns the subject to its retained job, verifies membership, then resumes (launch-v2.cs:375-377,521-545); exact LimitFlags 8192 is kill-on-close with no breakaway permission (311-328). Run scope continues after direct-subject exit until stop/deadline rather than step-subject termination (557-562). Accepted readiness compares full image E, PID+creation time, birth after custody, actual kernel parent, live handle, and IsProcessInJob against that particular retained job (659-705). Preserve inherited session guard variables: launcher environment overlay rejects OWL_SESSION_ID, SPT_AGENT_ID, SPT_ENDPOINT_ID and other protected overrides (279-283); the helper only supplies H/firewall opt-out.\nDirect unelevated daemon run does not take detached startup ladder. Direct E supervisor captures canonical E once, then spawns brains from that path with CREATE_NO_WINDOW, not breakaway (brainproc.rs:1213-1244,1304-1312); those children remain under the run job across planned brain restarts. Rollback deliberately selects E.old-N, however (1213-1218,1133-1136). Thus exact E for every brain is a SUCCESS criterion, not an unconditional guarantee even on trial failure. On rollback report the different image and refuse; never rename it back or conceal the failure.\n'update apply --finish' has a non-overridable endpoint/ancestry guard before swapping (cli.rs:9440-9455; 8092-8113). It then stops/restarts daemon through start_daemon (9741-9828). start_daemon can drive an OS service, potentially its registered image rather than E (daemon.rs:781-812), or spawn via WMI/schtasks/breakaway (1973-1988). WMI/scheduler-created processes are not descendants contained by the caller's non-breakaway job. Wrapping this command in v2 does not make its delegated work COMPLETE. Do not force the test-only SPT_FORCE_LAUNCH_RUNG seam or clear identity guards. Even direct daemon run when elevated may respawn with a linked token (daemon.rs:89-117); require unelevated ownership rather than assuming 'foreground' alone eliminates delegation.\nThe accepted architecture places each CLI step in its own owned STEP job and the supervisor/brain subtree in a sibling RUN job. It does NOT put every CLI helper in the same run job. If 'every descendant under accepted run job' literally includes the CLI steps themselves rather than the long-lived daemon subtree, accepted v2/r5 does not implement that topology; do not claim otherwise. Whole-operation containment is the aggregate of owned step jobs plus the one run job, excluding all delegated/autostart escape paths. Readiness is a point-in-time gate: serve's later ensure_running has a TOCTOU if the owned daemon disappears between check and dispatch; there is no no-autostart serve flag in this source. Treat daemon loss as a refusal and name this residual seam, not an absolute race-free guarantee.\n\nLAN SET GATE AND OUTPUTS\nlanhost.rs:184-222 requires staged Set (not legacy Single), signed metadata accepted under production policy, host triple present, signed host digest matching the executable read from canonical path, and exact Applied version equal set version. H/releases/applied-state.json must be {'phase':'applied','version':N}, not applied-pending/rolled-back. Authenticity policy is VerifyPolicy::production(0,0), deliberately neutralizing freshness/current-version axes beyond requiring positive version (239-268); home identity overlay still supplies debug trust/channel. Refusals: LAN_BOOTSTRAP_REFUSED:unsigned-exe, :sha-mismatch, :set-not-applied (74-78). Successful future setup outputs LAN_BOOTSTRAP_UP: <url> (port P), sha256 <triple> <digest>, and LAN-EXPOSED; only success reaches report_lan_admission/firewall request (serveverb.rs:233-261). Already-up output is not a new gate run (lanhost.rs:79-81) and cannot prove this run freshly created the intended surface.\n\nHISTORICAL r4 PROVENANCE DEFECTS\nr4:319-343 runs plain daemonless apply on fresh H and waits for promotion without ever starting a daemon. Pinned CLI explicitly does not start one: the script's assumed transition cannot complete. Its grep for '\"Applied\"' is also wrong: relcache.rs:83-114 uses serde tag phase and kebab-case, producing {\"phase\":\"applied\",\"version\":N}. r4's substring version grep is not numeric field equality. It describes apply stdout as primary promotion evidence, but stdout purposely says 'Updated' during AppliedPending or merely 'Installed … offline' for daemonless (cli.rs:9260-9416). Promotion JSON+generation/image/log corroboration must be primary proof of actual promotion, not a preference for optimistic human output. Its process collector considers every direct child a brain, does not authenticate creation time/job membership, and even continues past empty executable rows (r4:356-380). Its absent daemon.pid branch cannot establish successful promotion or no residual process by itself. Its timeout parent does not prove native descendants died. Preserve this script as history, do not run it or fill its pins as if it were approved.\n\nREQUIRED PROVENANCE EVIDENCE\nKeep existing consumer-compatible fields: rig_id, rig_exe, rig_exe_sha256, home, applied_version, trust_key_id, applied_evidence, provisioned_utc (r4:389-393; r5:2071-2100). The accepted r5 consumer only checks evidence-file existence and version substring, not full promotion semantics; provisioning must supply stronger evidence. Include in the evidence packet: unique exclusive creation receipt; source and tool/driver/helper pins; canonical E/H and exclusion paths; exact source/staged/pre/post/aside hashes; signed metadata set/channel/version/host-triple/digest/key and signed diagnostic provenance; actual apply argv/environment allowlist with secrets excluded, native exit/stdout/stderr/start/end; parsed before/pending/after state records including numeric N; actual supervisor promotion log and generation; legacy applied.json/last-outcome agreement; fresh brain.ready pid/generation/exe_hash; exact image paths plus PID/creation/parent for supervisor and brain; matching fresh retained-job membership request/answer, job flags, coverage and termination; no-autostart status output and live supervisor PID; any refusal/quarantine/rollback/unverified token preserved; explicit no hosted resources baseline; run-job stop/empty confirmation and residual state before r5 consumption. The old image aside is swap evidence, not proof by itself that promotion happened. Do not create/write an Applied record, invoke debug-mark-applied, or use an invented local-stage/promote/status verb.\n\nCURRENT MAIN DISTINCTION\nThe actual investigation followed the pinned worktree. A narrow current-main comparison found the same phase encoding and no-op/set-gate/launch-ladder definitions at relcache.rs:85, applyhost.rs:412, lanhost.rs:184, daemon.rs:1973. Current main cmd_update_apply is at cli.rs:9392-9452 versus pinned 9434-9487; the examined dispatch/guard logic is the same. Current main daemon-status entry is 8655 versus pinned 8691. Do not cite current-main line numbers as pinned evidence or infer source trees/binaries are identical from those matches."
}