Repository navigation
Commit ffba02e
docs(spec): record:related_list's parentDataSource is described as rendered (#24578)
Fixes #23585
Clause-②: no
`record:related_list`'s `parentDataSource` is rendered by the console at
its pin, and `@objectstack/spec` now says so. Before this change, the
key's describe opened with `[PLANNED — not yet rendered]`, its TSDoc
said no renderer reads it, and the liveness `_note` recorded it as
planned. All three told an author, an AI author first, not to use a
binding the console renders. The change is describe, TSDoc and ledger
text only: `RecordRelatedListProps` accepts exactly what it accepted
before, no key is added, and every refusal keeps its issue `code` and
`path`.
## The new describe, verbatim
> The PARENT record this related list hangs off, bound by a query of its
own: an object binding `{ object, view?, filter?, sort?, limit? }`, the
shape `dataSource` takes. Read by the single-record rule: the FIRST row
of the bound set by its `sort` is the parent (declare `limit: 1` to say
one row is meant), and when no row answers, the block renders a loud
absence, never an empty list, which would read as "this record has no
related records". `relationshipValueField` is read on that row. When
this key is absent, the record page's record context remains the parent.
The node-level `dataSource` on this block keeps its published meaning,
the CHILD rows the list draws (it fills `objectName`, `columns`,
`filter`, `sort` and `limit`), and is never read as the parent.
Only the marker left. Every sentence after it holds at the pin (P1
below), so no sentence was added or removed.
## P1 — the pin carries the renderer, and the renderer does what each
clause says
- `.objectui-sha` on `origin/main` is
`4016370af3c9c9dafec2bc5299afd8e8079701b8`. In `../objectui`, `git
merge-base --is-ancestor d81e460 4016370` exits 0, and `git
merge-base --is-ancestor d81e460 fe11eb1` (objectui `origin/main`)
exits 0. An exit 0 proves itself, so no control leg is owed. `git diff
--stat 4016370 fe11eb1` over the two renderer files prints
nothing: objectui `main` reads the key the same way.
- `scripts/sdui-manifest.record.json` records `objectuiSha`
`4016370af3…`, and `sdui.manifest.json` lists `parentDataSource` as an
input of `record:related_list`. The console this repository builds is
built from that pin.
- Every read below is `git show 4016370:PATH` in `../objectui`. R is
`packages/plugin-detail/src/renderers/`.
- **The key is read.** `R record-related-list.tsx:810` `const
parentBinding = schema?.parentDataSource;`, handed to
`ParentRecordBinding` at `:814`–`:824`.
- **The FIRST row by its `sort` is the parent.** `R
recordBinding.tsx:429` `const params: QueryParams = { $top: 1 };` and
`:431` `if (sortKey) params.$orderby = JSON.parse(sortKey);`. The row is
read through `useResolvedDataSource` (`:384`), the page's own adapter,
so under the caller's identity (module doc `:45`–`:46`).
- **No row is a loud absence, never an empty list.** `R
recordBinding.tsx:475`: when `absent` is given and the settled read has
no row, `BoundRecordProvider` returns `absent` in place of its children.
The related list passes `absent={NoParentRecord …}` at `R
record-related-list.tsx:821`, and `NoParentRecord` (`:772`–`:786`) draws
a `role="status"` notice. The absence replaces the children, so no child
query is sent. A read the server refuses as forbidden reads the same as
no row (`R recordBinding.tsx:449`).
- **`relationshipValueField` is read on that row.** `R
record-related-list.tsx:259`–`:263` reads it on the record context
(`ctx?.recordId`, or `ctx?.data[relationshipValueField]`).
`BoundRecordProvider` provides the bound row as that context.
- **Absent, the record page's record is the parent.** `R
recordBinding.tsx:274`: when `isElementDataSourceConfig(binding)` is
false (no binding), `ParentRecordBinding` returns its children as they
are, so the record page's record context still reaches the list.
- **The node-level `dataSource` is still the CHILD rows.** `R
record-related-list.tsx:724`–`:729` maps `columns`, `filter`, `sort` and
`limit` onto the list. The parent gate is given the parent binding alone
(`R recordBinding.tsx`, `ParentRecordBinding` docblock).
- objectui's own pin, `R
__tests__/record-related-list.parentDataSource-12294.test.tsx`, carries
a case for each clause: first row by `sort`, `relationshipValueField` on
the bound row, no row is the absence with no child query, 403 is the
same absence, no `parentDataSource` keeps the page record, and the
registration publishes the input.
No describe clause is untrue at the pin, so the prohibition does not
apply.
## P2 — the marker and the note were present on `origin/main`
`5b14b7f3ad`
`component.zod.ts:1743` (docblock) and `:1747` (describe) carried
`[PLANNED — not yet rendered]`. `liveness/page.json:3`'s `_note` carried
the `PLANNED RECORD (#23134 …)` sentence.
The card's criterion, on this head: `git grep -n "PLANNED — not yet
rendered" -- packages/spec/src/ui/component.zod.ts` names `:1170` and
`:1175` only, both on the `emptyState` description (out of scope, G4).
`git grep -c "PLANNED RECORD (#23134" --
packages/spec/liveness/page.json` answers nothing (exit 1).
## P3 — every text here that called `parentDataSource` planned, unread
or not rendered
Measured with `git grep -n parentDataSource` and `git grep -n "not yet
rendered"` over the whole tree.
Rewritten here:
1. `packages/spec/src/ui/component.zod.ts`, the describe: the marker is
gone.
2. The same file, the key's TSDoc: the "PLANNED, not yet read" paragraph
is now "RENDERED by the console", naming the read points with the
`objectui:` realm marker and the pin. The same docblock said the `api`
arm of `dataSource` "is still unrendered". That is false since objectui
`c4dd7078ed` (recorded in this ledger's `_note`), so the clause now says
why the key takes the object binding only: it is the shape the sibling
blocks read, and the shape objectui's parent read takes
(`isElementDataSourceConfig` asks the binding for an `object`).
3. `packages/spec/liveness/page.json`, `_note`: the `PLANNED RECORD
(#23134 …)` sentence is a `LIVE RECORD`, in the form the
`ElementApiDataSource` record took when its renderer shipped. It cites
the pin and each objectui path with the `objectui:` realm marker.
4. The same file, the `regions` row's component-member read-point list,
entry [10]: `record:related_list.parentDataSource (PLANNED)` pointed at
the old measurement (objectui `@f0532d8`, "the record context read").
It now lists the read points at `@4016370` in the list's own
`objectui @sha FILE#SYMBOL` spelling. The ledger keeps no
`parentDataSource` row; this entry is its one piece of
`parentDataSource` evidence, so I read it as inside the claim's "the
`parentDataSource` row's status, evidence" item. Named here so a
reviewer can disagree.
5. `content/docs/references/ui/component.mdx:1971`, regenerated by
`gen:docs`.
6.
`packages/spec/src/ui/component-record-related-list-parent-23134.test.ts`,
pin E: it asserted the describe opens with the marker. Re-trued, not
deleted: it now asserts that `check-liveness`'s planned matcher
(`MARKER_RE.planned`, copied with its source named) reads nothing in the
describe, with a DARK case showing the same matcher catches the replaced
marker.
Named, not edited:
- `.changeset/pre/23134-related-list-parent-data-source.md:13` and
`packages/spec/CHANGELOG.md:2200` ("Planned, not yet rendered"). Both
are the consumed changeset and the released entry for `4cc3ff9`. They
were true when that release was cut, so they are not factual errors, and
both are release-owned.
- `content/docs/**` (hand-written) and `skills/**`: no hit for
`parentDataSource`.
## G1–G4
- **G1.** The ledger carries no `parentDataSource` row, so there is no
row status to move and no author warning. The liveness record is the
`_note` (item 3) and the evidence entry (item 4). `pnpm --filter
@objectstack/spec run check:liveness` exits 0 (in the gate run below).
- **G2.** `pnpm --filter @objectstack/spec build`, then
`check:generated` named one stale artifact,
`content/docs/references/**`. `gen:docs` rewrote `component.mdx:1971` (1
line). A second `check:generated`: "All 14 generated artifacts are up to
date". `authorable-surface.base.json` did not move.
- **G3.**
`.changeset/23585-related-list-parent-data-source-rendered.md`, `patch`
on `@objectstack/spec`, `Clause-②: no`.
- **G4.** At the pin and at objectui `main`, `git grep -n emptyState --
packages/plugin-detail/src` outside tests answers nothing. The renderer
for the `:1170`/`:1175` `emptyState` markers (objectui#12932) has not
shipped, so those markers are still true.
## Tests
- `pnpm --filter @objectstack/spec test` on `131a5615e9`: 701 files
passed, 21312 tests passed, 1 todo.
- `pnpm --filter @objectstack/spec typecheck` on `131a5615e9`: exit 0;
`check:test-typecheck` OK.
- The pin file alone: 18 passed.
- **Reverse verification, one time.** With the change committed,
`scripts/ablation-replace.mjs` put the marker back into the describe
(anchor 1 → 0, blob `2d039146d858` → `d8a66adf1db4`). The pin file then
failed in the expected direction: 1 failed, 17 passed, the failure being
E's "no planned marker" case. The tool restored the file: blob equal to
HEAD, `git diff HEAD` empty.
- The merge of `origin/main` (`04669a467e`, `packages/objectql` and
`packages/services/service-automation` only) touches no package this
diff touches, so the spec suite was not re-run on the merge commit.
## Gates
Run on the final head, `git rev-parse --short HEAD` = `53624a10cf`.
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths; change set from the merge base
`04669a467`) derives 111 commands from the 5 changed paths. Each ran
with its exit code captured before any pipe: 111 of 111 exit 0. `--ran`
on that record: "111 derived, 111 run, 0 NOT-MEASURED, 0 UNRUN".
- A first run on `131a5615e9` recorded six PREREQUISITE NOT MET (exit
3): the two `@objectstack/lint` doc gates, `check:skill-examples`,
`check:docs-transcript-drift`, `check:dual-build-cjs-loads` and
`check:lean-entry-closure`. After the `@objectstack/lint` and
`@objectstack/objectql` closures were built, all six measured on
`53624a10cf` and exit 0. That earlier run is not the reading; the one
above is.
- Verdict lines on `53624a10cf`: `check:generated` "All 14 generated
artifacts are up to date"; `check:docs` "227 generated files in sync
with packages/spec"; `check:liveness` exit 0 ("1038 live · 1
experimental · 1 live-elsewhere · 112 dead · 23 planned = 1175
classified"); `check:nul-bytes` OK; `check:authorable-surface` exit 0.
- Local-only, outside the derivation: `pnpm check:dev-prereqs` exit 0.
- Every family CI runs is read from this PR's check-runs, not re-run
here.
## Acceptance notes
- The two `emptyState` markers in `component.zod.ts` (`:1170`, `:1175`)
stay. Their renderer has not shipped (G4).
- The released `4cc3ff9` text that calls the key planned stays as
released (P3, "Named, not edited").
---
_Generated by [Claude
Code](https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 2667e24 commit ffba02e
5 files changed
Lines changed: 49 additions & 17 deletions
File tree
- .changeset
- content/docs/references/ui
- packages/spec
- liveness
- src/ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1968 | 1968 | | |
1969 | 1969 | | |
1970 | 1970 | | |
1971 | | - | |
| 1971 | + | |
1972 | 1972 | | |
1973 | 1973 | | |
1974 | 1974 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
202 | 203 | | |
203 | 204 | | |
204 | 205 | | |
205 | | - | |
206 | | - | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
207 | 214 | | |
208 | 215 | | |
209 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
210 | 222 | | |
211 | 223 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1707 | 1707 | | |
1708 | 1708 | | |
1709 | 1709 | | |
1710 | | - | |
| 1710 | + | |
| 1711 | + | |
1711 | 1712 | | |
1712 | 1713 | | |
1713 | 1714 | | |
| |||
1734 | 1735 | | |
1735 | 1736 | | |
1736 | 1737 | | |
1737 | | - | |
1738 | | - | |
1739 | | - | |
1740 | | - | |
1741 | | - | |
1742 | | - | |
1743 | | - | |
1744 | | - | |
| 1738 | + | |
| 1739 | + | |
| 1740 | + | |
| 1741 | + | |
| 1742 | + | |
| 1743 | + | |
| 1744 | + | |
| 1745 | + | |
| 1746 | + | |
| 1747 | + | |
| 1748 | + | |
| 1749 | + | |
| 1750 | + | |
| 1751 | + | |
| 1752 | + | |
| 1753 | + | |
| 1754 | + | |
1745 | 1755 | | |
1746 | 1756 | | |
1747 | | - | |
| 1757 | + | |
1748 | 1758 | | |
1749 | 1759 | | |
1750 | 1760 | | |
| |||
0 commit comments