Repository navigation
feat(spec): ComponentPropsMap gains a 'list-view' row — a page-embedded list view is judged as a list view; stored objectName / viewType convert to data / type (#22444) - #24217
Conversation
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
…ource refusal Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
…n to its prescriptions Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 5 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 143 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin dce94ca12a2cbf606945c90389c70800196ea7ca && git checkout dce94ca12a2cbf606945c90389c70800196ea7ca
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6ec0e1222812996230b312da753a592026eaf6d9 e55aa1bfce055fae9fd16db9a9413f34d4084021 && git checkout -B drift-repro 6ec0e1222812996230b312da753a592026eaf6d9 && git merge --no-ff e55aa1bfce055fae9fd16db9a9413f34d4084021
node scripts/docs-audit/affected-docs.mjs --json 6ec0e1222812996230b312da753a592026eaf6d9
|
…meta sentence whole Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed as a read of the net diff against ① Derived judgments
Real-producer reading accepted as stated: the hotcrm 4.0.1 fixture carries 4 page ② Semver levelDoes not match what the diff publishes. The changeset is Why the ruling's letter does not settle it on this head: ruling What lifts this section: one changeset patch round on this PR, about three lines in
③ Boundary flags
Implemented-by: VERDICT: FAIL Scope of the FAIL: section ② only. Sections ① and ③ hold; the implementation is ruling C's spec half as ruled and as measured. The fix is one changeset patch round (or the maintainer's letter on #24219), then a new record on the head that carries it. Generated by Claude Code |
…lias prescription, in one literal Claude-Session: https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf Co-authored-by: Claude <noreply@anthropic.com>
|
Pointer — #24219 ruled A. From the director seat, summon #44 ( Ruling 6243467550, the maintainer's 「24217 A」, keeps this PR's changeset as shipped: |
Contract reviewServed-tier: Re-rendered record. It supersedes ① Derived judgments
② Semver levelMatches, against the ruling of record. What the diff publishes is two things at once: the exported Against that ruling the changeset is well-formed and complete: What this section records so the ledger of the review stays honest: the narrowing at the save door is real (judgment 4), it is not announced as BREAKING by the maintainer's choice, and under A the hotcrm card the ruling orders at landing (③) is that producer's only notice. ③ Boundary flags
Implemented-by: VERDICT: PASS Sections ① and ③ hold as in Generated by Claude Code |
席位核对 · ACCEPT · PR #24217 @
|
Fixes #22444
Clause-②: yes
Ruling C on #22444 (record
6100463199, the maintainer's 「同意」), its spec half: a list view embedded on a page is judged as a list view, and the page carrier's own spellingobjectName/viewTypeis refused by name and carried forward on stored nodes by an ADR-0087 D2 conversion. Dev session:session_01Q5DmD3Wg7eTiagmd5p9rqf(cloud dispatch from thedomain:spec#1seat, claim6238503560).What changed
ComponentPropsMap['list-view'](packages/spec/src/ui/component.zod.ts,ListViewPageProps). Every member isListViewSchema.shape's own schema object, and both of the list view's object-level checks are attached (checkListViewCalendarVisualization,checkListViewChartBinding). The two members the list overlay member declares instead, and nothing else:columnsoptional: the overlay member's own spelling,ListViewSchema.shape.columns.optional();optionsjudged per kind: the overlay member's own bag by reference,VIEW_METADATA_MEMBERS.listOverlay.shape.options. Eachoptions.KINDis judged by that kind's block, andoptions.gridgets its existing guidance.objectName/viewTypeare undeclared, and the row's guidance answers them by name. The guidance quotes the react tier's note for the same alias verbatim.ListViewShapeSchemais not: a top-level export would mint a def and duplicate everyui/ListViewkey inauthorable-surface/.check:authorable-surface,check:api-surfaceandcheck:docsare unchanged.REACT_RETIRED_OVERLAY_PROPS.ListView's two entries moved, byte for byte, to a leaf module outside theuibarrel (ui/list-view-retired-aliases.ts).react-blocks.tsreads it there, and so does the row. The row cannot importreact-blocks.ts, which readsComponentPropsMapat module load. The published value ofREACT_RETIRED_OVERLAY_PROPSis unchanged (check:react-blocksandcheck:export-originsare green).page-list-view-object-name-view-type-to-data-type(conversions/registry.ts, order 68,retiredFromLoadPath: true,retiredAfter: '17.7.0'). On every page component of typelist-viewthatmapPageComponentsreaches:objectName: 'x'becomesdata: { provider: 'object', object: 'x' };viewTypebecomestype;datasource or adataSource.objectnaming another object, aviewTypebeside a differenttype, or a non-string alias.page-list-view-object-name-view-type-retired(conversionIdsjoins it to the conversion), plus its step-18 rationale fragment inregistry.ts.template(order 101).page.zod.ts:PRINT_REFUSED_PAGE_COMPONENT_TYPESgainslist-view(it pages its rows, theobject-gridreason). Before this, the type was refused in a print page as unknown vocabulary, so the accept set does not move.refused-shapes.tsand the D3 entryview-data-api-provider-retired) now nameslist-viewamong the components whosedataprop takes a view data source. The detector reads each row'sdatamember, so it reaches a pagelist-viewnode for the first time with this row (contract review6240571802, ① item 8). The strings now name it.z.unknown()member ledger, therequiredPermissionscensus and the retired-prescription join each gained theirlist-viewlines.gen:strictness-ledger:ui/gains 1 strict site).Accept set, before → after
d9a749bae)PageSchema/PageComponentSchemalist-viewnode with anypropertiesos validate/os build/os lint, page save door)list-viewskipped as unregistered: 0 findingskanban.groupField,options.grid,properties.objectName,properties.viewTypearecomponent-props-unknown-key, each naming the keyobjectName/viewTypetodata/typeon readdefineStack)Measured against a real producer
The external corpus
objectstack-ai/hotcrm4.0.1 (the published-pages fixturepackages/objectql/src/__fixtures__/hotcrm-4.0.1-published-pages.artifact.json, 7 pages in package 2) carries 4 pagelist-viewnodes in the old spelling:objectNameandviewType);OS_METADATA_CONVERTEDnotices and 0 TODOs;filter,{ field, order }sortand stringcolumnsall pass).In-repo producers of page
list-viewnodes: 0 inpackages/**andexamples/**outside test fixtures (control: the same grep hitsreact-blocks.ts:292).Tests
All at head
945584a6unless noted.pnpm --filter @objectstack/spec test: 693 files, 20989 passed, 1 todo, exit 0.pnpm --filter @objectstack/spec typecheck: exit 0.pnpm --filter @objectstack/lint test: 143 files, 6821 passed, 5 skipped.typecheck: exit 0.list-viewnodes, after a closure build:@objectstack/objectqlregistry-installed-package-retired-page-declarations.test.ts(8 passed),@objectstack/service-package(8 files, 119 passed),@objectstack/cloud-connection(50 files, 602 passed). All exit 0.spec/src/ui/component-list-view-row.test.ts: the ruling's list, by-reference identity, the checks attached, one prescription for both tiers,PageSchemaunmoved;spec/src/conversions/page-list-view-object-name-view-type-to-data-type.test.ts: stored row → accepted by the row, notices, TODOs on conflict, not on the authoring funnel, idempotent, copy-on-write;lint/src/validate-component-props-list-view-22444.test.ts: the findings at the gate, and throughrunAuthoringRules.list-view-ablatedthroughscripts/ablation-replace.mjs, then spec was rebuilt. The marker was present indist/(proved by the run turning red). The lint pin went 5 failed / 3 passed: every flag case red, and the three contract-only cases still green, as expected with no row. Restore leg:git checkout HEAD --, bloba5e4dbed97equal to HEAD, rebuild,ablation-dist-preflight --absentexit 0, then the pin went 8/8 green.Gates
node scripts/pm/dispatch-gates.mjs --commands(90 derived families, change set vs merge based9a749bae), run at945584a6:pnpm check:dual-build-cjs-loadsexited 3, PREREQUISITE NOT MET (needs every package built), so it is NOT MEASURED locally and left to CI;node scripts/check-plugin-teardown-shape.mjs --self-testfirst exited 3 because its pinned fixture commit was outside the shallow clone. After fetching that one commit it exited 0.The
--ranreconciliation reports 90 accounted, 89 run, 1 NOT-MEASURED.check-adr-0087-registration: "this PR adds no declared-breaking changeset". Separately,pnpm --filter @objectstack/spec check:generatedreported 14/14 up to date aftergen:strictness-ledger, andcheck:dev-prereqsexited 0.origin/mainmoved to8259ea03after this branch was cut. Those commits touch none of this PR's files, so no merge was taken.Patch round 1 (
e55aa1bf)retired-key-migrate-sentence.test.ts(--project repo, Test Core) now passes 15/15. Eachlist-viewalias prescription now ends with the houseos migrate metasentence, verbatim and in one literal, and the react-tier note moved one sentence earlier. The conversion docblock now says--writerewrites a source. spectest:repo1115 passed, spectest20989 passed, lint 6821 passed; 90/90 derived gates exit 0 (report6241238026).6240571802(on86c001e7c; the delta toe55aa1bfis the reorder above) holds ① and ③ and FAILs ② only, on theClause-②arm. That item is the maintainer's, on [Decision] #22444's pagelist-viewrow refuses the oldobjectName/viewTypespelling atos validateand the page save door, but ruling C declared ityes (widening)on a warning-tier premise: declare the narrowing? #24219. This PR stays unarmed until [Decision] #22444's pagelist-viewrow refuses the oldobjectName/viewTypespelling atos validateand the page save door, but ruling C declared ityes (widening)on a warning-tier premise: declare the narrowing? #24219 is answered.Acceptance notes
The gate's tier is now
error, not the "warning" the ruling text names. Ruling item (1) says the row is lint-tier, "as everyComponentPropsMaprow has been since spec:record:reference_railhas no ComponentPropsMap row — an entryfilterparses, typechecks, validates, ships, and silently does nothing #8691", with no new gate. Measured:validate-component-propsemitserrorfor every finding since lint: the rest of the component-props gate's recorded plan — everycomponent-props-invalidclass andcomponent-props-unknown-keygo toerror, after an external-corpus inventory #23147, atos validate/os build/os lintand at the runtime page save door (ruling record 6161173492). This PR adds no gate and changes no tier: the row takes the rule's tier, as every row does. So in practice an authored page source carryingproperties.objectName/viewTypeon alist-viewfailsos validate, and a Studio, REST or MCP save of such a page is refused until it is rewritten. Stored rows load converted. TheClause-②arm follows the ruling (yes (widening), minor). The seat may want the arm re-read on this fact (see the report's open question).columnsis optional whatever the binding. The seat's note reads "optional under adataSource.viewbinding". The row judgespropertiesonly and cannot see the node'sdataSource. The overlay member's own difference is unconditional, and the list renderer draws a column-less list.Differences from objectui's
ListViewPropsBag(@object-ui/typesat the.objectui-shapin5e15928b46), read as a reference only:columnsoptional and adds named refusals on its kanban / calendar / gallery / timeline blocks; this row keepsListViewSchema's blocks as declared;So a page kanban with a kanban block that omits
columnspasses objectui's face and drawskanban.columnsrequired here..objectui-sha, objectui,PageSchema's accept set andvalidate-component-props.tswere not touched: the rule dispatches on map rows, and no dispatch change was needed.🤖 Generated with Claude Code
https://claude.ai/code/session_01Q5DmD3Wg7eTiagmd5p9rqf
Generated by Claude Code