Skip to content

docs(citations): re-anchor the eight ADR-0057 D10 citations to the framework's ADR-0124 D1 (#5701) - #5842

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-5701-reanchor-adr-citations
Aug 23, 2026
Merged

docs(citations): re-anchor the eight ADR-0057 D10 citations to the framework's ADR-0124 D1 (#5701)#5842
os-zhuang merged 1 commit into
mainfrom
claude/issue-5701-reanchor-adr-citations

Conversation

@os-zhuang

@os-zhuangos-zhuang commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Part of #5701

Re-anchors the eight citations of "the server enforces; client-side gating is a usability
courtesy"
from the framework's ADR-0057 D10 to the framework's ADR-0124 D1 — the
record that actually decides that rule.

⚠️Deliberately Part of, not a closing keyword. The dispatch asked for one here, but the
card's own ruling says "the card closes when both land", and the second half —
docs/adr/0036-field-conditional-rules.md — is a governed surface that merges on a
human's schedule (#5843). A closing keyword here would shut the card the moment
this PR merges and orphan the ADR half, which is the outcome the two-PR split exists to
avoid. Flip it if the card should close on this PR anyway — it is a one-word
body edit.

Why the old anchor is wrong

Framework ADR-0057D10 decides "Setup-nav surfacing follows the capability
(ADR-0029 K2); the object stays open"
— nav-entry tiering, not enforcement location. The
rule these eight sites invoke is decided by framework ADR-0124 D1, "The server is
the enforcement point; client-side gating is a usability courtesy"
(Accepted 2026-08-18).

The new anchor is derived from an authority, not chosen. Framework ADR-0057 carries a
note aimed at precisely this citation:

⚠️The general rule lives in ADR-0124, not here.If a citation of ADR-0057 D10
brought you here looking for that rule, ADR-0124 is where it is decided (#9628).

#5699 addressed the repo-ambiguity half of this defect — saying whose ADR numbering the
citation meant — and deliberately left the anchor half untouched. This is that half.

The eight sites

#Site
1packages/app-shell/src/views/RecordDetailView.tsx
2packages/app-shell/src/views/studio-design/PackageOwdOverviewPanel.tsx
3packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx
4packages/plugin-detail/src/useRecordEditable.ts
5packages/plugin-detail/src/useRecordEditable.test.tsx
6packages/plugin-grid/src/hooks/useRecordCrudVerdicts.ts
7packages/react/src/hooks/useCapabilityGate.ts
8packages/core/src/evaluator/fieldRules.ts — one of the two derivation authorities, which #5699 was correctly fenced out of because it already carried the framework qualifier; it pointed at the same wrong decision

Comment text only. git diff -U0 carries zero non-comment added or removed lines
(8 files, +19 / −23).

The wording, and what retires with the number

No third phrasing was invented. The form now shipping is the fieldRules.ts authority's,
with the anchor moved:

the framework's ADR-0124 D1 — server enforces, client is courtesy

The disambiguating parenthetical #5699 shipped — "framework numbering; this repo's own
ADR-0057 is an unrelated document"
retires with the number it disambiguated. It
warned about a collision specific to 0057; this repository has no ADR-0124 at all (its
own series stops at 0059), and framework ADR-0124 records that a fresh, unambiguous
number was chosen precisely so citations of it would not need such a warning. The
the framework's … possessive stays at every site, so each one still says whose numbering
it means — which was #5699's actual fix.

Three comment tails were re-wrapped where the shorter citation left a ragged line
(StudioDesignSurface.tsx, useRecordCrudVerdicts.ts, useCapabilityGate.ts). One
pre-existing odd wrap inside the same re-wrapped paragraph — it means "holds /
nothing" and gates normally in useCapabilityGate.ts — was joined rather than left
dangling next to fresh text.

Deliberately NOT touched

  • packages/data-objectstack/src/appAccessProbe.test.ts — byte-untouched. It cites
    D10 for "an app gated by an absent optional service", which the capability /
    service-gating family D10genuinely does decide. It is correct as it stands. The
    split here is per-site and was read, not pattern-matched: a blanket
    grep -l | xargs sed would have corrupted this file.
  • The framework's own citations. A meaningful share of them (rest-server's
    filterAppForUser, the dashboard requiresService gates) are the family D10 really
    decides. Not this repo's to change.
  • Published CHANGELOG.md entries (10 lines across 8 packages). Historical release
    records; they are not rewritten after the fact.
  • .changeset/adr-0057-d10-citation-attribution-5202.mdQualify ADR-0057 D10 as the framework's numbering at seven live citation sites #5699's own still-unreleased
    changeset, which accurately narrates what Qualify ADR-0057 D10 as the framework's numbering at seven live citation sites #5699 did. Rewriting another change's record
    to match a later change would make it false. Both entries compile into the same release
    in chronological order.

Enumeration — before and after, with controls

grep -rn "ADR-0057 D10" repo-wide, same pipeline every time.

totallive-source hits
base 5da0084632210
this branch 68e0b9957142

The 12 survivors that are not live source are the 10 CHANGELOG.md lines and the 2 lines
inside #5699's changeset, listed above. The 2 remaining live-source hits are
appAccessProbe.test.ts:25 (correct, out of scope) and
docs/adr/0036-field-conditional-rules.md:91, which #5843 moves.

Composition of the two PRs, measured rather than asserted:

