docs(teams): phase 4 — the forum's access model, switches and image policy

Records what building phase 4 settled, and what it disproved.

The structural correction first: TEAMS.md 3.1 gave the forum a CORE page and phase
3 deleted every core Team page. The ROUTES were unaffected — they are all /player
and /admin — but the participant surface had no home, and 5.4's route table did not
notice. Settled the way phase 3 settled the activity feed: module-uo declares a
second place on its guild page and core fills it, so the phase spans two repos
rather than the one the plan named.

Two slots rather than one, because a slot holds one component and the first fill
wins; the panel navigates by search param because a thread must be linkable and
core cannot mount a route on a page it does not own.

Two findings from the sanitiser worth not re-deriving: `rel` has to be on the
allowlist for the transform that WRITES it to survive, or every forum link ships
without noopener; and the bare-URL linkifier runs after sanitising, over escaped
text only, which is the property that makes it safe rather than an injection point.

Also recorded: the upload sweep runs regardless of the current image mode, which is
the mechanism behind the dialog's promise that disabling uploads does not delete
what is already there; the two routes the table lacked; and the org lead's decision
that all three proposed acknowledgement additions ship.

BACKEND_DESIGN gains the four forum tables and the reasoning a reader of the schema
alone would miss — why the guard is at the route and never at the data, why no
stored body ever contains an <img>, what `uploads` mode hardens, and what the
acknowledgement actually records. MODULE_API's inverted-slot section gains the rule
a module needs: one slot per PLACE, not one per page.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-18 07:25:05 -05:00
parent 7121b1a028
commit 0e665078e8
3 changed files with 102 additions and 4 deletions

View File

@@ -1202,11 +1202,19 @@ forced it is worth stating because it will recur:
```js
// In the module's entry chunk, at registration time:
registry.declareModuleSlot(ID, 'uo.guild.detail')
registry.declareModuleSlot(ID, 'uo.guild.forum')
// In the module's page, from the UI kit:
<Slot name="uo.guild.detail" externalId={guildId} moduleId="uo" />
<Slot name="uo.guild.forum" externalId={guildId} moduleId="uo" />
```
**A module declares one slot per PLACE, not one per page.** `module-uo` declares two on the same guild
page — core fills the first with the Team activity feed and the second with the Team forum — because a
slot holds one component and the first fill wins. Collapsing them into one would hand core the
decision about where each of its contributions sits, on a page the module owns. Two also keeps them
independent: a deployment with the forum switched off renders the feed unchanged.
**The name must be namespaced under the declaring module's id**, and that is enforced rather than
conventional: it is the only thing keeping two modules from claiming one name, and it makes the owner
readable at the fill site.