docs(adr): anchor the default-active-org session hook to ADR-0093 D9 (#8474) - #8529
docs(adr): anchor the default-active-org session hook to ADR-0093 D9 (#8474)#8529qq9340100 wants to merge 1 commit into
Conversation
…8474) `session.create.before` -> `defaultActiveOrg` was cited across plugin-auth, plugin-sharing and the dogfood suite as "ADR-0081 D1". ADR-0081 in this repo is the trusted `kind:'react'` page tier and has no D-numbered decisions at all, so the citation resolved to a real, accepted, plausible-looking record that says nothing about active organizations. Record the shipped behaviour as ADR-0093 D9 (seam, selection, only-when-absent, best-effort, opt-out, and the #8245/#8247 ordering) and re-point every active-org-stamp citation at it. ADR-0093 already owns `sys_member` and the membership lifecycle the stamp reads, ADR-0123 already anchors the hook there, and `scripts/adr-anchors/...auth-manager.ts.json` already lists ADR-0093 as that file's governing record. Behaviour is unchanged — comments and prose only. Part of #8474 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqe56GnYFddggeAyfkZFVz
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also reference the affected code. These are read-only:
|
The red
|
|
Ready for the maintainer to merge. Flipped out of draft by the Why the flip, stated explicitly so it is not mistaken for a step toward AI-merging this: This PR was parked as a draft "awaiting a human merge". That was a mistake on this seat's part — GitHub will not merge a draft PR for anyone, the maintainer included. Parking an ADR PR as draft does not wait for a human, it blocks the human. Flipping to ready-for-review is not merging, not enqueueing, and not arming auto-merge; it is the minimum required for the maintainer to be able to act. What this seat has deliberately not done, and will not do:
On merge, #8474 needs closing by hand — this PR says Generated by Claude Code |
Part of #8474
What was wrong
session.create.before→defaultActiveOrg(the hook that stamps a session'sactiveOrganizationIdfrom the caller'ssys_memberrow) was cited acrossplugin-auth, plugin-sharing and the dogfood suite as "ADR-0081 D1".
Two independent facts make that citation unusable:
docs/adr/0081-trusted-react-page-tier.mdis the trustedkind:'react'pagetier. It says nothing about organizations.
1–4. So "D1" names nothing even within the record.
pnpm check:adr-anchorscannot catch this: it verifies a cited ADR exists,and 0081 does. A reader following the citation lands on a real, accepted,
plausible-looking record with no signal they are in the wrong document.
Where the decision actually belongs
The card offered two options; the answer turned out to be a refinement of the
second — the decision was never recorded in this repo's ADR series, and
ADR-0093 already knew why. Its Relates to line says the label is inherited
from a decision record that "predates this repo's ADR series". That pre-repo
number now collides with this repo's ADR-0081.
Three independent signals put the record at ADR-0093:
scripts/adr-anchors/packages__plugins__plugin-auth__src__auth-manager.ts.jsonalready lists ADR-0093 (not 0081) as that file's governing record, and its
invariant text already describes the
session.create.beforeseam.twice — including the explicit
composeDatabaseHooks→defaultActiveOrgpointer.
only resolve an organization when a
sys_memberrow exists, and which rowexists is decided entirely by D1's policy and D2's reconciler.
But ADR-0093's existing D1/D2 do not decide the stamp — D1 is the membership
invariant, D2 is the
user.create.afterreconciler; the hook appears only asbackground in Context. Re-pointing the sites at "ADR-0093 D2" would have swapped
one wrong-but-existing anchor for another — the same defect class as #8386.
So per triage's ruling, this records the shipped behaviour as ADR-0093 D9
and points every site there.
Changes
docs/adr/0093-*: new D9 — seam, selection rule, only-when-absent,best-effort,
autoActiveOrganizationopt-out, and the audit: a user's FIRST session predates their membership, so every audit row written in that window carries a NULL tenant and is invisible to RLS readers #8245/[Decision] What is an authenticated session with NO active organization? Three subsystems answered it three contradictory ways in one shift (fail-open / fail-closed / permanently-invisible ledger rows) #8247 ordering.Marked in-record as a recording of shipped behaviour, not a new ruling. Also
states what it does not decide (the org-less state stays ADR-0123's).
TL;DR gains a D9 bullet; the Context line stops citing 0081.
⛔ D1–D8 are not renumbered — existing citations to them stay valid.
ADR-0093 D9:auth-manager.ts(x2),auth-manager.test.ts,impersonation-bearer-rotation.ts,exec-context-seam.testkit.ts,sharing-rule-org-less-caller.dogfood.test.ts(x2).
Behaviour is unchanged. The TypeScript diff is provably comment-only — zero
non-comment lines changed.
Why one PR and not the two-PR split
The split shape (#8290/#8291, #8384/#8385, #8437/#8440) needs the two halves to
be independent. Here they are not: the code half's new citations point at
ADR-0093 D9, which only exists in the ADR half. Landing the code half firstwould re-point six sites at a decision number that does not exist — reproducing
exactly the defect this card exists to close, with a different number. So this is
a single maintainer-merged draft.
Deliberately NOT in this PR
Re-deriving the census found 34
ADR-0081 D1sites carrying four distinctclaims. Only claim A — the active-org stamp, this card's subject — is fixed
here. The other three claims (the
ensureDefaultOrganizationbootstrap, the orgcapability gate, the posture/entitlement wall), plus the separate
ADR-0081 D2family, are a different set of decisions sharing the same inherited label. They
are filed separately and are not addressed here; #8474 covers claim A only.
Historical records were left untouched per the "keep history as history" rule
(#8291 / #8385 / #8440): two
.changeset/*.mdfiles and four publishedCHANGELOG.mdfiles carry the old label and are not rewritten.Verification
pnpm check:adr-anchors— OK. 121 decision numbers, 23726 citations across4016 files resolve; D9 accepted as a decision number.
node scripts/check-adr-links.mjs— OK, 540 link destinations resolve.pnpm check:nul-bytes·check:docs-audit-scope·check:test-source-alias·check:type-source-resolution·check:i18n— all OK.node scripts/check-adr-merge-approval.mjs— HTTP 401 locally (no token);CI judges it.
vitest run src/auth-manager.test.ts -t "active-org"— 9 passed.docs/adr/**is in the diff (Prime Directive #14). Noauto-merge, no enqueue.
Generated by Claude Code