Nine captures tagged rust (D65): the server list, feed, leaderboard,
live map, permissions and the RunicNPC profile editor on the web, and a
server's feed, its map and the player's Rust account in the app, from
an Android-app edge debug build.
D80: every name in a capture is a role (admin, moderator, player...),
from this phase on. D81: the Rust demo's players are mock data written
by scripts/mockRustDemo.mjs; the server, its status, map, permission
groups and RunicNPC sync state are the real Oxide test server's. The
captions and /modules/rust/ and /app/ say which part is a demo cast.
seedDemo.mjs gains --game rust (server row with a weekly wipe, public
presence for the demo, two NPC profiles, a VIP group). captureScreens.mjs
gains a click list per screen. The homepage shows the Rust live map beside
the UO capture (D76); three Rust docs pages carry their screen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
PLAN.md §16 phase 17, built on the org lead's answers of 2026-10-22,
recorded as D75-D79 (count of record 79).
- D75: core marketing pages describe what a game module adds in core's
words. "Game intelligence" became "What a game module adds"; each
game's own list moved to src/data/games/ and renders only on the new
/modules/uo/ and /modules/rust/. /modules/ is a card per game.
- The page-side capability check is per game (assertGameCoverage), the
item phase 13 moved here.
- D76: the homepage keeps its game screenshot, labelled. screens.mjs
entries may carry `game` (D67); Screenshot.astro and the app grid
print the game's name and mark the figure data-game.
- D77: /app/ describes the Rust screens (released the same day).
- D78: /runicnpc/, the standalone page, is in the header and footer;
the narrow header was re-measured so five links keep two rows.
- D79: checkTerms.mjs --built reads every built page's visible text
after the build; game routes and data-game elements allow their
game's words. Proven against ten plants. Still the twelfth check.
- Re-read fixes: /architecture/'s "two machines is also the maximum",
Discord "guild" on /integrations/, and collection.mjs against what
Steam sign-in and the Rust module keep (PLAY_DATA_SAFETY.md
regenerated; the Play answers are unchanged).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
D4 asked for screenshots of the review stack rather than placeholders. Seventeen
of them: eleven of the site in a browser, six of the app on a phone, all from one
demo deployment wired to a running ServUO shard over a real sidecar, captured on
one day (D42).
The deployment is branded "Runic Gateway Demo" rather than a real community (D43),
and the captures sit beside the claims they support — the homepage, /features/, and
five of the administration pages phase 7 could describe but not show (D44).
The rig is committed rather than remembered (D45):
scripts/seedDemo.mjs content, by driving the site's own API — never SQL,
because a row the product could not have produced is
a screenshot of a product that does not exist
src/data/screens.mjs every capture: route, viewport, scroll, alt, caption
scripts/captureScreens.mjs npm run screens:capture
scripts/checkScreens.mjs the ninth check script, in CI
Shard-side dressing is servuo-plugins' scaffolding (D46), never deployed.
The rig found five things nothing else had. One is fixed upstream — a fresh
module-uo install pinned wire protocol 3 against a sidecar speaking 4, released as
v1.0.2, which this repo's own facts check then caught in platform.json. Four are
raised as product observations and worked around in the rig: a renamed guild
member never reaches the site, a guild deleted while the shard is down is a ghost
row forever, "Houses in danger" cannot show a house that was already collapsing,
and the app's news list prints raw ISO timestamps.
Players online reads 0. Logging a character in needs a UO client driven by hand,
and that is where this stopped — PLAN.md §10 says exactly why, and how to retake
the two frames that would change.
Co-Authored-By: Claude <noreply@anthropic.com>
Builds `/app/` and `/beta/`, the SQLite signup store, the rate limiting and the
export CLI of PLAN.md §8, and adds this repository's first test suite.
Four decisions of record, D26–D29 (§8, "How phase 5 built the app and the beta"):
- D26 — the screenshot slot ships empty, reserved for phase 9. §10 promised
`/app/` "the 14 existing screenshots"; they are a July trusted-device smoke
test against an unseeded dev instance, captured before the theming work, and
five of the fourteen are two-factor prompts. Shipping them would break D4.
Phase 9 already builds the rig, so it gains an emulator pass.
- D27 — the public demo is the tester target. `ConnectScreen.kt` gates the whole
app on a validated deployment address, so a tester needs somewhere to point it.
The beta therefore waits on the demo VM, and the page says so.
- D28 — `/beta` handles its own POST; there is no `/api/beta-signup`. An endpoint
cannot report a validation error without JavaScript. §6's diagram is amended.
- D29 — the APK and the beta get equal billing, and the APK link is off:
`androidApk.serviceable` is false because the published v0.5.0 build does not
work. The panel stays and states that plainly rather than being removed.
Three mechanisms the plan did not anticipate:
- `liveBrand()` — a server-rendered page never passes through the boot rewrite,
so `/beta` reads the mounted brand.json itself. Pasting the Play opt-in URL in
takes effect on the next request rather than the next restart.
- `checkLinks.mjs` derives on-demand routes from `prerender = false` in the
source. A PLANNED_ROUTES entry would have been wrong: its reverse check fires
when a route has been built, and an on-demand route never produces a file, so
the entry could never rot out.
- `npm test` — the five existing checks all read built output, and none of this
logic appears there. A honeypot can stop working and leave the build identical.
Also: `checkFacts.mjs` gains the APK assets and `minSdk`, and learns that RFC 2606
reserved domains are not contact addresses; the D13 rule is otherwise unchanged.
Verified end to end against the built server: every outcome renders with no
JavaScript, cross-origin POSTs are refused, a mounted opt-in URL appears without
a restart, and the export CLI round-trips.
Co-Authored-By: Claude <noreply@anthropic.com>