#5843 blob of docs/adr/0036 — "ADR-0057 D10" hits: 0
#5843 blob of docs/adr/0036 — "ADR-0124 D1" hits: 1
this tree, live source, excluding docs/adr/0036: 1 hit
packages/data-objectstack/src/appAccessProbe.test.ts:25

→ with both PRs landed, the sole surviving live-source ADR-0057 D10 citation is the
one that is correct.

Controls on the same pipeline, so a broken grep cannot read as a clean sweep:
positive"absent optional service" still returns 3 hits, including the untouched probe
test; negative — a sentinel string returns 0.

Verification — all at 68e0b9957

CheckResult (the gate's own verdict line)
pnpm exec vitest run (7 targeted files, repo root, --maxWorkers=2)Test Files 7 passed (7) · Tests 95 passed (95)
type-check, 5 affected packagesall Done, 0 × error TS
check-changeset-presence.mjs✅ 8 source file(s) of 5 released package(s) changed, and this change declares 1 changeset(s)
check-control-bytes.mjs✅ check-control-bytes: OK (scanned 4856 tracked text file(s); skipped 85 binary)
eslint on the 8 touched files, --format json0 errors, 136 warnings — identical to the same 8 files at base: delta errors +0, warnings +0

The suites cover all eight touched files: every one is imported and executed by at least one
of them, which is what actually catches a malformed comment edit.

type-check first ran red with TS6305 … packages/types/dist/index.d.ts has not been built — the fresh-worktree false red. Re-run after building the dependency closure with
the caret-suffix filter form (pnpm --workspace-concurrency=2 --filter '@object-ui/core^...' build,
one per affected package); the numbers above are from the built closure.

Lint narrowing, declared. Repo-wide pnpm lint was not run locally; CI runs the farm
regardless. The narrowing to 8 files is a measurement, not a gap: eslint.config.js enables
no type-aware linting (no parserOptions.project, no projectService), so a file's
verdict depends only on its own text plus the config — this diff changes neither the config
nor any file outside the eight, so no untouched file's verdict can move. File count 8 is
read from eslint's own --format json output.

Nothing to ablate. These are comment-only changes with no behavioural leg — there is no
mutation that would make a test fail differently. Staging a decorative reverse-verification
would be theatre; the before/after enumeration above is the evidence.

Companion PR

docs/adr/0036-field-conditional-rules.md:91 — the wording all eight of these derive from,
carrying the same misattribution — moves in #5843 because docs/adr/** is a
governed surface that stops at draft for human merge. Bundling it here would make eight
ordinary code changes wait on a human for no reason.


Generated by Claude Code

…amework's ADR-0124 D1 (#5701)
The eight sites cite `ADR-0057 D10` for "the server enforces; client-side
gating is a usability courtesy". That decision is "Setup-nav surfacing follows
the capability (ADR-0029 K2); the object stays open" — nav-entry tiering, not
enforcement location. The rule they invoke is decided by the framework's
ADR-0124 D1 (Accepted 2026-08-18).
The anchor is derived from an authority, not chosen: framework ADR-0057 carries
a note aimed at exactly this citation — "If a citation of `ADR-0057 D10`
brought you here looking for that rule, ADR-0124 is where it is decided."
Comment text only; `git diff -U0` carries zero non-comment lines. The
"framework numbering; this repo's own ADR-0057 is an unrelated document"
parenthetical retires with the number it disambiguated — this repo has no
ADR-0124 (its own series stops at 0059) — while the "the framework's ..."
possessive stays, so every site still says whose numbering it means.
`packages/data-objectstack/src/appAccessProbe.test.ts` is left byte-untouched:
it cites the same decision for the capability/service-gating case that
decision genuinely does decide.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EuPCi56cnGyykygi3z9w4m
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 52 chunks)3228.5 KB3990.2 KB
Main entry chunk (gzip)152.7 KB350 KB
Entry fileindex-ByMDm73n.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)10.13KB3.77KB
app-shell (runtime-config.js)12.80KB4.47KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)503.98KB113.95KB
core (index.js)4.92KB1.97KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)164.55KB45.67KB
fields (index.js)238.40KB59.89KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)23.13KB7.63KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)7.77KB3.13KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)9.53KB3.38KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)4.64KB1.50KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)1.93KB0.88KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.62KB12.83KB
plugin-charts (index.js)64.66KB18.32KB
plugin-chatbot (index.js)186.91KB44.22KB
plugin-dashboard (index.js)132.43KB34.27KB
plugin-designer (index.js)212.30KB42.80KB
plugin-detail (index.js)242.34KB60.99KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)125.63KB30.64KB
plugin-gantt (index.js)164.15KB39.88KB
plugin-grid (index.js)200.79KB54.26KB
plugin-kanban (index.js)52.93KB14.60KB
plugin-list (index.js)111.80KB27.20KB
plugin-map (index.js)20.06KB6.62KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.49KB11.93KB
plugin-timeline (index.js)26.49KB7.59KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.51KB20.72KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)52.40KB17.45KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.33KB0.69KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)12.13KB3.65KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)7.54KB2.63KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (index.js)3.88KB1.85KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-zhuang
os-zhuang marked this pull request as ready for review August 23, 2026 14:55
@os-zhuang
os-zhuang added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit d40d295Aug 23, 2026
23 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5701-reanchor-adr-citations branch August 23, 2026 14:55
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude