How role archetypes are modelled
The role_archetype enum semantics, the succeeds_role_id FK, the citation gate that enforces SMC-grounded items on future-ready roles, and the change log.
The role_archetype enum
RPF's roles table carries a role_archetype column (Postgres enum) with three values plus an explicit NULL state. The enum is what every consumer of the role catalogue keys against — the archetype badge, the browse filter, the role-diff target picker, the metro map (M18.4), and the agent chip context.
legacyToday's role — the starting point of a transformation. Published without citation gating. Documents current practice.
future_readyThe role we're transforming toward. Citation gate is enforced at publish time: every item must carry ≥1 SMC citation.
hybridA transitional step between legacy and future-ready. Published without citation gating; useful for marking partial moves a market is making today.
NULL means "not yet classified". Pre-M18.3.1 published rows are NULL until an admin opens them in the builder and picks an archetype. The badge is suppressed for NULL rows.
succeeds_role_id — the successor FK
Every role can carry succeeds_role_id, a self-referencing foreign key pointing to the role this one transforms from. The constraint is set at the database level (db/schema.ts §40-47), with an index on (succeeds_role_id) so the role-diff target lookup is O(1).
The FK is nullable. Future-ready roles typically have no successor (they're the destination); legacy and hybrid roles typically point forward to a published future-ready successor. The FK does not enforce archetype-shape consistency — that's a validation rule at publish time, not a DB constraint.
The citation gate (Transformation Citations)
On publish of a role whose archetype is future_ready, RPF validates that every item attached to the role carries at least one cited source from the SMC registry. The gate is implemented in the role-publish path (PR #217 shipped this) — it returns a structured validation error per missing-citation item, which the role builder renders inline next to the offending row.
The gate does not validate on save-as-draft or on intermediate proposals; only the final publish path enforces it. This keeps the authoring experience fluid: you can sketch out a future-ready role with un-cited items in draft, then walk the citation list before publishing.
Legacy and hybrid archetypes are exempt from the gate. They document observed practice, which is grounded in the surface itself rather than in a citation. If you want hybrid items cited anyway, the standard cited-source UI is still available — the gate just doesn't compel it.
Edge cases
- A role with role_archetype = NULL renders without a badge and is excluded from archetype-keyed filters unless the "unset" filter is explicitly picked. It is publishable until an admin sets the archetype, at which point future-ready gating kicks in retrospectively.
- A role cannot succeed itself (succeeds_role_id = id). The DB-level FK does not enforce this; the publish-path validator catches it.
- If succeeds_role_id points to an archived/unpublished role, the successor link in the UI shows a "successor archived" caveat; the role-diff target falls back to ?vs= override.
- Citations on draft items don't count toward the citation gate until the item itself is published; the gate runs over the role's published item set at publish time.
- Flipping archetype from legacy → future-ready on an existing published role re-runs the citation gate at the next publish; uncited items block the flip until they carry citations or the items are removed.
Stability tier
The role_archetype enum and succeeds_role_id FK are at stability tier beta. Adding a fourth archetype (e.g. "experimental") would be an additive enum change and would not require a major bump; removing or renaming an existing value would. Schema changes are journal-driven (db/migrations/meta/_journal.json); shape changes will be called out in the change log.