Astro 7 with the Node adapter, Starlight mounted at /docs, the token file, both
self-hosted typefaces, the layout shell, and the two build-time checks from §12.
The palette's gold and cyan are sampled from runic-emblem.png rather than
guessed, per §11: 494,059 opaque pixels binned by hue, each value annotated with
its measured contrast against the ground, and restricted rather than brightened
where a ratio fails.
- checkTokens.mjs fails the build on any colour literal outside tokens.css,
which is what keeps §7's "recolouring is a file copy" promise true.
- checkFacts.mjs re-reads all 14 externally-sourced facts from their authorities
over the Gitea API and fails on disagreement. It also enforces D13: no email
address in the source outside brand-default/brand.json.
- Both were negative-tested; neither has ever been allowed to pass by default.
§6 asks for output:'server' with per-page prerender=true. Astro 7 expresses the
same runtime shape as output:'static' with an adapter, opting individual routes
out — so the default is static rather than accidentally server-rendered.
Co-Authored-By: Claude <noreply@anthropic.com>
The domain still has no mailbox. Rather than delay the beta on Cloudflare
Email Routing, the org lead elected to publish the existing address.
- D13 recorded: whitlocktech@gmail.com is the published contact, held only
in brand.json so a later privacy@/security@ is a file copy, not a rebuild.
- Phase 0 PR 0.10 withdrawn -- SECURITY.md already carries that address.
- checkFacts.mjs gains the rule that keeps the promise true: no email
address in the source outside brand-default/brand.json.
- Phase 0 marked complete (docs#172, docs#173, .profile#4, Module-uo#19).
Co-Authored-By: Claude <noreply@anthropic.com>
Revision 1 ended in five open questions. All are now answered, plus the
domain and Gitea-registration facts, so the plan states decisions instead
of asking.
New section 5 holds the twelve decisions of record. Sections 6-9 design
against them: the Astro + Node adapter runtime, branding resolved out of a
bind mount against baked defaults, the Android closed-beta signup, and the
legal pages the beta cannot ship without.
Re-verified every version against the Gitea API and corrected three things
revision 1 got wrong: the bundle manifests live at the root of the bundles
branch rather than under bundles/, the website publishes no releases at
all, and the Android app targets no server of ours - the user enters the
address, which is load-bearing for the privacy policy.
Phase 0 grows from the four operator-facing documentation fixes to all
ten conflicts, plus retiring the personal Gmail that SECURITY.md
publishes as the public vulnerability contact.
Two design notes worth flagging. Play does not notify testers on the
email-list path either, so a site that sends no mail looked blocked - but
the closed-testing opt-in URL only works for addresses already on the
list, so it is safe to publish on the confirmation screen, with Discord
carrying the announcement. And the CSV export is a CLI against the bind
mount rather than an admin page, so the site keeps no authenticated
surface at all.
The demo instance is recorded as planned and out of scope: a Proxmox VM
running the full stack including ServUO, restricted and reset hourly. The
site reserves its slot now so it costs one line in a bind-mounted file
later.
Co-Authored-By: Claude <noreply@anthropic.com>
Reconnaissance across the nine RunicGateway checkouts, and the plan for the
public site + documentation experience built on top of them.
The site is a presentation layer over existing project knowledge: normative
contracts stay canonical in docs/ and are linked, never copied. What the site
authors is the journey — install, configure, administer, extend — which no
existing document owns end to end, because the repos are organised by
component and an operator is not.
Two things worth reading before the rest:
- Section 3 lists eleven places the repositories contradict each other,
verified against origin/main rather than resolved quietly. The sharpest is
that link/INTEGRATION.md documents the protocol-4 event kinds while its
normative section 2 still declares X-UOLink-Version: 3 — one document
disagreeing with itself. installer/INSTALL.md still hands operators
"Protocol version 3", which is the value they paste into Admin -> Shard,
and its own troubleshooting table says a stale number looks exactly like
the shard going offline.
- Section 4 makes fixing those a Phase 0 that lands before the site quotes
anything: four PRs across docs and .profile, none of which touch code or a
contract. They correct documentation to match what main already does.
Section 1 also records a process failure and the rule taken from it. An
earlier draft claimed the platform was on protocol 3 with 4 "not cut over".
Every checkout was on a feature branch whose local main ref had never been
fetched, so git show main:<path> answered from a months-old blob. Every fact
in section 2 is now read from origin/main or the Gitea API, and section 7
turns that into a build-time check instead of a promise.
Section 9 leaves five questions open rather than assuming answers.
Co-Authored-By: Claude <noreply@anthropic.com>