docs(website): settle the three de-entanglement registries and what they cost #129
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/module-registries"
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 2 PR 4 of
MODULE_SYSTEM.md§2.7 — the docs half of website#131. Records what §1.8's three entangled files and §1.9's extension slot actually became, and the four decisions taken with them.MODULE_API.md§2.4 — the registration surfaceregisterNotificationStreamstakes the catalog alone.mapEventwas a leftover from before §1.8's push inversion was settled: a module ownsfromShardEventoutright and callspublish()with a stream id it already resolved, so core never needs a second route to the same place. It follows that the public-safety filter (a sensitive kind can never produce a public push) is module-internal — which is the right home, because the kinds, the streams and the filter then become one file that moves together rather than a rule in core about data only the module defines.scope. The entry shape is the response body ofGET /auth/me/notifications/streams, and a shipped Android client reads both fields.scopewas never the wire shape.registerAnnounceLeggainslabel, so a module's leg renders in the admin panel with no client change — the panel used to hold a client-side{ towncrier, discord }label table.announce_jobscarried leg-prefixed column groups; a module cannotALTERa core table, so a registered leg had nowhere to live. Henceannounce_job_legs, and a rollup over all of a job's legs.register()leaves nothing behind — the registry-side twin of §4.3's second-pass mount rule.New §6.5 — grandfathered names
Eight names predate the module system and cannot take a module prefix: seven stream ids (stored in
notification_subs, read by a shipped Android client) andtowncrier(a stored value inannounce_job_legs.leg). Allowed touoalone by explicit allowlist — the same shape and reasoning as the loader'sLEGACY_TABLE_PREFIXES. Grandfathering rather than dropping the rule is what keeps it real for every module written after this one.New §6.6 — a slot is invisible to static analysis
§6.1 settled the fragment merge for modules. PR 4 found core needs the identical machinery for its own slot fills, one phase earlier than the plan expected: a slot's router is created by
declareSlot()and filled later, so there is no literal mount forswagger-autogento follow. Moving the six users-detail routes behind the slot deleted 407 lines fromswagger-output.json— withSwagger-autogen: Successand no warning. Same failure as §7.4, different cause, and it would have shipped six undocumented core routes against CLAUDE.md's standing rule.Which slots, and where each hangs, are both derived — from
registries.filledSlots()and from the live express stack viarouteManifest's ownmountPath— because a written-down copy of either is a copy that drifts.Also
MODULE_SYSTEM.md§1.8 / §1.9 record the outcome per file; §2.7 the progress.BACKEND_DESIGN.mdandwebsite-README.mdfollow the moved files. ThePUBLIC_KINDSreference in the visibility section namednotificationStreams.js; it has always lived inutils/shardBroadcast.js, and is corrected.Pairs with website#131. AI-assisted (Claude Code).
🤖 Generated with Claude Code
https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8