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
14 changes: 14 additions & 0 deletions .changeset/spec-ui-provenance-anchors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@objectstack/spec': patch
---

Provenance comments in `ui/` were re-anchored

Comment and docblock lines under `src/ui/`, and in
`src/data/filter-subtree-provenance.ts` and
`src/meta-spelling/manifest-collection-spelling.ts`, that cited tracker numbers
which no longer resolve on GitHub now cite the commit in this repository's
history that decided the matter, or the ADR amendment they quote, and say in
their own words what was decided. Two references to objectui numbers now name
objectui on each number. Comments only: no type, schema, export or runtime
behaviour changes.
4 changes: 2 additions & 2 deletions content/docs/references/ui/expression-bindable-text-keys.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ above, its omission is not merely unmeasured: `value` there is a fallback
spelling for the same slot `content` already evaluates (see `content` NOT a
member, above), not a second read point, so a `text: ['value']` row would
legitimize the fallback spelling and give one slot two declared evaluation
paths. The objectstack#13670 ruling settled `text`'s intended evaluation
paths. The ruling that commit 8c6a7fc0b records settled `text`'s intended evaluation
channel as `content` alone and declared `text.value` OUT on those grounds —
this omission is deliberate, not pending measurement. Adding a row is
additive and spec-first; do it here, never as a renderer-side inference.
Expand All @@ -91,7 +91,7 @@ rule would in the same motion grant rows to `element:button` and
`properties` bag and never read these keys at the node's top level.

