You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Migrated from objectstack-ai/objectstack#7147 under the file-at-destination ruling (objectstack-ai/objectstack#7167, maintainer 2026-08-10). Originally filed 2026-08-09T23:49:46Z. The full prior thread — including triage rulings and hold/restart conditions — remains on the source issue and MUST be read before acting on this card.
Dispatched by the repo:objectui PM seat (session session_01RnQd8iMMUwXQEV1crFmQiQ), branch claude/issue-4025-kanban-top-dead-key.
Adjudication. Fix per the prior PM triage on the source thread (objectstack#7147, 2026-08-10): move the kanban row cap from the dead options: { $top: 100 } nesting to a top-level $top, wired as schema.limit ?? 100 following the timeline shape from objectstack PR #4009; correct the object-kanbanlimit cell in content/docs/guide/data-source.md (the "— fixed window" claim is the sentence this card falsifies); the packages/fields/src/index.tsx:236 same-shape hit is adjudicated harmless (primary-key equality, ≤1 row) — verify and either leave or make the zero-cost top-level move, dev's call.
Mechanism assumptions (all re-verified on origin/main today): ObjectKanban.tsx:213 still carries options: { $top: 100 } with $filter at top level; no find consumer reads params.options (both adapter read points are top-level only); the kanban dataSource mapping deliberately omits limit on the strength of the now-falsified "fixed window" rationale.
Suggested route. Test asserts the widget's find call carries top-level $top (and honors schema.limit when set). Changeset: plugin-kanban patch — objectui has NO skip-changeset mechanism; run check-changeset-presence and comply with its verdict. The card's suggested mechanical defense line (lint/check for options as a find param key) is in scope only if it lands as a small check:* addition; otherwise file it as a follow-up finding rather than growing this PR.
Dev report for #4025 — draft PR #4735 is open on claude/issue-4025-kanban-top-dead-key @ b0fb625fd.
{
"issue": 4025,
"branch": "claude/issue-4025-kanban-top-dead-key",
"pr_number": 4735,
"pr": "https://github.com/objectstack-ai/objectui/pull/4735",
"head_sha": "b0fb625fd7f94b5e4ecde8c5012e7e263ef9203b",
"status": "done",
"premise_still_valid": true,
"summary": "The kanban row cap moved from the dead `options: { $top: 100 }` nesting to a top-level `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` (100), the shape PR #4009 used for object-timeline; `KanbanSchema` gains `limit?: number` and the block's ElementDataSourceMapping gains `limit: 'limit'`, so a bound view's `pagination.pageSize` (or the binding's own `limit`) now caps the board. `content/docs/guide/data-source.md`'s `object-kanban` limit cell no longer says '— fixed window' (it is now checked, with a paragraph recording what was actually wrong and why `sort` still reads '— no ordering'), and `content/docs/plugins/plugin-kanban.mdx` documents the board's `limit` and its distinction from a column's WIP `limit`. Behaviour change stated in the changeset and the PR body: a board that used to fetch unbounded now fetches 100 rows by default — the declared intent taking effect, but visible on objects with more than 100 matching records. ListView-hosted boards are unaffected (they receive records through the `data` prop and never run this fetch).",
"tests": "pnpm exec vitest run packages/plugin-kanban/ packages/fields/ --maxWorkers=2 -> 'Test Files 104 passed (104)', 'Tests 1493 passed (1493)'. New coverage: 4 assertions in packages/plugin-kanban/src/ObjectKanban.elementDataSource.test.tsx covering the default window, a block-authored `limit`, a bound view's pagination.pageSize (7) and a binding `limit` (3) overriding it; each also asserts `params.options` is undefined. Reverse verification (fix committed first, reverted with `git checkout origin/main -- ...`, restored from the branch): direction was RED as expected — 'Tests 4 failed | 4 passed (8)', each failure 'expected undefined to be 100 / 20 / 7 / 3', the four pre-existing tests in the file unaffected. No ablation/dogfood leg in this card, so no dist rebuild claim is made. All commands run from the repo root; the union above was run on b0fb625fd, the head of the branch and the only commit on it.",
"mechanism_assumptions_checked": [
"ObjectKanban.tsx still carried `options: { $top: 100 }` with `$filter` at the top level on origin/main (worktree base baa89a1ea, line 213) — CONFIRMED, premise intact.",
"No find consumer reads `params.options` — CONFIRMED: a repo-wide scan of packages/apps/examples for an `options` object containing $-prefixed keys returned exactly 2 live instances (plugin-kanban, fields) plus 4 prose mentions in comments/test headers; `convertQueryParams` (@object-ui/data-objectstack) and ApiDataSource both read `params.$top`.",
"The kanban ElementDataSourceMapping omitted `limit` on the now-falsified 'fixed window' rationale — CONFIRMED verbatim in packages/plugin-kanban/src/index.tsx; the mapping now carries `limit: 'limit'` and the comment states which of columns/sort/limit is mapped and why.",
"Timeline shape from PR #4009 (commit 523be4820) re-read before copying: `$top: schema.limit ?? DEFAULT_TIMELINE_LIMIT` + mapping `limit: 'limit'`. Followed, with one deliberate difference — the timeline also mapped `sort` because #4009 added an `$orderby` read site; the kanban has none, so `sort` stays unmapped.",
"packages/fields/src/index.tsx same-shape hit adjudicated harmless — VERIFIED independently: the branch runs only when the adapter exposes no `findOne`, and the filter is `{ id: value }` (primary-key equality, at most one row), so the cap cannot change the answer. Took the zero-cost top-level move anyway (dispatch left it to the dev).",
"objectui has no skip-changeset mechanism — CONFIRMED (no such label used, none applied); `node scripts/check-changeset-presence.mjs` reports '5 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'.",
"New default cap cannot regress ListView boards — CHECKED: ListView renders the generated `object-kanban` schema with a `data` prop, so `hasExternalData` is true and the internal fetch never runs. plugin-view's ObjectView passes no `limit` in baseProps.",
"`limit` needs no zod declaration in @object-ui/types — CHECKED: ObjectKanbanSchema there extends a passthrough BaseSchema and does not declare the long-standing `filter` either; left untouched rather than half-fixing that surface."
],
"gates": {
"package_tests": "pass — pnpm exec vitest run packages/plugin-kanban/ packages/fields/ --maxWorkers=2: 104/104 files, 1493/1493 tests",
"type_check": "pass — pnpm --workspace-concurrency=2 --filter @object-ui/plugin-kanban --filter @object-ui/fields run type-check (both 'Done'), after pnpm --filter '@object-ui/fields^...' --filter '@object-ui/plugin-kanban^...' run build",
"lint": "pass — 0 errors (103 pre-existing warnings, unchanged)",
"check-changeset-presence": "pass",
"check-changeset-no-major": "pass",
"check-control-bytes": "pass — 4249 tracked text files scanned",
"check-doc-links": "pass — links valid across 13 scan roots",
"ci": "in_progress — reported at draft-PR time per the dispatch contract; CI convergence not awaited"
},
"deviations": [
"Card item 4 (mechanical defence against `options` as a find-param key) NOT landed here — filed as #4734 instead. The dispatch allowed it only as a small check:* script addition; in this repo a new gate is script + pin test in scripts/__tests__ + a ci.yml step (or an eslint-rules/ rule + RuleTester test), and the choice between those two has real reach differences. The follow-up records the AST signature that needs no allowlist and notes the repo is at zero live instances after this PR — the cheapest moment to install it.",
"Beyond the literal dispatch text: added `limit: 'limit'` to OBJECT_KANBAN_DATA_SOURCE. Implied by item 1 rather than extra scope — the mapping's omission rationale was the very 'fixed window' claim this card falsifies, and #4009 mapped `limit` in the same PR that added the timeline's read site. Without it, a bound board's view page size would still be accepted and dropped.",
"Docs touched a second file beyond the one the dispatch named (content/docs/plugins/plugin-kanban.mdx): the board's `limit` is newly authorable and collides by name with a column's WIP `limit`, so the plugin page documents both — AGENTS.md #2 (docs-driven).",
"packages/fields hit taken rather than left (dispatch item 3, dev's call): stated in the PR body, changeset and commit message as a no-behaviour-change consistency move that leaves no live instance of the dead spelling in the repo."
],
"followups_filed": [
"filed as #4734: nothing mechanically catches OData query params nested under a dead `options` key in a find() call — unassigned, unlabeled for PM triage, with both candidate mechanisms (check:* AST script vs object-ui/* ESLint rule) costed"
],
"open_questions": [],
"out_of_scope_findings": []
}
Activity
yinlianghui commentedon Aug 15, 2026
Dispatched by the
repo:objectuiPM seat (sessionsession_01RnQd8iMMUwXQEV1crFmQiQ), branchclaude/issue-4025-kanban-top-dead-key.Adjudication. Fix per the prior PM triage on the source thread (objectstack#7147, 2026-08-10): move the kanban row cap from the dead
options: { $top: 100 }nesting to a top-level$top, wired asschema.limit ?? 100following the timeline shape from objectstack PR #4009; correct theobject-kanbanlimitcell incontent/docs/guide/data-source.md(the "— fixed window" claim is the sentence this card falsifies); thepackages/fields/src/index.tsx:236same-shape hit is adjudicated harmless (primary-key equality, ≤1 row) — verify and either leave or make the zero-cost top-level move, dev's call.Mechanism assumptions (all re-verified on
origin/maintoday):ObjectKanban.tsx:213still carriesoptions: { $top: 100 }with$filterat top level; nofindconsumer readsparams.options(both adapter read points are top-level only); the kanban dataSource mapping deliberately omitslimiton the strength of the now-falsified "fixed window" rationale.Suggested route. Test asserts the widget's
findcall carries top-level$top(and honorsschema.limitwhen set). Changeset:plugin-kanbanpatch — objectui has NO skip-changeset mechanism; runcheck-changeset-presenceand comply with its verdict. The card's suggested mechanical defense line (lint/check foroptionsas afindparam key) is in scope only if it lands as a smallcheck:*addition; otherwise file it as a follow-up finding rather than growing this PR.Generated by Claude Code
yinlianghui commentedon Aug 15, 2026
Dev report for #4025 — draft PR #4735 is open on
claude/issue-4025-kanban-top-dead-key@b0fb625fd.{ "issue": 4025, "branch": "claude/issue-4025-kanban-top-dead-key", "pr_number": 4735, "pr": "https://github.com/objectstack-ai/objectui/pull/4735", "head_sha": "b0fb625fd7f94b5e4ecde8c5012e7e263ef9203b", "status": "done", "premise_still_valid": true, "summary": "The kanban row cap moved from the dead `options: { $top: 100 }` nesting to a top-level `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` (100), the shape PR #4009 used for object-timeline; `KanbanSchema` gains `limit?: number` and the block's ElementDataSourceMapping gains `limit: 'limit'`, so a bound view's `pagination.pageSize` (or the binding's own `limit`) now caps the board. `content/docs/guide/data-source.md`'s `object-kanban` limit cell no longer says '— fixed window' (it is now checked, with a paragraph recording what was actually wrong and why `sort` still reads '— no ordering'), and `content/docs/plugins/plugin-kanban.mdx` documents the board's `limit` and its distinction from a column's WIP `limit`. Behaviour change stated in the changeset and the PR body: a board that used to fetch unbounded now fetches 100 rows by default — the declared intent taking effect, but visible on objects with more than 100 matching records. ListView-hosted boards are unaffected (they receive records through the `data` prop and never run this fetch).", "tests": "pnpm exec vitest run packages/plugin-kanban/ packages/fields/ --maxWorkers=2 -> 'Test Files 104 passed (104)', 'Tests 1493 passed (1493)'. New coverage: 4 assertions in packages/plugin-kanban/src/ObjectKanban.elementDataSource.test.tsx covering the default window, a block-authored `limit`, a bound view's pagination.pageSize (7) and a binding `limit` (3) overriding it; each also asserts `params.options` is undefined. Reverse verification (fix committed first, reverted with `git checkout origin/main -- ...`, restored from the branch): direction was RED as expected — 'Tests 4 failed | 4 passed (8)', each failure 'expected undefined to be 100 / 20 / 7 / 3', the four pre-existing tests in the file unaffected. No ablation/dogfood leg in this card, so no dist rebuild claim is made. All commands run from the repo root; the union above was run on b0fb625fd, the head of the branch and the only commit on it.", "mechanism_assumptions_checked": [ "ObjectKanban.tsx still carried `options: { $top: 100 }` with `$filter` at the top level on origin/main (worktree base baa89a1ea, line 213) — CONFIRMED, premise intact.", "No find consumer reads `params.options` — CONFIRMED: a repo-wide scan of packages/apps/examples for an `options` object containing $-prefixed keys returned exactly 2 live instances (plugin-kanban, fields) plus 4 prose mentions in comments/test headers; `convertQueryParams` (@object-ui/data-objectstack) and ApiDataSource both read `params.$top`.", "The kanban ElementDataSourceMapping omitted `limit` on the now-falsified 'fixed window' rationale — CONFIRMED verbatim in packages/plugin-kanban/src/index.tsx; the mapping now carries `limit: 'limit'` and the comment states which of columns/sort/limit is mapped and why.", "Timeline shape from PR #4009 (commit 523be4820) re-read before copying: `$top: schema.limit ?? DEFAULT_TIMELINE_LIMIT` + mapping `limit: 'limit'`. Followed, with one deliberate difference — the timeline also mapped `sort` because #4009 added an `$orderby` read site; the kanban has none, so `sort` stays unmapped.", "packages/fields/src/index.tsx same-shape hit adjudicated harmless — VERIFIED independently: the branch runs only when the adapter exposes no `findOne`, and the filter is `{ id: value }` (primary-key equality, at most one row), so the cap cannot change the answer. Took the zero-cost top-level move anyway (dispatch left it to the dev).", "objectui has no skip-changeset mechanism — CONFIRMED (no such label used, none applied); `node scripts/check-changeset-presence.mjs` reports '5 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'.", "New default cap cannot regress ListView boards — CHECKED: ListView renders the generated `object-kanban` schema with a `data` prop, so `hasExternalData` is true and the internal fetch never runs. plugin-view's ObjectView passes no `limit` in baseProps.", "`limit` needs no zod declaration in @object-ui/types — CHECKED: ObjectKanbanSchema there extends a passthrough BaseSchema and does not declare the long-standing `filter` either; left untouched rather than half-fixing that surface." ], "gates": { "package_tests": "pass — pnpm exec vitest run packages/plugin-kanban/ packages/fields/ --maxWorkers=2: 104/104 files, 1493/1493 tests", "type_check": "pass — pnpm --workspace-concurrency=2 --filter @object-ui/plugin-kanban --filter @object-ui/fields run type-check (both 'Done'), after pnpm --filter '@object-ui/fields^...' --filter '@object-ui/plugin-kanban^...' run build", "lint": "pass — 0 errors (103 pre-existing warnings, unchanged)", "check-changeset-presence": "pass", "check-changeset-no-major": "pass", "check-control-bytes": "pass — 4249 tracked text files scanned", "check-doc-links": "pass — links valid across 13 scan roots", "ci": "in_progress — reported at draft-PR time per the dispatch contract; CI convergence not awaited" }, "deviations": [ "Card item 4 (mechanical defence against `options` as a find-param key) NOT landed here — filed as #4734 instead. The dispatch allowed it only as a small check:* script addition; in this repo a new gate is script + pin test in scripts/__tests__ + a ci.yml step (or an eslint-rules/ rule + RuleTester test), and the choice between those two has real reach differences. The follow-up records the AST signature that needs no allowlist and notes the repo is at zero live instances after this PR — the cheapest moment to install it.", "Beyond the literal dispatch text: added `limit: 'limit'` to OBJECT_KANBAN_DATA_SOURCE. Implied by item 1 rather than extra scope — the mapping's omission rationale was the very 'fixed window' claim this card falsifies, and #4009 mapped `limit` in the same PR that added the timeline's read site. Without it, a bound board's view page size would still be accepted and dropped.", "Docs touched a second file beyond the one the dispatch named (content/docs/plugins/plugin-kanban.mdx): the board's `limit` is newly authorable and collides by name with a column's WIP `limit`, so the plugin page documents both — AGENTS.md #2 (docs-driven).", "packages/fields hit taken rather than left (dispatch item 3, dev's call): stated in the PR body, changeset and commit message as a no-behaviour-change consistency move that leaves no live instance of the dead spelling in the repo." ], "followups_filed": [ "filed as #4734: nothing mechanically catches OData query params nested under a dead `options` key in a find() call — unassigned, unlabeled for PM triage, with both candidate mechanisms (check:* AST script vs object-ui/* ESLint rule) costed" ], "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
fix(plugin-kanban): the board's row cap reaches the wire as a top-lev…