# W6 dispatch brief — SEAMLESS-UPDATES (#331), for todlando (doyle, 2026-09-24)

**Status: READY TO SEND. Held only until W5 (#338 apply) closes.** The blocker that made W6
undispatchable is gone: the three REQs it needs were minted and landed at `09ac94fd` (core PR #267,
on main at `437562d9`).

## Requests in the wave

| Request | REQ to activate | Stages to set |
|---|---|---|
| #337 now-signal update divulge | `REQ-NOW-SIGNAL-UPDATE-DIVULGE` | `["doc", "impl", "unit"]` |
| #64 `spt update status` trust anchor | `REQ-UPDATE-STATUS-TRUST-ANCHOR` | `["doc", "impl", "unit"]` |
| #340 adapter summary + changelog | `REQ-ADAPTER-CHANGELOG` | `["doc", "impl", "unit", "int"]` |

All three are on main at `required_stages = []` with a rule-5 comment naming exactly these stages.
**Activation is the first commit of the lane, not the last** — set the stages, then satisfy them, so
`traceable-reqs check` is gating the work the whole way rather than ratifying it afterwards.

## #337 — the divulge row

Row shape: `UPDATED <subject> <old> → <new> at <HH:MMAM|PM YYYY-MM-DD> — changelog: <url>`.
Unmoved subjects keep their current one-line shape **to the byte**.

- **Operator re-ruling, 2026-09-24 08:20Z, binding: NO new notification surface, NO ADR-0046 notif
  row.** The divulge lives inside the existing now-signal `<UPDATES>` block. A design that mints a
  notif row contradicts a standing ruling and I will refuse it at the gate.
- Reshape `gather_updates` in `crates/spt/src/api/nowsignal.rs` (~1216).
- The old version and the applied-at time come from the **apply record**, which both writers must
  write: the CLI path and the daemon pump path. A subject moved by either must read identically.
- **The seen-set stays the only event detector.** Its key already carries the version, so a moved
  subject re-tells exactly once. Do not add a second source for "something moved" — that clause is
  load-bearing in `REQ-NOW-SIGNAL-UPDATES` and this change must not weaken it.
- Degrade, don't error: an apply record that is absent, unreadable, or carries no prior version
  falls back to the unmoved one-line shape. No error line, no half-filled row. This rides a
  turn-boundary hook where a diagnostic is noise the author cannot act on.
- `[update].message` / the post-step notice folds into the same row. `spt update status`'s
  last-applied line per subject is UNCHANGED.

## #64 — the trust-anchor line

`spt update status` gains: `trust anchor OVERRIDDEN (identity/release-keys.json, key <id>,
channel <ch>, expires <date|EXPIRED>)` plus the cleanup hint.

- An **EXPIRED** override is still reported as PRESENT. An expired override changes what verifies;
  hiding it is the failure the requirement exists to kill.
- With no override file the verb says nothing new and its existing lines are unchanged to the byte.
- Read-only, like the rest of the verb: asks no peer, no channel, never rewrites or prunes the
  override file. `--json` carries the same facts as fields.
- **Not** `REQ-TRUST-WARNING-OVERRIDE` — that is the endpoint trust-*warning* advisory paragraph
  behind an elevation gate. Shared noun, different claim. This extends `REQ-UPDATE-STATUS-VERB`
  (landed at `9a77dc68`), it does not replace it.

## #340 — adapter summary + changelog

- Manifest `[adapter].summary` ≤ 300 chars plain text; `[adapter].changelog` an **archive-relative**
  markdown path, so the changelog ships inside the artifact it describes.
- Render md → HTML at install/update time (once, not per request); serve at
  `…/<node>/a/<adapter>/changelog`.
- **New dependency: `pulldown-cmark`.** Justify it in the PR body — that is a PR-body requirement,
  and a new dep landing without its justification is a gate finding.
- Both keys optional and additive: a manifest written before this stays valid.
- A declared path that is missing from the archive, unreadable, or not markdown **fails the INSTALL
  loudly** rather than installing an adapter whose changelog route serves a broken page.
- Schema + `docs/MANIFEST.md` amended in the **same commit as the parser**. The `REQ-SHELL-HINTS`
  precedent: a manifest section no manifest author can find reads as absent, so the doc stage lands
  where an adapter author looks, not only in the CLI reference.

## Coupling

#337 and #340 are coupled: the divulge row's `changelog:` suffix appears **only** when the subject
declares one. With no declaration the row ends after the applied-at time. Build #340's declaration
before or alongside #337's suffix, and prove the no-declaration arm in a unit — it is the common
case, not the edge case.

## What the gate will check

- `traceable-reqs check` exit 0 with the three REQs activated and their evidence tagged **on** the
  evidence, never at file tops.
- The unmoved-subject row byte-identical to today's (a pinned negative control, not an eyeball).
- Both apply-record writers proven, not one — a unit per writer.
- The no-declaration arm of the changelog suffix.
- The `pulldown-cmark` justification present in the PR body.
- No notif row, no second render site (the operator ruling).

## Lane hygiene

Branch off **current main** at dispatch time, not off this brief's sha. Claim the W5 pool only
after W5's lane is landed or explicitly finished — the claim records the lane's git identity and an
unlanded branch refuses. Pool verdicts come at the BUILD, never from `pool-claim` (IR-42).
