docs(website): settle Phase 3's shape, slices and merge order
Phase 2 is closed, so Phase 3 needs a plan before any of it is extracted. Four decisions, and one finding that set the first of them. The finding: because API URLs are preserved (§1.2), a feature's server and client halves are independent. Core's client keeps calling /api/v1/public/shard/status after the module serves it, and a module page calls the same URL while core still does. Nothing forces vertical slices, so the extraction is server-first then client, sliced by feature, ten slices. Merge order within a slice is module-uo first, then website. The loader's ownedByCore probe stops a module LOADING while core owns its prefix, but the module's own CI never loads it into core, so its PR merges fine beforehand -- and edge then serves the feature from core right up to the moment core drops it, with no window where the branch is missing it outright. Criterion 1's grep reads code, not prose: filenames, import specifiers, route path literals and declared identifiers. Core's marketing copy legitimately says "shard" in a dozen places and a literal word grep would have failed CI on each while proving nothing about the boundary. That copy is rewritten in its own slice instead, which is real work with a real review rather than an exemption hidden in a pattern. module-uo's CI clones core at a pinned ref to freeze its route manifest -- nothing else proves the URLs it claims are the URLs it serves -- and the module-rust dry run lands in docs/modules/ where §2.10 already aggregates module documentation. Also records the measured surface (72 server files, 51 client, 32 test files), which supersedes the Phase 0 estimate, and the one kit gap: lib/format.js is vendored by the module rather than becoming an eighth §3.4 member. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -817,6 +817,25 @@ specifiers in the client bundle are the four declared externals. A hit fails the
|
||||
Phase 3's acceptance criterion 1: no `shard`, `uoLink`, `cliloc`, `atlas` or `towncrier` outside
|
||||
`modules/`, as a CI grep test rather than a review promise.
|
||||
|
||||
**Settled 2026-08-11: the grep reads code, not prose.** It covers four things, and each of them is a
|
||||
thing a module owns:
|
||||
|
||||
1. **File and directory names** under `server/src/`, `server/scripts/`, `server/db/` and `client/src/`.
|
||||
2. **Import and require specifiers** — the path in `require('…')` / `from '…'`.
|
||||
3. **Route path literals** — the string arguments to `.get`/`.post`/`.put`/`.patch`/`.delete`/`.use`.
|
||||
4. **Declared identifiers** — function, const, class and property names.
|
||||
|
||||
It does **not** read comments or string content generally, and that is not a loophole. Core's
|
||||
marketing copy legitimately says "shard" — `About.jsx`, `Screenshots.jsx`, `SiteFooter.jsx`,
|
||||
`heroLayout.js` — and a literal word grep would turn each of those into a CI failure while proving
|
||||
nothing about the boundary. Worse, it would forbid a core comment from ever using the word as an
|
||||
example, which is the sort of rule people work around rather than obey. The boundary this test exists
|
||||
to defend is *structural*: core must not name a module's files, import them, route to them, or
|
||||
declare their symbols. It can talk about them in English.
|
||||
|
||||
Core's UO-flavoured default copy is dealt with directly instead, as `MODULE_SYSTEM.md` §2.7.1's
|
||||
slice 8 — a rewrite with its own review, not an exemption.
|
||||
|
||||
### 5.3 Zero-line route manifest diff (CI, both repos)
|
||||
|
||||
`npm run routes:manifest -- --check` in core; the module generates and freezes its own manifest in
|
||||
@@ -824,6 +843,16 @@ its own repo, using the same script pointed at a core+module app. Phase 2 must p
|
||||
diff in core's; Phase 3 moves the UO entries out of core's and into module-uo's, which is the one
|
||||
diff the whole workstream is allowed.
|
||||
|
||||
**Settled 2026-08-11: `module-uo`'s CI checks core out at a pinned ref.** The module's workflow
|
||||
clones `RunicGateway/website` at a ref recorded in the module repo, drops itself in as `modules/uo`,
|
||||
and runs core's own `routeManifest.js`. Nothing else proves the URLs a module claims are the URLs it
|
||||
actually serves — a manifest frozen by hand goes stale silently, and the failure it would have caught
|
||||
is a route that moved.
|
||||
|
||||
Pinning the ref rather than tracking `edge` is what keeps this from being a source of unexplained red
|
||||
Xes: core moves for reasons that have nothing to do with the module, and a bump is then a deliberate
|
||||
commit that says which core the module was last proved against.
|
||||
|
||||
---
|
||||
|
||||
## Part 6 — Amendments to MODULE_SYSTEM.md
|
||||
|
||||
Reference in New Issue
Block a user