Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .changeset/adr-0057-d10-citation-attribution-5202.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
---

Traceability only — this publishes nothing, declared explicitly with an empty frontmatter
rather than left undeclared. The change is comment text at seven live source sites; no
executable line moves, and `git diff -U0` carries zero non-comment added or removed lines.

`server enforces, client is courtesy` was cited at those seven sites as a bare
**`ADR-0057 D10`**. The substantive claim is correct and is unchanged here; what was missing
is the **framework qualifier**. In this repository the bare string resolves to
`docs/adr/0057-console-ai-chat-one-conversation-docked.md` — a document about console AI chat
docking, which contains no `D10` at all and is the one a reader greps first. The intended
anchor is the *framework's* ADR-0057, whose D10 decides *"Setup-nav surfacing follows the
capability (ADR-0029 K2); the object stays open"*.

Each site now carries the disambiguation already shipped by the two authorities in this
repository — `docs/adr/0036-field-conditional-rules.md:91` and
`packages/core/src/evaluator/fieldRules.ts:38` — rather than a third phrasing:
`the framework's ADR-0057 D10 — framework numbering; this repo's own ADR-0057 is an
unrelated document`.

Three sites are deliberately left byte-untouched, all three already correct:
`packages/data-objectstack/src/appAccessProbe.test.ts:25` (a verbatim quotation of the
objectstack#8013 ruling, and about the capability/nav gate — the one family D10 really does
decide), plus the two authorities above.
4 changes: 3 additions & 1 deletion packages/app-shell/src/views/RecordDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,9 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri
// a record the user may only read: the form opened, the user retyped a
// field, and the server rejected the save with a 403. Ask the explain
// engine for the row-level verdict (fail-open; the server stays the
// authority per ADR-0057 D10) and fold it into the same affordance gates.
// authority per the framework's ADR-0057 D10 — framework numbering; this
// repo's own ADR-0057 is an unrelated document) and fold it into the same
// affordance gates.
const recordWriteAllowed = useRecordEditable(
objectDef?.name,
pureRecordId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ export interface PackageOwdOverviewPanelProps {
publishNonce?: number;
/** Notify the surface so its pending-changes counter refreshes after a save. */
onDraftSaved?: () => void;
/** Courtesy gate: read-only packages render badges only (ADR-0057 D10). */
/**
* Courtesy gate: read-only packages render badges only (the framework's
* ADR-0057 D10 — framework numbering; this repo's own ADR-0057 is an
* unrelated document).
*/
readOnly?: boolean;
locale: SupportedLocale;
/** Object to scroll to / highlight (deep-link from the permission matrix badge). */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,11 +423,12 @@ export function StudioDesignSurface({ aiSlot }: StudioDesignSurfaceProps): React
const tab = params.tab ?? 'interfaces';
const locale = useMetadataLocale();

// Courtesy gate (ADR-0057 D10): a read-only code/installed package refuses
// authoring server-side (ADR-0070), so don't let the user build up doomed
// local edits first — disable the authoring affordances up front. Unknown
// writability (fetch failed / still loading) stays ungated; the server gate
// remains the authority either way.
// Courtesy gate (the framework's ADR-0057 D10 — framework numbering; this
// repo's own ADR-0057 is an unrelated document): a read-only code/installed
// package refuses authoring server-side (ADR-0070), so don't let the user
// build up doomed local edits first — disable the authoring affordances up
// front. Unknown writability (fetch failed / still loading) stays ungated;
// the server gate remains the authority either way.
const [pkgWritable, setPkgWritable] = React.useState<boolean | null>(null);
React.useEffect(() => {
let cancelled = false;
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin-detail/src/useRecordEditable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
* the row-level verdict instead.
*
* Every uncertainty must fail OPEN — a courtesy hint may never be the reason a
* permitted user cannot act. The server is the authority (ADR-0057 D10).
* permitted user cannot act. The server is the authority (the framework's
* ADR-0057 D10 — framework numbering; this repo's own ADR-0057 is an
* unrelated document).
*/
import * as React from 'react';
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
Expand Down
5 changes: 3 additions & 2 deletions packages/plugin-detail/src/useRecordEditable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
* sharing rule sits inside an object the user may otherwise create and edit
* freely — so the header offered a primary "Edit" CTA that opened the form, let
* the user retype a field, and only then bounced with a 403. The server is the
* authority (ADR-0057 D10) and stays so; this is the courtesy check that stops
* the UI from inviting a write it knows will fail.
* authority (the framework's ADR-0057 D10 — framework numbering; this repo's
* own ADR-0057 is an unrelated document) and stays so; this is the courtesy
* check that stops the UI from inviting a write it knows will fail.
*
* The answer comes from the explain engine's record-grained verdict
* (`POST /api/v1/security/explain` with a `recordId`, ADR-0090 D6 / ADR-0095
Expand Down
7 changes: 4 additions & 3 deletions packages/plugin-grid/src/hooks/useRecordCrudVerdicts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@
* SPA origin where the cookie doesn't reach the API: the row's verdict is
* `undefined` and the caller keeps the OBJECT-level answer, i.e. exactly what
* this list rendered before this hook existed. The server is the authority
* (ADR-0057 D10) and stays so; hiding a capability on missing data would be a
* worse defect than the wasted click this fixes, and it is the same posture
* `useRecordEditable` takes for the detail header.
* (the framework's ADR-0057 D10 — framework numbering; this repo's own
* ADR-0057 is an unrelated document) and stays so; hiding a capability on
* missing data would be a worse defect than the wasted click this fixes, and
* it is the same posture `useRecordEditable` takes for the detail header.
*
* The probe rides the host's AUTHENTICATED fetch (`SchemaRendererProvider`'s
* `apiFetch`) rather than the bare global one: a bearer-token session carries
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/hooks/useCapabilityGate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
*
* **Fail-OPEN when unknown.** No runner, no user, no `systemPermissions` array:
* the action shows. Unknown is not denied, the server is the authority
* (ADR-0057 D10), and hiding a permitted user's button on missing client data
* is the worse failure. An EMPTY array is not unknown — it means "holds
* (the framework's ADR-0057 D10 — framework numbering; this repo's own
* ADR-0057 is an unrelated document), and hiding a permitted user's button on
* missing client data is the worse failure. An EMPTY array is not unknown —
* it means "holds
* nothing" and gates normally.
*/

Expand Down
Loading