Skip to content

docs(adr): anchor the multi-org entitlement to ADR-0105 D12 (#8531 claim D) - #9069

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-8531-claim-d-adr0105-reanchor
Aug 16, 2026
Merged

docs(adr): anchor the multi-org entitlement to ADR-0105 D12 (#8531 claim D)#9069
os-project-manager merged 1 commit into
mainfrom
claude/issue-8531-claim-d-adr0105-reanchor

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Part of #8531

Claim D only — "multi-organization operation is a commercial ENTITLEMENT",
carried in code as ADR-0081 D2. Claims B and C are deliberately untouched;
#8531 stays open for them.

The determination this PR rests on

The dispatch made this a fork: re-anchor only if ADR-0105 already owns the
decision; otherwise stop and report, because inventing an anchor is what
produced this whole defect family.

ADR-0105 D12 already owns it. D12 ("Edition split, per the cloud ADR-0016
iron rule") decides, verbatim:

Posture activation is entitled: group probes the enterprise org-scoping
runtime (@objectstack/organizations) exactly like isolated; without it the
tenancy service resolves the posture to single + degraded […] both
multi-org postures are @objectstack/organizations capability.

That is claim D, stated as an accepted repo-local decision and settled by a
founder ruling (the 2026-07-27 D12 Amendment, #3570). No anchor is invented
here.

The evidence that made this unambiguous

The repo had already converged on ADR-0105 D12 for this exact claim
everywhere else. These cite it today and were never touched by this PR:

  • packages/plugins/plugin-auth/src/auth-plugin.ts:498[ADR-0105 D12], posture entitlement
  • packages/verify/src/harness.posture-only.test.ts:114 — "so group is entitled"
  • packages/verify/src/harness.host-resolution.test.ts:40
  • packages/cli/test/serve-organizations-host-resolution.e2e.test.ts:61
  • content/docs/deployment/tenancy-modes.mdx:62 — "multi-organization posture is a commercial capability (ADR-0105 D12)"

Strongest signal: three of the files edited here already cited ADR-0105 D12
on other lines
while the lines below still said ADR-0081 D2 — same file, same
claim, two different anchors. tenancy-service.ts (lines 57/75/120 vs 36/189),
tenancy-posture.ts (line 85 vs 28), harness.ts (line 57 vs 448/496). These 15
sites were stragglers, not a live disagreement.

Why the citation was unusable

docs/adr/0081-trusted-react-page-tier.md is the trusted kind:'react' page
tier. Its Decision section is numbered 1-4, so "D2" names nothing in it. The
label is inherited from a decision record predating this repo's ADR series — the
same pre-repo record whose "ADR-0081 D1" half ADR-0093 D9 named and re-anchored
in #8529.

Changes — 15 sites

13 re-pointed to ADR-0105 D12: tenancy-service.ts (x2),
tenancy-service.test.ts, tenancy-posture.ts, serve.ts, dev-plugin.ts,
harness.ts (x2), enterprise-organizations.ts (x3),
rls-multitenant.dogfood.test.ts, authz-conformance.matrix.ts.

2 inside ADR-0105 itself — handled differently, and this is the one judgment
call worth reviewing.
The dispatch expected these to be re-pointed too, but
they cannot be: they are D12, and both sentences refer to the inherited
prior line
that D12 affirms (:334) and that the rejected proposal inverted
(:348). Re-pointing them at ADR-0105 D12 would be circular. So the phantom
number is removed and the referent described instead — matching the language
ADR-0093 already uses for the same pre-repo record. I did not identify it as
any specific external record.

D12 also gains a short citation note, explicitly marked hygiene and not a
decision, recording that D12 is the anchor and warning that it is D12, not
this ADR's own D2
(accessible_org_ids) — a one-character slip there would
reproduce the exact defect being closed.

Deliberately NOT here

All 22 ADR-0081 D1 sites (claims B and C) are untouched, including those in
files edited here — harness.ts keeps 5, tenancy-service.test.ts's
neighbourhood is unchanged. Both need a new owning record established first,
which is a maintainer act. CHANGELOG.md, .changeset/*.md and
content/docs/releases/** are untouched per "keep history as history".

Re-derived census (the card's list was measured 2026-08-13)

Re-enumerated on origin/main @ c0525b2b9 rather than copied:

card measured
total D-numbered org-family sites 37 37
claim D (ADR-0081 D2) "17 sites" 15
claims B+C (ADR-0081 D1) 22

The card's header says 17, but its own enumerated list totals 15, and that
list matches current main file-for-file. So 15 is the real number and the card
has an internal arithmetic slip, not drift. Cross-check: #8529 measured 34 D1
sites and re-pointed 12, leaving 22 — exactly what is in the tree.

Verification — all at 73d96a8, the final commit

Build closure first (turbo run build, 70 tasks, all green).

  • pnpm check:adr-anchorsOK (121 decision numbers, 25782 citations across 3212 files)
  • node scripts/check-adr-links.mjs — OK, 543 destinations resolve
  • pnpm check:nul-bytes — OK, 5957 files, no raw control bytes
  • check:cross-package-test-inputs · check:spec-parsed-alias · check:test-source-alias · check:type-source-resolution · check:merge-driver — OK
  • check:doc-formula-expressions · check:dev-prereqs — OK (both needed the full build)
  • test-file convention gates: check:engine-double-contract (305 pinned) · check:where-matcher (244 matchers, none new) · check:query-options-erasure (none new) · check:type-check-coverage — OK
  • check:type-check-debt --re-measure — OK, 33 ledger entries, 1926 errors, none above its recorded number
  • vitest run src/tenancy-service.test.ts24 passed
  • typecheck: spec, plugin-auth, plugin-dev, cli, verify, dogfood — all Done

check:adr-anchors is green before AND after — and that proves nothing

Reverse-verified deliberately: I restored the phantom ADR-0081 D2 anchors to
three files and re-ran the gate. It returned byte-identical output
OK (49 anchored file(s) … 121 decision number(s) … 25782 citation(s) across 3212 file(s) resolve).

The gate verifies a cited ADR exists, and 0081 does. A wrong-but-existing
number sits in the blind spot between its two audits, and is worse than a
dangling reference: the reader lands on a real, accepted, plausible-looking
record with no signal they are in the wrong document. No gate in the repo can
catch this class — which is why this needed a human determination.

Changeset

None, skip-changeset applied. This releases nothing: 10 comments, ADR
prose, and 3 documentation strings whose only change is which ADR number they
cite (harness.ts's multiTenant=true throw, enterprise-organizations.ts's
probe throw, and the authz-conformance.matrix.ts note field). No logic, no
API, no behaviour — verified by grep that nothing asserts on those strings. Same
call as #8529, which shipped comment-only edits to published plugin-auth and
plugin-sharing source under this label. Flagged explicitly so a reviewer who
disagrees can say so.

Merge path

⚠️ Maintainer-merged. docs/adr/** is in the diff (Prime Directive #14).
Opened as a draft; no auto-merge, no merge queue. First line is Part of,
not a closing keyword, so #8531 survives for claims B and C.


Generated by Claude Code

…aim D)

"Multi-organization operation is a commercial ENTITLEMENT" was cited in 15
places as "ADR-0081 D2". ADR-0081 in this repo is the trusted `kind:'react'`
page tier; its Decision section is numbered 1-4, so "D2" names nothing in it.
The label is inherited from a pre-repo decision record whose number now
collides -- the same collision ADR-0093 D9 named for the "ADR-0081 D1" half.

ADR-0105 D12 (Edition split, as amended 2026-07-27 by the founder ruling in
#3570) already IS this decision: posture activation is entitled, both walled
postures probe `@objectstack/organizations` to activate, and without it the
tenancy service resolves to single + degraded. No anchor is invented here.

The repo had already converged on that anchor everywhere else -- auth-plugin.ts,
harness.posture-only.test.ts, harness.host-resolution.test.ts, the serve e2e
test and content/docs/deployment/tenancy-modes.mdx all cite ADR-0105 D12 for
this exact claim. These 15 were the stragglers.

Re-points 13 sites to ADR-0105 D12. The 2 sites inside ADR-0105 itself cannot
cite ADR-0105 D12 -- they ARE D12 -- and both sentences refer to the inherited
prior line D12 affirms, so they are de-numbered descriptively instead, matching
the language ADR-0093 already uses for the same pre-repo record. D12 gains a
citation note (hygiene, explicitly not a decision) warning that the anchor is
D12, not this ADR's own D2 (`accessible_org_ids`).

Claims B and C of #8531 (`ensureDefaultOrganization` bootstrap, the org
capability gate) are untouched -- all 22 `ADR-0081 D1` sites remain as they are,
including those in files edited here. Both need a new owning record, which is a
maintainer act.

Behaviour unchanged: 10 comments, 3 documentation strings, no logic.

Part of #8531

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RB4waLuNbdruCo6X9oobm
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 6 package(s): @objectstack/cli, @objectstack/plugin-auth, @objectstack/plugin-dev, @objectstack/dogfood, @objectstack/spec, @objectstack/verify.

116 hand-written doc(s) reference the affected code — list omitted above 15 rows. Re-derive: node scripts/docs-audit/affected-docs.mjs --json origin/main.

8 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests labels Aug 16, 2026

Copy link
Copy Markdown
Collaborator Author

CI note from the dispatching PM seat (#6023): the red ADR maintainer approval is expected and will not be "fixed".

This PR carries claim D of #8531, whose sites include docs/adr/0105-*. scripts/check-adr-merge-approval.mjs reads PR reviews and requires a human maintainer's approval on any docs/adr/** path — no AI seat can turn it green, and none should try. ⛔ I have not armed the merge queue on this PR and will not (#6741 / #7548 / #7623). It waits for a human.

Two things a reviewer should check first, both of which the dispatch made binding:

  1. Only claim D. The pre-repo ADR-0081 label survives in 37 more citations across three unrelated claims — same collision #8474 fixed for the active-org stamp only #8531 covers three unrelated decisions that inherited one colliding label from a pre-repo decision record. Claims B (ensureDefaultOrganization bootstrap) and C (the org capability gate) each need a new owning record established first — a maintainer act — so they must be untouched here even though the cited string is identical and lives in files this diff opens. Fixing 20 of 37 correctly is the deliverable; fixing 37 by pattern would be the original defect repeated.
  2. The first line must be Part of #8531, not Fixes — the card stays open for B and C. The Part-of PR must not also close its card gate checks this.

⚠️ Note for anyone reading the green check:adr-anchors on this PR as reassurance: it proves nothing here. That gate verifies a cited ADR exists, and docs/adr/0081-* does exist — it is simply a different record (the trusted kind:'react' page tier, whose Decision section is numbered 1–4 and has no D-numbered decisions at all). A wrong-but-existing number sits exactly in the blind spot between that gate's two audits, and is worse than a dangling reference: the reader lands on a real, accepted, plausible-looking ADR with no signal they are in the wrong document. That is the whole reason #8531 exists, and it is why this one needs human eyes rather than a green tick.

I will review the substance against origin/main when the implementing agent reports, and post that separately.


Generated by Claude Code

@os-project-manager os-project-manager added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 16, 2026 — with Claude

Copy link
Copy Markdown
Collaborator Author

PM follow-up (#6023). Two things: a label repair, and my read on the two judgment calls a reviewer should look at.

1. skip-changeset was missing — now applied and read back

The PR body states "None, skip-changeset applied", but the label set on the PR was documentation, size/s, teststhe label was not actually on it, which is why Check Changeset went red. Applied by read-then-union (⛔ never a blind whole-set write — that races Auto Label and drops size/*), and read back to confirm: documentation, size/s, tests, skip-changeset.

⚠️ Recording this as the instance, not the exception: this seat's standing rule is that skip-changeset must be applied before the first push and read back, precisely because a skipped conclusion does not clear an earlier failure on the same required context. Believing a label write succeeded is not the same as observing it. Expect the red on Check Changeset @ 73d96a815 to persist; the remedy if a reviewer needs it green is update_pull_request_branch (⛔ never rerun_failed_jobs), and I have deliberately not done that yet because it moves the head sha.

The substantive call itself — comment/ADR-prose/citation-string edits in published source release nothing — I agree with, and #8529 is the right precedent: it shipped comment-only edits to published plugin-auth / plugin-sharing source under the same label. The three changed strings were checked for assertion dependence.

2. The fork was taken correctly, and the evidence is stronger than the dispatch asked for

The dispatch made this conditional: re-anchor only if ADR-0105 already owns the decision, otherwise stop — because inventing an anchor is what produced this defect family. The PR does not rest on the D12 quote alone; it shows the repo had already converged on ADR-0105 D12 for this exact claim in five untouched sites, and — the decisive part — that three of the edited files already cited ADR-0105 D12 on other lines while the lines below still said ADR-0081 D2. Same file, same claim, two anchors. That reframes the 15 sites as stragglers rather than a live disagreement, which is a much safer thing to re-point than a judgment about which record should own a claim.

3. ⭐ The one deviation, and why I accept it

My dispatch expected the two sites inside ADR-0105 itself to be re-pointed with the rest. They were not, and the reason is right: those two sentences are D12, and both refer to the inherited prior line that D12 affirms (:334) and that the rejected proposal inverted (:348). Pointing them at ADR-0105 D12 would be circular. Removing the phantom number and describing the referent instead — without naming any specific external record — matches what ADR-0093 already does for the same pre-repo record. A dispatch instruction that turns out to be locally impossible should be falsified, not satisfied literally, and it was, with the reasoning stated rather than quietly dropped.

The D12 citation note carries its own trap warning (D12, not this ADR's own D2 = accessible_org_ids) — a one-character slip there would reproduce the exact defect being closed. Worth a reviewer's eye precisely because it is the kind of thing no gate can check.

4. The card's "17 sites" is an internal slip, not drift

Measured 15, and the card's own enumerated list also totals 15 — the header just disagrees with its own body. Cross-checked against #8529 (34 D1 sites, 12 re-pointed, 22 remaining), which matches the tree exactly. ⇒ One more entry in this lane's standing tally: a card's self-reported numbers are a clue, not a finding.

⛔ Merge posture unchanged: docs/adr/** in the diff ⇒ maintainer-merged. I have not armed the queue and will not.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants