Uh oh!
There was an error while loading. Please reload this page.
fix(types): object-map / object-gantt — objectName optional behind a record-source refinement (objectui#6939, group 6 of 8) - #7471
Conversation
…record-source refinement (objectui#6939, group 6 of 8) Both mirrors in packages/types/src/zod/objectql.zod.ts REQUIRED objectName, a key both renderers read THIRD: getDataConfig in plugin-map/src/ObjectMap.tsx and plugin-gantt/src/ObjectGantt.tsx resolve records from data, then staticData, then objectName. A document authored on staticData alone drew correctly and was refused by safeValidateSchema — six catalog entries, three per component. - objectName becomes optional on both mirrors and both TS twins in the same stroke. - Each member ends in requireRecordSource: a superRefine whose issue sits at the root path, carries params.code RECORD_SOURCE_REQUIRED and names data / staticData / objectName. Presence is `!== undefined` (the ruling's wording), so the accept set only widens: objectName alone, an empty one included, still parses. - object-gantt additionally declares `data` (ViewDataSchema, the map's spelling): the resolver's FIRST read was undeclared on both faces, which would have left the refinement naming a key the validator had never heard of. - Pins: validator contract in packages/types (six catalog entries validate; negative arm checked by path / params.code / message), and render identity in each renderer's own harness with BEFORE literals measured on d88e20f. - Docs: the two plugin pages' Schema API blocks say which of the three is required. Maintainer ruling recorded 2026-09-02 (director seat, summon #8, decision batch #8). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
❌ 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. Which half objected:
📦 Bundle Size Report
Size Limits
|
os-project-manager
commented
Sep 3, 2026
Seat bookkeeping — ⛔ NOT a contract review
Verified on the branch by content, ⛔ not from the report
The fence row is the one I care most about: five other groups of #6939 and three other in-flight PRs live in those files, and none of them moved. ⭐ The addition beyond the ruling's literal wording — correctly surfaced, and necessaryThe ruling says only " That is not scope creep, it is what makes the ruled refinement coherent: a refusal message naming Two measurement details worth keeping⭐ The vacuous pin was measured and discarded, not avoided by luck. A bare ⭐ A The ablation split is the right shape: 19 red / 16 green, with every failure validator-facing and every render-identity, anti-vacuity and widening case green. Restore proven by state. Filed, not acted on#7470 — both plugin registrations' designer-facing
Generated by Claude Code |
os-project-manager
commented
Sep 3, 2026
⛔ Correction to my own comment above — I called the |
os-project-manager
commented
Sep 3, 2026
Contract review — VERDICT: PASS (content); landing blocked by the per-chunk eager-closure ceiling, not by this diff's correctnessImplemented-by: objectui execution seat ( ① Derived judgments. Executes the #6939 ruling row for this group (recorded 2026-09-02, batch #8): ② Semver / changeset. ③ Boundary flags. No governed path; Landing — blocked, and not by this PR. Every check is green except Bundle Analysis: Generated by Claude Code |
✅ 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
|
os-project-manager
commented
Sep 3, 2026
✅ Landing — the ceiling this was parked behind is fixed. Contract PASS stands; ready + auto-merge.
The blocker named in the review is goneThe contract review (5522971250) returned PASS on content and blocked landing on one thing only:
#7399 was ruled (maintainer, 2026-09-03, option A′) and landed as
The three pre-landing conditions, checked rather than assumed
⭐ Why re-review was not required, established mechanically rather than assumedThe review was performed at head ⇒ the reviewed contract increment is byte-identical at the landing head. The merge resolved nothing in this branch's own files.
|
Uh oh!
There was an error while loading. Please reload this page.
Part of #6939 — group 6 of 8 (
object-map+object-gantt), dispatched as its own PR per the maintainer ruling recorded 2026-09-02 (director seat, summon #8, decision batch #8, comment 5510084784). ⛔ Deliberately not a closing keyword: the card stays open until all eight groups land.The defect
Both mirrors in
packages/types/src/zod/objectql.zod.tsREQUIREDobjectName. Both renderers read their records from one of THREE keys, in this order — measured at the read sites, not taken from the card:packages/plugin-map/src/ObjectMap.tsxgetDataConfig(lines 122-167):if (schema.data) … if (schema.staticData) … if (schema.objectName) … return nullpackages/plugin-gantt/src/ObjectGantt.tsxgetDataConfig(lines 312-331): the same three keys, the same orderNo fourth source on either; all three are read by both. A document authored on
staticDataalone draws correctly and was refused bysafeValidateSchema— six catalog entries, three per component, allstaticData-only.The shape
objectNameis optional on both mirrors and on both TypeScript twins (packages/types/src/objectql.ts), moved in the same stroke.requireRecordSource— asuperRefinefollowing the in-repo shape ofFormFieldSchema's refinement inform.zod.ts: issue at the ROOT path (no single key is at fault, and blamingobjectNamewould re-teach the requiredness this removes),params.code = 'RECORD_SOURCE_REQUIRED', message naming the three keys an author can supply. Presence is!== undefined— the ruling's wording — not the renderers' truthiness, so the accept set only widens (the changeset carries the argument).object-ganttadditionally declaresdata(ViewDataSchema, the map's spelling) on both faces. It is the FIRST key that resolver reads and was declared on neither face — a refinement over it would have named a key the validator had never heard of. Reported here as the one addition beyond the ruling's literal wording; it is a declared-equals-enforced restoration of the kind the card is about, and the parity ledger is unaffected because both faces gain the same pairing the map pair already carries.content/docs/plugins/plugin-map.mdx(which still publishedobjectName: string) andplugin-gantt.mdxnow say which of the three is required.@object-ui/typespatch — the accept set only widens toward what already renders.The pin — both halves the ruling asks for
Validator half (
packages/types/src/__tests__/objectql-record-source-refinement-6939.test.ts): the six catalog entries validate (control: each authors noobjectNameand does authorstaticData); any one of the three alone validates;objectName: ''still parses (widening); a document with none of the three is refused ON THE REFINEMENT — exactly one issue, root path,RECORD_SOURCE_REQUIRED, all three key names in the message;.shapeis still exposed on both objects (zod 4 attaches the check in place); ganttdatais declared, not a passthrough hole.Render half — BEFORE literals measured on
origin/maind88e20f55with the mirrors untouched, through the pin's OWN harness (aSchemaRendererProvider-wrapped bareSchemaRenderer,Datefrozen). The harness is named because it matters twice over: a bareSchemaRendererwithout the provider renders the error boundary for both components (4 elements, "failed to render") — an identity pin over that is the vacuous pin the ruling warns about — and the docs-gallery harness gives different absolute counts for the same tile.examples/schema-catalog/test/objectql-record-source-render-identity-6939.test.tsx): 407 / 354 / 436 elements, a tag census, the visible text as a literal, and a SHA-256 of the full textContent (the chart's own style block is part of it). Identical before and after. Anti-vacuity: every authored task title on screen, no error box.packages/plugin-map/src/ObjectMap.catalogRecordSource-6939.test.tsx): 16 / 14 / 14 elements, text = the geolocate glyph plus one marker glyph per row, tags in document order, 4 / 3 / 3 markers. Identical before and after. Anti-vacuity: one marker perstaticDatarow, drawn on a LIVE maplibre stand-in (aria-label="Map"control). It lives in plugin-map because the samevi.mock('react-map-gl/maplibre')is measured INERT fromexamples/schema-catalog(the specifier does not resolve there; the real maplibre mounts and crashes ondestroy).Red-then-green ablation on the committed tree: restore both mirror sources to
d88e20f55(blob hashes checked equal to the base and unequal to HEAD; anchored LINE countsrequireRecordSource5 to 0, TSobjectName?: string;5 to 3, controlObjectMapSchema = BaseSchema.extend1) → the three pins read 19 failed | 16 passed, exit 1 — every failure validator-facing; every render-identity, anti-vacuity and widening case green. Restore pinned to HEAD and proven by state:git diff HEADempty,git status --porcelainempty, both blobs equal to HEAD, anchors back to 5 / 5.Parity ledger
packages/types/src/__tests__/zod-mirror-parity.test.tsis UNTOUCHED. Measured before starting: neitherobjectql.zod.ts#ObjectMapSchemanorobjectql.zod.ts#ObjectGanttSchemahas an entry inKnownDrift,UnmirroredDeclaredorRuntimeOnlyDeclared; their only mention is theSPEC_DERIVED_PAIRSlist, which is unaffected. Both faces moved together, so the pairs still record zero drift — asserted, not assumed:@object-ui/typestype-check(which compilestsconfig.test.json) exit 0, andtsc -p tsconfig.test.json --listFileslists the parity test, the new test and both edited sources (552 files in the program).Verification (all at
afcb85788, heavy runs serialized through the shared verify lock)pnpm exec vitest run packages/types/ packages/plugin-map/→ Test Files 112 passed (112) / Tests 1662 passed (1662)pnpm exec vitest run packages/plugin-gantt/ examples/schema-catalog/→ Test Files 81 passed (81) / Tests 2431 passed (2431)type-check:@object-ui/types,@object-ui/plugin-map,@object-ui/plugin-gantt,@object-ui/example-schema-catalog— all exit 0 against a freshly built dependency closure (turbo build, 34 tasks)lintfor types / plugin-map / example-schema-catalog: 0 errors (267 + 141 pre-existing warnings, none in the new files)check:readme-exportsexits 1 only becauseplugin-ai's dist was not part of the built closure (3 unjudgeable self-imports; 403 judged, 0 fabricated); this diff edits no README and adds or removes no export.Landing
Clause ② yes: this changes what a published mirror accepts. Labelled
needs:contract-review, stays DRAFT, waits on the project director seat — not self-reviewed, not enqueued, no auto-merge. That is the expected end state.Out of scope, filed separately: objectui#7470 — both plugin registrations' designer-facing
inputsstill declareobjectNamerequired: true.Session
session_01EMrWaQw3XS5DxTHxp4yRyC.🤖 Generated with Claude Code
https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
Generated by Claude Code