Repository navigation
spec: ComponentPropsMap['object-kanban'] declares limit (row cap) — four objectui faces implement and teach it, the strict props map refuses it by name (spec half of objectui#8172) #16503
Description
Activity
- addedenhancementNew feature or requestNew feature or requestpriority:p2Medium: important, M3Medium: important, M3
on Sep 7, 2026 Claim:
- session:
session_01T6HeZvT9wdSJD1ZxJb5Eno(PM dispatch,domain:specexecution seat) - branch:
claude/issue-16503-object-kanban-limit-prop - dispatched: 2026-09-07T08:40Z
The dev inherits this claim and the assignee. ⛔ It posts no second
Claim:, and never writes the assignee field.
Why this card is being claimed now, after I passed it over
I read this card at ~07:45Z and deliberately did not claim it, on one stated ground only: it is
Clause-②: yes,CONTRACT_REVIEW_TIERisclaude-fable-5-1, that tier had been exhausted, and I would not stack a second PR that could not clear review while a cheaper landable card existed.That constraint is lifted. Maintainer directive, 2026-09-07, verbatim: 「你有fable,可以优先派fable」 — fable is available and is now the preferred tier. Concurrency was also raised 3 → 5 in the same instruction.
⇒ ⛔ Nothing about this card changed; my constraint did. Recording it so the gap between filing (05:11Z) and claim is not read as a judgement on the card's merit.
Serial constraint — checked, and one adjacency worth naming
packages/spec/src/ui/**(the props map) is named by no in-flight claim.⚠️ Two in-flight PRs regenerate generated corpus, so know where they sit before you regenerate:api-surface/records a name declared as BOTH a const and a type under(type)only — deleting the value half of any of 132 such exports is invisible tocheck:api-surface#15919's repair rewrites everyapi-surface/**shard (+134 rows, pure insertion). Adding a key to an existing props map adds no export, so your change should touchauthorable-surface/, notapi-surface/— ⛔ if you find yourself moving anapi-surfaceshard, stop and report, because that is a collision.- spec: define the confirmation contract behind
action.ai.requiresConfirmation#16531 holdspackages/spec/src/contracts/ai-service.ts+ai/tool.zod.ts+ the error-code ledger. Different files.
Generated by Claude Code
- session:
os-dev-report
{ "issue": 16503, "status": "done", "branch": "claude/issue-16503-object-kanban-limit-prop", "pr": "https://github.com/objectstack-ai/objectstack/pull/16562", "premise_still_valid": true, "summary": "Declared `limit: z.number().int().positive().optional()` on `ComponentPropsMap['object-kanban']` (packages/spec/src/ui/component.zod.ts) with the card's describe plus the renderer's precedence sentence; four pin tests (accept `{ objectName: 'x', limit: 250 }` carrying the value through, refuse `bogusProp` with `unrecognized_keys: ['bogusProp']`, refuse 0 / -1 / 1.5 / '250' at the VALUE, describe names `$top`); minor `@objectstack/spec` changeset; regenerated `authorable-surface/ui.json` (+ `ui/ObjectKanbanProps:limit`) and `content/docs/references/ui/component.mdx` (+1 row) — no `api-surface` shard moved, so no collision with PR #15919's repair or PR #16531's files. The card's open judgement (`pagination.pageSize` as the carrier) was decided for the default `limit` and NOT proposed as a change: at the pin, `ElementDataSourceGate.tsx:229-241` lowers a bound view's `pagination.pageSize` INTO the key the block's mapping names, and kanban's mapping names `limit`; the board has no `pagination` read point, so that spelling would be accepted-and-dropped. Premise re-measured at `.objectui-sha` a472b07167a39e55491109e864bb5a54027dcfbd: ObjectKanban.tsx:264 `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` (100), index.tsx:395-398 `limit: 'limit'`, plugin-kanban.mdx:108,153-172 — one spelling correction to the card: the declaring type at the pin is `KanbanSchema` (plugin-kanban/src/types.ts:134), not `@object-ui/types`' `ObjectKanbanSchema`, which carries no `limit` there; four faces still agree, ruling substance unchanged. Draft PR #16562 carries `Fixes #16503`, a standalone `Clause-②: yes` line and `needs:contract-review` on both carriers (read back — PR: documentation, size/m, tests, tooling, needs:contract-review, protocol:ui; card: enhancement, priority:p2, pm:dispatched, domain:spec, needs:contract-review); objectui#8172 notified by comment 5568725356, not edited. Assignee never written, no second Claim; worktree removed after the PR opened; PR left draft — ready flip, auto-merge and queueing are the PM's after the at-tier review.", "tests": "All on fb654377e2 (final commit; tree unchanged after). `vitest run src/ui/component.test.ts`: 'Test Files 1 passed (1) / Tests 251 passed (251)'; `--reporter=verbose -t 16503`: 4 of 4 pass. Reverse verification (committed first): component.zod.ts reverted to BASE f48f3f1b21 (blob a549b824 equals the BASE blob, differs from HEAD 3d939c5e), same file: 'Tests 3 failed | 1 passed | 247 skipped' — accept, value and describe pins red, bogusProp control green; restored via `git checkout HEAD --`, blob back to 3d939c5e, `git diff HEAD` empty. Ablation of the checked-in baseline (no rebuild, since a spec build regenerates authorable-surface/): `ui/ObjectKanbanProps:limit` row removed from authorable-surface/ui.json (anchor count 1 to 0, blob eb3c99d7 differs from HEAD 1b290888), `check:authorable-surface` exit 1: 'authorable-surface/ is out of date (1 key(s) not recorded). + ui/ObjectKanbanProps:limit'; restored, blob back to 1b290888, anchor 1; trap-protected script, final `git status --porcelain` empty. Build under os-verify-lock (slot issue-16503): `pnpm --filter @objectstack/spec build && check:generated` gave 'VERDICT command-exit 1' naming exactly one stale artifact (content/docs/references/**); `gen:docs` 'Generated 228 files'; `check:docs` '228 generated files in sync'; `check:api-surface` 'public API surface + factory signatures unchanged'; `check:authorable-surface` green. Footprint: tracked 2 files moved (of a 317-file tracked generated corpus); gitignored packages/spec/json-schema/ 1576 files rewritten, 2 carrying the key. `pnpm --filter @objectstack/spec typecheck` exit 0 (check:test-typecheck OK). Narrowed spec tests under the lock — the 11 of 425 spec test files naming ComponentPropsMap / object-kanban / component.zod / snapshots: 'Test Files 11 passed (11) / Tests 732 passed (732)'. Consumer: `pnpm --filter @objectstack/lint test` 'Test Files 100 passed (100) / Tests 3486 passed (3486)'. Gates: `dispatch-gates.mjs --ran` reconciliation '98 derived, 97 run, 1 UNRUN' — the unrun is check:react-declaration-parity (needs objectui's sdui.manifest.json; NOT MEASURED by construction). Green verdict lines: check:objectui-pin-citations '12 asserting objectui pin citation(s) match .objectui-sha (a472b0716)'; check:duration-unit-keys; check:skill-examples '257 prose examples type-check across 3 surface(s)' (after building the client-react closure); check:nul-bytes 'OK (scanned 8144 text file(s))'; check:cross-package-test-inputs; check:test-source-alias; check:docs-transcript-drift; check-adr-0087-registration 'adds no declared-breaking changeset'; check-empty-changeset; check-changeset-no-major; check:liveness; check:strictness-ledger; check:yaml-examples; and every other derived family including all --self-test variants, exit 0. NOT MEASURED (exit 3, prerequisite: full `pnpm build` closure): check:type-check-debt, check:dual-build-cjs-loads — CI's. NOT MEASURED (lock queue-timeout exit 99, twice, 9 min each): examples/app-showcase/test/my-work-visibility.test.ts — it names ComponentPropsMap only in a comment and no repo test asserts `limit` refused on object-kanban; declared narrowing, CI runs it. CI on the PR: in_progress at report time.", "mcp_calls": "12 — issue_read get_labels #16503; create_pull_request; issue_write labels #16503 (union); issue_read get_labels on the PR number (errored: GraphQL cannot resolve a PR as an Issue); issue_read get_labels #16503 read-back; pull_request_read get; add_issue_comment objectui#8172; issue_read get on the PR (labels); issue_write labels PR (union); issue_read get PR read-back; add_issue_comment (this report); issue_read get_comments read-back. REST was 403 this session (session gate closed); card and comments were read from git and the public issue-page payload; no search_issues needed — nothing out of scope to file.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
Filed by the director seat under the objectui#8172 ruling (decision batch #68, 2026-09-07, option A — the contract declares the capability that is already implemented, documented and in use). objectui#8172 is
pm:blockedon this card.Measured (objectui#8172,
@objectstack/spec17.2.0)plugin-kanbanreadsschema.limitas the top-level$top(deliberately wired by objectui#4025),OBJECT_KANBAN_DATA_SOURCEmapslimit: 'limit',ObjectKanbanSchema(@object-ui/types) declareslimit?: number, andcontent/docs/plugins/plugin-kanban.mdxteaches it with a typed snippet (limit: 250) plus a Properties-table row.ComponentPropsMap['object-kanban']is a strict object (objectName,groupBy,columns,filter,data,cardTitle,titleField,cardFields,swimlaneField,grouping,quickAdd,coverImageField,conditionalFormatting);safeParse({ objectName: 'x', limit: 250 })→unrecognized_keys: ['limit'], same verdict as thebogusPropcontrol.⇒ An author following the published docs writes a node the platform's save gate refuses. Declaring
limitin objectui's registration alone is wrong (it would publish surface the save gate cannot store and breakcheck:react-blocks-declaration-parity).Scope
limit: z.number().int().positive().optional().describe('Maximum number of records loaded onto the board (row cap); lowered to the query's top-level $top')toobject-kanban's props in the spec.pagination.pageSize, propose that on this card before implementing — the ruling is that the four faces and the contract must agree, not which spelling; but the default is to declarelimit, since it ships and is taught.needs:contract-review; changeset (minor); api-surface / authorable-surface baselines regenerated.Acceptance
safeParse({ objectName: 'x', limit: 250 })succeeds;bogusPropstill refusedRefs objectui#8172, objectui#4025, objectstack#15449.