SEAMLESS-UPDATES W8: the node's surfaces show what is installed.

Fixes BigscreenVR/spt-bs-releases#332
Fixes BigscreenVR/spt-bs-releases#269
Fixes BigscreenVR/spt-bs-releases#259

## What changes

- **Docs sidebar (#332).** The bundle's pages load mdBook's *fingerprinted* sidebar script (`toc-<hash>.js`). The daemon answers that name with the static script plus an **Installed on &lt;node&gt;** part, placed just before Reference.
  - The part lists spt-core first, then the Harness / Shell / Gateway Adapters groups. All three groups always appear, and Reference shifts by a fixed 4 on every node.
  - Only this one response is `no-store`, because its name does not change when the roster does.
  - A script that is not in mdBook's shape is served verbatim.
- **Adapter pages (#332).** `/<node>/a/<adapter>/about` is new and every installed adapter gets one.
  - Header: version, installed time, and source (`built-in` / `subnet` / `release`).
  - Then the summary, the install-time changelog embedded as-is, and a docs link on the title. Each appears only when declared; everything undeclared is named on one dim line.
  - The page is a per-request template over records. The daemon never renders markdown, and `/changelog` keeps its landed contract.
  - The time and source come from the retained-archive sidecar (`current_source`, `current_at_ms`), which is written only when new bytes land. They do not come from the registry stamp, which moves when the same path is re-added.
- **`spt adapter list` (#269 + the #264 tangential).**
  - A Types header, then groups in the order HARNESS / GATEWAY / SHELL.
  - Each row reads `name vX.Y.Z` in cyan, with `(built-in)` when it applies. Shipped profiles nest dimmed as `:profile`, and local ones show in orange as `:profile (custom)`.
  - An **Available on subnet** section lists what peers publish that this node lacks, read from the registry snapshots with no dial. Versions are ordered numerically.
  - No registry jargon. `--json` is additive only.
- **Roster row** gains `hostable_types` (serde-default, skipped when empty), so a peer's Gateway adapter groups correctly. A unit test pins both directions: an old decoder ignores the key, and an old row decodes as an empty list, which groups by kind.
- **Picker (#259).** Every place that names an adapter shows ` v#.#.#`. A remote endpoint's version comes from its own node's roster.

Pure logic lives in `spt-runtime::surfaces`, `crates/spt/src/adapterlist.rs` and `picker::model::versioned`. W9 (#305) moves only the call sites in `webserve.rs`.

`chrono` joins `spt-runtime`; it is already in the workspace via `spt`. No new supply chain.

## Requirements

REQ-DOCS-NODE-TOC, REQ-DOCS-ADAPTER-PAGE and REQ-ADAPTER-LIST-SURFACE are activated with the doc/impl/unit/int stages. REQ-PICKER-ADAPTER-VERSION is activated with impl/unit.

## Evidence at 1aecaa95 (HFENDULEAM, rebased on 75fc889a)

- `xtask check` rc=0; `traceable-reqs check` rc=0; clippy `-D warnings --all-targets` rc=0.
- nextest units (surfaces, relcache, adapterlist, picker, net::update): 128/128.
- `docs_server_e2e` 5/5, `json_emit` 2/2.
- HEAVY runs solo, the box checked idle first: `adapter_peer_e2e` 1/1 and `source_ladder_e2e` 1/1. Zero leftover `spt` processes.
- Every new integration test has a negative control that fails when its code is broken, and each mutation was restored with a sha256 check.
- **No new test binaries.** The new integration tests are fns in the existing `docs_server_e2e` (in-process, port 0) and `json_emit` (`adapter list` reads files only). No `spt api` call, no `daemon run`, no autostart verb.
- Not run: Linux locally (this PR's CI covers it).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_014j8UXzGXXsDsTJBYYUSCTC
