What
`packages/spec/src/ui/portal.zod.ts` (~L250) still uses the REMOVED Profile concept as the portal's access gate: `profiles: z.array(...)` with docstrings like "A portal must admit at least one profile" and "Portal ≠ permission boundary. The Profile is."
ADR-0090 D2 deleted `isProfile` / the Profile concept from the permission model; the audience story is now positions + audience anchors (D5/D9) and the external OWD dial (D11).
Blast radius
- Auto-generated `content/docs/references/ui/portal.mdx` teaches the removed concept (L16/L32/L36/L50/L101).
- `examples/app-showcase/src/ui/portals/index.ts` authors `profiles: ['client_portal_user']` — a grant that references nothing.
Fix (breaking, needs migration)
Replace `profiles` with position-based admission (e.g. `positions: string[]`, or an explicit external-audience binding per ADR-0090 D11 principals). Requires: zod change + tombstone in `UNKNOWN_KEY_GUIDANCE` + changeset with FROM→TO mapping + showcase portal update + doc regen.
Found while aligning docs + showcase to ADR-0090 (P4 follow-up).
What
`packages/spec/src/ui/portal.zod.ts` (~L250) still uses the REMOVED Profile concept as the portal's access gate: `profiles: z.array(...)` with docstrings like "A portal must admit at least one profile" and "Portal ≠ permission boundary. The Profile is."
ADR-0090 D2 deleted `isProfile` / the Profile concept from the permission model; the audience story is now positions + audience anchors (D5/D9) and the external OWD dial (D11).
Blast radius
Fix (breaking, needs migration)
Replace `profiles` with position-based admission (e.g. `positions: string[]`, or an explicit external-audience binding per ADR-0090 D11 principals). Requires: zod change + tombstone in `UNKNOWN_KEY_GUIDANCE` + changeset with FROM→TO mapping + showcase portal update + doc regen.
Found while aligning docs + showcase to ADR-0090 (P4 follow-up).