Skip to content

Commit 0af4f66

Browse files
chore(spec): quote the props-read sites of three ComponentPropsMap rows, ASSERTED_ANCHOR_FLOOR 7 to 10 (#22038)
Part of #20471 Clause-②: no (docblock text and a gate constant: the accept set and the public type surface are unchanged) #20471 remains open. This PR quotes the load-bearing anchor of three of the six `ComponentPropsMap` rows the card names. The other three rows (`action:group`, `action:menu`, `element:repeater`) cannot take a quote yet: their records cite lines that do not hold at the pin they assert. That has to be re-measured first, which is outside this card's claimed surface. Measurements below. ## What changed - `packages/spec/src/ui/component.zod.ts`: three docblock anchors gain a quoted first line, which `check:objectui-pin-citations` checks against objectui at the pin (`.objectui-sha` = `a58626c88`): - `action:button`: `action-button.tsx:215-318` first line `type: schema.actionType,`, the head of the `forwarded: ActionDef` literal. - `action:icon`: `action-icon.tsx:160-211` first line `type: schema.actionType,`, the same literal in that renderer. - `element:definition-list`: `data-list.tsx:42-47`, quoting its first line, the opening line of the `readProps` call (in the source, `const props = readProps` followed by the generic's opening bracket and brace). - Each assertion spells its path. A bare `:215-318` continuation inherits the nearest preceding FULL anchor, which is `static-params.ts:91-101` for the two action rows and `action-group.tsx:40-42` for the definition list, so it would be checked against the wrong file. - `packages/spec/scripts/check-objectui-pin-citations.ts`: `ASSERTED_ANCHOR_FLOOR` goes from 7 to 10, exactly the three quotes. Its docblock names the three and why the other three rows carry none. It also replaces the stale "145" worklist count with 418, as `--verify-anchors` reads it at `a58626c88`. - `.changeset/20471-component-row-anchor-quotes.md`: a `patch` changeset for `@objectstack/spec`. See "Changeset" below. ## Which anchor is load-bearing, per row The reading I used: a row's load-bearing anchor is its **props-read site**, the one place in objectui where the row's key set is read as a set. For the element rows that is the `readProps` call, whose type literal is the key set. For the leaf action rows it is the annotated `forwarded: ActionDef` literal, where the keys handed to the runner are enumerated: 23 of `action:button`'s 28 declared keys and 21 of `action:icon`'s 25, measured from the built schemas. The rest (`icon`, `variant`, `size`, `visible`, `disabled`) are first read above the literal, so a line shift there moves the quoted line too. Per-key lines inside or beside that site are not quoted. Quoting them all would be roughly 60 quotes across six rows, the bulk fill triage excluded. One quote also already goes red on any line shift above it in the same file. | Row | Load-bearing anchor | Holds at `a58626c88`? | Quoted | |---|---|---|---| | `action:button` | `action-button.tsx:215-318` (runner forward) | yes, file byte-identical across the last hop | yes | | `action:icon` | `action-icon.tsx:160-211` (runner forward) | yes, byte-identical | yes | | `element:definition-list` | `data-list.tsx:42-47` (`readProps`) | yes | yes, but the quoted line is not unique in the file (also `:125`, the repeater's `readProps`): it verifies, and drift still goes red, but the relocation report cannot name the new line (ablation C) | | `action:group` | `actions` `:303` and member forward `:329-382` | no, at `:300` and `:325-374` | no | | `action:menu` | `actions` `:342` and member forward `:264-328` | no, at `:335` and `:261-321` | no | | `element:repeater` | `readProps` `:97-107` | no, at `:125-135` (`:97-107` is the definition list's registration) | no | Every other anchor in the `action:button` and `action:icon` records was re-read too, and all hold except one (next table). The definition list's per-key reads `:48`, `:49`, `:51-53`, `:63`, `:66` and `:68` hold. ## Finding: the records of three rows (and two lines in two more) do not hold at the pin they assert The section's asserting citation reads `.objectui-sha` = `a58626c88`. Its history note for that hop says only the `objectName` forward moved in `action-group.tsx` / `action-menu.tsx`, and that it "is cited below at this pin". Measured at `a58626c88` against the previous pin `0abd4f9f8` (`git diff`, per-line reads): | Row | Record cites | Read at objectui `a58626c88` | Since | |---|---|---|---| | `action:group` | `actions` `:303`, `actionRendersAt` `:304`, own `visible` `:290` | `:300`, `:301`, `:287` (-3) | `299a2c62` | | `action:group` | member forward `:329-382`, its static values `:329-335`, `objectName` `:381` | forward `:325-374`, `objectName` `:373` (-8). The static-values read was deleted by objectui#11638, so that parenthetical now describes nothing | `299a2c62` | | `action:group` | `display` `:404`; `label` / `icon` `:424` / `:408`; `variant` `:414` + `:456`; `size` `:415` + `:457`; `visible` `:401`; host `disabled` `:418`; registration `inputs` `:487-528` | `:396`; `:416` / `:400`; `:406` + `:448`; `:407` + `:449`; `:393`; `:410`; `:479-520` (all -8) | `299a2c62` | | `action:menu` | own `visible` `:235` + `:336`; `icon` `:240`; `variant` / `size` `:241` / `:242` | `:232` + `:329`; `:237`; `:238` / `:239` | `299a2c62` | | `action:menu` | `actions` `:342`; member forward `:264-328`, its static values `:264-270`, `objectName` `:327`; `ActionAutoTrigger` `:363-370`; `tags` `:408` | `:335`; forward `:261-321`, `objectName` `:320`, static-values read deleted (objectui#11638); `:356-363`; `:401` | `299a2c62` | | `action:menu` | `label` `:389` + `:398-399`; host `disabled` `:388`; registration `inputs` `:435-463` | `:382` + `:391-392`; `:381`; `:428-456` (-7) | `299a2c62` | | `element:repeater` | `readProps` `:97-107`, every per-key read (`:120`, `:128`, `:143-146`, `:152`-`:155`, `:181`, `:186`, `:191-192`, `:194-196`) and `data-list.tsx:119-120` | every one 28 lines lower (`readProps` at `:125-135`) | `0d421041` (pin `31971ff1e`, objectui#11168 slice 2); the record went through 7 pin commits, each of which recorded `data-list.tsx` as byte-identical and its anchors as unmoved | | `element:repeater` | `data-objectstack/src/index.ts:4782-4793` for `serializeOrderBy` | `:4782-4793` is `rawFindWithPopulate`'s pagination. `serializeOrderBy` is declared at `:868` and called from `find` at `:5031` | not dated | | `action:button` | `readStaticParamValues`, `static-params.ts:91-101` | declared at `:98` (+7; objectui#11638 rewrote that file) | `299a2c62` | | `element:definition-list` | "The registration's enum publishes the STRINGS '1' / '2' (`:82`)", "The registration marks it required" | `:82` is a comment. The `columns` input publishes the NUMBERS 1 and 2, and `items` is no longer `required`: objectui#11168 slice 2 aligned the registration with the row. Prose, not a line shift | `0d421041` | | `element:definition-list` | designer `columns` control, `previews/block-config.ts:307` | `:320` | not dated | Proof that `data-list.tsx` moved at `0d421041`: its blob is `5237dc269` (220 lines, `RepeaterRenderer` at `:96`) at `dd3f7e1be`, `db11afd49` and `e420df310`. It is `e54574ef4` (262 lines, `RepeaterRenderer` at `:124`) at `31971ff1e` and `a58626c88`. At `e420df310` every repeater anchor and the `:82` claim read exactly as recorded. This is the failure #20471 was filed to prevent, already happened: under a pin label that was current, the read points moved and nothing went red. I left these records untouched. The claim's surface is quotes plus the floor, and the dispatch says a non-holding anchor is reported, not re-pointed. The re-point for `action:group` / `action:menu` is also not purely mechanical: the two "static values" parentheticals describe a read that no longer exists. How to finish the remaining three rows is the open question in the report on #20471. ## Gates (run at `ba23f992`) - `pnpm --filter @objectstack/spec check:objectui-pin-citations` with objectui readable at the pin: **exit 0**. The self-test is green including its live round-trip; "10 anchor content assertion(s) verified against objectui at a58626c; 496 file:line anchor(s) seen". - `… exec tsx scripts/check-objectui-pin-citations.ts --verify-anchors`: **exit 0**. "10 asserted, 418 objectui anchor(s) still carry no content assertion." - The same ordinary run with no objectui checkout (CI's shape): **exit 0**, printing "10 anchor content assertion(s) NOT VERIFIED — no git checkout". This gate does not verify content in CI by design. A quote is checked when it is written, and at pin bumps with `--verify-anchors`. - Before the floor was raised the gate went red, "You ADDED coverage — set ASSERTED_ANCHOR_FLOOR to 10". So exactly 3 assertions were parsed, and none mismatched. - `node scripts/pm/dispatch-gates.mjs --commands` derived 82 commands at `ba23f992` from the merge base. `--ran` reconciliation: "82 derived, 81 run, 1 NOT-MEASURED, 0 UNRUN", every exit code recorded before any pipe. - NOT MEASURED: `pnpm check:dual-build-cjs-loads` (exit 3, PREREQUISITE NOT MET). It loads every package's built entry, and 87 workspace packages are unbuilt in this worktree. This diff moves no emitted JS (below). CI runs it on a full build. - `check:doc-formula-expressions` and `check:lean-entry-closure` first exited 3 for missing builds. After `turbo run build` of formula, lint and objectql (14 tasks, exit 0) both exited 0. - `pnpm --filter @objectstack/spec typecheck`: **exit 0**. Its `check:scripts-typecheck` compiles the edited script (`tsc -p tsconfig.scripts.json --listFilesOnly` lists it). - `pnpm --filter @objectstack/spec exec vitest run --project local`: **exit 0**, 619 files, 18485 tests passed. - `pnpm --filter @objectstack/spec build`: exit 0, tree clean afterwards. ## Ablation (gate goes red when a quoted line changes) Each leg ran through `scripts/ablation-replace.mjs` in WRAP mode. Each anchor hit exactly once, the mutation was proven on disk by blob change, and the restore was proven by blob == HEAD (`5cc2ff27`) with `git diff HEAD` empty. No `dist` sits between the gate and the edited file: it reads `src` with `readFileSync`. - A, quote altered (`type: schema.actionType,` to `…actionTypeX,`): **exit 1**. "the asserted first line does not match … That line is NOWHERE in `…/action-button.tsx` at this pin." - B, anchor drifted by one line (`:215-318` to `:216-318`, a pin-bump shift): **exit 1**. "That line IS in the file — at :215, not :216. Either the anchor drifted by -1 lines, or it was wrong when written." - C, the same drift on the definition list (`:42-47` to `:43-47`): **exit 1**. "That line appears 2 times in the file (:42, :125), so it cannot locate the read point on its own." Still red, but without the relocation hint. ## Changeset `patch` for `@objectstack/spec`, measured. `files[]` ships `src/**/*.zod.ts` verbatim, and after the build the new text is in 2 `dist` declaration files and 0 runtime JS files. Positive controls: the row docblock hits 2 declaration files, and a `.describe()` string hits 14 JS files. So the published bytes move, while the runtime surface does not. Local precedent agrees: `15fe567c`, a comment-only re-anchor of `src/**` (0 non-comment lines), shipped a `patch` changeset. No `skip-changeset`. The script change alone would not publish (`scripts/` is not in `files[]`). ## Acceptance notes - The definition list's quote is not unique in its file (see ablation C). Making it unique would mean re-anchoring a record that is correct, so it stays as the gate prescribes: the range's first non-blank line. - The member docblock on `actionContainerMemberShape` is a HISTORICAL record (`.objectui-sha` pin `2e818d0b51ec`), so it got no quote. A quote is checked against the CURRENT pin, which would turn a dated record into a current claim. --- _Generated by [Claude Code](https://claude.ai/code/session_01GV6oYwgc1kWiUCb1YaprQ7)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0db5ad5 commit 0af4f66

3 files changed

Lines changed: 35 additions & 7 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
Three `ComponentPropsMap` read-point records now quote the objectui line they cite
6+
7+
Clause-②: no
8+
9+
The docblocks of `action:button`, `action:icon` and `element:definition-list` in
10+
`src/ui/component.zod.ts` each quote the first line of the row's props-read site, re-read
11+
against objectui at the pin this package builds against (`a58626c88`): the runner-forward
12+
literal of the two action blocks, and the `readProps` call of the definition list. A pin bump
13+
that moves one of those lines, or changes it, now fails `check:objectui-pin-citations` and
14+
names where the quoted line went, where before only the cited sha was checked. The other
15+
three rows of that section (`action:group`, `action:menu`, `element:repeater`) carry no quote
16+
yet. Comment text only: no schema, key, type or export changes.

‎packages/spec/scripts/check-objectui-pin-citations.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,20 @@ export function verifyAssertion(
808808
* `53ded82b` when that docblock's claim about the map renderer was corrected:
809809
* the two flatten sites and their whitelist, the renderer's own
810810
* `ObjectMapConfigSchema`, the `safeParse` and the spread beside it, and
811-
* `LIST_VIEW_LOCAL_OVERRIDES`. 145 objectui anchors elsewhere in
812-
* `packages/spec/src` still carry none — `--verify-anchors` prints that
813-
* worklist.
811+
* `LIST_VIEW_LOCAL_OVERRIDES`.
812+
*
813+
* The next three are the props-read sites of three `ComponentPropsMap` rows in
814+
* `src/ui/component.zod.ts`, re-read at pin `a58626c88`: the
815+
* `forwarded: ActionDef` literal of `action:button` and of `action:icon`, where
816+
* the keys each row forwards to the runner are enumerated, and the `readProps`
817+
* call of `element:definition-list`, whose type literal is that row's key set.
818+
* The section's other three rows (`action:group`, `action:menu`,
819+
* `element:repeater`) carry none yet: their cited lines do not hold at that
820+
* pin, and a quote goes only beside a line that does. 418 objectui anchors in
821+
* `packages/spec/src` still carry none, read against objectui `a58626c88` —
822+
* `--verify-anchors` prints that worklist.
814823
*/
815-
const ASSERTED_ANCHOR_FLOOR = 7;
824+
const ASSERTED_ANCHOR_FLOOR = 10;
816825

817826
// ---------------------------------------------------------------------------
818827
// self-test — the shapes, not the corpus

‎packages/spec/src/ui/component.zod.ts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,7 +3418,8 @@ const ACTION_NODE_GUIDANCE = {
34183418
* hoist makes `schema.params` the same object, so an array here is the input
34193419
* list and an object is the static values. (A node-level object `params`
34203420
* outside `properties` is ignored with a development warning.)
3421-
* - Forwarded to the runner (`:215-318`): `description`, `target`, `openIn`,
3421+
* - Forwarded to the runner (`action-button.tsx:215-318` first line
3422+
* `type: schema.actionType,`): `description`, `target`, `openIn`,
34223423
* `method`, `bodyExtra`, `bodyShape`, `operation`, `patch`,
34233424
* `confirmText`, `successMessage`, `errorMessage`, `refreshAfter`,
34243425
* `undoable`, `recordIdField`, `locations`, `toast`, `resultDialog`,
@@ -3532,7 +3533,8 @@ export type ActionButtonPropsParsed = z.infer<typeof ActionButtonPropsSchema>;
35323533
* `action:button`. `variant` — `:119`, `primary` mapped to `default`,
35333534
* renderer default `ghost`.
35343535
* - `params` — `:143-146`, routed exactly as on `action:button`.
3535-
* - Forwarded (`:160-211`): `actionType`, `name`, `target`, `openIn`,
3536+
* - Forwarded (`action-icon.tsx:160-211` first line
3537+
* `type: schema.actionType,`): `actionType`, `name`, `target`, `openIn`,
35363538
* `method`, `bodyExtra`, `bodyShape`, `operation`, `patch`,
35373539
* `confirmText`, `successMessage`, `errorMessage`, `refreshAfter`,
35383540
* `locations`, `toast`, `resultDialog`, `onSuccess`, `objectName`.
@@ -3997,7 +3999,8 @@ export type ActionMenuPropsParsed = z.infer<typeof ActionMenuPropsSchema>;
39973999
/**
39984000
* `element:definition-list` — a compact key/value `<dl>`
39994001
* (`components/src/renderers/basic/data-list.tsx` at the pin). Props are read
4000-
* through `readProps` (`:42-47`, `properties` first). Read points: `items`
4002+
* through `readProps` (`data-list.tsx:42-47` first line
4003+
* `const props = readProps<{`, `properties` first). Read points: `items`
40014004
* (`:48`), `columns` (`:49`), `inline` (`:63`), and per item `term` (`:66`) and
40024005
* `description` (`:68`).
40034006
*

0 commit comments

Comments
 (0)