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>
This commit is contained in:
100
README.md
Normal file
100
README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user