Commit Graph

4 Commits

Author SHA1 Message Date
769d213c80 feat(demo): list the demo's sign-ins on /beta and link into it per game
Some checks failed
PR checks / checks (pull_request) Failing after 2m16s
The public demo (demo.runicgateway.com) is live, so the site's demo slot
can be switched on. Two decisions of record, PLAN.md §15:

- D82: /beta reads the demo's GET /api/v1/public/settings demo.logins on
  the server, caches it for a minute, and lists the published sign-ins
  with the next wipe. If the demo does not answer, /beta links to its
  sign-in page instead. Gate two reads as in place.
- D83: a deep link into a game module's pages carries data-demo-game, and
  applyBrand.mjs fills it only for games in the new mounted demoGames
  list. The Rust features gain links into /rust and /rust/servers/demo.
  UO's stay hidden on a Rust demo.

The public-demo not-built entry is removed, because its resolvedBy was met.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-28 15:32:34 -05:00
9938e71e07 feat(facts): phase 13 - per-game facts, Rust and RunicNPC checked, main green again
All checks were successful
PR checks / checks (pull_request) Successful in 8m25s
platform.json drops the single protocol/bundle/capability list for a
`games` object (uo, rust) plus a `runicnpc` block. checkFacts.mjs loops
the protocol, plugin-protocol, capability and bundle checks over both
games, reads the schema-2 bundles at v2/<game>/current.json, checks each
module's coreApi, and reads RunicNPC's plugin.toml. 41 facts, up from 19;
clears the two that were red on main (Module API 1.17.0, installer
v0.8.0).

D66: the hero, footer and structured data show the Module API only; each
game's protocol and bundle go on that game's pages, and the docs landing
table splits into shared versions plus one column per game.

The re-read section 1 requires found, and this fixes:
- three hard-coded "1.6.0" Module API versions in the module docs
- module-lifecycle saying modules load alphabetically (the loader now
  refuses a second module, W19), and the install pages never mentioning
  the one-module rule
- "there is one module" in five places, now two modules both built
  inside this project; the Integration Kit keeps its draft banner
- the homepage diagram's ServUO/uo-link sub-labels (D63 wording now)

notBuilt drops `second-module` (resolved by Module-Rust's release) and
rewords `multi-module`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-22 08:09:22 -05:00
1313e748ae feat(beta): phase 5 — the app page and the closed-beta signup
All checks were successful
PR checks / checks (pull_request) Successful in 1m5s
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>
2026-08-24 03:50:51 -05:00
2d19ee4220 feat(marketing): phase 4 — the marketing pages
All checks were successful
PR checks / checks (pull_request) Successful in 9m9s
PLAN.md §13 phase 4: /features/, /architecture/, /modules/, /integrations/, and
/community/ — plus the two scope items the phase table never assigned to anyone.

Six decisions taken by the org lead before coding, recorded in PLAN.md §10 as
D20-D25:

- D20 /features/ is the homepage's list with a `detail` line, not a second list.
  One data file, two renderings, so they cannot disagree about what exists.
- D21 /architecture/ draws reasons, not reference: three new inline SVGs, one per
  boundary. No endpoint tables, no config keys — those are phase 8's and stay
  canonical in docs/.
- D22 The deliberate absences of §2 become one tagged data file, rendered on the
  three pages that promise them.
- D23 Phase 4 absorbs /community/ (specified in §10 and §14 N3, linked from the
  header since phase 1, built by no phase) and checkLinks.mjs.
- D24 `needsModule`: writing the Teams detail exposed a false claim phase 3
  shipped. Teams are module-sourced only — teams.module_id is NOT NULL, there is
  no create route, sync is gated on providerModuleId() — so the Community group
  no longer says a bare core does all of it.
- D25 The per-capability demo affordance brand.json had promised since phase 2 is
  a deep link, filled at boot from data-demo-path.

checkLinks.mjs reads the built HTML rather than src/, because half these links
are assembled from data files and template literals. Its PLANNED_ROUTES list is
checked in both directions, so it cannot rot into a permanent exemption.

applyBrand.mjs gained a pass that recomputes deep links from their immutable
path, making it idempotent and reversible; checkBrand.mjs lifts that pattern out
and runs it against the stock markup so the two cannot drift. Both proved
against a real mount, in both directions.

Fixes a cascade bug the checks could not see: [data-demo-url=''] and a scoped
component class are both specificity 0,1,0, so .demo-link's `display` beat the
hide rule and twelve links to a nonexistent demo rendered, each resolving to the
current page. The rule is now !important.

The four diagrams' shared SVG vocabulary moved to src/styles/diagram.css.

Verified from a clean checkout: npm ci, all five checks, astro check (0 errors),
production build, and a live browser pass at desktop and 390px.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-24 01:53:11 -05:00