docs(website): the module API contract, validated by the atlas spike (phase 1) #124
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/module-api"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 1 of the module system — the API contract, plus the throwaway spike that validates it.
What's here
website/MODULE_API.md— the normative contract between core and an installed module. Every member is derived from what the UO code actually imports today, re-read against the working tree; nothing speculative.MODULE_API_VERSION, and what is deliberately not contract)module.json, the entry point,ctx, theregister*calls, lifecycle, schema fragments, the OpenAPI fragmentwindow.__rg, the registry, the curated UI kit, the request primitive, the Vite library buildstartup_failedMODULE_SYSTEM.mdThe spike
websitebranchspike/module-atlas, cut fromedgeand deliberately never merged — it is evidence, not implementation. It carries the six public spawn-atlas routes intomodules/uo/.All three exit criteria met:
ctx.express/ctx.validator; the built chunk has zero bare specifiers and bundles no Reactroutes.manifest.jsondiffscript-src 'self', zero violation reports729 core tests and 81 module tests pass. Verified end to end against a real database: schema fragment replays after core's,
onBootruns the atlas refresh, the six API URLs answer unchanged.Decisions taken in this PR
Both approved by the org lead on 2026-08-10:
swagger-fragment.json; core merges started modules' fragments into/api/docs.jsonand always wins a key collision. Needed becauseswagger-autogenstatically parsesapp.jsand cannot follow a dynamic loader — unlikerouteManifest.js, which walks the live Express stack. The spike confirmed this empirically: regenerating the spec silently deleted all 361 lines of atlas paths withSwagger-autogen: Success, while the manifest kept all six in the same run.window.__rg(§3.4). The atlas pages import five core modules beyond React, so a module either reaches into core's tree or ships copies that drift. Adding to the kit is a minor version bump; changing a member's props is a major one.What the spike changed in the contract
ctx.express/ctx.validator— a module lives outsideserver/, so Node never reachesserver/node_modulesandrequire('express')fails outright. This is the server-side twin of the one-React rule that §2.6 only had for the client.window.__rg.jsxRuntime— so a module builds with the automatic JSX runtime its tooling already assumes.Also corrected
27 UO tables, not 25. Six atlas routes, not five.
MODULE_SYSTEM.mdgains a pointer to the contract and the corrected count;README.mdgains index rows for both docs.🤖 Generated with Claude Code
The normative contract between core and an installed module: the `ctx` handed to a module's entry point, the `register*` calls, the client-side registry and shared-dependency global, the schema-fragment rules, and the loader's validation and failure obligations. Every member is derived from what the UO code actually imports today, re-read against the working tree. Part 6 records four places the survey contradicted MODULE_SYSTEM.md: • OpenAPI generation is STATIC analysis (swagger-autogen parses app.js as text), unlike routeManifest.js which walks the live Express stack. A filesystem-scanning loader is invisible to it, so module routes would be silently absent from swagger-output.json. Three options, one recommended; needs a decision before Phase 2. • The client contract is much larger than §2.1 implies — the atlas pages import five core modules beyond React, so the plan needs a curated UI kit and a request primitive on window.__rg. • shardVisibility is module-owned and the atlas depends on it, so the spike carries it; two copies coexist during the spike by design. • Two counts corrected: 27 UO tables (not 25), 6 atlas routes (not 5). MODULE_SYSTEM.md gains a pointer to the contract and the corrected table count. Co-Authored-By: Claude <noreply@anthropic.com>