Files
Module-uo/README.md
wtclaude 26f2079cca chore(module-uo): bootstrap repo with governance docs and templates
First commit for the UO module — the game-specific half of the Runic Gateway
website, extracted from core so that core can become game-agnostic. Phase 0 of
the module system plan (docs/website/MODULE_SYSTEM.md §2.7) calls for this repo
to get its initial commit before any module work starts.

Governance scaffolding only; no module code. The design of record settles the
API surface in Phase 1 and Phase 3 is what fills the repo, so writing module
code now would be writing against a contract that does not exist yet.

- README.md          what module-uo is, the phase table, the packaging layout,
                     and why an operator never builds anything
- CONTRIBUTING.md    planning status, the dev loop (a module is not runnable on
                     its own), the zero-internal-imports and one-path-segment
                     rules, schema fragments instead of migrations
- SECURITY.md        private reporting, plus the module-specific notes: the
                     module boundary is not a security boundary, access control
                     lives in core, and the uo-link token stays write-only
- CODE_OF_CONDUCT.md, CONTRIBUTORS.md, LICENSE.md (GPL-3.0-or-later),
  PR + issue templates — the same set every repo in the org carries
- .gitignore         Node-shaped; client/dist/ is ignored deliberately, since it
                     is a release artifact built by CI, not a source artifact

CI lands next, in a PR, mirroring how the installer repo was bootstrapped: an
empty repo cannot take a pull request, but everything after it can.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-10 02:39:23 -05:00

101 lines
5.6 KiB
Markdown

# module-uo — the Ultima Online module for Runic Gateway
The Runic Gateway website is becoming **game-agnostic**: core keeps accounts, sessions, the wiki,
posts, branding, theming and the admin panel, and everything that knows what a *shard* is moves out
into an installable module. This repo is that module — the first one, and the reference for every
module that follows.
```
RunicGateway/website (core — game-agnostic)
│ loads modules at boot, synchronously, from the filesystem
┌───────────────────────────────────────────┐
│ module-uo (>>> HERE <<<) │
│ shard status · spawn atlas · marketplace │
│ governors · cliloc · town crier · uo-link│
└───────────────────────────────────────────┘
│ server half: routers, models, schema fragment
│ client half: prebuilt ESM chunk, SPA routes + nav
the shard bridge (RunicGateway/link → RunicGateway/servuo-plugins)
```
The module's **id** is `uo` — that is what appears in `module.json`, in the `installed_modules`
table, in the `modules/<id>/` path on disk and in the URL segment (`/uo/*`, `/admin/uo/*`,
`/player/uo/*`). `Module-uo` is the repository; `module-uo` is the module and its release artifact.
## Status: planning — no module code exists yet
This repo currently holds governance scaffolding only. The design of record is
[`website/MODULE_SYSTEM.md`](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/website/MODULE_SYSTEM.md)
in the docs repo — **read it before opening a PR here.** It defines the module API surface, the
packaging, the state machine, the install/uninstall/purge model, and the phases.
| Phase | Where it happens | State |
|---|---|---|
| 0 — CI trigger fix, cut `website` `edge`, bootstrap this repo | `website`, here | 🟡 in progress |
| 1 — module API contract (`docs/website/MODULE_API.md`) + the atlas spike | `docs`, `website` | ⬜ blocking |
| 2 — core scaffolding: loader, `installed_modules`, registries, client registry | `website` | ⬜ |
| 3 — extract the UO half of the site into this repo | `website`, here | ⬜ |
| 4 — delivery: the admin Modules screen + the Docker path | `website` | ⬜ |
Nothing lands here until Phase 1 has settled the contract this module is written against. Phase 3 is
what fills the repo.
## What it will contain
One repo, one bundle: the server half and the client half live side by side and version together, so
a route and the screen that calls it can never be mismatched.
```
module.json id, version, coreApi range, mounts, extensions
server/ routers, controllers, models, utils
server/db/schema.sql idempotent fragment, replayed by core's ensureSchema()
server/db/purge.sql destructive; only ever run by an explicit purge
client/src/ route components, nav registrations, feature provider
client/dist/ PREBUILT ESM chunk, built by CI — never by an operator
```
Release artifact: `module-uo-<version>.tar.gz`, plus a manifest carrying its `sha256`.
## How it reaches an operator
**An operator never builds anything.** Installing a module is the WordPress-plugin experience: an
admin-panel action, or a directory mounted into the Docker container — never a build step, because
production runs a prebuilt, pull-only image. That constraint is why the client half ships as a
prebuilt ESM chunk that resolves React from a `window.__rg` global rather than an import map (an
import map must be inline, and the site's CSP is `script-src 'self'`).
The [installer](https://gitea.whitlocktech.com/RunicGateway/installer) is **not** the delivery path.
It deploys the *shard* side — the plugin overlay and the uo-link sidecar — and never contacts the
website. Module delivery is website-side only.
## Compatibility
`module.json` declares a `coreApi` semver range, checked at boot against core's `MODULE_API_VERSION`.
A mismatch fails **loudly** — the module is marked `startup_failed` and the site comes up without it,
rather than mis-loading. This is a separate number from `PROTOCOL_VERSION`, which versions the shard
wire protocol and says nothing about a website module.
A module that fails to load must never take the site down.
## Related repos
| Repo | What |
|------|------|
| **this**`RunicGateway/Module-uo` | The UO module: the game-specific half of the website. |
| [RunicGateway/website](https://gitea.whitlocktech.com/RunicGateway/website) | Core — the site, admin panel and API that loads this module. |
| [RunicGateway/link](https://gitea.whitlocktech.com/RunicGateway/link) | The **uo-link sidecar** — the network-facing half of the game bridge this module talks to. |
| [RunicGateway/servuo-plugins](https://gitea.whitlocktech.com/RunicGateway/servuo-plugins) | The **C# ServUO plugin** that feeds the sidecar. |
| [RunicGateway/installer](https://gitea.whitlocktech.com/RunicGateway/installer) | Deploys the shard side. Not the module delivery path. |
| [RunicGateway/docs](https://gitea.whitlocktech.com/RunicGateway/docs) | All project documentation, including the module system design and this module's docs under `modules/uo/`. |
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md). Contributions are welcome, AI assistance must be disclosed,
and security problems go to [SECURITY.md](SECURITY.md) rather than a public issue.
## License
**GNU General Public License v3.0 or later** — see [LICENSE.md](LICENSE.md).