TEAMS.md gains a dated amendment on phase 3 with five corrections, all found by
building the thing it describes:
- §3.2 and §3.4 contradict each other about `team.member.row`'s props, and
§3.2 wins because it is the security rule. A client slot can only receive
what the browser was sent, so §3.4's `{ memberKey, userId, displayName }`
means publishing both identifiers in every public roster, module installed
or not. The slot is redeclared with what core can honestly supply.
- §3.3's projection is an EIGHTH MODULE_API member where 1.6.0 listed seven.
Settled by the org lead: 1.6.0 is amended in place, on the rule Protocol 4
was given in phase 2 — a contract owes a bump only once it has reached
`main`.
- "the module declines" needed splitting in two before it could be built. No
module at all withholds nothing and must serve the roster whole; a module
whose rungs could not be consulted must serve none of it. Only the second
fails closed, or bare core shows an empty roster on every Team page.
- the module answers with member KEYS, not rows, so it can narrow what is
published and cannot widen it.
- core's five activity kinds are four until the forum lands, and a Team's
FIRST roster emits no join items at all.
§2.11's route table gains the activity endpoint it never had, and MODULE_API.md
documents `projectRoster`, the inverted fail-closed semantics that make it
different from every other provider call, and `ctx.teams.activity.push`'s item
shape and its four contractual properties.
BACKEND_DESIGN.md: the seventh Team table, its retention, and the three public
routes' new behaviour — `enabled` on the index, the slot props on the single
Team, the per-caller row projection on the roster, and the feed.
Co-Authored-By: Claude <noreply@anthropic.com>