docs(modules): close Phase 4 — de-UO the backend reference, record the acceptance run #144

Merged
whitlocktech merged 1 commits from docs/module-phase4-slice4 into main 2026-08-12 14:19:19 +00:00
Member

Phase 4 slice 4 — the phase closes here. Pairs with website#146 (the one code change, a three-line reorder). Either order is safe; the docs describe the fix as landed, so merging this one second is tidier.

The thing nobody had checked: BACKEND_DESIGN.md was never de-UO'd

Phase 3 rewrote core's code, and slice 5 did core's README and OpenAPI metadata. But §5.2's identifier check reads code, not prose — so nothing ever looked at the design document. A phase after core stopped being able to serve any of it, BACKEND_DESIGN.md still described 27 shard_* tables, 20 UO route rows and the shard visibility ladder as core's.

Moved, text unchanged (a relocation that also reworded makes it impossible to tell what changed meaning):

Was Now
§3 — six shard_* schema sections, 226 lines modules/uo/SCHEMA.md (new)
§4 — 13 public + 7 admin UO route rows, the /admin/shard tier prose modules/uo/API.md (new)
§6.5 — the audience ladder, 70 lines modules/uo/API.md §4

What core keeps is the seam: installed_modules, /public/modules, the extension slot, and — new here — the eight /admin/modules routes, which slices 1–3 shipped and never documented. §6.5 becomes "Module-owned audience boundaries": core's security boundary ends at authentication, roles and the session, and a module that serves game data brings its own.

The general rule, added as settled decision 27: documentation follows the code out. §2.10 already said module docs aggregate in docs/modules/<id>/; that has to include the parts core used to own, or core's reference silently becomes wrong the first time someone runs it without the module.

Two stale claims fell out

  • users.router.js was still listed as 15 routes. It is 9 — six went to the extension slot in Phase 2 PR 4.
  • The push-notification section still promised config/shardStreams.js "belongs to module-uo and moves out with it", in the future tense, four slices after it left.

SHARD_VISIBILITY.md and SPAWN_ATLAS.md now point at the module docs for the contract and the column listings.

The acceptance table has results

# Criterion Result
1 Installs, starts and serves with no shell and nothing built Met (slice 2) — real release URL, five mounts, seven streams, its nav rows
2 Uninstall leaves the data, purge removes it Met (slice 4) — see below
3 A hostile archive cannot escape modules/<id>/ Met (slice 1) — 16 tests over real crafted tars
4 A declared module resolves at container start, offline Met (slice 3) — zero requests, module up

Criterion 2 was the one nobody had run. module-uo v0.3.0 from the real release, onto a brand-new empty database: 27 tables, a real atlas and a 67,496-row cliloc import, a marker row, then taken away twice.

  • uninstall → reinstall: marker row and all 27 tables intact
  • uninstall with purge: purged: 27, every table gone, row gone, directory gone
  • reinstall: tables recreated empty
  • standalone purge: 409 while started, 200 while disabled

It also exposed the ordering defect website#146 fixes — the purge ran before the stop, so 27 tables were dropped under a module that was still serving and ingesting. Generalises: an ordering that is only wrong for a few seconds is invisible to every test and to any smoke without a live producer.

And one thing worth writing down because it surprised the run: after purge-and-reinstall the atlas and cliloc content comes back — it is re-derived from the operator's own ServUO tree at the next onBoot. What is gone is everything the shard and its players produced. The two settings rows survive on purpose.

AI disclosure

  • This contribution was AI-assisted (Claude Code).

🤖 Generated with Claude Code

https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8

