Phase 13 was the only phase in the workstream with no as-built section, which
6.0b makes a phase's own deliverable. It has one now, and it has something to
record beyond "it merged":
* the window missed steps 5 and 7 (Integration-kit, runicgateway.com); they
landed afterwards, with a third PR clearing a leftover from step 4;
* Gitea's `raw` API route is CDN-cached for six hours, and a stale read fails
BOTH ways -- it failed a correct site AND reported an already-republished
bundle as current. All three cross-repo checks read `contents` now;
* the Integration-kit equality check never goes red on its own. It clones the
ref the kit itself pins, so the kit sat three minor versions behind, green,
for the whole workstream. Step 5 is the only thing that makes anyone look;
* `registerEngagementSeeds` does not validate the body it seeds, and the kit's
own example was malformed. Only a run through core's REAL registry found it,
which the kit's CI does not do and cannot;
* every `edge` was deleted rather than fast-forwarded. Recorded as the
convention, because a branch that does not exist cannot be branched from
stale -- which was 6.0a's actual failure.
Phase 12's second finding becomes **Phase 14**, scoped and not started: four
tables with no retention sweep, and they are not one problem with one horizon.
`engagementCooldowns.db.prune()` already exists with no caller; the send log has
two live readers (the hourly cap's index and the operator screen) that bound how
short its horizon may be; and suppressions probably should NOT expire at all,
because ageing out a bounce re-mails an address that already hard-bounced. The
phase owes `/privacy` and the Play answers, which today say "nothing here expires
on its own" -- true now, false the moment it lands.
Also: ticks on the phase headings that were done and unmarked (4, 9, 10, 11, 12,
13), a status header that still said everything from Phase 10 on was design, and
three status lines that outlived the cutover -- `link/v5.md` and this README's
index row both said protocol 5 was built but unreleased, and INTEGRATION.md named
the v2.0.0/v1.0.0 pairing as the shipped one.
Co-Authored-By: Claude <noreply@anthropic.com>
125 lines
8.2 KiB
Markdown
125 lines
8.2 KiB
Markdown
# Runic Gateway — Documentation
|
|
|
|
Central documentation for the Runic Gateway platform. The docs here were
|
|
extracted from the two code repositories (with full commit history preserved)
|
|
so they live in one place, independent of either codebase.
|
|
|
|
## Layout
|
|
|
|
```
|
|
website/ docs from the website core (Node/Express + MariaDB + React/Vite)
|
|
modules/ docs for installable game modules — one directory per module id
|
|
link/ docs from the ServUO bridge (C# plugin + Rust sidecar + Node WS)
|
|
android/ docs from the native Android client (Kotlin + Jetpack Compose)
|
|
installer/ docs for the installer that deploys a shard's bridge components
|
|
ci/ cross-cutting CI/quality notes
|
|
```
|
|
|
|
**Setting up a shard?** [`installer/INSTALL.md`](installer/INSTALL.md) is the operator guide, and
|
|
the installer is the supported path: one binary deploys the plugin overlay, installs the uo-link
|
|
sidecar as a service, and hands you the values the website needs.
|
|
|
|
### `website/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [BACKEND_DESIGN.md](website/BACKEND_DESIGN.md) | API contract, DB schema, security model |
|
|
| [ARCHITECTURE.md](website/ARCHITECTURE.md) | The system diagram — how core, an installed module, the sidecar and the clients fit together |
|
|
| [TEAMS.md](website/TEAMS.md) | Teams as a platform primitive: roster, forums, notifications, Discord slash commands and voice — design of record |
|
|
| [ENGAGEMENT.md](website/ENGAGEMENT.md) | The engagement system: module-declared event triggers, rules, cooldowns, templates and the email / push / in-app delivery channels — design of record |
|
|
| [HERO_EDITOR.md](website/HERO_EDITOR.md) | Hero canvas editor feature spec |
|
|
| [THEMING_AND_NAV.md](website/THEMING_AND_NAV.md) | Admin-configurable theme, brand assets and navigation — build contract |
|
|
| [MODULE_SYSTEM.md](website/MODULE_SYSTEM.md) | Making the site game-agnostic: game logic becomes an installable module — design of record |
|
|
| [MODULE_API.md](website/MODULE_API.md) | The module ↔ core contract: `ctx`, the `register*` calls, the client registry and the loader's obligations |
|
|
| [UPGRADE_NOTES.md](website/UPGRADE_NOTES.md) | **Operator-facing, newest first** — the upgrades that need an operator to do something, or that change behaviour quietly enough to be discovered by accident |
|
|
| [WIKI_UPGRADE.md](website/WIKI_UPGRADE.md) | Wiki subsystem upgrade notes |
|
|
| [SHARD_VISIBILITY.md](website/SHARD_VISIBILITY.md) | Who sees which shard data — the admin-configurable audience framework |
|
|
| [TRUSTED_DEVICES_MFA.md](website/TRUSTED_DEVICES_MFA.md) | TOTP two-factor, trusted devices and recovery codes |
|
|
| [MODERATION_APPEALS.md](website/MODERATION_APPEALS.md) | Moderation actions, content reports and the appeals flow |
|
|
| [SPAWN_ATLAS.md](website/SPAWN_ATLAS.md) | The bestiary / spawn atlas: what the shard contains, parsed from its own ServUO tree |
|
|
| [CLILOCS.md](website/CLILOCS.md) | UO's id → name table: converting one from your client so items have names |
|
|
| [UOFIDDLER.md](website/UOFIDDLER.md) | **Operator runbook** — step-by-step extraction from your own UO client (cliloc table, creature art) |
|
|
| [MARKETPLACE.md](website/MARKETPLACE.md) | The player-vendor index: how it is gathered, what it costs, how to tune it |
|
|
| [website-README.md](website/website-README.md) | Snapshot of the website repo's README (setup/run reference) |
|
|
| [test-plan.md](website/test-plan.md) | The website's test strategy and harness |
|
|
| [API_V2_PLAN.md](website/API_V2_PLAN.md) | Router domain split + CSP hardening. The split is complete; only the CSP enforce step remains |
|
|
| [API_V2_SKELETON.md](website/API_V2_SKELETON.md) | **Superseded** — the `/api/v2` scaffold that was never built. Kept as the record of why the split was done in place instead |
|
|
| [PROJECT_TREE.md](website/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `modules/`
|
|
|
|
Documentation for installable game modules aggregates here rather than in each module's repo
|
|
([MODULE_SYSTEM.md](website/MODULE_SYSTEM.md) §2.10). The website core knows nothing about any
|
|
particular game; a module is what makes it a site *for* one.
|
|
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [uo/](modules/uo/README.md) | **module-uo** — the Ultima Online module: what it serves, what it owns, and what an operator needs |
|
|
| [uo/API.md](modules/uo/API.md) · [uo/SCHEMA.md](modules/uo/SCHEMA.md) | module-uo's own route surface and the tables it owns |
|
|
| [kit-acceptance.md](modules/kit-acceptance.md) | The Integration Kit acceptance run — building a module by following the kit alone, and what it found |
|
|
| [rust-dryrun.md](modules/rust-dryrun.md) | A written, deliberately unimplemented `module-rust` — the test that the module contract generalises past the game it was extracted from |
|
|
|
|
### `link/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [INTEGRATION.md](link/INTEGRATION.md) | How the website integrates with the uo-link sidecar |
|
|
| [PROTOCOL_2.md](link/PROTOCOL_2.md) | Protocol 2.0 / 2.1 design |
|
|
| [v3.md](link/v3.md) | Protocol 3.0 design — shard content/standings streams + the visibility framework |
|
|
| [v4.md](link/v4.md) | Protocol 4.0 — guild membership on the wire (`guild.roster`, `guild.leave`) |
|
|
| [v5.md](link/v5.md) | Protocol 5 — three enrichments in one bump: `house.decay`'s decay schedule, `vendor.listing`'s fee state, and `account.login.result`. **The current protocol**, shipped 2026-09-01 as bundle 2026.09.01 (sidecar v2.1.0 + overlay v1.1.0) |
|
|
| [ADMIN_CONTROLS.md](link/ADMIN_CONTROLS.md) | Staff write-plane (kick/ban/broadcast, page queue) |
|
|
| [SHARD_PREREQS.md](link/SHARD_PREREQS.md) | Shard-side prerequisites for the bridge |
|
|
| [PLAN.md](link/PLAN.md) | uo-link build plan |
|
|
| [RESEARCH.md](link/RESEARCH.md) | Research notes |
|
|
| [link-README.md](link/link-README.md) | Snapshot of the link repo's README |
|
|
| [PROJECT_TREE.md](link/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `android/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [PLAN.md](android/PLAN.md) | Android client build plan / milestones |
|
|
| [COVERAGE_PLAN.md](android/COVERAGE_PLAN.md) | Test-coverage rollout plan |
|
|
| [APP_LINKS.md](android/APP_LINKS.md) | Android App Links / deep-link setup |
|
|
| [theme-plan.md](android/theme-plan.md) | Theming plan |
|
|
| [THEMING_AND_NAV.md](android/THEMING_AND_NAV.md) | The app's half of admin-configurable theming and navigation — build contract |
|
|
| [TRUSTED_DEVICES_APP_HANDOFF.md](android/TRUSTED_DEVICES_APP_HANDOFF.md) | Trusted-devices app handoff notes |
|
|
| [PROJECT_TREE.md](android/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `installer/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [INSTALL.md](installer/INSTALL.md) | **Start here to set up a shard** — the installer deploys the plugin overlay and the uo-link sidecar, registers the service, and connects it to the website. Appendix A is the same thing by hand, still supported |
|
|
| [PLAN.md](installer/PLAN.md) | Installer design of record — phases, locked decisions, the bundle/compat-matrix model |
|
|
| [PROJECT_TREE.md](installer/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `ci/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [SONARQUBE.md](ci/SONARQUBE.md) | The SonarQube setup: project keys, how analysis runs, and how to read a report |
|
|
|
|
## Provenance
|
|
|
|
- `website/*` was extracted from `RunicGateway/website` via `git filter-repo`.
|
|
- `link/*` was extracted from `RunicGateway/link` via `git filter-repo`.
|
|
|
|
Commit history and authorship for each doc are preserved. The two source repos
|
|
retain a short pointer to this repo in their own READMEs; the authoritative copy
|
|
of each document now lives here.
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
Runic Gateway's documentation is free: licensed under the **GNU General Public
|
|
License v3.0 or later** — see [LICENSE.md](LICENSE.md).
|
|
|
|
Copyright (C) 2026 Runic Gateway
|
|
|
|
This documentation is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY. You may redistribute and/or modify it under the terms of
|
|
the GNU General Public License as published by the Free Software Foundation,
|
|
either version 3 of the License, or (at your option) any later version.
|
|
|
|
Contributions are welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) (note
|
|
the **AI-usage disclosure** requirement) and our
|
|
[Code of Conduct](CODE_OF_CONDUCT.md).
|