Uh oh!
There was an error while loading. Please reload this page.
docs(adr-anchors): make the ADR-0057 D10 citation attributive where it names the general rule - #9655
Conversation
… it names the general rule The rule "server enforces, client is courtesy" is true and independently stated, but no ADR decides it: D10 of the ERP-authorization ADR-0057 decides Setup-nav capability surfacing (its PS-2 note carries the server-enforcement half, scoped to nav), and the other ADR-0057 has no D-numbered decisions. Convert the sites that cite D10 for the GENERAL rule from an assertion that the anchor resolves into an attribution, following the objectui#3888 precedent. The nav/capability-gate citations are correct and are left alone. Recording the decision itself is #9628. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
…itation Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
📓 Docs Drift CheckThis PR changes 3 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 21 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 2bd80204b3344e5ce96a6bc35732eae296e743ea && git checkout 2bd80204b3344e5ce96a6bc35732eae296e743ea
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 07e630e5830c633d069798975f1b7883e7749bdb e341eeba2288541e2535011b716fa9434f0e0513 && git checkout -B drift-repro 07e630e5830c633d069798975f1b7883e7749bdb && git merge --no-ff e341eeba2288541e2535011b716fa9434f0e0513
node scripts/docs-audit/affected-docs.mjs --json 07e630e5830c633d069798975f1b7883e7749bdb
|
|
Uh oh!
There was an error while loading. Please reload this page.
Part of #9255. Traceability only — no behaviour, no rule, and no gate semantics change.
Local gate union re-run at the final commit
e341eeba2(same tree as the head of this PR).What the corpus search actually found (H1)
The card's premise is half right, and the half that is wrong changes the fix.
ADR-0057 D10does resolve to a real heading —docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md:422, "Setup-nav surfacing follows the capability (ADR-0029 K2); the object stays open". What does not hold is that it decides the rule people cite it for. This is the #8386 family (a D citation whose content does not match), not a dangling anchor.The lineage is traceable and explains everything. The first commit ever to write the string is
2256e9369— "feat: gate Setup Org/Invitations nav on multi-org, server-side (ADR-0057 D10) (#2150)". D10's own PS-2 implementation note (2026-06-22,:516, "D10 realized via server-enforcedrequiresService") says the Setup nav is filtered server-side infilterAppForUserand thatrequiresObjectis "a client-side (objectui) gate, not enforced in this repo". That contrast is the seed of "server enforces, client is courtesy" — and it is scoped to nav / app-metadata visibility. Later citers kept the number and dropped the scope.Did I find an ADR that decides the general rule? No. Searched the whole corpus (127 records) by content, not by number —
courtesy,server enforces,server is the authority,enforcement point,fail-closed,UI absence, plus every decision heading matchingserver|client|enforc|authorit:ADR-0057D10 + PS-2 note0057-system-data-lifecycle-and-retention.mdPer the dispatch ruling, the re-anchoring stops here rather than guessing: pointing ~30 sites at a "closest" decision would convert a detectably-broken citation into an undetectably-wrong one. What ships is the safe half — attributive phrasing, following the objectui#3888 precedent. Recording the decision is proposed in #9628 (evidence included there).
H4 — classification of all citing sites, and the disposition it implies
The card says 20 files. It was already 40 at the card's own measured commit
23abe2782, and it is 40 today — so the count was understated 2x, but it has not grown in-repo since filing.The classification splits the sites into two groups the card treats as one, and that split is the whole disposition:
Group A — CORRECT citations, deliberately untouched (nav / capability
requiresServicegate)These cite D10 for exactly what D10 decides. Retargeting them would have been the real damage.
packages/rest/src/rest-server.ts(12 sites —filterAppForUser,filterNav,filterDashboardForUser)packages/rest/src/rest.test.ts(7),meta-app-area-nav-gate.test.ts(2),meta-app-publish-gate.test.ts(3),rest-exec-ctx-principal-kind.test.ts(1)packages/rest/src/rest-api-plugin.tspackages/platform-objects/src/apps/account.app.ts,account-approvals-nav.test.tsscripts/check-meta-type-normalized.mjspackages/spec/liveness/app.json,dashboard.json,README.md:572Group B — over-generalized citations. Changed where live, listed where not.
scripts/adr-anchors/…rule-validator.ts.json:7packages/lint/src/validate-expressions.ts:766packages/lint/src/validate-expressions.ts:702packages/objectql/src/validation/rule-validator.ts:115, :660packages/objectql/src/engine.ts:4973packages/plugins/plugin-hono-server/src/current-user-endpoints.ts:240, :867docs/qa/platform-checklist/RUNNER.md:78(rule 4)packages/lint/src/validate-expressions.test.ts,packages/objectql/src/engine-readonly-when-parent.test.ts,packages/plugins/plugin-hono-server/src/fold-wildcard-superuser.test.ts,packages/qa/dogfood/test/showcase-readonly-when-parent.dogfood.test.tsdocs/qa/platform-checklist/areas/*.json— 7 files, ~13 clausesCHANGELOG.mdfilesdocs/audits/2026-07-studio-package-create-ux-dogfood.md:9.claude/skills/dogfood-verification/SKILL.md:113H2 — the anchor's
adrsfield could NOT be disambiguated, and this is a hard mechanical blockThe dispatch expected the anchor's bare
ADR-0057to move to "the repo's established disambiguated spelling". There is no such spelling, and the gate actively rejects one.adr-anchors.json与 328 处代码注释按裸编号引用,无法消歧 #5992's maintainer ruling (2026-08-07) was "C first, B to finish". C landed (number-uniqueness audit + shrink-only allowlist, PR fix(scripts): assert an ADR number names one decision + repair a broken ADR link (#5992) #6593). Route B — the slug-qualified spellingADR-0057-lifecycle— never landed.scripts/check-adr-anchors.mjs:191definesADR_ID = /^ADR-(\d{4})$/. Anadrsentry must be exactly four digits.adr-anchors.json与 328 处代码注释按裸编号引用,无法消歧 #5992's route B is the separate change that fixes it", and prints them as tracked debt on every green run.Ablation, predicted red / observed red. Set
adrs[0]toADR-0057-erp-authorization-core-business-units-and-scope-depth, ran the real gate: exit 1,"ADR-0057-…" is not an ADR id (expected e.g. ADR-0090). Restored from the branch; tree byte-clean, gate green again.So the disambiguation went into the invariant prose instead, which is free-form and is what a reader actually reads — it now names both
0057-*files and says which one D10 lives in.adrsstays bare, deliberately, and the gate's ambiguity note still lists these four anchors so route B's debt stays visible.H3 — objectui: the citation IS actively spreading (re-grade input)
The card recorded two objectui inheritances. Measured at
objectui origin/maintoday: 20 files, of which 9 are live source/test sites asserting the anchor (RecordDetailView.tsx,PackageOwdOverviewPanel.tsx,StudioDesignSurface.tsx,appAccessProbe.test.ts,useRecordEditable.ts+ its test,useRecordCrudVerdicts.ts,useCapabilityGate.ts), plus 10 CHANGELOGs.The irony worth noting: the two sites the card knew about (
fieldRules.ts, ADR-0036) are exactly the two written attributively on purpose. The other 9 are the plain inheritance. No objectui PR is opened from this card — filed as objectui#5202, which also flags thatappAccessProbe.test.tsis a correct nav-gate citation that should survive any sweep there.Verification
pnpm --filter "@objectstack/lint" test— 74 files, 2088 passedpnpm --filter "@objectstack/objectql" test— 217 files, 3836 passedpnpm --filter "@objectstack/plugin-hono-server" test— 18 files, 211 passedtypecheck— lint, objectql, plugin-hono-server all Done (each script echoed; no zero-match silent pass)e341eeba2:check:adr-anchors,check:nul-bytes,check:engine-double-contract,check:where-matcher,check:query-options-erasure,check:cross-package-test-inputs,check:durability-log-level,check:error-code-casing,check:route-envelope,check:stack-collection-maps,check:test-source-alias,check:type-source-resolution— all PASSnode scripts/pm/dispatch-gates.mjs.check:type-check-debtwas not run locally: it needs a full built workspace closure, and this diff adds no test code (comment edits only), so its tsc counts cannot drift up. CI runs it.docs/adr/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md,content/docs/releases/**.Generated by Claude Code
Generated by Claude Code