TEAMS.md §5.4, §5.5.7 (new), §5.6 and the Part 12 phase entry; BACKEND_DESIGN.md's schema and admin route tables. **The largest change is a decision, not a description.** §5.6's first rule said "a leader may also see and act on reports for their own Team, but staff always receive them". The org lead settled on 2026-08-18 that the leader half is **decided against, not deferred**: the gap the section exists to close is that leaders moderate their own forum and a Team's leaders are exactly the people who will not report their own Team, so a leader-visible queue hands a complaint about a leader back to them — and a read-only leader view still tells them who reported what. Recorded as an amendment rather than by editing the sentence away, because the reasoning for the original is what makes the correction legible. **§5.6's `content_reports` DDL does not work as written, and the amendment says so rather than quietly swapping it.** With `status` in the unique key, CLOSED rows collide with each other: dismiss a report, let the behaviour recur, dismiss the second one, and the UPDATE lands on a tuple that already exists — so the queue starts throwing duplicate-key errors on the first repeat reporter. The shipped table keys on a generated `open_marker`, the same encoding `team_forum_grants.active_marker` uses. Three smaller departures are recorded beside it: `handled_note`, the two username snapshots §2.10 asks for everywhere else, and a real CASCADE on `team_id`. **New §5.5.7 for `teams_forum_edit_window_minutes`** (0–1440, default 15), and the rule under it: the window is resolved on the server TWICE — the read path stamps `canEdit`/`editableUntil` so a client knows whether to draw the control, the write re-derives it from `created_at` before allowing anything. The read is advice and the write is enforcement, because a time-bounded permission must not take its clock from the party it bounds. That is also why the key is not published: the client needing the number is the admin screen, and the client needing the decision already has it per post. **§5.4 gains three notes its route table does not carry**: thread creation splits authority by TYPE rather than widening the leader gate (and reports it as two booleans, since one would make a client guess which right it described); post moderation is its own route whose validator accepts all eight actions so the model can say "pin applies to a thread, not to a post"; and a reply's three refusal codes are chosen to be distinguishable — 404 absent, 400 announcement, 409 locked — with locked refusing staff too. The Part 12 entry records what the phase disproved, its four acceptance criteria, that it spans ONE repo where phase 4 needed two, and the single defect the live rig found. It also notes that phase 4 shipped `uploads` with the default off, so §5.6's "pull reports forward if uploads is enabled anywhere" never triggered. Co-Authored-By: Claude <noreply@anthropic.com>
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 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 | API contract, DB schema, security model |
| HERO_EDITOR.md | Hero canvas editor feature spec |
| THEMING_AND_NAV.md | Admin-configurable theme, brand assets and navigation — build contract |
| MODULE_SYSTEM.md | Making the site game-agnostic: game logic becomes an installable module — design of record |
| MODULE_API.md | The module ↔ core contract: ctx, the register* calls, the client registry and the loader's obligations |
| WIKI_UPGRADE.md | Wiki subsystem upgrade notes |
| SHARD_VISIBILITY.md | Who sees which shard data — the admin-configurable audience framework |
| SPAWN_ATLAS.md | The bestiary / spawn atlas: what the shard contains, parsed from its own ServUO tree |
| CLILOCS.md | UO's id → name table: converting one from your client so items have names |
| UOFIDDLER.md | Operator runbook — step-by-step extraction from your own UO client (cliloc table, creature art) |
| MARKETPLACE.md | The player-vendor index: how it is gathered, what it costs, how to tune it |
| website-README.md | Snapshot of the website repo's README (setup/run reference) |
| 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 §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/ | module-uo — the Ultima Online module: what it serves, what it owns, and what an operator needs |
| 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 | How the website integrates with the uo-link sidecar |
| PROTOCOL_2.md | Protocol 2.0 / 2.1 design |
| v3.md | Protocol 3.0 design — shard content/standings streams + the visibility framework |
| ADMIN_CONTROLS.md | Staff write-plane (kick/ban/broadcast, page queue) |
| SHARD_PREREQS.md | Shard-side prerequisites for the bridge |
| PLAN.md | uo-link build plan |
| RESEARCH.md | Research notes |
| link-README.md | Snapshot of the link repo's README |
| PROJECT_TREE.md | Auto-generated snapshot of the repo's tracked file layout |
android/
| Doc | What it covers |
|---|---|
| PLAN.md | Android client build plan / milestones |
| COVERAGE_PLAN.md | Test-coverage rollout plan |
| APP_LINKS.md | Android App Links / deep-link setup |
| theme-plan.md | Theming plan |
| TRUSTED_DEVICES_APP_HANDOFF.md | Trusted-devices app handoff notes |
| PROJECT_TREE.md | Auto-generated snapshot of the repo's tracked file layout |
installer/
| Doc | What it covers |
|---|---|
| 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 design of record — phases, locked decisions, the bundle/compat-matrix model |
Provenance
website/*was extracted fromRunicGateway/websiteviagit filter-repo.link/*was extracted fromRunicGateway/linkviagit 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.
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 (note the AI-usage disclosure requirement) and our Code of Conduct.