# Census: wake latency, pass 1

Status: ACCEPTED as proposed by the census owner on #280, 2026-10-24, as
`census-ruling-wake-latency-1`. Every row now carries
`rev3=census-ruling-wake-latency-1`; the `@legacy` fingerprints were
recomputed and the seal moved to
`09e20ea4bbc534710334e632e903878656dabfb5817d4d96c6e7c56508172148`.

The census owner's rationale (the recommendation, accepted): clock reads and
journal lines only, no read added or moved, the same class as the accepted
envelope re-pins.

The branch is `wake-latency-1`, cut from amadan `main` at 64a002c8. A dev
wake took 843 ms for an app that boots in milliseconds, and a box-wide
`systemctl daemon-reload` inside instance-control's generation start took
297 ms of it (dev box journal, 2026-10-24 11:16:31). The branch:

- starts a generation without the reload when systemd already reads its
  drop-in (`internal/instancectl/gen.go`, `startGen` and
  `genDropInApplied`): one `systemctl show` of Slice, NeedDaemonReload and
  the tier's three memory lines, and a reload only when any of them is not
  the drop-in's, then the same check again before the start;
- backs off health probes from 5 ms to 50 ms instead of a fixed 150 ms
  (`waitHealthy`, `waitHealthyAddr`);
- logs per-step wake timing to the journal (`wakeSteps`).

It adds one root-read overlay,
`internal/provision/testdata/plan14-root-reads-wake-latency-1.tsv`, loaded
last in `TestPlan14RootReadCensus`, after `db-region-forward-3` (the overlay
main loads last at 64a002c8).

## Root reads

Executing identity, for every unit: the agent (`/opt/carlos/carlos agent`,
`carlos-edge.service`, user carlos).

| unit | change | proposed disposition |
|---|---|---|
| `internal/activator/activator.go` `Service.doWake` | marks the end of each wake step on the wake's timer: `a.now()` and a slice append, journal only. No read added, no step moved | re-frozen at `census-ruling-292fix` with this change appended |
| `internal/activator/activator.go` `Service.wake` | logs that timer's breakdown after a successful wake. No read added | re-frozen at `census-ruling-carlos-run` with this change appended |
| `internal/activator/backend_exec.go` `ExecBackend.startUnitAt` | times the unit's launch and its health wait with `time.Now()`, and logs both after a successful health wait. The log names `rt.Host`, which is the new `registry:Host` site. No read added, no behaviour changed | re-frozen at J1 (`root-route`) with this change appended |

Frozen declarations are added, so the seal moves from
`79cb56b4c7d3a8e155d1eff1902715d818fcf4c09b1d8a82921c413b116938a9`
(`db-region-forward-3`'s, checked before the overlay loads) to
`09e20ea4bbc534710334e632e903878656dabfb5817d4d96c6e7c56508172148` (it
was `5976190a…4b1a` while the rows were PROPOSED).

Two envelopes are re-pinned:

| envelope | why |
|---|---|
| `internal/activator` | the units above, `wakesteps.go`, and the health-probe backoff in `backend_exec.go` and `backend_unit.go` |
| `internal/instancectl` | `startGen`'s drop-in check in `gen.go`, and the timings on its start log line |

`startGen` is outside the scanner's units: its `systemctl` calls run as
instance-control (`carlos-instance-control.service`, root), the same calls
in a different order, and the reload is now conditional. Review: Astra round
1 found one P2 (NeedDaemonReload is mtime-based, so a reused and
still-loaded generation could read as applied). It was fixed by checking the
tier's memory lines, and round 2 was clean.

Record-write census (9B8): unchanged. Claim routes: unchanged. go.mod:
unchanged.
