---
name: node-local-book-gate
description: "The spt docs book at localhost:5474 is NODE-LOCAL — a published core version's docs are unreadable here until this node updates; and validate the instrument before trusting a zero-hit grep."
metadata: 
  node_type: memory
  type: project
  originSessionId: 2c19f52d-24b6-4027-8f3f-a5841747c348
  modified: 2026-08-26T01:52:16.776Z
---

2026-08-26. doyle said "core v0.63.0 is PUBLISHED — check the book for the pass-through section your
build gates on; if it is NOT showing, that is a docs-publish gap on our side." It was showing nothing,
and it was **not** a publish gap.

**The book at `http://localhost:5474` is served from this node's own docs bundle.** Core stays at the
installed version until `spt update` runs; the docs bundle rides that same update
(`UPDATE_DOCS_LANDED: %LOCALAPPDATA%\spt-core\docs`). So a section can be published upstream and be
genuinely absent locally, indefinitely. `spt update --core-only` fetched core + the docs bundle and
the section appeared immediately — no daemon restart needed to read the book (a restart is only owed
for daemon-coordinated features, and `--restart` would bounce hosted sessions including me).

⭐ **"The published book" and "the book on this node" are different artifacts.** When a build gate says
read it on this node's own book, the first move on a "docs are published" message is
`spt update --core-only`, not a grep. doyle banked this too — his future "check the published book"
instructions will say "after `spt update --core-only`".

⭐⭐ **Validate the instrument before trusting a zero.** The pre-update grep returned 0 hits, which reads
identically to "the book server is down" or "I fetched the wrong URL". I confirmed HTTP 200 / 657KB on
`print.html` AND that control terms (`mnemonics-json` ×4, `EVENT` ×58) hit on the same fetch, so the
zero was a real absence. Same discipline as [[msys-grep-instrument-traps]] and
[[list-vs-predicate-assertions]]: a reassuring answer from an unvalidated instrument is the recurring
trap here, and it costs nothing to prove the instrument on the fetch that produced the negative.

⭐⭐⭐ **2026-08-28 — localhost:5474 is not a local MIRROR of a canonical web surface; it IS the canonical
surface.** I hit `https://sabermage.github.io/spt-releases/manifest.schema.json` returning 404 (the whole
Pages host 404s) and reported it to doyle as a public-surface OUTAGE. It is not an outage: **ADR-0036
("The Forkening", 2026-07-14) deliberately killed public Pages** and privated `SaberMage/spt-releases`
— GitHub has no private Pages below Enterprise, so the 404 is by construction and permanent. The
canonical docs AND schema URL is `http://localhost:5474`, shipped as a signed docs-bundle asset with
every release so it always matches the installed core; the schema's own `$id` already says so, and the
release asset (`manifest.schema.json` in each signed update-set) is the other sanctioned source.
Refreshing a vendored schema from localhost:5474 is the CONTRACT-CORRECT move, not a workaround.
The report was still worth making: `docs-site/reference/schema.md` still calls the dead Pages URL "the
stable URL" (hand-written prose the drift gate cannot see), plus two sibling pages — core is amending
all three. **Reporting rather than working around turned a stale doc into a fix; and I had to retract
"outage" in doyle's favour.** Note the AGENTS.md public-surface rule names the Pages site — read that
as localhost:5474 now.

Related: [[v0300-seal-carry]] (the build this gated), [[stale-update-notice-spool-copies]] (`spt notif`
is a spool, not a version truth — `spt --version` is).

## ⭐⭐ SHARPENED 2026-09-11 — the served book is not evidence about what a VERSION SHIPPED

The gate above says the book at `localhost:5474` comes from THIS NODE's bundle, so "published" does
not mean readable here. The 2026-09-11 case is the mirror image and it cost a wrong conclusion:
**this node's bundle carried text NEWER than its own binary.** Running spt-core 0.67.1, the served
`harness-contract/echo-commune` already stated "The echo routes; it does not file" — and the TAGGED
0.67.1 doc does not contain that statement. How the node acquired newer doc content is unestablished.

So the served page can skew in BOTH directions, and neither direction is a version claim:

- **older than published** → the original gate (a feature reads as missing when it shipped).
- **newer than installed** → I argued a shipped manifest floor was too high, from a page describing
  behaviour the running binary did not have.

⭐⭐ **Only the RELEASE TAG answers a version question.** doyle settled it by checking the behaviour
in two tagged releases; I reasoned from a web page about behaviour I had never observed. A served doc
describes whatever bundle is on disk — use it to learn a contract, never to date one.

See [[v0400-echo-race-workaround-retired]] for the full case, including the sharper consequence: on
0.67.1 the race was PRESENT, so the single wake I had cited fired by WINNING it.
