Repository navigation
refactor(types,plugin-calendar,plugin-gantt,plugin-list,plugin-view)!: flat object-calendar / object-gantt keys leave the published schemas; producers emit the block - #26411
Conversation
…aces; producers emit the blocks Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J Co-authored-by: Claude <noreply@anthropic.com>
…ck spelling; hand-off pins in plugin-gantt The published faces no longer declare the flat keys, so the pins that read them there now pin their absence, and the producer tests read the emitted calendar / gantt block. READMEs and the changeset follow. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
Contract reviewServed-tier: Inputs read: card #25923 body and all 11 comments (rulings 6412606977, premise 6430806588, claim 6430908258, os-dev-report 6432621418 included); PR #26411 body, 30-file list, net diff against main; check-runs on the head, read 2026-10-27T03:00Z, 03:06Z, 03:07Z and 03:09Z (readings in ③). Nothing built, run or re-run locally. ① Derived judgments
② Semver level
③ Boundary flags
Two FAIL reasons, both mechanical and both inside the declared surface: the unused Implemented-by: VERDICT: FAIL |
…ng, point the calendar tombstones at the block - ListView and ObjectView hand a gantt binding the spec's GanttConfigSchema refuses flat, as before, since getGanttConfig validates a gantt block and would show its refusal screen where the flat branch drew. - The object-calendar dateField / endField tombstones prescribe calendar.startDateField / calendar.endDateField. - Drop the unused SpecCalendarConfig import; the plugin-gantt README writes the gantt block. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
…ombstone prescription Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
|
Test UI (7/16) is red on head The two failing rows are Generated by Claude Code |
Contract reviewServed-tier: Inputs read: card #25923 body and all 12 comments (rulings 6412606977, premise 6430806588, claim 6430908258, os-dev-report 6432621418, the r1 record is on the PR); PR #26411 body, 31-file list, both PR comments (record 6432801280 on 254db19 = FAIL; the author's Test UI note 6433437322), the net diff against main and the incremental diff 254db19...89e1321; the 61 check-runs on the head, read 2026-10-27T04:06Z; main's check-runs on 08ed7e2, 75afeff, d15f99d, 9494dd8 and 26e7c75 for the Test UI comparison. Nothing built, run or re-run locally. ① Derived judgments
② Semver level
③ Boundary flags
One FAIL reason of substance and its prose shadow, both inside the declared surface: the Implemented-by: VERDICT: FAIL |
…, drop the flat fallback The producers hand the gantt binding on as the node's `gantt` block whether or not the spec's GanttConfigSchema accepts it; a silent flat fallback for an off-spec block is consumer-side tolerance. The prose now says what moves: a binding carrying a spec-refused value, which the unvalidated flat branch drew, reaches the renderer's refusal screen. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
Contract reviewServed-tier: Inputs read: card #25923 body and all 11 comments (triage 6408059640, transfer 6408067630, premise 6409923362 and 6430806588, claims 6410175297 and 6430908258, os-dev-reports 6412566640 and 6432621418, ruling 6412606977, accept 6413782781, landed 6416705898); PR #26411 body (revised for this head), its 30-file list, all three PR comments (record 6432801280 on 254db19 = FAIL; the author's Test UI note 6433437322; record 6433646970 on 89e1321 = FAIL), the net diff against main and the incremental diff 89e1321...4676da4; the 61 check-runs on the head, read 2026-10-27T05:00:53Z. Nothing built, run or re-run locally. ① Derived judgments
② Semver level
③ Boundary flags
Both r2 FAIL reasons are closed on this head and the behaviour change they concerned is declared once, in the same words, across the two producers' comments, the renderer's docblock, the changeset (ADR-0087 marker and package bullet) and the PR body, and routed to store conversion rather than tolerated. The contract judgments of r1 and r2 hold; every required context is green. Implemented-by: VERDICT: PASS |
Seat reading · REWORK r3 (patch round) ·
|
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
…the producers hand off the block The explanatory clause of OBJECT_CALENDAR_FLAT_FIELD_GUIDANCE and OBJECT_GANTT_FLAT_CONFIG_GUIDANCE said ObjectView / ListView emit the flat spelling; they now hand the binding off in the calendar / gantt block, and the flat spelling is only a stored-document fallback the renderer still reads. The prescription itself is unchanged. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 147 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…tadata-protocol line Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
Contract reviewServed-tier: Inputs read: card #25923 body and all 11 comments (claim 6430908258 as amended 05:18Z, premise 6430806588, os-dev-report 6432621418, ruling 6412606977); PR #26411 body (revised for this head), its 31-file list, all six PR comments (records 6432801280 FAIL on 254db19, 6433646970 FAIL on 89e1321, 6434353541 PASS on 4676da4; the REWORK r3 order 6434412515; the Test UI note 6433437322; the docs-drift bot 6435023674); GET /compare 4676da4...2f10566 (54 commits) and, to separate the branch from main, GET /compare f9a1752...2f10566, 00a4593...4676da4 and 00a4593...f9a1752; the net diff against main; the head's files via GET /contents; the 70 check-runs on the head, read 2026-10-27T06:38:54Z and again 06:47:16Z (readings in ③); a read-only ① Derived judgments
② Semver level
③ Boundary flags
One FAIL reason, mechanical and bounded, in the one file this round edits: the JSDoc over the two guidance constants and the Implemented-by: VERDICT: FAIL |
…cers hand off the calendar / gantt block The JSDoc around the object-calendar / object-gantt flat-key guidance, and the comments this PR's files carry, still said ObjectView / ListView emit or flatten into the flat spelling and that ObjectGanttSchema declares it. They now say the producers hand the binding off in the block, the flat spelling is a stored-document fallback the renderer still reads, and the flat keys live on the package-local hand-off types. Comments only. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J
Contract reviewServed-tier: Inputs read: card #25923 body and all 11 comments (premise 6409923362 and 6430806588, claim 6430908258 as amended 05:18Z, os-dev-reports 6412566640 and 6432621418, ruling 6412606977, accept 6413782781, landed 6416705898, triage and transfer); PR #26411 body as it stood at 08:04:49Z (the PR's updated_at is 08:03:39Z, so the body judged is the post-update one), its 31-file list (+1051 / -1085 = 2136 changed lines), all seven PR comments (records 6432801280 FAIL on 254db19, 6433646970 FAIL on 89e1321, 6434353541 PASS on 4676da4, 6435670761 FAIL on 2f10566; the REWORK r3 order 6434412515; the Test UI note 6433437322; the docs-drift bot 6435023674); GET /compare 2f10566...eba2028 as JSON and as a diff; the net diff against main (GET /pulls/26411 as a diff); every one of the 31 files at the head via GET /contents?ref=eba20284; the 70 check-runs on the head, read 2026-10-27T08:04:49Z and re-read before this post (readings in ③); a read-only ① Derived judgments
② Semver level
③ Boundary flags
The one FAIL reason of 6435670761 is closed by a comment-only increment whose 72 changed lines were each verified as comment text (D1); the file no longer contradicts its own prescriptions (D2), no live sentence in component.zod.ts or in any of the PR's ui files says the producers emit the flat calendar or gantt spelling or that Implemented-by: VERDICT: PASS |
维护者速读 (席位终稿)
席位意见:接受。四轮契约复核后 PASS(6436950621);r1 时席位下令加的平铺回退违反 Prime Directive #12,已在 r2 撤回,这是席位的失误。 席位核对 · ACCEPT ·
|
Requested by Yibo Wang · project thread
Part of #25923 (work item 1 only; items 3, 4 and the FormField follow-up stay on the card).
Clause-②: yes (narrowing)
Metadata-protocol: narrowed
Skills-docs: none —
skills/objectui/guides/page-builder.mdalready authors theganttblock and no skill authors a flatobject-calendarorobject-ganttkey; the two plugin READMEs are corrected here维护者速读
@object-ui/types里object-calendar和object-gantt节点不再公开“平铺”的字段映射键(如startDateField),这些键只能写在calendar/gantt块里;ListView和ObjectView生成节点时也改为写块。objectui validate因此放行了日历节点上 spec 拒绝的写法,作者会被误导。options.gantt带有 spec 拒绝的值,现在显示甘特拒绝屏而不是照常绘制(数量未测,由卡片第 3 项的存量行盘点来数)。另一风险在于手写 TS 代码里写了平铺键的会编译失败(按 changeset 里的迁移改成块即可)。回滚就是 revert 本 PR。ui/packages/plugin-list/src/ListView.tsx(calendar / gantt 两个分支的出块条件)、ui/packages/types/src/zod/objectql.zod.ts(被删的成员)、ui/packages/plugin-gantt/src/ObjectGantt.tsx(ObjectGanttFlatFields)。pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.gantt-binding-7070.test.tsx packages/types/src/__tests__/gantt-flat-config-declared-keys.test.ts,预期全部通过。What changes
The flat field-mapping keys of
object-calendarandobject-ganttleave the published@object-ui/typesfaces (TypeScript interface and tolerant zod mirror) and move to package-local hand-off types next to their one reader (ui/AGENTS.md Commandment #0.1). The producers emit the block.Moved off the published faces
ObjectCalendarSchema:startDateField,endDateField,titleField,colorField,allDayField(5). New home:ObjectCalendarFlatFields/ObjectCalendarHandoffinplugin-calendar/src/ObjectCalendar.tsx.ObjectGanttSchema: the 29GanttConfigkeys (startDateField,endDateField,titleField,progressField,dependenciesField,colorField,borderColorField,parentField,typeField,lockField,objectField,summaryExtent,defaultCollapsedDepth,tooltipFields,baselineStartField,baselineEndField,groupByField,resourceView,assigneeField,effortField,capacity,quickFilters,autoZoomToFilter,timeSegments,interactions,exportFileName,timeZone,dependencyTypes,viewMode), plus the legacydependencyFieldalias and thesearch/searchableFieldspair onlyListView's toolbar writes (32). New home:ObjectGanttFlatFields(derived fromGanttConfig, so the two spellings cannot fork) /ObjectGanttHandoffinplugin-gantt/src/ObjectGantt.tsx.Kept
ObjectCalendarSchema: thecalendarblock, thedateField/endFieldaliasKeyRefusal tombstones, and every other node key.ObjectGanttSchema:gantt,staticData,filter,sort, and every other node key.FormFieldindex signature) is not touched.For gantt, the strict authoring face already refused every flat key (its
object-ganttarm is thepropertiesbag,ObjectGanttBlockSchema, objectui#10859), so the narrowing there is the published TypeScript and zod export only. For calendar the strict face derived from the declared keys and accepted the five flat; it now refuses them by name, as the spec does.Producers.
ListView(calendar and gantt branches) andObjectView'sgenerateViewSchema(calendar and gantt cases) emitcalendar: {…}/gantt: {…}instead of the flat keys. They emit the block only where the renderer's flat branch drew, so what a view shows is unchanged, with the one exception under Acceptance notes: a calendar oncestartDateFieldis declared; a gantt once both dates are, withtitleFieldfloored at'name'as the flat branch floored it.Renderers are unchanged.
getCalendarConfigandgetGanttConfigstill read the block first and fall back to the flat spelling, now typed on the hand-off type. READMEs of both plugins are corrected (they said the producers emit the flat spelling), and so are the explanatory clauses of the two@objectstack/specprescriptions that said the same (packages/spec/src/ui/component.zod.ts, rework r3).Tests
@object-ui/types: the pins that declared the flat keys now pin their absence on both published faces and the strict-face refusal (calendar-flat-color-allday-8466,gantt-flat-config-declared-keys,gantt-dependency-field-deprecated-alias,gantt-search-keys-10250,gantt-view-mode-declaredre-pointed togantt.viewMode,object-gantt-properties-bag-10859-b6,calendar-date-alias-refusal-8355).plugin-calendar:calendarUnionReads-8651pinsObjectCalendarComponentProps['schema']asObjectCalendarHandoffand the hand-off key census.plugin-gantt: newganttHandoffFlatFields-25923pins the hand-off as exactlyGanttConfig's keys plus the three, no overlap with the published interface, the renderer prop typed with it, and the alias's@deprecatedtag.plugin-list/plugin-view: the producer tests read the emitted block and red on any flat key coming back; new rows pin "no block without the axis" and the'name'floor.colorFieldtoObjectGanttSchemaandstartDateFieldtoObjectCalendarSchemaredscalendar-flat-color-allday-8466.test.ts(182),gantt-flat-config-declared-keys.test.ts(316)andzod-mirror-parity.test.ts(4474)undertsc -p tsconfig.test.json, each naming the key or schema.Acceptance notes
getCalendarConfig/getGanttConfigand the hand-off types with it. No producer in this tree writes the flat spelling any more; about 80 renderer tests still author flat nodes and would move to the block.ObjectGanttSchema.safeParse({ …, colorField: 5 })now passes.passthrough()), which is why the declaration readsyes (narrowing)rather than the order'sno (narrowing). The strict face and the spec still refuse them; the value check lives in the block (gantt.capacity: 'one'is refused atgantt.capacity).getGanttConfigparses aganttblock against the spec'sGanttConfigSchema(objectui#13459) and never validated the flat branch. app-shell relays a stored row'soptions.ganttunvalidated (storedLegacyOptions). So under main's write door, a pre-door stored row whoseoptions.ganttcarries a spec-refused value (e.g.viewMode: 'hour') now lands ongantt-invalid-configinstead of drawing. The producers emit the block unconditionally and never a flat key; such a row is converted at the store (ADR-0087), not tolerated at a consumer. The population is unmeasured; work item 3 (the stored-row census) on the card is where it gets counted. The prose inListView.tsx, plugin-viewObjectView.tsx,ObjectGantt.tsxand the changeset (including its ADR-0087 marker, which used to say "nothing that drew before stops drawing") says this.dateField/endFieldtombstones now prescribecalendar.startDateField/calendar.endDateField(rework r1; this round made the old prescription false). Pinned incalendar-date-alias-refusal-8355andcalendarUnionReads-8651, with a control that the bare canonical is never prescribed.ui/packages/app-shell/src/views/ObjectView.tsxis not touched.@objectstack/specprescription prose (rework r3): the explanatory clauses ofOBJECT_CALENDAR_FLAT_FIELD_GUIDANCEandOBJECT_GANTT_FLAT_CONFIG_GUIDANCEinpackages/spec/src/ui/component.zod.tssaidObjectView/ListViewemit, or flatten into, the flat spelling. This PR made that false. They now say the producers hand the binding off in thecalendar/ganttblock, and that the flat spelling is only a stored-document fallback the renderer still reads, not authorable. Nothing else in the prescriptions changes, including the "Write this as a key of the … config object instead" sentence. The changeset now carries'@objectstack/spec': minor. The grade is minor becausecheck-changeset-no-majorgrades only the root workspace and the narrowing lives in the ui workspace (@object-ui/types), while the spec diff itself is prescription prose. Before editing, I searched for the old wording and found it nowhere else inpackages/spectests,json-schema/,content/docs/orsdui.manifest.json(only in historical CHANGELOGs), so nothing needed regenerating. Rework r4 also rewrote the JSDoc around those two guidance sets, plus the docblock of the object-gantt props schema. It used to say the producers "emit on their runtime handoff", "EMIT when they flattenoptions.gantt", call the flat branch the "HOT path", say thatObjectGanttSchema"declares the whole flat face", and call the flat keys "the flatten product". It now says the producers hand off the block, the flat spelling is a stored-document fallback, and the flat keys live on the package-local hand-off types. A sweep of this PR's ui files fixed six more comments of the same kind:ObjectCalendar.tsx,ObjectGantt.tsx,objectql.ts,objectql.zod.ts,calendar-flat-color-allday-8466andobject-gantt-properties-bag-10859-b6. These are comments only; no string, key, example or accept set moved.Verification
ui vitest (under os-verify-lock)
packages/types packages/plugin-calendar packages/plugin-gantt: Test Files 557, Tests 11881 passed / 209 skipped after the strict-face row fix (first run: 5 failed in one file, fixed).packages/plugin-list packages/plugin-view: first run 32 failed (the producer tests reading flat keys); after re-pointing, the 12 failing files plus the types file: Test Files 13/13, Tests 214/214.Final head (
254db190, after merging main):pnpm --dir ui exec vitest run packages/types packages/plugin-calendar packages/plugin-gantt packages/plugin-list packages/plugin-view: VERDICT command-exit 0, Test Files 797 passed / 1 skipped, Tests 14252 passed / 209 skipped.Rework r2 head (
4676da49): the same five-package command: VERDICT command-exit 0, Test Files 797 passed / 1 skipped, Tests 14252 passed / 209 skipped.type-checkandlinton plugin-list / plugin-view / plugin-gantt: exit 0.Type-check
pnpm --dir ui --filter '...@object-ui/types' type-check: every importer Done after building the missing dists (the first two runs failed only on unbuilt@object-ui/auth,layout,plugin-designer,plugin-chatbot,plugin-editordists; none of the 561 errors named a calendar or gantt key).@object-ui/typestsc -p tsconfig.test.json: exit 0.@objectstack/spec (rework r3)
Under the lock:
pnpm --filter '@objectstack/spec^...' --filter @objectstack/spec build && pnpm --filter @objectstack/spec testgave VERDICT command-exit 0, Test Files 728 passed, Tests 22040 passed / 1 todo.Rework r4 head (
eba20284): same command, VERDICT command-exit 0, Test Files 728 passed, Tests 22040 passed / 1 todo.Dispatch gates
node scripts/pm/dispatch-gates.mjs --commandson the merged head: 35 commands, all exit 0 (check:type-check-debtfirst exited 3 while the dogfood run held the verify lock, then 0 on re-run).--ran: 35 accounted, 0 NOT-MEASURED.check-sdui-manifestfirst exited 1 (registry sources moved);node scripts/gen-sdui-manifest-node.mjsregenerated it. Main has since retired the per-package records (ci(sdui): retire the per-package SDUI manifest records; CI's regeneration holds freshness (#26137 PR B) #26367), so nothing of that lands here.Rework r2 head (
4676da49): 35 commands, all exit 0;--ran: 35 run, 0 NOT-MEASURED.Rework r3 head (
d5d316b1, after merging origin/main00a4593a):--commandsderived 82 commands. The first pass gave 81 exit 0 and 1 exit 3:node scripts/check-plugin-teardown-shape.mjs --self-test, whose positive-control commit621a4876was missing from the shallow clone. After fetching that commit, the re-run exited 0.--ran: 82 run, 0 NOT-MEASURED.Rework r4 head (
eba20284): 82 commands, all exit 0;--ran: 82 run, 0 NOT-MEASURED.Dogfood battery (title carries `!`)
pnpm --filter '@objectstack/dogfood^...' build && pnpm --filter @objectstack/dogfood test: VERDICT command-exit 1, Test Files 297 passed / 2 failed / 3 skipped, Tests 2521 passed / 10 failed / 18 skipped.test/authz-conformance.test.ts([finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 ledger-figure pin, 6 rows) andtest/authz-probe-blind-spot.test.ts(authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260 census ofpackages/rest/src/rest-server.tsandrest-route-ledger.ts, e.g.expected 70 to be 69, 4 rows). This diff touches nopackages/rest, no dogfood input and no@objectstack/*package.origin/main9a0108cdthe two files read 108/108 passed. On the branch (head89e13213, baseb33dd25b) they read 10 failed / 98 passed, because the base predates test(dogfood): re-measure the authz census for the approval record-lock read #26406's census re-measure. CI's Dogfood Regression Gate on the merge ref is green.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGufzetP4CSWdmfU9t887J