title: feature: automatic background updates — the daemon applies core + adapter updates unattended, by update class state: OPEN author: SaberMage (Reavo End) labels: state: GREENLIT, type: FEATURE comments: 0 assignees: projects: milestone: number: 336 -- Milestone body item (releases#331): heartbeat checks; runs the update when packages are available; covers spt-core + adapters; users rarely run `spt update` by hand. Today the pump's `UpdateWorker` already queries peers each round and auto-STAGES; `full_auto_update` exists but nothing ever auto-applies (`produce_consent_notif` is a no-op for AutoApproved). GitHub fetch lives in the CLI, never the daemon. Ruled (grill 2026-09-23, CONTEXT.md cadence/consent): automatic by update class, by default. The node's AUTO SET is config data, default `[brain_only, adapters]` — the classes whose apply is zero-interruption under the handoff invariant. Broker-compatible / broker-breaking stay consent-gated (notif to the most-recently-active live session; byte-for-byte unchanged until acked). The set widens by config when releases#334 lands; an operator may narrow it to fully gated. No boolean full-auto switch. Mechanics: peer check keeps the pump cadence; the release-channel check runs on a heartbeat (recommend hourly, jittered) by the brain spawning the `spt update` CLI as a child, so the fetch stays CLI-owned and a service-hosted daemon without gh simply stays peer-fed. Apply order: core (brain swap) → adapters leg run from the NEW brain (closes the releases#329 class structurally) → notif. Sources tried per the update-source order (pinned → learned → peers → release channel). Gate: int e2e on a two-daemon rig — B auto-applies a BrainOnly set staged from A with no operator verb, the adapters leg runs post-swap, a BrokerBreaking set stays staged + notified. --- Requester: doyle