Repository navigation
fix(types): object-master-detail-form, object-metric and pivot validate (objectui#10859, batch 2) - #10927
Conversation
… AnyComponentSchema (objectui#10859, batch 2) pivot mirrors PivotTableSchema from data-display.ts member for member. object-metric and object-master-detail-form are ADR-0080 public blocks whose published declaration is their @objectstack/spec ComponentPropsMap row; each arm reads that row as its properties bag, by reference, the objectui#10872 convention, through a union of their own. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…lower the ratchet to 73 (objectui#10859) Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…ock sentence the pivot arm made false (objectui#10859, batch 2) Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…false (objectui#10859, batch 2) Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
|
changeset-claim-re-read
|
✅ Console Performance Budget
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
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsThe route change: sound.
What the renderers read.
Handler slots. Refusing
The new union.
Counts.
Changeset, sentence by sentence. All true except the flat-key sentence in the third bullet. On Dated notes. Both follow the objectui#10533 form and leave the frontmatter byte-identical.
The objectql.zod.ts docblock. It calls The dev's three out-of-scope notes. All three are real.
Notes 1 and 2 are marked "承接者:无, not filed". Ruling Aside for the split: under this PR's criterion ② Semver level
③ Boundary flags
Implemented-by: VERDICT: FAIL Four text fixes (dev round, text only, no behaviour change) and two carriers (seat, no PR change). Nothing else stops landing.
|
…sentence, pivot drillDown describe, MasterDetailFormSchema wording, 7352 note (objectui#10859, batch 2) Text only; no behaviour change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
✅ Console Performance Budget
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
Size Limits
|
Contract reviewServed-tier: This is an in-seat delta review of fix round 1 ( ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…0859-validate-registered-types-b2 Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
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
Size Limits
|
…on the object schema The case "keeps that button in client mode" gated only on the view type (`data-list`), which client mode satisfies on the first commit, then read the `Total` sort button synchronously. Since the sort-button row reads the masked stamp (objectui#10728), every column carries it until `getObjectSchema` resolves, so the button existed only once the schema commit had landed: a scheduling race (the #7007 trap described in the file's own docblock). It now awaits `settleObjectSchema(dataSource)`, the gate its windowed sibling already uses. Test-only: no retry, no raised timeout, no source change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN (cherry picked from commit b92ab92)
…(empty frontmatter) `check-changeset-presence` counts every file under a released package's `src/`, test files included, so the test-only gate needs an explicit no-release declaration. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN (cherry picked from commit 3abab7c)
Seat note:
|
✅ Console Performance Budget
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
Size Limits
|
…jectstack-ai#10802 and objectstack-ai#10821 made false (objectui#10905) (objectstack-ai#10939) Fixes objectstack-ai#10905 Clause-②: no — comment and describe text only; no accept set or public surface moves. ## What changed Two docblocks in `packages/types/src`, comment text only, plus an empty-frontmatter changeset. No `.describe()` string, type, value or accept set moves. 1. **`ObjectChartSchema.series`, the TS interface in `objectql.ts`.** The sentence "A `type` written on this arm anyway is an excess property on a literal typed by this interface" is replaced. Since PR objectstack-ai#10802 (objectui#10770), each `series` entry is either the spec's `ChartSeries` (the `{ name }` arm) or the internal `{ dataKey }` arm. The `{ name }` arm declares `type`, and excess-property checking on that union accepts a key that either arm declares, provided the value fits that declaration. So `{ dataKey: 'amount', type: 'line' }` compiles. The zod half of the paragraph (a plain `z.object`, which strips `type`, so the entry parses clean and the key is dropped) is still true and is kept. "The mirror's `.describe()` says the same" now reads "names the same omission". The `.describe()` string names the omission and never made the excess-property claim, so it is not touched. 2. **The route overview headed "WHERE THIS ARM IS INSTALLED", in `zod/objectql.zod.ts`.** Its second-route paragraph made three claims. It said a named view's `listViews` "is unmirrored". It said `generateViewSchema` merges the same two nestings. It named a `custom` issue at `listViews.KEY.options.kanban.groupBy`. Since PR objectstack-ai#10821 (objectui#7928), `listViews` is `stripImportedDefaults(SpecViewSchema).shape.listViews`. That record refuses a named view's `options` bag whole, `generateViewSchema` reads no `options` bag, and `checkNamedViewKanbanStrayGroupBy` reports at `listViews.KEY.kanban.groupBy` only. The heading ("TWO NESTINGS EACH") and the final sentence ("cannot depend on which route or nesting") described the same pre-objectstack-ai#10821 shape, so they are corrected in the same docblock. Three nestings now take the one string. A named view's `options.kanban.groupBy` meets the protocol's refusal of `options` instead. Route 1 of the overview (`list-view`: `kanban` plus `options.kanban`) was re-read against `ListView` and `ListViewSchema.options` and is unchanged. ## Measurements The probes are kept outside the tree and were run once. Everything was measured on `733fd5ac6`. **Sentence 1, a `tsc` probe.** Three literals typed `ObjectChartSchema`, run under the package's own tsconfig: - `series: [{ dataKey: 'amount', type: 'line' }]` produced no diagnostic, so the sentence under test is false. - Positive control: `series: [{ dataKey: 'amount', zzzUnknownKey: 1 }]` produced TS2353 ("Object literal may only specify known properties"), so a genuinely unknown key IS refused. - Value control: `series: [{ dataKey: 'amount', type: 'not-a-chart-family' }]` produced TS2322, so the value must fit the spec's `ChartType`. **The zod half, a parse probe** (`ObjectChartSchema.safeParse`): - `{ dataKey: 'amount', type: 'line' }` succeeds with series `[{"dataKey":"amount"}]`, so the key is stripped and that half stays true. - Controls: `{ dataKey, chartType: 'line' }` keeps `chartType`, and `{ name, type: 'line' }` keeps `type`. **Sentence 2, a parse probe** (`ObjectViewSchema.safeParse`, a named view carrying `columns` and `kanban.columns`): - `kanban.groupBy` gives `unrecognized_keys` at `listViews.board.kanban` naming `groupBy`, plus `custom` at `listViews.board.kanban.groupBy`. - `options.kanban.groupBy` gives only `unrecognized_keys` at `listViews.board` naming `options`. There is no `custom` under `options`. - Dark control (`groupByField` and `columns` only): success. - `generateViewSchema` reads no `options` bag: a `.options` read pattern hits `plugin-view`'s `ObjectView.tsx` zero times, and hits `plugin-list`'s `ListView.tsx` (the positive control) 48 times. **Lit control.** I extracted each of the `checkNamedViewKanbanStrayGroupBy` and `namedViewKindRefusals` docblocks, from its opening line through the declaration line, before and after the edit. Both are byte-identical: `cmp` is silent, and the sha256 prefixes are `aaa003254ab7127a` and `7c8aa1b4f5cd6a3d` on both sides. ## Changeset On the docblock commit alone, `node scripts/check-changeset-presence.mjs` answered exit 1, because both files are published source of `@object-ui/types`. So a declaration is owed. The declaration uses empty frontmatter, not `patch`. Nothing a consumer acts on moves. Both docblocks reach the build output only as comment text: after `pnpm --filter @object-ui/types build`, the new `series` sentence is in `dist/objectql.d.ts` and the route overview is in the zod module's JS. At the time of writing, both changes that made the sentences false (PR objectstack-ai#10802 and PR objectstack-ai#10821) are still pending changesets, so no release has carried the false text. ## Gates I derived these by hand from the root `package.json` and `.github/workflows/`, because the objectstack `dispatch-gates.mjs` does not cover this repository. At head `950bf6406`: - Exit 0 for all of these: `check-control-bytes`, `check-new-cross-file-line-citations` ("0 new citation(s)"), `check-changeset-presence` (empty-frontmatter pass), `check-changeset-fixed`, `check-changeset-no-major`, `check-changeset-overwrite`, `check-changeset-claims`, `check-pending-changeset-literals`, `check-spec-symbol-derivation`, `check-handler-key-read-sites` and `check-unreferenced-sources`. - `pnpm exec vitest run packages/types/`: 264 files and 5854 tests passed, exit 0. - `pnpm exec vitest run` on the three script tests that read `objectql.zod.ts` as text (`check-eager-closure-budget`, `check-handler-key-read-sites` and `vite-types-zod-lazy`): 3 files and 241 tests passed, exit 0. At `7449bc6a9`, which differs from the head only in the changeset's wording (`git diff --stat` shows one file under `.changeset/`): - `pnpm --filter @object-ui/types build` exit 0, and the dist completeness check reported complete. - `pnpm --filter @object-ui/types type-check` exit 0. - `pnpm --filter @object-ui/types lint` exit 0, with 0 errors. `node scripts/check-governed-queue-guard.mjs --test` over the three paths answered NOT GOVERNED. NOT MEASURED: - `check:eager-closure`, reason: it reads every package's built dist, and a comment-only diff moves no import edge. Its script test above ran green. - A downstream consumer type-check, reason: the `.d.ts` changes JSDoc text only, and no type bytes move. Known repo-wide red, left alone: `Spec Main Shape Gate` (objectui#10916, owned by another seat). ## Acceptance notes - Nothing pins either half of the corrected `series` sentence: a `type` on a `{ dataKey }` entry compiles, and the mirror strips it. The probes above were run once. This is an observation, not filed. Carrier: none. - `main` has not moved from `733fd5ac6` on either file. PR objectstack-ai#10927 edits `objectql.zod.ts` at its imports and its tail, which are disjoint from this docblock. Implemented by the dispatched dev run of the `domain:spec` seat, session `https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm`. --- _Generated by [Claude Code](https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Part of #10859
Clause-②: yes
Batch 2 of the family card: the three (i) keys batch 1 held for file reasons. Draft, head
6ee675b45d(fix round 1, text only, on72cf9d3123); a dispatched dev's PR, so ready and landing are the seat's.What changed
packages/types/src/zod/data-display.zod.ts.PivotTableSchema, a member for member mirror of the TypeScriptPivotTableSchema(packages/types/src/data-display.ts):rowField,columnField,valueField,datarequired as declared;aggregationthe five-value vocabulary;drillDownthe sharedDrillDownConfigSchema;body/childrenrefused by name (the declaration's?: never, objectui#9256).drillDown's.describesays the member is inert on apivotnode (fix round 1).DataDisplaySchemalists it. TheDrillDownConfigSchemadocblock sentence that named this pair unmirrored is amended.packages/types/src/zod/objectql.zod.ts.ObjectMetricBlockSchemaandObjectMasterDetailFormBlockSchema:BaseSchema+ thetypeliteral +properties, which IS the block's@objectstack/specComponentPropsMaprow, by reference throughstripImportedDefaults(the objectui#10872 convention). The master-detail arm also refusesonSuccess,onError,onCancelwithhandlerKeyRefusal(…, 'runtime-slot'). Both reachAnyComponentSchemathrough a new union,ObjectQLPublicBlockComponentSchema.packages/types/src/zod/index.zod.ts. Four new barrel exports;ObjectQLPublicBlockComponentSchemajoinsAnyComponentSchema's arm list.packages/types/src/zod/README.md. Data Display gainsPivotTableSchema; a new "ObjectQL Public Blocks (2)" group.packages/types/src/data-display.ts. One docblock sentence onObjectPivotDrillDownConfig("Neitherobject-pivotnorPivotTableSchemahas a zod mirror") that this change made false. Comment only.packages/types/src/__tests__/registered-type-arms-10859-b2.test.ts(new) and the ratchetpackages/cli/src/__tests__/registered-types-validate-ratchet-10859.test.ts.zod-mirror-parity.test.ts— thedata-display.zod.ts#PivotTableSchemapair (EXPECTED_MIRROR_PAIRS169 to 170) and threeEXCLUSIONSrows (the two spec-owned arms, the union);imported-defaults-8317.test.ts— the two rows'IMPORTEDentries..changeset/10859-pivot-object-block-zod-arms.md('@object-ui/types': minor, theClause-②: yesline, no BREAKING banner: every document naming these types was refused attypebefore, at the root and at every child slot, so nothing that parsed is refused now). Dated notes, objectui#10533 form, frontmatter byte-identical, on7352-drill-down-config-mirror.mdand10685-drilldown-per-block.md.H1 — the declaration of each key
pivotPivotTableSchemainpackages/types/src/data-display.ts,type: 'pivot'object-metric@object-ui/types.@objectstack/spec/ui(17.4.0):ComponentPropsMap['object-metric']=ObjectMetricPropsSchema, typeObjectMetricProps. objectui's other type,ObjectMetricWidgetProps(plugin-dashboard), is the widget's React props (a translator function, a React-node icon), not a document shapeproperties= the rowobject-master-detail-form@object-ui/types. Spec:ComponentPropsMap['object-master-detail-form']=ObjectMasterDetailFormPropsSchema.@object-ui/plugin-formalso exportsMasterDetailFormSchema, the type ofMasterDetailForm'sschemaprop (the renderer's post-hoist reading):typeoptional, three host callbacks, noBaseSchemaproperties= the row, + three runtime-slot refusalsBoth object-* keys have a published declaration (the spec row, which batch 1's (i) criterion counted), so neither is held. Route change, declared: the order's assumption was a TS-face interface mirrored with an
Equalpin. For these two the declaration is aComponentPropsMaprow, and the house route for arming from a row is objectui#10872'spropertiesby reference; the shipped documents (H3) areproperties-form, which a flat restatement would refuse. WhereMasterDetailFormSchemaand the row disagree (it requiresobjectNameanddetails; it typestitle,submitText,cancelTextasstringwhere the row takesI18nLabel), the spec is the contract. Their own union, notObjectQLComponentSchema: that union mirrors the TS union inobjectql.tsmember for member, andobjectql-union-arms-7363.test.tspins its length.H2 — reproduced on
main(733fd5ac6)safeValidateSchema, on source:At head all three are accepted;
objectui validate(the CLI'svalidate, in-process) on the showcase master-detail document prints✓ Schema is valid!andType: object-master-detail-form.H3 — taught and shipped documents
pivot: no JSON document is taught or shipped. The registry tables inpackages/plugin-dashboard/README.mdandcontent/docs/plugins/plugin-dashboard.mdxname it only.packages/plugin-dashboard/SKILL.md'stype: 'pivot', and the showcase chart-gallery dashboard's, are the dashboard WIDGET type, not this node.object-metric: the objectstack showcase ships it in{ type, properties }form (examples/app-showcase/src/ui/pages/index.ts, four KPIs;my-work.page.ts, three) — accepted on both faces; the firstindex.tsKPI is pinned.command-center.page.ts'skpi()node is accepted by the tolerant face; the strict face refuses itsresponsiveStyles, an envelope keyBaseSchemadoes not declare on any arm. objectui teaches no JSON document (thedata-source.mdbinding table, registry tables).object-master-detail-form: the showcase'sproject-workspace.page.tsform,{ type, properties }— accepted on both faces, pinned.docs/adr/0001-master-detail-subform.mdandapps/console/src/dev/DevMasterDetail.tsxwrite it FLAT: the tolerant face accepts them (a flat keyBaseSchemadoes not declare is unjudged) and the strict face refuses those keys by name, while a flat keyBaseSchemadoes declare is judged byBaseSchema's own type on both faces — the same boundary objectui#10872 left open for the public blocks.H4 — runtime readers
pivot→PivotTable(registered aspivot): its destructure reads all 11 declared members (title,rowField,columnField,valueField,aggregation,data,showRowTotals,showColumnTotals,format,columnColors,drillDown).object-metric→ObjectMetricBlock→ObjectMetricWidget: its destructure reads all 18 row members;objectNameandfilteralso arrive through thedataSourcebinding.object-master-detail-form→MasterDetailFormRenderer→MasterDetailForm: every one of the 14 row members is read offschema, and so areonSuccess,onError,onCancel(the runtime slots;check:handler-key-readsnow judges them:OK 131 arm(s) … 53 judged).No declared member without a reader, so nothing is narrowed. Two read-side observations are in Acceptance notes.
Pins, red on base and green on head
Base = a detached worktree at
733fd5ac6with the two pin files copied in; head = this branch. From the repo root:pnpm exec vitest run packages/types/src/__tests__/registered-type-arms-10859-b2.test.ts packages/cli/src/__tests__/registered-types-validate-ratchet-10859.test.ts.Tests 30 failed / 9 passed (39): every new row red, the ratchet red (refuses 76 registered bare key(s) at type; the pin is 73.); green = the 9 pre-existing ratchet-file rowstsc -p tsconfig.test.jsonTests 39 passed (39)pnpm --filter @object-ui/types type-check(all three programs)--listFilesOnlyshows the pin in the test programRows: each key's minimal document on
safeValidateSchemaand the strict face; the two showcase documents on both faces (each first parsed by the spec's own row); a fullpivotdocument; a page of the three; an undeclared node key refused by name on the strict face per arm (tolerant passes it); an undeclared bag key refused on the TOLERANT face per spec-row arm; one spec-invalid value per arm (aggregation: 'median',properties.colorVariant: 'pink',properties.formType: 'wizzard', eachinvalid_valueat that path);pivot's requireddata;drillDownjudged by the shared mirror; both content channels; the three runtime slots; the bag's key set equal to the row's and answering four probes as the row does. Type level:pivot's key set and member types invariantly equal to the declaration's; each bag's input type equal to the spec'sObjectMetricProps/ObjectMasterDetailFormProps; an instrument-fires row.Type-level reverse validation (objectstack
scripts/ablation-replace.mjs, WRAP mode, anchor x1 to x0, restored to the HEAD blob withgit diff HEADempty):PivotTableSchema.formatretyped toz.number()→tsc -p tsconfig.test.jsonexit 2, TS2344 on the member-types row plus the mirror-parity ledgers namingdata-display.zod.ts#PivotTableSchemaandformat; theobject-metricbag restated as a one-member strict object → exit 2, TS2344 on the bag row.Ablation.
ObjectQLPublicBlockComponentSchemadropped fromAnyComponentSchema's list andPivotTableSchemafromDataDisplaySchema's, two nested WRAP invocations inside a script with its own EXIT/INT/TERM trap: anchors x1 to x0, blobsbdd57555a921toa431c90b3df6andbbeac45eafb5to1a2f01f85196, both restored to the HEAD blob,git diff HEADempty. ResultTests 28 failed / 11 passed (39). Observed direction: the order predicted that only the acceptance rows and the ratchet redden; every refusal row reddens too, because with no arm those documents are refused attypeinstead of by name (batch 1 observed the same). Green: the two rows that read the arms directly and the 9 pre-existing ratchet rows. Vitest aliases@object-ui/types/zodtosrc/, so no build sits between mutation and reading.The sweep
git grepover every tracked test file forAnyComponentSchema,StrictAnyComponentSchema,safeValidateSchema,nodeOracles,KNOWN_SCHEMA_TYPES,propsLevelOf,PUBLIC_BLOCKS,unmirroredAlias,collectArms,getPublicConfigs,ComponentPropsMap,check-handler-key-read-sites,block-config-schema-parity-8216,registry-inputs-spec-parity,strict-authoring-face-8345,zod-mirror-parity: 229 files (the order's nine terms alone: 132, all inside the 229). Plus the handler-key census readers outsidepackages/types(detail-handler-slots-7804,detail-view-handler-slots-9447,handlerKeyDispositionsMeasured-7804,kanban-handler-slots-7664, the two7077button-group files) andmarkdown-test-inputs.test.ts.packages/types/andpackages/cli/whole, at72cf9d3123, with the changeset-reading script suites:Test Files 294 passed (294),Tests 6549 passed (6549).Test Files 113 passed (113),Tests 1945 passed (1945)— among themblock-config-schema-parity-8216(its node oracle now judgesobject-metric's designer fields atproperties),registry-inputs-spec-parity,public-contract,check-handler-key-read-sites.Gates
Under the verify lock where they build or test.
pnpm --filter @object-ui/types type-checkexit 0;pnpm --filter @object-ui/cli type-checkexit 0 afterpnpm --filter '@object-ui/cli^...' build.exit 0:
check-changeset-presence(9 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)),pnpm changeset:check,check-changeset-overwrite(report-only; the two dated notes),check:changeset-claims(report-only; 46 pending changesets name a file touched here, read below),check:pending-changeset-literals,census:changeset-polarity,check:handler-key-reads(OK 131 arm(s)),check:control-bytes,check:new-line-citations(0 new citation(s)),check:test-path-roots,check:spec-symbols,check:doc-types,check:prompt-keys,check:registry-bare-names,check:unreferenced-sources,check:esm-specifiers,check:element-data-source-declaration,check:component-surface-parity,check:designer-field-key-parity,check:side-effects-array,check:self-import,check:phantom-deps,check:installed-pin-claims,check:doc-example-readers,check-type-check-coverage,markdown-test-inputs.mjs --audit(105 candidate test files, all adjudicated).eslint, a proven narrowing: the eight changed
.tsfiles,--no-inline-config --format json→ 8 files, 0 errors, 33 warnings; the same seven pre-existing files at733fd5ac6carry the same 33 (allno-explicit-any), the new file 0. Population:@object-ui/typeslints.,@object-ui/clilintssrc;eslint.config.jssets noprojectService/parserOptions, so no rule can move an untouched file's verdict. The fullpnpm lintis CI's.NOT MEASURED:
check:readme-exports(PREREQUISITE NOT MET — unbuilt packages, population floor),check:sdui-registration-pins(no console build),check:doc-snippets,check:doc-examples(full package build). No README code fence changed; CI measures them.Serial
objectui#10908 (objectui#10872 batch 2) shares
index.zod.ts,zod/README.md, the ratchet file,zod-mirror-parity.test.tsandimported-defaults-8317.test.tswith this branch; every hunk here sits outside its hunks (the ratchet change is theREFUSED_AT_TYPEline, not theNAMESPACED_one).git merge-tree --write-treeof this head72cf9d3123against its headfe8f6a6aad: exit 0. Against a freshorigin/main733fd5ac65: exit 0.objectql.zod.ts,data-display.zod.tsanddata-display.tsare held by no open PR (the claim's reading).Fix round 1 (contract review FAIL, text only)
One commit,
6ee675b45d, no behaviour change:BaseSchemadoes not declare (unjudged on the tolerant face, refused by name on the strict face) from one it does (label,description: judged byBaseSchema's own type on both faces).PivotTableSchema.drillDown's.describeno longer promises a drill: it names the member inert on apivotnode and points atobject-pivot. No test quoted the old string.ObjectMasterDetailFormBlockSchemadocblock and itsEXCLUSIONSreason callMasterDetailFormSchemathe type ofMasterDetailForm'sschemaprop (the renderer's post-hoist reading), and "all four keys" became "both keys".7352dated note names the second "Unchanged" bullet and the opening paragraph's count (two referencing declarations, three for the release). Frontmatter byte-identical; the note is this PR's own and was only amended.At
6ee675b45d, under the verify lock:pnpm exec vitest run packages/types/+ the ratchet + six changeset / markdown script suites →Test Files 272 passed (272),Tests 6168 passed (6168); the b2 pin,zod-mirror-parity,drill-down-config-mirror-7352,content-channel-family-d-9256and the ratchet named →Test Files 5 passed (5),Tests 864 passed (864);pnpm --filter @object-ui/types type-checkexit 0. exit 0:check:changeset-claims(report-only),check:pending-changeset-literals,check:control-bytes,check:new-line-citations(0 new citation(s)).git merge-tree --write-treeof6ee675b45dagainst a freshorigin/main733fd5ac65: exit 0; against objectui#10908's headfe8f6a6aad: exit 0.Acceptance notes
REFUSED_AT_TYPE76 to 73.NAMESPACED_REFUSED_AT_TYPEuntouched (398 onmain).check:changeset-claimsnames, grepped for claims about these keys, arm counts and category modules. Dated notes where a sentence became false:7352-drill-down-config-mirror.md("PivotTableSchema.drillDownhas no zod mirror at all") and10685-drilldown-per-block.md("neitherobject-pivotnorPivotTableSchemahas a zod mirror"). Read and left:8344(no new category module),8499and7363(their counts are their own change's reading),9024(PivotTableSchemastill declares nofilter).pivot'sdrillDownmakes cells interactive only when a host passesonDrillDown; onlyObjectPivotTabledoes, so on the registry path (DashboardGridLayout's static-data pivot, an authoredpivotnode) it is inert.object-master-detail-form'stitle,submitText,cancelTextasI18nLabel;MasterDetailFormrenderssubmitTextandcancelTextas React children and interpolatestitleinto a toast, so a locale map there is not resolved.responsiveStyleson every arm (BaseSchemadoes not declare it); the strict face has no CLI door.object-metric/object-master-detail-form(ADR-0001, the dev harness, plugin-form's own composed nodes) is not judged against the spec row: a flat keyBaseSchemadoes not declare is unjudged on the tolerant face and refused by name on the strict face, while one it does declare (label,description) is judged byBaseSchema's type. Route A, confirmed by the contract review; the flat channel stays the question objectui#10872 left open for the whole public-block family (the seat's note on objectui#10872 names these two arms for that batch), and declaring it later is additive.needs:contract-reviewwas applied by the seat after the dev report.Attribution: the batch-2 dev of
domain:uiseat 2, sessionhttps://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN.Generated by Claude Code