feat(site): phase 17 - per-game module pages, /runicnpc/, and checkTerms over the built site
All checks were successful
PR checks / checks (pull_request) Successful in 2m37s
All checks were successful
PR checks / checks (pull_request) Successful in 2m37s
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
This commit is contained in:
109
PLAN.md
109
PLAN.md
@@ -237,7 +237,7 @@ Taken by the org lead (Colby Whitlock) on 2026-08-19. Recorded so they are not r
|
||||
|
||||
**Decisions after D13 are recorded where they were taken**, in the section describing the phase that
|
||||
raised them, rather than appended here — a decision is only re-litigated when its reasoning is
|
||||
somewhere other than the thing it decided. The count of record is **seventy-four**:
|
||||
somewhere other than the thing it decided. The count of record is **seventy-nine**:
|
||||
|
||||
| # | Where | What it settled |
|
||||
|---|---|---|
|
||||
@@ -260,6 +260,7 @@ somewhere other than the thing it decided. The count of record is **seventy-four
|
||||
| D68–D69 | §16, "How phase 14 built it" | A game's real example on a core page is a tagged, labelled block; *Verify the whole stack* stays in Getting started, game-neutral (amending D60) |
|
||||
| D70–D71 | §16, "How phase 15 built it" | The Rust group is fifteen pages, one per admin screen where it can be; the Rust event kinds are checked against the module's own classification |
|
||||
| D72–D74 | §16, "How phase 16 built it" | The RunicNPC subgroup is eight pages with a shared profile-field reference; the API check compares signatures and every data shape's field names; the site's API page carries the current API only, with no decision numbers and no version history |
|
||||
| D75–D79 | §16, "How phase 17 built it" | Core marketing pages describe what a game module adds in core's words and link to each game's page; the homepage keeps its game screenshot, labelled; `/app/` describes the Rust screens, released the same day; `/runicnpc/` is in the header; `checkTerms.mjs` gains a pass over the built pages |
|
||||
|
||||
---
|
||||
|
||||
@@ -1675,8 +1676,10 @@ a mechanism rather than diligence:
|
||||
- **`scripts/checkTokens.mjs`** — no colour literal outside the token file (§7).
|
||||
- **`scripts/checkTerms.mjs`** — added in phase 14 for D63 and D64, the twelfth check. No game's
|
||||
vocabulary outside that game's section: its docs group, its sidebar group, or a
|
||||
`<GameExample>` block (D68). Reads the docs and both sidebar trees; phase 17 widens it to all of
|
||||
`src/`.
|
||||
`<GameExample>` block (D68). Reads the docs and both sidebar trees before the build; since
|
||||
phase 17 (D79) a second pass, `--built`, reads every built page's visible text after it, so
|
||||
the marketing pages and the words their data renders are covered too. A game's own routes, and
|
||||
an element marked `data-game`, allow that game's words.
|
||||
- `astro check` plus a production build, in CI on every PR.
|
||||
|
||||
---
|
||||
@@ -2262,6 +2265,106 @@ exception to "every page links out".
|
||||
The check parses them line by line and was not affected. Fixed at the org lead's ask in `docs`
|
||||
#371, which removes the two blank lines and changes nothing else.
|
||||
|
||||
### How phase 17 built it
|
||||
|
||||
Five decisions, taken by the org lead on 2026-10-22 before any page was written, each from a
|
||||
concrete example. The count of record is now **seventy-nine**.
|
||||
|
||||
**D75 — core marketing pages describe what a game module adds in core's words, and link to
|
||||
the games.** The homepage, `/features/`, `/architecture/` and `/app/` name both games and use
|
||||
neither game's vocabulary. The module-supplied group became *What a game module adds*: seven
|
||||
things both modules supply, each in its own way (live server status, a live feed, leaderboards,
|
||||
maps, Teams from the game, players' own game accounts, game steps for events), with a button
|
||||
to each game's page. Each game's real list, in its own words, lives in `src/data/games/` and
|
||||
renders only on `/modules/uo/` and `/modules/rust/`. The alternative was D68 applied to
|
||||
marketing — game-labelled blocks carrying each game's real list on the core pages. It was
|
||||
declined as longer, and as the front door carrying two games' jargon at once.
|
||||
|
||||
**D76 — the homepage's "What it looks like" keeps its game screenshot, labelled.** This is
|
||||
D67's choice, made. The capture stays the Ultima Online live-status screen, now printing
|
||||
"Ultima Online" beside it, because the claim under the data-path diagram is live game state
|
||||
on a public page and no core screen shows that. Phase 18 adds a labelled Rust capture beside
|
||||
it. The alternative, a core screen such as the admin dashboard, was declined.
|
||||
|
||||
**D77 — `/app/` describes the app's Rust screens.** When the phase began they were on
|
||||
`Android-app` `edge` only, 26 commits ahead of `main` and in no release. The org lead chose to
|
||||
describe them and release them the same day, rather than hold the page or say "next release".
|
||||
`/app/`'s game section is now *The game, live*: one item per game, titled with the game's name
|
||||
and written in core's words, plus Rust's half of *Your own side of the game*.
|
||||
|
||||
**D78 — `/runicnpc/` is in the header.** The top navigation is now five items, so a Rust
|
||||
server owner who runs no Runic Gateway finds the plugin from any page (D61's reason). It is in
|
||||
the footer's Product column and on the Rust module page's RunicNPC card too. The alternative
|
||||
was the footer and the card only.
|
||||
|
||||
**D79 — `checkTerms.mjs` reads the built pages.** D64 had the check widen to all of `src/`. A
|
||||
source scan of the marketing pages would see expressions rather than the words they render —
|
||||
a capability label, a screenshot caption, a value from `platform.json` — and would take ids
|
||||
like `shard-status` and slugs like `guilds` for prose. So the check gained a second pass,
|
||||
`--built`, run after the build the way `checkLinks.mjs` is. It reads every page's visible text
|
||||
plus `alt`, `title`, `aria-label`, `placeholder`, the `<title>` and the meta description, and
|
||||
not link targets, scripts, styles or comments. A game's routes (`GAME_ROUTES`: its docs group,
|
||||
its module page, and `/runicnpc/` for Rust) allow its words, and so does any element marked
|
||||
`data-game` — `<GameExample>` and, new this phase, a game-tagged `<Screenshot>`. Starlight's
|
||||
sidebar and the previous/next links are skipped, because the source pass reads the sidebar as
|
||||
data and each neighbour's title is checked on its own page. The source pass is unchanged and
|
||||
still runs first, naming a file and a line. Failures from the built pass name a route and a
|
||||
snippet. It is still the twelfth check: one script, one word list, one allowlist (whose entry
|
||||
now carries a `route` as well as a `file`). The alternative was a source scan with per-file
|
||||
exemptions.
|
||||
|
||||
**The check was proven before it was trusted.** Ten plants went into the built HTML. Six
|
||||
failed, each naming where: a word in a core page's text, in an `alt`, in a `title`, a
|
||||
UO word inside a block marked Rust, a word split across two syntax-highlighting `<span>`s, and a
|
||||
UO word on a Rust page. Four passed: a word only in an `href`, one in a `<script>`, UO words on
|
||||
`/modules/uo/`, and a UO block on a core page. On the build as it stood before this phase, the
|
||||
pass found 49 words on seven marketing pages; all are gone.
|
||||
|
||||
**What was built.**
|
||||
|
||||
- **`/modules/`** is core now. Its Ultima Online worked example became a card per game, from
|
||||
`src/data/games/index.mjs`, and what the modules share — a sidecar, their own tables, their
|
||||
own releases — is said once beneath them.
|
||||
- **`/modules/uo/`** carries the Ultima Online list that used to be *Game intelligence*, the
|
||||
three pieces with their versions, and the five screenshots `/features/` showed until now.
|
||||
- **`/modules/rust/`** carries eight features for players and four for staff, written from the
|
||||
Rust docs group phase 15 walked, the four pieces (the module, rust-link, `RunicGateway.cs`,
|
||||
RunicNPC) and the RunicNPC card D61 asked for. It has no screenshots and no slots for them
|
||||
(D65, D4).
|
||||
- **`/runicnpc/`** is written for a server owner with no site: what it does, the two ways to run
|
||||
it, and where to get it. Every number is read — release, API version and floors from
|
||||
`platform.json`, the counts of calls and hooks from `runicnpc.mjs`, which phase 16's check
|
||||
holds to `API.md`.
|
||||
- **The page-side capability check is per game**, closing the item phase 13 moved here.
|
||||
`assertGameCoverage()` holds each game's list to its module's declared capabilities in both
|
||||
directions. The homepage, `/features/` and each game page call it, and
|
||||
`assertDetailCoverage()` now reads the games' lists too.
|
||||
- **The supported-games strip** (D63) is `src/components/SupportedGames.astro`, on the homepage,
|
||||
`/features/` and `/modules/`.
|
||||
- **D67 is in the components.** `screens.mjs` entries may carry `game`; nine are tagged `uo`.
|
||||
`Screenshot.astro` and `/app/`'s phone grid print the game's name beside each tagged capture
|
||||
and mark it `data-game`.
|
||||
|
||||
**What the re-read found**, fixed here:
|
||||
|
||||
- **`/architecture/` said two machines is "the minimum and also the maximum"**, false since Rust
|
||||
shipped: one sidecar serves one server, so a community with six servers runs six. The caption
|
||||
now says two is the minimum and a sidecar sits beside each game server, and its game host
|
||||
section no longer says the installer prints "four values" (that count was one game's).
|
||||
- **`/integrations/` and the Discord capability called a Discord server a "guild"** — Discord's
|
||||
API word, but read on this site as a game's. They say *Discord server* now, as phase 14 made
|
||||
the docs say.
|
||||
- **`collection.mjs` was re-read against what the Rust module and Steam sign-in keep**, as the
|
||||
plan required, before anything was claimed. *Account records* now names linked sign-in
|
||||
identities, Steam's display name and avatar address included (`user_identities`). *Game data
|
||||
from the connected server* names, for Rust, each player's Steam id and in-game name, their
|
||||
statistics, who is online, and the event record, which includes chat, player reports and the
|
||||
IP addresses on sign-in attempts and bans, readable by staff only. Its retention now states
|
||||
the module's 30 days for that record and the sidecar's 14-day default. The Play Data Safety
|
||||
answers did not change: the app's Rust screens read from the deployment and send it only a
|
||||
one-time link code, which the existing "everything you read and post" row already covers. Its
|
||||
wording lost "shard", so `PLAY_DATA_SAFETY.md` was regenerated.
|
||||
|
||||
---
|
||||
|
||||
[api]: https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/website/MODULE_API.md
|
||||
|
||||
Reference in New Issue
Block a user