# W7 (#336 background updater) — prep map, todlando 2026-09-24 ~18:00Z (read-only, main 02d024c4 + W6 lane)

Facts (file:line on W6 worktree; re-verify at dispatch sha):
- `DaemonConfig.full_auto_update: bool` config.rs:147 (file struct Option<bool> :99, default false :217, from_file :274, save_to :317). File `<spt_home>/daemon.json`. Precedent list fields: `detached_subnets`, `startup_endpoints` (Option<Vec<..>> + unwrap_or_default; no migration code anywhere).
- Only reader: pump/update.rs:411 `decide(self.full_auto_update, most_recently_active(..))` (via PumpConfig pump/mod.rs:342/350, UpdateWorker::new :667). Tests set it false in twohost.rs:691, registry_lifecycle.rs:392, pump.rs:438/613/808, mesh_recovery.rs:225, mesh.rs:252; unit config.rs:503 `full_auto_update_is_gated_by_default` [unit->REQ-UPD-4].
- **AutoApproved applies NOTHING today** — it only suppresses the consent notif (pump/update.rs:410 "Full-auto writes nothing"). Only the CLI applies (cmd_update_apply -> apply_staged / apply_staged_daemonless). applyhost.rs:12-14 + update.rs:242-245 docs say "never auto-applied" (REQ-UPD-4) -> must change.
- UpdateClass { BrainOnly, BrokerCompatible, BrokerBreaking } update.rs:90; classify :115; apply gate applyhost.rs:237 refuses non-BrainOnly (RefusedClass, CLI exit 3). No adapter class in the enum -> auto_classes values `brain_only`, `adapters` (+ others) are a NEW vocabulary spanning core classes + adapters.
- Pump runs INSIDE the brain process (brainproc.rs:433 spawn_net_consumers -> spawn_peer_pump). Update cadence `update_check_period` default 3600s (config.rs:42/168), scheduled by `due()` in pump/mod.rs:679. **No jitter anywhere in crates/.**
- Spawn helpers: daemon::detached_no_inherit_env (daemon.rs:1695 win / :1861 unix), runtime::run_bounded_command_in (spt-runtime runtime.rs:1075). Exe: KH 6.11 canonical exe captured at broker start (brainproc.rs:1353; lanhost.rs:92 CANONICAL_EXE pattern) — current_exe() follows the .old-N rename on Linux, so the brain must spawn the CANONICAL path.
- Composite `spt update` cmd_update_composite cli.rs:10110 legs FetchApply/Fetch/Adapters/Finish; NoUpdate -> exit 0; RefusedClass 3; UPDATE_FINISH_REFUSED from hosted endpoint.
- AUTO-SET SEAM cli.rs:9866 (bundle member Upgrade arm) — gate on auto set, else offer (consent).
- No code references releases#329; "adapters leg from the NEW brain" is unbuilt.
- Rig: crates/spt/tests/peer_rig/ (InprocNode, ReleaseSigner/SetBuilder, MockAdapter, MockBundle, wait.rs StreamCursor/wait_for); real-daemon ints DaemonGuard in adapter_peer_e2e.rs / source_ladder_e2e.rs; bundled_adapters_e2e.rs stage_and_apply.
- REQs: none minted for #336 yet. Touch: REQ-UPD-4 (its "gated by default" contract is SUPERSEDED by CONTEXT.md:720 cadence/consent ruling), REQ-ADAPTER-UPDATE-PARALLEL (names the background updater), REQ-BUNDLE-APPLY-MEMBERS ("apply or offer per the configured auto set"), REQ-TEST-PEER-RIG-FIXTURES.

Open questions for doyle (sent 2026-09-24):
1. REQ-UPD-4 retire/amend vs new REQ — its title contradicts the ruling.
2. Who applies: the brain spawning `spt update` CLI (JIT plan) means the child apply does apply_staged -> request_brain_restart on its OWN parent brain. Confirm that is the intended shape (child outlives the brain it restarts? spawn detached/job-neutral).
3. BrokerCompatible/BrokerBreaking in the default set? Plan says default ["brain_only","adapters"]; BrokerBreaking "stays staged + notified".
4. Jitter: none exists — spec the band (e.g. ±10% of period).

## doyle RULINGS 2026-09-24 17:58Z (binding; he folds 2-4 into the W7 seed mint)
1. REQ-UPD-4 AMENDED, not replaced: keeps the CONSENT GATE (outside-set staged update -> consent notif to most-recently-active session; consent::decide + most_recently_active evidence stands); title loses the boolean default. New REQ-UPDATE-AUTO-CLASS-SET owns the auto set as config data + full_auto_update migration.
2. Heartbeat child STAGES ONLY, never applies. Auto-apply = existing broker trial PROMOTION path gated on the auto set. Child spawned from CANONICAL exe captured at broker start (KH 6.11), detached, no inherited job object/stdio; killed child = no-op retried next heartbeat.
3. auto_classes = OWN vocabulary {brain_only, broker_compatible, broker_breaking, adapters}; total mapping UpdateClass -> first three. Default = [brain_only, adapters]. broker_compatible OUT of default (until releases#334 hot-swap widens by config).
4. Release-channel check: NEW config period 3600 s + jitter uniform [0,600) s drawn per check, additive (never more often than hourly). Do NOT touch update_check_period_ms (peer pump cadence).
5. (17:59Z, accepted) Swap INITIATOR: the BROKER calls applyhost::apply_staged in-process when a newly staged set's class is in the auto set; trial/promotion then unchanged. OPEN impl-shape (decide deliberately, state reasons): apply_staged takes a broker SOCKET NAME (out-of-process signature) — broker would dial itself; options = daemonless variant, a split fn, or real self-dial.