`action:button` is therefore deliberately OUT, and `ui:button` with it
(objectstack#13672); the `button` row above covers the bare `button`
(commit e854a531a); the `button` row above covers the bare `button`
spelling alone, which is why its citation names `form/button.tsx` only. Two
measured grounds, the same two kinds every other row runs on — zero pull
(the objectui corpus census of 736 JSON documents / 2747 typed nodes finds 5
Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/data/filter-subtree-provenance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ export const FILTER_SUBTREE_PROVENANCE: symbol = Symbol.for(
* This paragraph used to end by calling the mark *"safe on filter objects that
* are reused across requests (view metadata, cached scopes): the
* classification of one subtree does not change between requests"*. The
* #8794 survey measured that claim and it is true in ONE direction only; the
* correction is pinned by `filter-subtree-provenance.test.ts` (#8836). The
* survey commit 1850ebbb0 records measured that claim and it is true in ONE direction only; the
* correction is pinned by `filter-subtree-provenance.test.ts` (same commit). The
* claim holds where provenance is **intrinsic** to the subtree, and a caller's
* `where` is the half where it is not:
*
Expand All @@ -153,7 +153,7 @@ export const FILTER_SUBTREE_PROVENANCE: symbol = Symbol.for(
* > that vouched it.
*
* It holds across every in-repo caller today — enumerated with controls in
* #8794 — and it holds *incidentally*: every caller in a markable position
* the survey commit 1850ebbb0 records — and it holds *incidentally*: every caller in a markable position
* (`options.where` itself, or an arm of a pure `$and` root) happens to build
* its filter fresh per request. This module does not and cannot enforce it,
* because "the request" is not a concept it can see. What is enforced is that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ export const PLURAL_TO_SINGULAR: Record<string, string> = {
reports: 'report',
datasets: 'dataset',
actions: 'action',
// `themes: 'theme'` was removed at #10485 (ADR-0049; the carrier key is
// `themes: 'theme'` was removed by commit 35ad101bc (ADR-0049; the carrier key is
// retired). Its absence here is load-bearing twice over: the generated
// `META_URL_TO_SINGULAR` (gen:meta-url-spelling) loses the fold, so
// `/meta/theme` gets `unrecognisedMetaTypeRefusal`'s loud verdict instead of
// the pre-#10194 store-anything branch; and `applyConversionsToStoredItem`
// the store-anything branch from before commit 2306a765c; and `applyConversionsToStoredItem`
// passes legacy `theme` rows through untouched rather than manufacturing a
// collection for them.
flows: 'flow',
Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/ui/action-param-carryover.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// #11992 — `ActionParamSchema.carryOver`, the #11753 ruling's spec half
// #11992 — `ActionParamSchema.carryOver` (commit 0e4e51b0a), the carry-over ruling's spec half
// (maintainer 2026-08-25, recommendation A): a declared carry-over param is
// seeded from the row, rendered as a NON-EDITABLE summary, and submitted
// VERBATIM. These pins hold the ruled shape: the accept set (key + parsed
Expand All @@ -9,8 +9,8 @@
//
// Measured constraint restated from the parent card, because it is the reason
// the key exists at all: `visible: false` is NOT this contract — it omits the
// param from the dialog AND from the submission, which is the #11703
// silent-drop shape. `carryOver` must keep the param in the submission.
// param from the dialog AND from the submission, which is the silent-drop
// shape commit 5cb62d88b fixed. `carryOver` must keep the param in the submission.
import { describe, it, expect } from 'vitest';
import { ActionParamSchema } from './action.zod';

Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/ui/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ describe('requiresFeature lowering', () => {
expect(bare).not.toHaveProperty('requiresFeature');
});

// #5970 gave `visible` a boolean arm, so the lowering now meets two literals
// Commit 97e7e3caa gave `visible` a boolean arm, so the lowering now meets two literals
// it never could before. Boolean algebra decides both, in opposite directions.
it('treats `visible: true` as the explicit default — lowers to the gate alone', () => {
const result = ActionSchema.parse({
Expand Down Expand Up @@ -301,7 +301,7 @@ describe('requiresFeature lowering', () => {
});
});

// ── #5970 — `visible` / `disabled` speak ONE shape ────────────────────────────
// ── commit 97e7e3caa — `visible` / `disabled` speak ONE shape ─────────────────
// Ruled 2026-08-06: both keys are `boolean | string(CEL) | {dialect, source}`.
// Before this, `visible` had no boolean arm while `disabled` did, so the very
// common `visible: true` was a spec-side parse error that objectui's `ActionDef`
Expand Down Expand Up @@ -351,7 +351,7 @@ describe('ActionSchema — visible/disabled unified condition shape', () => {
});

// The widening must not shrink the rejection surface by one shape. Each
// of these was rejected before #5970 and is asserted to still be.
// of these was rejected before commit 97e7e3caa and is asserted to still be.
it.each([
['an empty CEL string', ''],
['a number', 1],
Expand Down
16 changes: 8 additions & 8 deletions packages/spec/src/ui/action.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const ACTION_PARAM_KEY_ALIASES: Readonly<Record<string, string>> = {
default: 'defaultValue',
// The words an author borrows from `FieldSchema` (`readonly`) or widget
// vocabulary (`disabled`) for "the user must not edit this". On a param the
// declared contract is `carryOver` (#11753): non-editable AND still
// declared contract is `carryOver` (commit 0e4e51b0a): non-editable AND still
// submitted verbatim — which is the half `readonly`'s field semantics
// (write-path strip) would get exactly wrong here.
readonly: 'carryOver',
Expand Down Expand Up @@ -387,17 +387,17 @@ export const ActionParamSchema = lazySchema(() => strictObject(
*/
defaultFromRow: z.boolean().optional().meta({ title: 'Default From Row' }),
/**
* Carry-over declaration (#11753 ruling, 2026-08-25): the param's value is
* Carry-over declaration (maintainer ruling 2026-08-25, commit 0e4e51b0a): the param's value is
* carried through the dialog rather than collected from the user — seeded
* from the current row (`defaultFromRow` is required alongside), rendered as
* a NON-EDITABLE summary, and submitted VERBATIM in the request body.
*
* The knob exists because neither neighbour expresses this contract:
*
* - `visible: false` omits the param from the dialog AND from the submission
* — measured on #11753; a clone action that hid its facet params this way
* would silently stop copying them, which is exactly the #11703 defect
* shape.
* — the measurement commit 0e4e51b0a records; a clone action that hid its facet params this way
* would silently stop copying them, which is exactly the defect shape
* commit 5cb62d88b fixed in `clone_permission_set`.
* - Leaving the param editable invites the failure the ruling names: the
* clone dialog offered `member_default`'s `row_level_security` — a JSON
* array of 17+ policy objects — as a prefilled textarea on the platform's
Expand All @@ -406,7 +406,7 @@ export const ActionParamSchema = lazySchema(() => strictObject(
* (`PermissionSetSchema` validates shape, not intent).
*
* "Not editable" is expressed by contract and enforced by the renderer
* (maintainer ruling on #11753, recommendation A): objectui's
* (maintainer ruling 2026-08-25, recommendation A, commit 0e4e51b0a): objectui's
* `ActionParamDialog` renders a declared carry-over as a read-only summary
* while keeping the seeded value in its submit state, so what is declared is
* what is sent. Requiring `defaultFromRow: true` is the declared = enforced
Expand Down Expand Up @@ -457,7 +457,7 @@ export const ActionParamSchema = lazySchema(() => strictObject(
// A carry-over param must have its row seed declared. The pair is checked at
// parse time because the failure it prevents is silent at runtime: a
// `carryOver: true` param with no `defaultFromRow` would render an empty
// read-only control and submit `undefined` — the #11703 silent-drop shape,
// read-only control and submit `undefined` — the silent-drop shape commit 5cb62d88b fixed,
// reintroduced through the very key added to close it.
(p) => !p.carryOver || p.defaultFromRow === true,
{
Expand Down Expand Up @@ -816,7 +816,7 @@ export type ActionAiParsed = z.infer<typeof ActionAiSchema>;
* | `string` | `disabled: "record.status == 'closed'"` | CEL shorthand, normalized to the envelope at parse time |
* | `{ dialect, source }` | `{ dialect: 'cel', source: '…', meta: { rationale } }` | the full envelope, for authorship metadata or a non-default dialect |
*
* The two keys were asymmetric until #5970 — `visible` had no `boolean` arm, so
* The two keys were asymmetric until commit 97e7e3caa — `visible` had no `boolean` arm, so
* the very common `visible: true` was a parse error on the spec side while
* objectui's `ActionDef` accepted it and stored metadata was already written
* that way. An asymmetry between two keys that mean the same *kind* of thing is
Expand Down
4 changes: 2 additions & 2 deletions packages/spec/src/ui/bulk-action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('BulkActionDefSchema (#4457)', () => {
expect(def.params?.[0]).toMatchObject({ object: 'sys_user', labelField: 'name' });
});

// ── RE-JUDGED, NOT RE-SPELLED (#18177) ─────────────────────────────────
// ── RE-JUDGED, NOT RE-SPELLED (commit adabccf5f) ───────────────────────
// This case used to be `forwards unknown WIDGET config on a param — the
// renderer declares a catch-all`, and it asserted that `min`/`max`/`step`
// rode through. That is the exact behaviour letter A removed, so the
Expand Down Expand Up @@ -304,7 +304,7 @@ describe('BulkActionDefSchema (#4457)', () => {
});

// ─────────────────────────────────────────────────────────────────────────
// #18177 — maintainer ruling batch #146 item 4, letter A.
// Commit adabccf5f — maintainer ruling batch #146 item 4, letter A.
//
// The card that produced this ruling turned on ONE measurement: the open
// shape accepted `zzz_nonsense_key_that_no_producer_emits_8755` in the same
Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/ui/bulk-action.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { FieldType } from '../data/field.zod';
// error for a blank screen. Localizing means declaring a real action and
// naming it in `bulkActions`: THAT path runs through the i18n resolver
// (`toBulkActionDef`'s `localize`).
// - `params[]` is STRICT (#18177, maintainer ruling batch #146 item 4,
// - `params[]` is STRICT (commit adabccf5f, maintainer ruling batch #146 item 4,
// letter A). It used to be `.passthrough()`, mirroring the
// `[key: string]: unknown` catch-all on objectui's `BulkActionParam` — and
// that made its accept a NULL READING: measured against installed spec
Expand Down Expand Up @@ -166,7 +166,7 @@ const BULK_PARAM_WIDGET_CONFIG_KEYS = [
* (merged over the def's static `patch`); for an aggregate `custom` def they
* ride along as the action's params.
*
* STRICT since #18177 — see the module header. An unknown key is refused by
* STRICT since commit adabccf5f — see the module header. An unknown key is refused by
* name, carrying either the rename or the prescription that fixes it, exactly
* as on `ActionParamSchema`. The sentence this replaced said strictness "would
* lie" at this level; the measurement said the opposite — the OPEN shape was
Expand Down Expand Up @@ -259,7 +259,7 @@ export const BulkActionParamSchema = lazySchema(() => strictObject(

/**
* Cascade binding — the ONE key this close DECLARES rather than refuses
* (#18177, ruling batch #146 item 4 letter A).
* (commit adabccf5f, ruling batch #146 item 4 letter A).
*
* Shape and description mirror the single-record twin. ⚠️ That twin is
* `FieldSchema.dependsOn` (`data/field.zod.ts`), NOT `ActionParamSchema`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* [#17987] Record-click navigation on the STANDALONE element faces — the spec
* [commit e233db9db] Record-click navigation on the STANDALONE element faces — the spec
* half of the objectui#8652 maintainer ruling (four options were put; the reply
* was verbatim `B`: declare `navigation` on the platform element schemas).
*
Expand Down
4 changes: 2 additions & 2 deletions packages/spec/src/ui/component-type-vocabulary.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* Pins for the page-component type vocabulary claim (#12950) — the
* Pins for the page-component type vocabulary claim (commit 225e7690f) — the
* `vocabulary-derivation.test.ts` discipline applied to the namespace claim:
* every set here is DERIVED in the source module, so these tests assert the
* derivation still holds and the ledger still earns its rows. The failure mode
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('KNOWN_COMPONENT_TYPES covers every declared face', () => {
});

/**
* #12950's own readiness verdict, pinned: `global:search` and
* Commit 225e7690f's own readiness verdict, pinned: `global:search` and
* `global:notifications` STAY declared — the 2026-08-26 ruling retires a
* member only when no data source covers the horizon, and both are backed by
* shipped platform data sources (the cross-object search protocol behind
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/ui/component-type-vocabulary.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* The page-component TYPE vocabulary claim (#12950, riding the #12183 ruling of
* The page-component TYPE vocabulary claim (commit 225e7690f, riding the #12183 ruling of
* 2026-08-26) — which `PageComponentSchema.type` strings the spec answers for,
* and which half of the string space stays open.
*
Expand Down
Loading
Loading