feat(types): arm record:line_items from its @objectstack/spec 17.6.0 row, the last public block refused at type (objectui#10872) - #11570
Conversation
…ComponentPropsMap row The last ADR-0080 public block AnyComponentSchema refused at `type`. The arm reads ComponentPropsMap['record:line_items'] by reference as its properties bag, spreads the flat-props refusals and the node envelope, declares the node's dataSource binding as the spec's ElementDataSourceSchema (the registration is gate-wrapped; the row leaves childObject optional because the binding supplies it), and refuses node-level children / body by name. Pins: the batch-1 / batch-10 / batch-8 population rows gain the block, the import-boundary list gains the row, the namespaced refused-at-type ratchet falls 361 -> 360, and a new pin file carries the block's own readings. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 Co-authored-by: Claude <noreply@anthropic.com>
…nknown-type message less its options list zod-mirror-parity: one EXCLUSIONS row, directly after RecordAlertBlockSchema, recording that RecordLineItemsBlockSchema is spec-owned by reference. any-component-union-fanout: the unknown-type refusal's message carries the discriminator's options list, which grows by one literal per arm; at 204 literals the whole message read 4,007 against a 4,000 bound. The bound now reads the message less that list, and the docblock gains the reading (flat union 14,126 -> discriminated 193) beside the original one. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 Co-authored-by: Claude <noreply@anthropic.com>
|
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
|
…ma's declaration stays under TS's serialization ceiling Against @objectstack/spec built from objectstack main, the record:line_items row is larger, and with the arm printed inline `AnyComponentSchema` failed declaration emit with TS7056, so @object-ui/types emitted no .d.ts (Spec Main Shape Gate). The arm is now built as a private const and exported as RecordLineItemsBlockSchema typed by an exported interface that extends the arm's own inferred type and adds no member, so declaration emit prints the arm once and refers to it by name. Runtime object, parse results and the strict face are the arm's; compile-time rows pin the arm's input and output types against the spec row and binding. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 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
|
Contract reviewServed-tier: Written 2026-10-03T19:10Z by an isolated at-tier reviewer (subagent of the History of this record. An earlier head of this PR, efa2ef2 (spelled without a code span on purpose: this record is a review of c9e205d alone), was NOT passed: its ① Derived judgmentsDiff against
② Semver level
③ Boundary flags
Check-runs on the head (REST, Implemented-by: VERDICT: PASS |
…use to the measured one The docblock said objectstack main's spec makes the record:line_items row larger. Measured on objectstack main 5c9138b, the arm's own serialized size is the same as against 17.6.0; the rest of AnyComponentSchema grew. Comment only; the family is tracked in objectui#11573. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 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
|
|
Generated by Claude Code |
Part of #10872
Clause-②: yes
safeValidateSchema(whatobjectui validateruns) and the strict authoring face acceptrecord:line_items, the last ADR-0080 public block they refused attype.@objectstack/spec17.6.0, which objectuimainresolves, carries the block'sComponentPropsMaprow, measured atLineItemsPanel's reads, and itsSTRING_ARM_REGISTERED_TYPESledger is empty. The arm reads that row by reference, by the batch-1 method, with the flat-props refusal and the content-channel refusals as on every other arm.This is
Part ofthe card: therecord:reference_railREADME sentence (comment5943728376) stays on it, because open PR objectui#11512 holdspackages/plugin-detail/README.md.What changed
packages/types/src/zod/public-blocks.zod.ts:RecordLineItemsBlockSchema, a member ofPublicBlockComponentSchema:propertiesisComponentPropsMap['record:line_items']through the objectui#8317 import boundary (stripImportedDefaults(RecordLineItemsProps)), sorelationshipFieldandcolumnsare required in the bag andchildObjectis optional, as the row declares;NODE_ENVELOPE(responsiveStyles) andflatPropRefusals: a row member written on the node is refused by name, towardproperties.KEY;dataSource, the spec'sElementDataSourceSchemaby reference. The registration is gate-wrapped andElementDataSourceGateputsdataSource.objectintochildObject, which is why the row leaveschildObjectoptional. This follows the module's own rule (an arm whose renderer reads the binding declares it) and the objectui#11440 precedent. Without it the strict face would refuse the row's own bound node asunrecognized_keys;children/body: neither-channel tombstones, from oneneitherContentChannelGuidancestring.packages/types/src/zod/index.zod.ts: the barrel exports the arm.record-line-items-arm-10872.test.tscovers the row's requiredness, the bound node, the binding by reference, and both content channels, each held to the installed spec's own verdict;public-block-arms-10872), batch-10 (flat-props-refusal-10872) and batch-8 (public-block-responsive-styles-10872,DECLARES_DATA_SOURCE) population rows gain the block;IMPORTEDlist (imported-defaults-8317) gains the row;any-component-union-fanout.test.ts: the unknown-typebound now reads the message LESS the discriminator'soptionslist. That list names everytypeliteral, so it grows by one per arm by design. The whole message read 4,007 against the 4,000 bound at 204 literals. The docblock gains the new reading beside the old one.zod-mirror-parity.test.ts: oneEXCLUSIONSrow (see serial notes)..changeset/10872-record-line-items-arm.md(@object-ui/typesminor), and dated notes appended to10872-public-block-zod-arms.mdand10872-held-public-block-arms.md. Each note corrects only the "record:line_items is still refused at type" sentences this change makes false. Both frontmatters are byte-identical.Measurements
ab18797, by a source probe: 8record:line_itemsdocuments × 2 faces = 16 readings. All areinvalid_unionattype: the block was refused, not passed unjudged.ablation-replace.mjs(WRAP mode, anchor x1 → x0). The five pin files read 26 failed, 371 passed. The restore was proved by "blob == HEAD (060da1ed48fd) and git diff HEAD is empty". The pins importsrcthrough the vitest alias, so there is no dist leg.z.union(AnyComponentSchema.options, …)(the same 20 members and the same message map), and the bound reported "expected 14126 to be less than or equal to 4000". Restored: "blob == HEAD (370406be767a) and git diff HEAD is empty". The discriminated reading is 193.PublicBlockNodeaccepts the bag node. It refuses an invented bag key (TS2353) and a flatrelationshipField(TS2322). There were exactly those two errors.@object-ui/plugin-formdependency closure was built (11 packages);children/bodyreads, both Reactchildrenprops of unrelated components, and 0 inLineItemsPanelor its registration;@object-ui/reactprogram's one hit isElementDataSourceGate's own render-propchildren;SchemaRendererand registry (one-off) rendered node-levelchildren/bodymarkers 0 times, with the DOM equal to the no-channel mount. Control:page:cardproperties.childrenrendered its marker once;PageComponentSchemarefuses a node-levelchildrenon this block (pinned).registry-inputs-spec-parity.test.tspasses unchanged: the arm moves no booked count.Tests (head
efa2ef2)pnpm exec vitest run --maxWorkers=2 packages/types/ packages/cli/gives Test Files 373 passed (373) and Tests 9719 passed (9719), VERDICT command-exit 0.pnpm --filter @object-ui/types type-checkandpnpm --filter @object-ui/cli type-checkboth exit 0.b9a8a40, the head before the two test-only changes inefa2ef2: the consumer sweep (21 files outsidepackages/typesthat read the union or the ratchet, includingregistry-inputs-spec-parityandpublic-contract) passed 680 tests, VERDICT command-exit 0.check:control-bytes;check:new-line-citations(0 new);check:changeset-claims(report-only; the 21 pending changesets that name a touched file were read, and none is falsified by one arm in an existing module, oneEXCLUSIONSrow, or the bound change);check:pending-changeset-literals;check:handler-key-reads;check:test-path-roots;check-changeset-presence;check-changeset-no-major.pnpm --filter '@object-ui/types^...' buildhas an empty closure (ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT), so nothing ran.pnpm --filter @object-ui/types buildexits 0.pnpm lint, which CI owns.Serial notes
packages/types/src/__tests__/zod-mirror-parity.test.tsis also edited by open PR objectui#11512. This PR adds exactly ONEEXCLUSIONSrow,'public-blocks.zod.ts#RecordLineItemsBlockSchema', directly after theRecordAlertBlockSchemaentry, and changes nothing else in that file. objectui#11512's hunks there sit in theWiderThanDeclaredcensus summary, theWiderThanDeclaredinterface and theWIDER_ARMSmap, so the two do not overlap textually. The seat admitted the row in comment5972030168.NAMESPACED_REFUSED_AT_TYPEpin, and the fanout bound's population, the discriminator literals. A sibling lane that arms a block, such as objectui#11216 inobjectql.zod.ts, moves the same ratchet. Whichever lands second recomputes it.Acceptance notes
inputsdeclarechildObjectrequired: true, while the spec row makes it optional. As a result, the JSX page compile andvalidateTreerefuse adataSource-bound node withoutchildObject(missing-required-prop), and the zod faces accept it. Measured; the seat files it as its own card.plugin-formis not touched here.record:related_listis gate-wrapped too, and its arm declares nodataSource, so the strict face refuses a node-level binding there. This is dormant: the strict face has no consumer yet, and the undeclared set is pinned as a decision. Noted only.Generated by Claude Code