**Phase 4 slice 4 — the phase closes here.** Pairs with **website#146** (the one code change, a three-line reorder). Either order is safe; the docs describe the fix as landed, so merging this one second is tidier. ## The thing nobody had checked: `BACKEND_DESIGN.md` was never de-UO'd Phase 3 rewrote core's *code*, and slice 5 did core's README and OpenAPI metadata. But §5.2's identifier check reads code, not prose — so nothing ever looked at the design document. A phase after core stopped being able to serve any of it, `BACKEND_DESIGN.md` still described **27 `shard_*` tables**, **20 UO route rows** and **the shard visibility ladder** as core's. Moved, **text unchanged** (a relocation that also reworded makes it impossible to tell what changed meaning): | Was | Now | | --- | --- | | §3 — six `shard_*` schema sections, 226 lines | **`modules/uo/SCHEMA.md`** (new) | | §4 — 13 public + 7 admin UO route rows, the `/admin/shard` tier prose | **`modules/uo/API.md`** (new) | | §6.5 — the audience ladder, 70 lines | `modules/uo/API.md` §4 | What core keeps is the **seam**: `installed_modules`, `/public/modules`, the extension slot, and — new here — the eight `/admin/modules` routes, which slices 1–3 shipped and never documented. §6.5 becomes *"Module-owned audience boundaries"*: core's security boundary ends at authentication, roles and the session, and a module that serves game data brings its own. The general rule, added as settled decision **27**: *documentation follows the code out.* §2.10 already said module docs aggregate in `docs/modules/<id>/`; that has to include the parts core used to own, or core's reference silently becomes wrong the first time someone runs it without the module. ### Two stale claims fell out - `users.router.js` was still listed as **15 routes**. It is **9** — six went to the extension slot in Phase 2 PR 4. - The push-notification section still promised `config/shardStreams.js` *"belongs to module-uo and moves out with it"*, in the future tense, four slices after it left. `SHARD_VISIBILITY.md` and `SPAWN_ATLAS.md` now point at the module docs for the contract and the column listings. ## The acceptance table has results | # | Criterion | Result | | --- | --- | --- | | 1 | Installs, starts and serves with no shell and nothing built | **Met** (slice 2) — real release URL, five mounts, seven streams, its nav rows | | 2 | Uninstall leaves the data, purge removes it | **Met** (slice 4) — see below | | 3 | A hostile archive cannot escape `modules/<id>/` | **Met** (slice 1) — 16 tests over real crafted tars | | 4 | A declared module resolves at container start, offline | **Met** (slice 3) — zero requests, module up | Criterion 2 was the one nobody had run. `module-uo` v0.3.0 from the real release, onto a **brand-new empty database**: 27 tables, a real atlas and a 67,496-row cliloc import, a marker row, then taken away twice. - uninstall → reinstall: marker row and all 27 tables intact - uninstall **with purge**: `purged: 27`, every table gone, row gone, directory gone - reinstall: tables recreated **empty** - standalone purge: `409` while `started`, `200` while `disabled` It also exposed the ordering defect website#146 fixes — the purge ran *before* the stop, so 27 tables were dropped under a module that was still serving and ingesting. **Generalises: an ordering that is only wrong for a few seconds is invisible to every test and to any smoke without a live producer.** And one thing worth writing down because it surprised the run: after purge-and-reinstall the atlas and cliloc content **comes back** — it is re-derived from the operator's own ServUO tree at the next `onBoot`. What is gone is everything the shard and its players produced. The two `settings` rows survive on purpose. ### AI disclosure - [x] This contribution was AI-assisted (Claude Code). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8
wtclaude added 1 commit 2026-08-12 14:17:00 +00:00
Phase 4 slice 4. BACKEND_DESIGN.md had never been de-UO'd: Phase 3 rewrote core's
code and README, but §5.2's identifier check reads code, not prose, so nothing
ever looked at the design document. It still described 27 shard_* tables, 20 UO
route rows and the shard visibility ladder as core's, a phase after core stopped
being able to serve any of them.

Moved, text unchanged:

  BACKEND_DESIGN §3   six shard_* schema sections (226 lines) → modules/uo/SCHEMA.md
  BACKEND_DESIGN §4   13 public + 7 admin UO route rows       → modules/uo/API.md
  BACKEND_DESIGN §6.5 the audience ladder (70 lines)          → modules/uo/API.md §4

Core keeps the seam and gains the eight /admin/modules routes it had never
documented. §6.5 becomes "Module-owned audience boundaries": core's security
boundary ends at authentication, roles and the session, and a module that serves
game data brings its own.

Also fixed on the way: users.router.js was still listed as 15 routes (it is 9 —
six went to the extension slot), and the push section still promised
config/shardStreams.js "moves out with it" four slices after it left.

The acceptance table now carries results. Criterion 2 was proved for real against
module-uo v0.3.0 on an empty database, which turned up the uninstall ordering
defect fixed in website#146.

AI disclosure: this contribution was AI-assisted (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 91ac28e11d into main 2026-08-12 14:19:19 +00:00
whitlocktech deleted branch docs/module-phase4-slice4 2026-08-12 14:19:19 +00:00
Sign in to join this conversation.
No description provided.