Observation-class, filed unassigned. Surfaced while implementing #9046 (PR #9669); deliberately not fixed there — a content/docs/** edit pulls in a different gate family than that card's packages/** surface, so it fails the in-place bounding test and gets its own card.
What the page says
content/docs/permissions/authorization.mdx:296-299, in the "Grant lifecycle: validity windows (ADR-0091 L1)" section:
Every user-grant row (sys_user_position, sys_user_permission_set) carries optional effective-dating columns — valid_from / valid_until (half-open [from, until), UTC; null = unbounded) — plus the lifecycle-audit columns reason, delegated_from, last_certified_at / certified_by.
Four columns are named in one list, as one kind of thing. Measured on main, they are two kinds:
| column | status |
|---|
reason | enforced — the delegated-admin gate requires it on delegation rows; packages/lint/src/validate-security-posture.ts errors on a delegation row without one |
delegated_from | enforced — read by plugin-security/src/delegated-admin-gate.ts, and by the explain engine for attribution |
last_certified_at | inert — no producer, no consumer anywhere in the repo (#9046's sweep) |
certified_by | inert — same |
Why it is worth a line rather than a shrug
The page is not lying outright, and that is what makes it easy to miss: further down (line ~330) it correctly says "Break-glass activation and recertification campaigns remain enterprise product … their community shapes (a time-boxed direct grant with a reason; certification stamps) are the L1 substrate above." So the page does distinguish campaign from substrate — just not in the sentence where a reader meets the four column names side by side.
Access recertification is a compliance surface (SOX / ISO 27001 access review), so the reader most likely to scan that list is the one for whom the conflation is expensive: it reads as four audit columns the platform maintains, when two are maintained and two are storage nothing touches.
#9669 has now made the field descriptions themselves state the inertness outright. That leaves this page as the remaining place where the two classes are presented as one, and it is now weaker than the metadata it documents.
Suggested shape (not a spec)
One clause splitting the list — e.g. naming reason / delegated_from as enforced audit columns and last_certified_at / certified_by as the D5 substrate that no framework code writes or reads today, matching the wording that landed on the declarations in #9669. No behavior change, no ADR change: ADR-0091 D5 already says framework ships the substrate and cloud ships the campaign.
Refs: #9046 (the finding this came out of) · #9669 (the field-description fix) · ADR-0091 D5 · ADR-0049.
Generated by Claude Code
Observation-class, filed unassigned. Surfaced while implementing #9046 (PR #9669); deliberately not fixed there — a
content/docs/**edit pulls in a different gate family than that card'spackages/**surface, so it fails the in-place bounding test and gets its own card.What the page says
content/docs/permissions/authorization.mdx:296-299, in the "Grant lifecycle: validity windows (ADR-0091 L1)" section:Four columns are named in one list, as one kind of thing. Measured on
main, they are two kinds:reasonpackages/lint/src/validate-security-posture.tserrors on a delegation row without onedelegated_fromplugin-security/src/delegated-admin-gate.ts, and by the explain engine for attributionlast_certified_atcertified_byWhy it is worth a line rather than a shrug
The page is not lying outright, and that is what makes it easy to miss: further down (line ~330) it correctly says "Break-glass activation and recertification campaigns remain enterprise product … their community shapes (a time-boxed direct grant with a reason; certification stamps) are the L1 substrate above." So the page does distinguish campaign from substrate — just not in the sentence where a reader meets the four column names side by side.
Access recertification is a compliance surface (SOX / ISO 27001 access review), so the reader most likely to scan that list is the one for whom the conflation is expensive: it reads as four audit columns the platform maintains, when two are maintained and two are storage nothing touches.
#9669 has now made the field descriptions themselves state the inertness outright. That leaves this page as the remaining place where the two classes are presented as one, and it is now weaker than the metadata it documents.
Suggested shape (not a spec)
One clause splitting the list — e.g. naming
reason/delegated_fromas enforced audit columns andlast_certified_at/certified_byas the D5 substrate that no framework code writes or reads today, matching the wording that landed on the declarations in #9669. No behavior change, no ADR change: ADR-0091 D5 already says framework ships the substrate and cloud ships the campaign.Refs: #9046 (the finding this came out of) · #9669 (the field-description fix) · ADR-0091 D5 · ADR-0049.
Generated by Claude Code