# W7 dispatch brief — releases#336, automatic background updates

**Lane:** `feat/331-w7-auto-apply` off main **`9315f649`** (the seed, already landed).
**Builder:** todlando. **Rig:** hertz's `auto_apply_e2e`, proven RED on main 2/2 before any
implementation existed — it rides THIS lane, it does not land separately.

## The four REQs are already minted and are yours to activate

All at `required_stages = []`; activation is the lane's FIRST commit, never ahead of it:

| REQ | stages to activate |
|---|---|
| `REQ-UPDATE-AUTO-CLASS-SET` | `impl`, `unit` |
| `REQ-UPDATE-AUTO-APPLY` | `impl`, `unit` |
| `REQ-UPDATE-RELEASE-HEARTBEAT` | `impl`, `unit` |
| `REQ-UPDATE-AUTO-APPLY-ORDER` | `impl`, `int` |

`REQ-UPD-4` was amended in the seed. Do not re-amend it, and do not move its tags: its shipped
`consent::decide` / `consent::most_recently_active` evidence is unchanged by W7.

## What is already ruled — build it, do not re-derive it

1. **The migration is three cases.** `full_auto_update: true` → every class. An **explicit**
   `false` → the EMPTY set. **Absent** → the default `[brain_only, adapters]`. Only the absent
   case becomes more automatic than today. The deprecated key is read once, never written back;
   a config carrying both keys takes `auto_classes` and says so once in the daemon log.
2. **`auto_classes` is its own vocabulary** over `{brain_only, broker_compatible, broker_breaking,
   adapters}`, with a total mapping from `UpdateClass` onto the first three. `broker_compatible`
   is OUT of the default until releases#334.
3. **The heartbeat child stages and never applies.** Spawn from the canonical exe path captured
   at broker start (KNOWN-HAZARDS 6.11 binds every spawn on this path), detached, no inherited
   job object or stdio. A killed child is a no-op retried next heartbeat.
4. **The broker is the swap initiator** — it calls `applyhost::apply_staged` in-process when a
   newly staged set's class is in the auto set; the existing trial/promotion path then proceeds
   unchanged.
5. **Cadence:** a SECOND period, default 3600 s + additive jitter uniform `[0, 600)` s per check.
   `update_check_period_ms` stays the peer pump cadence and is not overloaded.
6. **Ordering is provable from state:** the apply record carries the core version that performed
   each adapter update; the int asserts it equals the NEW core version.

## The one thing NOT ruled, deliberately

`apply_staged`'s signature takes a broker socket name — written for an out-of-process caller — so
a broker calling it would be dialling its own socket. The daemonless variant, a split, or a
deliberate self-dial with stated reasons are all answerable. **Decide it with the code in front
of you and say which you chose and why.** Do not inherit whichever compiles first.

## Pre-flight, standing

- Claim the pool from INSIDE your worktree; release it at lane end.
- Census writers on the box BEFORE any capture, and read the census before you act on it — that
  is a lesson I paid for on my own reap today, not advice.
- Right-size the legs: `cargo check` before suites, targeted units before batteries, and never
  fire an e2e into a window where another lane holds the box.
- Stop-and-refer on any NEW class of decision. A known-mechanism red is yours to rule and record.

## Gate expectations

I will gate from my own rig at your head: compile gate, the targeted units, hertz's
`auto_apply_e2e` int, `traceable-reqs check`, and the two-daemon acceptance #336 names. I will
re-run the security-shaped and ordering-shaped tests BY NAME — a pass count is not evidence that
the test I care about exists.
