Repository navigation
feat(types,plugin-kanban)!: retire ObjectKanbanSchema.onQuickAdd; the object-kanban path renders an internal board that takes the quick-add pair as props (objectui#11234) - #11269
Conversation
…ect-kanban renders an internal board (objectui#11234) `ObjectKanban` now renders the internal `KanbanBoardCore`, which takes the Quick Add pair only as explicit props, and supplies neither half. The exported `KanbanRenderer` renders the same board and passes `schema.quickAdd` / `schema.onQuickAdd` unchanged, the host pair ruling B keeps. With no read of the key left on the `object-kanban` path, `ObjectKanbanSchema.onQuickAdd` becomes `?: never` on the TypeScript face and `handlerKeyRefusal(..., 'retired', ...)` on the zod mirror. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
…anban; move its ledger rows (objectui#11234) - new `object-kanban-on-quick-add-retired-11234.test.ts`: refused by name on the JSON face, `never` on the TS face, and RETIRED against the lit `onCardClick` runtime slot on the same arm; - objectui#6124 ledger: the row moves from RUNTIME_SLOT to RETIRED (60 + 22); - zod-mirror-parity: the key leaves the `ObjectKanbanSchema` drift entry (86 keys); - objectui#7340 census: 29 retired members, `onQuickAdd` unambiguously retired; - objectui#7804 / #7664: the object-kanban board now receives no Quick Add pair, with `onCardClick` as the lit control; the read sites split across `KanbanRenderer` and the internal `KanbanBoardCore`; - check-handler-key-read-sites: `onQuickAdd` leaves the object-kanban census and its arm reads `retired`. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
…re-point two source-reading pins (objectui#11234) The two docs passages now say `onQuickAdd` is retired on `object-kanban`, with the pair on `KanbanRenderer` for a React host. The objectui#9357 arity pin quotes the hand-off to `KanbanBoardCore` as the `index.tsx` hop, and the objectui#8932 firing control finds the live board's lazy import in `KanbanBoardCore.tsx`. One changeset. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
…al board (objectui#11234) The objectui#8801 pin quoted `KanbanRenderer`'s signature as the component the `object-kanban` schema spread stops at. `ObjectKanban` renders the internal `KanbanBoardCore` now, so the pin quotes that render and that component's signature. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec 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
|
…n object-kanban too (objectui#11234) The pending objectui#8285 changeset closed with an "Unchanged" note saying `ObjectKanbanSchema.onQuickAdd` stays a runtime slot. This PR retires it in the same release, so that note would ship false. It now says the key is retired on `object-kanban` by objectui#11234 and the Quick Add pair on `KanbanRenderer` is unchanged. The rest of that file, frontmatter included, is byte-identical. This change's own changeset drops its "supersedes" note, which the amendment made false. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec 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
|
…untime slot on object-kanban (objectui#11234) The pending objectui#7804 entry said `onCardClick` and `onQuickAdd` are both declared as runtime slots, and the pending objectui#8285 html-diagnostic entry said `onQuickAdd` is a runtime slot. This PR retires `onQuickAdd` on `object-kanban` in the same release, so both sentences would ship false. Each false sentence is amended; the rest of each file, frontmatter included, is byte-identical. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec 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: Inputs: card objectui#11234 (body and its 4 comments: claim Gate verdicts on the head (check-runs, ① Derived judgments
Public-surface summary: ② Semver level
③ Boundary flags
Deviations (report
Follow-up reports Noted-not-filed observations:
Implemented-by: VERDICT: PASS Generated by Claude Code |
…, mirror two chatbot keys, file eighteen runtime slots by name (objectui#6152, round 4) (objectstack-ai#11285) Refs objectstack-ai#6152 Clause-②: yes (narrowing). The two mirrors widen `@object-ui/types/zod` and the strict authoring face to keys the TypeScript face already invited and the renderers read (`requestBody`, `floatingConfig`). The four retirements (`label.content`, `report.chartConfig`, `report.reportType`, `detail-view.autoDiscoverRelated`) narrow both faces at once, under the startup no-gradualism rule. It is priced in `.changeset/6152-unmirrored-round4.md` as `minor`, with the break stated. Round 4 of objectui#6152, dispatched under claim `5919877490` (the `domain:devx` seat 2, session `session_01TdiauJaVCHuj45EzZGUxHh`, on the maintainer's direct order). The rulings are the seat review `5914490915`: Q1 B, Q2 A, Q3 B. ⛔ This is a draft from a dispatched dev: do not mark it ready and do not enable auto-merge. The card stays open, because `ObjectGridSchema`, the spec-derived pairs and three `DataTableSchema` keys (below) are not this round's. ## What changed 1. **Q1 B: `LabelSchema.content` is retired.** It is `?: never` on `form.ts` and a `retirementTombstone` on `form.zod.ts` that names the kept spellings `text` and `label`. The `label` renderer drops its third read limb (`schema.text || schema.label`). Re-measured: 0 documents author it (JSON, Markdown JSON fences and typed literals); its only author was a test in `form-renderers.test.tsx`, which now pins the refusal. Which of `text` / `label` is canonical is not decided here. 2. **Q2 A: `DetailViewSchema` `activities`, `comments`, `history` and `recordNavigation` go to `RuntimeOnlyDeclared` by name.** Each has a row with its reason on `RuntimeOnlyNamedAllowList`, in round 3's shape. They carry host-fetched runtime data, and `recordNavigation.onNavigate` is a required function. 3. **Q3 B, under objectui#7654 ruling B: `displayMode` keeps its TypeScript-only refusal.** It gets no zod arm, because stored designer documents carry `displayMode: 'floating'` (pinned by `chatbot-display-mode-retired.test.ts`). The ledger entries no longer call the mirror half "owed"; the key stays listed by decision. Separately, after a reader census for each: - `ChatbotSchema.requestBody` is mirrored through the shared pick. All three chatbot registrations read it (`body: schema.requestBody`). - `ChatbotFloatingSchema.floatingConfig` is mirrored through a module-private restatement of `FloatingChatbotConfig`. That restatement judges the six members `FloatingChatbot` destructures, and carries the `triggerIcon` tombstone's runtime half that the objectui#7654 tripwire asked for. 4. **The three zero-read candidates are retired on both faces.** They are `ReportComponentSchema.chartConfig`, `ReportComponentSchema.reportType` and `DetailViewSchema.autoDiscoverRelated`, each `?: never` plus a `retirementTombstone`. `reportType`'s one in-code producer, `specReportToPresentation` in `spec-report.ts`, no longer writes it, and `LegacyReportPresentationLike` no longer declares it. 5. **`DataTableSchema`: 14 of 17 keys go to `RuntimeOnlyDeclared` by name.** They are produced only in code, by `ObjectGrid`'s in-code `data-table` node or `RelatedList`'s, and authored by no document. Three keys fit none of the classes, so the round stopped at them (see "Stopped" below). 6. **The pagination corpus fix, carried from round 3.** `components-basic-pagination/with-item-count.json` no longer authors `pageSize` / `totalItems`, which neither face declares and nothing reads. The plaintext interface block on `content/docs/components/basic/pagination.mdx` stops listing them, and its section is retitled from "With Page Size" to "On a Later Page". 7. **Changesets.** One new: `.changeset/6152-unmirrored-round4.md` (`@object-ui/types` minor, `@object-ui/components` minor, with the break stated). Four dated, append-only corrections were added, each 2 lines with frontmatter unchanged: `6639-objectgrid-title-mirrored.md` (the stale "97 + 1 + 23" sentence), `7654-floating-chatbot-trigger-icon-tombstone.md`, `7655-chatbot-registration-authoring-faces.md` and `9447-detail-view-handler-key-refusal.md`. Every other pending changeset was re-read after the merges, including the 8 that landed since the base, and none is made false by this round. ## Ledger totals, before and after These are read by the file's own pins (`objectui#7279` derives every figure) and re-counted with the TypeScript parser on the final head. | ledger | before (`origin/main` `e420df3`) | after (`2cc4ab9`) | | --- | --- | --- | | `UnmirroredDeclared` | 9 entries / 44 keys: 3 / 14 spec-derived, 6 / 30 local | **6 / 20**: 3 / 14 spec-derived, 3 / 6 local | | `RuntimeOnlyDeclared` | 4 / 9 | **4 / 27** | | `RuntimeOnlyNamedAllowList` | 1 entry / 2 rows | 3 / 20 | | cross-ledger | 2 of the 4 are in `UnmirroredDeclared`; union 11 = 9 + 2 | **1 of the 4**; union **9** = 6 + 3 | | `KnownDrift` | 49 / 86 | 49 / 86, unchanged. This round does not edit its total line; PR objectstack-ai#11269's 87 to 86 edit is kept as merged. | | `WiderThanDeclared`, `MirroredUndeclared` | 3 / 3, 2 / 2 | unchanged | The 24 keys that left `UnmirroredDeclared` moved by three routes, which must not be added up as one repair: 2 were mirrored, 4 were retired, and 18 were reclassified by name. The reclassification is one move seen from both ledgers: it is not new debt, and it mirrors nothing. ## Per-key table | pair · key | measured (type-checker read census over 5548 sources; authored census over tracked JSON, Markdown JSON fences and `type` literals) | route | | --- | --- | --- | | `label` · `content` | 1 read (the third limb in `label.tsx`), 0 documents (1 test) | retired on both faces; the read is dropped | | `report` · `chartConfig` | 0 typed reads. The untyped `widget?.chartConfig` hits are plugin-dashboard's `DatasetWidget` (`widget: any`, a dashboard widget), which plugin-report never imports. 0 documents | retired on both faces | | `report` · `reportType` | 0 reads; one in-code producer (`specReportToPresentation`); 0 documents | retired on both faces; the producer write is removed | | `detail-view` · `autoDiscoverRelated` | 0 reads (typed or untyped), 0 documents | retired on both faces | | `chatbot` · `requestBody` | 3 reads (all three chatbot registrations) | mirrored (shared pick) | | `chatbot-floating` · `floatingConfig` | 1 read (`floatingConfig={schema.floatingConfig}`); 6 of 7 `FloatingChatbotConfig` members read, and `triggerIcon` 0 | mirrored, with a `FloatingChatbotConfig` restatement | | `chatbot`, `chatbot-floating` · `displayMode` | 0 reads; stored documents carry it | unchanged by ruling (TypeScript-only refusal) | | `detail-view` · `activities` (7 reads), `comments` (4), `history` (7) | host-fetched rows; 0 documents | `RuntimeOnlyDeclared` by name | | `detail-view` · `recordNavigation` | 11 reads; its value carries a required function | `RuntimeOnlyDeclared` by name | | `data-table` · `disableInnerScroll`, `manualPagination`, `manualSearch`, `manualSorting`, `page`, `rowActionDefs`, `rowClassName`, `rowCount`, `rowStyle`, `search`, `selectionResetKey`, `showAddRow`, `showSelectionCount`, `sort` | read by `data-table`; produced only in code (`ObjectGrid`, `RelatedList`); 0 docs and 0 catalog documents | `RuntimeOnlyDeclared` by name; the reasons are on the allow-list | | `data-table` · `editable`, `singleClickEdit` | read; produced in code by `ObjectGrid`; 0 documents, but `data-table.mdx` lists both and teaches `editable: true` | **stopped**, ruling needed | | `data-table` · `selectionStyle` | read; 0 producers and 0 documents (0 hits in objectstack too) | **stopped**, ruling needed | ## Runtime probe for the three zero-read retirements AGENTS.md requires more than a source census, because leftover keys reach a renderer as spread props. So the probe used the real `SchemaRenderer` and the real registry, and varied only the key. It was a one-off: the files were deleted afterwards and `git diff HEAD` is empty. - `report`: the DOM is identical with and without `chartConfig` plus `reportType` (797 = 797 characters, byte-equal). Lit control: changing `title` changes the DOM (805). - `detail-view`: the DOM is identical with and without `autoDiscoverRelated: true`, after normalising React's `useId` tokens. The only raw difference was `radix-_r_5_` against `radix-_r_d_`. The data-source and `fetch` call log is identical: `getObjectSchema(account)` and two `security/explain` fetches. Lit control: changing `title` changes the DOM (5943 against 5951). ## Ablations The predictions were written at `4c272dc` before any run, and every leg was restored with the blob equal to `HEAD` and `git diff HEAD` empty. - **A1:** plant a `LabelSchema` literal carrying `content` into `label.tsx`. Components `tsc --noEmit` exits 2 with exactly one TS2322 there (`'string' is not assignable to type 'undefined'`), as predicted. This red direction also shows the consumer read the rebuilt `.d.ts`. - **A2:** restore the four `zod/*.zod.ts` files to base `f61dab1`. `unmirrored-declared-round4-6152.test.ts` reads `27 failed | 6 passed (33)`, exactly as predicted, and `tsc -p tsconfig.test.json` exits 2 with its only error in the ledger reconciliation of `zod-mirror-parity.test.ts`. - **A3:** rename the allow-list row `rowCount` to `rowCountRenamed`. `tsc -p tsconfig.test.json` exits 2 with exactly two TS2344, at the two allow-list pins, as predicted. ## Verification on the final head `2cc4ab9` This round resumed after two container restarts, so every run below was redone on `2cc4ab9`. That head carries `origin/main` `e420df3`, merged twice (never rebased): once through PR objectstack-ai#11275, and before that through PRs objectstack-ai#11267, objectstack-ai#11268, objectstack-ai#11269, objectstack-ai#11271, objectstack-ai#11273 and objectstack-ai#11274. Each run went through the shared verify lock with at most 2 workers. - `@object-ui/types`: `type-check` (the `--noEmit`, `tsconfig.examples.json` and `tsconfig.test.json` legs) exits 0; `vitest run packages/types/` gives 299 files and 7498 tests passed; `build` exits 0 (138 emitted files verified). - Consumers, from the type-checker census: `type-check` exits 0 with 0 TS errors for `components`, `plugin-report`, `plugin-detail` and `plugin-chatbot`. `vitest run packages/plugin-report/ packages/plugin-chatbot/` plus `form-renderers.test.tsx` gives 78 files, 827 passed and 7 skipped. All 228 `plugin-detail` test files, run in two halves, give 227 files passed plus 1 skipped, and 2264 tests passed plus 8 skipped. - Zod-face consumers: `vitest run examples/schema-catalog/ packages/cli/` plus the 17 app-shell files that import `@object-ui/types/zod` or sit in `metadata-admin/previews/__tests__` give 77 files and 2741 tests passed. - Gates, all exit 0: `check:changeset-claims`, `check:pending-changeset-literals`, `check-changeset-presence` (16 source files of 2 released packages, 1 changeset), `check-changeset-no-major`, `check-changeset-fixed`, `check-changeset-overwrite` (report-only; its 4 findings are the 4 dated appends above), `check:control-bytes` (9717 files), `check:doc-fences`, `check:doc-snippets` (697 of 697 blocks judged, 0 failed), `check:doc-examples`, `check:doc-types`, `check:doc-example-ids`, `check:doc-example-readers`, `check:skill-examples`, `check:handler-key-reads`, `check:component-surface-parity` (report-only), `check:designer-field-key-parity`, `check:element-data-source-declaration`, `check:new-line-citations` (0 new), `check:prompt-keys`, `check:readme-exports`, `check:spec-symbols`, `check:test-path-roots`, `check:unreferenced-sources` and `check-type-check-coverage`. `doc-snippets` and `doc-examples` ran after the scoped build their own `--build-filter` names (35 turbo tasks, all successful). - Lint, narrowed: `eslint --no-inline-config --format json` over the 16 lintable changed files gives 0 errors. All 16 were judged and 0 were ignored, a population read from eslint's own output. The 39 warnings are pre-existing `no-explicit-any`, and the diff adds no explicit `any`. `eslint.config.js` declares no `parserOptions.project` or `projectService`, and no custom rule in `eslint-rules/` reads the disk, so this diff cannot move any untouched file's verdict. The repo-wide `pnpm lint` is CI's. - Governed surface: `check-governed-queue-guard.mjs --test` over the 23 paths reports NOT GOVERNED. - NOT MEASURED: - `check:sdui-registration-pins`: it needs a console build, and this diff changes no registration. - The full `pnpm test` farm and repo-wide lint: CI's. - `plugin-grid`: its code and tests are untouched. The 14 reclassified keys moved between two test ledgers and no declaration changed. ## Stopped (ruling needed; reported in the card report with options) - `DataTableSchema.editable` and `singleClickEdit`. `data-table` reads both and `ObjectGrid` sets both in code, while no document authors them. But `content/docs/components/complex/data-table.mdx` lists both in its interface block and teaches `editable: true`. Filing them runtime-only would contradict that page. Mirroring them would rest on no authored document, and, from the source, an authored `editable: true` stages cell edits locally and persists nothing without the `onRowSave` / `onCellChange` function slots. - `DataTableSchema.selectionStyle`. `data-table` reads it (`'always'` or `'hover'`), and nothing authors or produces it in either repository. - Noted, not narrowed: `ChatbotSchema.floatingConfig` has 0 reads on the `chatbot` node (only `chatbot-floating` reads it), which makes it an ADR-0049 narrowing candidate. The `chatbot` half of `floating-chatbot-trigger-icon-retired.test.ts` pins its absence as a tripwire. ## Parallel discipline PR objectstack-ai#11269 and PR objectstack-ai#11273 edited `zod-mirror-parity.test.ts` in disjoint hunks: the `KnownDrift` total line, the Kanban entry and one `EXCLUSIONS` row. Both merges were clean. This round's ledger edits stay in the `UnmirroredDeclared` / `RuntimeOnlyDeclared` / `RuntimeOnlyNamedAllowList` blocks, their prose totals and its own pairs' entries. Every prose total was reconciled to the measured count above. The diff does not touch `zod/objectql.zod.ts`, `zod/index.zod.ts`, `zod/nested-component-walk.ts`, `strict-authoring-face.ts`, `zod/README.md`, `field-types.ts`, the `DetailViewField` member, or `data-table.tsx` (read only). ## Acceptance notes - 23 files, under the ~25-file size guard, so no pair was cut. - Every pending changeset this round made false carries a dated append. The ones it leaves true were re-read: `7654-chatbot-display-mode-tombstone.md`, `6150-…`, `7804-…`, `6175-…`, `7722-…`, `7947-…` and `8072-…`. Session: `https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh` --- _Generated by [Claude Code](https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Fixes #11234
Clause-②: no (narrowing)
Retires
ObjectKanbanSchema.onQuickAddonobject-kanbanon both faces, completing ruling B of the director seat's decision batch #91 (5583979207, recorded on objectui#8285): the object-bound board does not grow an inline record-creation write path, and the Quick Add pair stays with a React host. Direction is option A of the PR objectui#11231 dev, as adopted in the card; no inline creation path is added, andKanbanRenderer's host pair is unchanged.What changed
@object-ui/types:ObjectKanbanSchema.onQuickAddis?: neveron the TypeScript face (objectql.ts), andhandlerKeyRefusal('onQuickAdd', 'retired', 'Quick Add handler')on the zod mirror (zod/objectql.zod.ts). The JSON face still refuses the key by name with codecustom; the guidance now says RETIRED instead of RUNTIME SLOT.@object-ui/plugin-kanban:src/KanbanBoardCore.tsxholds the board body that used to live inKanbanRenderer: the bucketing memo, the lazyKanbanImpl, and the Suspense fallback. It takes the Quick Add pair ONLY as explicit props (quickAdd,onQuickAdd), and itsschematype isKanbanRendererProps['schema']with those two keys omitted, so aschema.onQuickAddread written into it fails type-check. It is not re-exported from theindex.tsxbarrel.KanbanRenderer(public) now rendersKanbanBoardCoreand passesschema.quickAdd/schema.onQuickAdd. Its props interface is byte-identical, and so is what a host gets.ObjectKanbanrendersKanbanBoardCoreand passes neither half. The oldquickAdd: undefinedline oneffectiveSchemais removed, because nothing on this path readsschema.quickAddany more; the comment in its place says where the cut now is.check:handler-key-readsrefuses aretireddisposition while a renderer reachable from the registration reads the key off the document. Theobject-kanbanpath reachedKanbanRenderer'sschema.onQuickAddread. After this change, the gate's census forobject-kanbanholds one row,onCardClick [runtime-slot], read inKanbanBoardCore.tsx.content/docs/plugins/plugin-kanban.mdx(the handler-key paragraph and the "Quick Add is a React-host capability" section) andcontent/docs/api/schema-reference.md(theObjectKanbanSchemahandler-keys callout, and one clause of thequickAddcallout)..changeset/11234-object-kanban-onquickadd-retired.md, withminoron@object-ui/types(a narrowing, breaking semantics stated in the body) andpatchon@object-ui/plugin-kanban(no public props moved). Three pending entries that this release would otherwise ship with a false sentence are amended, one sentence each, with every other byte and the frontmatter unchanged:8285-object-kanban-quick-add-retired.md(its closing note saidonQuickAddstays a runtime slot),7804-object-kanban-handler-keys-judged.md(it saidonCardClickandonQuickAddare both runtime slots) and8285-kanban-quickadd-html-diagnostic.md(it saidonQuickAddis a runtime slot).Pins
never: newpackages/types/src/__tests__/object-kanban-on-quick-add-retired-11234.test.ts.customat pathonQuickAdd, for an action object and for a live function. The.describe()text is the parse message. A near-miss key is kept. The CLI union refuses a whole node carrying the key.onQuickAddagainstonCardClickon the same arm and helper, which still reads RUNTIME SLOT. ThatonCardClickreading is the lit control.Equaltoundefined, notany, not callable, and an@ts-expect-erroron a literal that writes the key. The sibling slotonCardClickis still callable.quickAddRetiredNotForwarded-8285.test.tsxrow 2, unchanged.KanbanRendererwithquickAdd: trueplus a function draws one control per lane, and a submitted title reaches the host.object-kanbannode draws no Quick Add: the same file's row 1, unchanged, through the real registry and the real board. It was already green before this change, becausequickAddwas cut. The readings that discriminate ononQuickAdditself flip in two files, each withonCardClickas the lit control on the same render:handlerKeyDispositionsMeasured-7804.test.tsxsuite 2: the board receivesonQuickAdd: undefinedandquickAdd: undefined, while the authoredonCardClickruns once.kanban-handler-slots-7664.test.tsxsuite 1.Ledger rows moved with it:
RUNTIME_SLOTtoRETIRED, 61 + 21 becomes 60 + 22 with the total unchanged at 82, and the type blocks move the key fromKeepsFunctiontoRetiredIsNever;zod-mirror-parity:onQuickAddleaves theobjectql.zod.ts#ObjectKanbanSchemadrift entry, and the header key total goes 87 to 86 with its history sentence;objectql.ts2, andonQuickAddjoins the unambiguously retired names;KanbanBoardCoreis not published;check-handler-key-read-sites.test.ts:onQuickAddleaves theobject-kanbancensus, the arm readsretired, and theonCardClickrow's file isKanbanBoardCore.tsx.Three source-reading pins had to be re-pointed at the moved text:
index.tsxhop is now the hand-off toKanbanBoardCore;KanbanBoardCore.tsx;KanbanBoardCore's signature.Measured producers of
onQuickAddonobject-kanban: 0 in both reposonQuickAdd, excluding tests and markdown, number 7 at the final head. They areKanbanImpl.tsx(the board's props),index.tsx(the host face), the two declarations, one comment in the gate script,KanbanBoardCore.tsx(its internal prop pair), and one comment inObjectKanban.tsx. None writes the key onto anobject-kanbannode. Lit control on the same instrument: 7 non-test files write atype: 'object-kanban'node, and 2 JSON files inexamples/schema-catalogcarryobject-kanban. JSON/YAML files namingonQuickAdd: 0.origin/main4d0b9cd54(read-onlygit grep):onQuickAddappears only in docs, CHANGELOGs, comments and diagnostic message text (component.mdx, the sdui-parser interim diagnostic and its test, the spec CHANGELOG, aconversions/registry.tsnote).packages/spec/src/ui/component.zod.tshas 0 hits foronQuickAdd. Lit control on the same instrument:quickAddhits 17 files,component.zod.tsamong them.Verification
All runs from the worktree root, through
os-verify-lock, withNODE_OPTIONS=--max-old-space-size=4096. Pass counts are read from the vitest summary line, not from exit codes. Final head isb1e88910f. Its two commits overe2bf34b97are changeset text only, so the test and type-check runs below ate2bf34b97stand; the changeset gates were re-run atb1e88910f(last table row).pnpm exec vitest run packages/plugin-kanban/src/(verbose)611112e0ekanban-quick-add-8285, react 9357, scriptscheck-handler-key-read-sites611112e0epnpm exec vitest run packages/types/plus the 14 test files outside types/scripts that import plugin-kanban (console, schema-catalog, app-shell, cli, core, i18n, plugin-calendar, plugin-list, runner)e2bf34b97pnpm exec vitest run scripts/__tests__/(whole root suite, owed because docs were edited)e2bf34b97pnpm --filter @object-ui/types type-check(3 tsc projects; the test project lists 294 test files, the new pin among them)e2bf34b97pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-kanban^...' build(13 packages), thenpnpm --filter @object-ui/plugin-kanban type-checke2bf34b97error TS. The rebuiltpackages/types/dist/objectql.d.tscarriesonQuickAdd?: never, so the plugin read the new typingscheck:handler-key-readse2bf34b97check-changeset-presence,check-changeset-no-major,check:control-bytes,check:new-line-citationse2bf34b97check-i18n-call-site-keys,check-i18n-en-drift,check-i18n-dead-keys(thekanban.uncategorizedtranslation hook moved modules)e2bf34b97node scripts/markdown-test-inputs.mjs --audite2bf34b97pnpm exec eslint --format jsonover the 16 changed code filese2bf34b97check-governed-queue-guard --testover the 19 pathse2bf34b97check-changeset-presence,changeset:check,check:changeset-claims,check:pending-changeset-literals,check-governed-queue-guard --testover the 22 pathsb1e88910fDeclared narrowing: repo-wide
pnpm lintand the fullpnpm testfarm are left to CI. eslint's population is its ownfiles: ['**/*.{ts,tsx}']block. The file count, 16, is read from the JSON output.eslint.config.jsconfigures noprojectServiceand noparserOptions.project, so linting is not type-aware and this diff cannot move a verdict on an untouched file.Ablation: re-declare
onQuickAddas a runtime slot, one face at a timeRun on the committed head
e2bf34b97through objectstack'sscripts/ablation-replace.mjsin wrap mode, inside a script with its owntraprestore, under the lock. The predictions were written before the run.'retired'becomes'runtime-slot'inobjectql.zod.ts. The anchor went x1 to x0 and the blobc106c73cb1ecto6b9fc742c9d5. Vitest over the 11234 pin and the 6124 ledger read 2 failed, 341 passed. The two failures are exactly the predicted legs: the 11234 retired-disposition leg, and the 6124 "guidance wording distinguishes a runtime slot from a retired key" leg.onQuickAdd?: never;becomes the callable inobjectql.ts. The anchor went x1 to x0 and the blobdde43cddfea1toafedc0cab24b.tsc -p packages/types/tsconfig.test.jsonexited 2 with 5 errors:@ts-expect-errorbecame unused);RetiredIsNeverrow: TS2344;zod-mirror-parity's type-map ledger: TS2322, because the drift entry is owed again. This fifth error was not in the written prediction. It is the right direction, since the ledger answers to the faces.git diff HEADover both paths is 0 bytes, both blob hashes equal HEAD's, andgit status --porcelainhas 0 lines.Acceptance notes (observations; nothing filed)
onQuickAddis, or stays, a runtime slot onobject-kanban, which would ship false in the same release:8285-object-kanban-quick-add-retired.md,7804-object-kanban-handler-keys-judged.mdand8285-kanban-quickadd-html-diagnostic.md. Each false sentence is amended in this PR, and the rest of each file, frontmatter included, is byte-identical. The seat added the three files to the claim's file surface.RetiredIsNevertype block has noObjectKanbanSchema['onCardMove']row. That key'sneveris pinned by a source read in the 7804 suite 3 leg instead. Not added here.KanbanRenderer's lazy boundary", and several tests' pre-warm comments say their'../KanbanImpl'specifier matchesindex's. The lazy import now lives inKanbanBoardCore.tsx. It resolves to the same module, so the pre-warm imports still hit the cache. The comments are not swept; per AGENTS.md they get repaired when a change touches those files anyway. I fixed the ones on lines this change touched.handlerKeyRefusalwording (the node-type remedy). The practical remedy for this key, mountingKanbanRenderer, is carried by the TS docblock, the docs and the changeset, the same as foronCardMove.Clause-②: yes; the PM claim saysno (narrowing). This body copies the claim's line, as the dispatch order directs.Session:
https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec(a dispatchedos-devrun; branchclaude/issue-11234-kanban-onquickadd-retire).Generated by Claude Code