Merge pull request 'docs(modules): core offers a contribution, never a slot name' (#165) from docs/teams-slot-contributions into edge

Reviewed-on: #165
This commit is contained in:
2026-08-19 06:18:55 +00:00
2 changed files with 71 additions and 30 deletions

View File

@@ -830,18 +830,20 @@ named for a *place* and never for a meaning):
> **Superseded 2026-08-17 (phase 3, org lead).** Both slots are gone, and the DIRECTION is what
> changed. They assumed core rendered the Team page; core renders no Team page. The replacement is
> `registry.declareModuleSlot(id, name)` — a **module** declares a place on its own page, namespaced
> under its own id, and **core** fills it:
> `registry.declareModuleSlot(id, name, { core })` — a **module** declares a place on its own page,
> namespaced under its own id, naming which of core's contributions goes there, and **core** offers it:
>
> | Slot | Declared by | Rendered in | Filled by core with | Props |
> | --- | --- | --- | --- | --- |
> | `uo.guild.detail` | `module-uo` | its guild detail page | the Team activity feed (§4.3) | `{ externalId, moduleId }` |
> | `uo.guild.forum` | `module-uo` | the same page, below the feed | the Team forum (Part 5) added in phase 4 | `{ externalId, moduleId }` |
> | `uo.guild.detail` | `module-uo` | its guild detail page | `team.activity` — the Team activity feed (§4.3) | `{ externalId, moduleId }` |
> | `uo.guild.forum` | `module-uo` | the same page, below the feed | `team.forum` — the Team forum (Part 5), added in phase 4 | `{ externalId, moduleId }` |
>
> Core's fills are applied at MOUNT, not eagerly: core's bundle evaluates before every module chunk,
> so when core registers a fill the slot does not exist yet. A fill for a slot no installed module
> declares is a no-op, not an error — the mirror of an unfilled slot rendering nothing. `Slot` becomes
> the eighth member of the shared UI kit so a module renders the place with core's own error boundary,
> Core's contributions are applied at MOUNT, not eagerly: core's bundle evaluates before every module
> chunk, so when core offers one, no module-declared slot exists yet. A contribution nothing asks for
> is a no-op, not an error — the mirror of an unfilled slot rendering nothing. **Core names the
> contribution and never the slot** (amended phase 11, inside 1.6.0: as first built it filled the
> literal names above, which reached `module-uo` and no other game). `Slot` becomes
> the ninth member of the shared UI kit so a module renders the place with core's own error boundary,
> which matters here because the thing being contained is CORE's content failing inside the MODULE's
> page.
>
@@ -2547,13 +2549,16 @@ guild called "Admin" cannot put an official-looking page on the site.
>
> **So the extension slots invert, and that is a new `MODULE_API` §3.7 direction.** `team.overview`
> and `team.member.row` assumed core rendered the page. They are replaced by
> `registry.declareModuleSlot(id, name)`: a **module** declares a place on its own page, namespaced
> under its own id, and **core** fills it. `module-uo` declares `uo.guild.detail`; core fills it with
> the activity feed, because only core can resolve whether a viewer is inside the Team and the
> public/members split is a security boundary. Core's fills are applied at mount rather than eagerly —
> core's bundle evaluates before every module chunk, so at the moment core registers a fill the slot
> does not exist yet. `Slot` joins the shared UI kit as its eighth member so the module renders the
> place with core's own error boundary.
> `registry.declareModuleSlot(id, name, { core })`: a **module** declares a place on its own page,
> namespaced under its own id, and names which of core's contributions belongs there. `module-uo`
> declares `uo.guild.detail` and asks for `team.activity`; core offers the activity feed, because only
> core can resolve whether a viewer is inside the Team and the public/members split is a security
> boundary. **Core names the contribution, never the slot** — amended in phase 11, inside 1.6.0, after
> the integration kit found that the literal-name version worked for one module and silently did
> nothing for any other. Core's contributions are applied at mount rather than eagerly — core's bundle
> evaluates before every module chunk, so at the moment core offers one, no module-declared slot exists
> yet. `Slot` joins the shared UI kit as its ninth member so the module renders the place with core's
> own error boundary.
>
> **A module names a Team in its own vocabulary**, so `GET /public/teams/by-external/:moduleId/:externalId`
> is added: core's row id and slug are core-internal and handing them to a module is how a module ends