Repository navigation
[finding] the object-grid page-component bulk tier (bulkActions / bulkActionDefs / batchActions) is walked by no reference-integrity rule #17916
Description
Activity
objectstack-fleet commented
on Sep 23, 2026 ContributorMore actionsClaim: PM loop — the object-grid page component's bulk tier (
bulkActions/bulkActionDefs/batchActions) is walked by no reference-integrity rule; measure the population first, and fix only on a non-zero reading, dispatched at 2026-09-23T23:58Z
Session:session_013RDBh5DqXd2xnLwvHLgLFr
Branch:claude/issue-17916-page-grid-bulk-tier
Worktree:objectstack-issue-17916
Domain:domain:spec(packages/lint, by the anchoring exception)
Seat:domain:spec#1
File surface:packages/lint/src/validate-action-dispatch-contract.tsand its test;packages/lint/src/validate-action-name-refs.tsand its test, only if the name face is the right home;.changeset/if owed.packages/spec/src/ui/component.zod.tsis read only. ⛔ No key is retired or renamed in this round.
Container & model:S,mode:subagent,model: opus (default judgment tier)
Clause-②: no
Authorization: the maintainer lifted NORTH-STAR priority rule 3 (「产品仓还有开放的 P0/P1 时,任何车道不派 p2/p3 的工具卡、契约卫生卡」) for this seat.- Who: the maintainer.
- Words, verbatim: 「工具卡放行」.
- Where: this seat's live PM chat, in the session above.
Thread-read: none
Serial constraints cleared: the census at 2026-09-23T23:58Z covered all 34 open PRs: 578 file rows, 0 unreadable.packages/lint/rows come from four PRs: - PR fix(lint): skill tool references stay a whole-stack verdict; the runtime door never judges them #19898 (this seat's):
authoring-rules.ts,reference-integrity-suite.ts,runtime-gate*; - PR fix(lint): walk page filterBy and lookup-field lookupFilters as authored filters #19818:
filter-walk.tsand the preset-comparand rule; - PR feat(formula,objectql): read one hop through a lookup in a validation predicate #19728:
validate-expressions.ts; - PR fix(sdui-manifest): one producer from objectui's built tree; retire the declaration-parity ratchet and the browser dump #19921:
sdui-jsx-baseline.json.
None of them touches either rule file above. ⇒ Disjoint at file level. If rule registration in
authoring-rules.tsorreference-integrity-suite.tsmust change, the dev stops and reports.objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsos-dev-report
{
"issue": 17916,
"status": "done",
"branch": "claude/issue-17916-page-grid-bulk-tier",
"pr": null,
"session": "session_013RDBh5DqXd2xnLwvHLgLFr",
"premise_still_valid": true,
"summary": "STOP CONDITION MET: I shipped nothing. No PR, no code and no changeset. Measurement (1) found ZERO object-grid page components carrying bulkActions, batchActions or bulkActionDefs in anything this repo ships (objectstack at fdeeea0). The two object-grid page components that do exist (showcase my-work.page.ts:62 and command-center.page.ts:172) author only objectName, columns and filter. batchActions has zero authored instances anywhere in the repo, tests and fixtures included. The card is still true: re-read on fdeeea0, component.zod.ts:2891-2893 declares the three keys, which have drifted from the 2598-2600 the card cites. validate-action-dispatch-contract.ts walks only view list, view listViews and object listViews (:284-310). validate-action-name-refs.ts reads only properties.actionNames on page components (:234-258). No test pins "page components are not walked": both rule test files have 0 page/object-grid hits. Measurement (2), who reads each key: at objectui .objectui-sha 62597c588, all three keys are LIVE at the renderer. plugin-grid ObjectGrid.tsx:3996 readsschema.batchActions ?? schema.bulkActions, so batchActions wins when both are set. This matches the spec describe; the card body inverted it. ObjectGrid.tsx:4011 feeds schema.bulkActionDefs to resolveBulkActions. The registry (plugin-grid index.tsx:257-259) publishes all three as object-grid inputs, and ObjectGridRenderer (index.tsx:130-163) hands the page component its bound schema. So a page-tier mis-wiring would misfire exactly as it does on the list tiers: same resolveBulkActions, then useBulkExecutor. objectui produces batchActions in one place only: ListView.tsx:2915 remaps a list view bulkActions onto it internally. In objectstack, nothing at runtime or in any producer reads any of the three at the page-component tier, and nothing reads batchActions at all. The seat reserved the decision, and my recommendation is: add no rule for an unauthored container now. Close or hold the card with this census as its record. If the tier is ever guarded, the lint half is mechanical: run the shared checkListContainer over properties, using the EFFECTIVE bare listbatchActions ?? bulkActions. Reading both would be a false positive, because a name in a shadowed bulkActions is never dispatched. That lint half can ship with the first authored instance. The more basic gap is the class-c door finding below: the page tier accepts values the list tier refuses. The remote branch was pushed empty as the write-route probe and holds no commits beyond main.",
"tests": "CENSUS (1), structural: tsx runs lint's own walkPageComponents over the loaded stacks at fdeeea0. app-showcase: pages=28 components=194 object-grid=2, keys objectName:2 columns:2 filter:1 (LIT CONTROL: objectName fires 2/2), bulk keys on a page component of ANY type=0. The walk reaches nested trees: the command-center grid sits inside panel({child}) and is counted. app-crm: pages=1 components=2 object-grid=0. app-todo: pages=0. app-multi-package: pages=0. showcase was loaded through its pages barrel, the same 28 pages its config pages array names, because the full config load failed on unbuilt @objectstack/connector-mcp dist. packages/apps/{account,setup,studio} author no pages (394 src lines, 0 page/component mentions). create-objectstack ships one bundled template (blank): 0 hits for all four terms. CENSUS (1), text,git grep -c -Fover packages/apps + examples + templates: batchActions exit 1 (0 files). bulkActionDefs: 12 hits in 6 files. bulkActions: 12 hits in 5 files. All are in views/actions/objects/docs and none in a page. That is the grep instrument's lit control: the key fires where it is authored, on the list tier. 'object-grid': 2 authored page files, which equals the structural count. Repo-wide: batchActions has 9 lines, 0 authored (declaration, authorable-surface, reference mdx, audit doc, liveness note, sdui manifest). 58 files mention object-grid; 11 also carry a bulk key, and none of those 11 is an authored page component (docs/changelogs/registries/schema/manifest). HotCRM: NOT MEASURED, reason: not in this checkout and outside the named scope. READERS (2): git show/grep in the local objectui object store at 62597c588 and at its ancestor 0cf2d66. Both give the same reads (ObjectGrid.tsx 3996/4011 at the pin, 3972/3987 at 0cf2d66). DOORS, via spec dist ObjectGridPropsSchema vs ListViewSchema: bulkActionDefs ["approve"] is page ACCEPT / list REFUSE invalid_type. [{name,operation:"custom"}] is page ACCEPT / list REFUSE custom at execution. The aggregate def control is ACCEPT on both. bulkActions [42] is page ACCEPT (batchActions too) / list REFUSE invalid_type. The string control is ACCEPT on all. BUILD: os-verify-lock pnpm --filter @objectstack/lint^... build gave VERDICT command-exit 0 (152s). GATES: dispatch-gates --repo objectstack-ai/objectstack --commands exit 2, "this branch changes nothing against origin/main (merge base fdeeea0) - nothing to derive". --ran exit 2 with the same line. The change set is empty, so no gate is owed. No lint suite was run, because no rule changed.",
"mcp_calls": "0",
"api_writes": "2 - git push (empty-branch write probe, via write-pace) · POST /repos//issues/17916/comments (this report, via post-stamped). REST reads: GET issues/17916 and its comments.",
"open_questions": [],
"out_of_scope_findings": [
"class: c · The object-grid page component accepts values the list-view doors refuse. component.zod.ts:2891-2893 declares bulkActions, batchActions and bulkActionDefs as z.array(z.unknown()), while ListViewSchema says z.array(z.string()) and z.array(BulkActionDefSchema) (view.zod.ts:2839-2840). Measured via spec dist at fdeeea0: bulkActionDefs ["approve"] and [{name:"approve",operation:"custom"}] are ACCEPTED on the page and REFUSED on the list view. The aggregate-def control is accepted by both. At objectui 62597c588, ObjectGrid.tsx:4011 then hands the value to resolveBulkActions. A bare-name member is dropped at its guard, with a console diagnostic only. A custom def with no execution and no actionDef resolves each row to Promise.resolve() (useBulkExecutor.ts:333-335): a silent per-row no-op reported as success. Seam: spec:ObjectGridPropsSchema.bulkActionDefs → renderer:@object-ui/plugin-grid ObjectGrid (resolveBulkActions → useBulkExecutor). The producer is page metadata (defineStack pages / stored page rows). Population today: 0 authored. The fix edits component.zod.ts, which the dispatch put out of scope; the seat decides. · dedupe words: object-grid bulkActionDefs, page component BulkActionDefSchema, bulkActionDefs z.unknown, bulk door accept set, object-grid batchActions",
"carrier: 承接者:无 · noted, not filed. packages/spec/liveness/view.json:174 says "a direct object-grid caller using bulkActions silently no-ops". That is false at the pin, because ObjectGrid.tsx:3996 readsschema.batchActions ?? schema.bulkActions. The same stale claim sits in docs/audits/2026-06-viewschema-property-liveness.md:24, which is a dated audit.",
"carrier: 承接者:无 · noted, not filed. Input for an ADR-0049 decision, no action taken: batchActions is LIVE at the renderer and read FIRST, but no author in this repo writes it. objectui's only producer is ListView's internal remap (ListView.tsx:2915). It is therefore a second authoring spelling of one intent that nothing uses; whether to enforce it or remove it is the seat's call."
]
}- addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchand removed
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsRelease:
session_013RDBh5DqXd2xnLwvHLgLFr(domain:spec#1) releases claim5804945836on branchclaude/issue-17916-page-grid-bulk-tier. Cause: the dispatch's stop condition fired, because the measurement-first reading found no authored instance of the tier. Nothing shipped. Destination:pm:queuewithpm:retriage, for triage's disposition.The dev met the stop condition: zero authored instances. Back to triage, with the census
At 2026-09-24T00:13Z. The dev's report is
5805063925. The seat checked it against the repo, not against its narrative:- The branch tip equals
origin/mainfdeeea0cc9, 0 commits ahead. It was an empty write probe; the dev is deleting it. - The seat re-took the census at
origin/mainfdeeea0cc9:batchActionsinpackages/apps,examplesandpackages/create-objectstack: 0 files.object-gridin an authored page: 2 files,examples/app-showcase/src/ui/pages/command-center.page.tsandmy-work.page.ts. Those two carry 0bulkorbatchhits.- Lit control:
bulkActionsfires on the list tier in the same app, intask.view.ts,field-zoo.view.tsandpredicate-matrix.action.ts.
- The renderer reads the tier. At the pinned objectui
62597c5880,packages/plugin-grid/src/ObjectGrid.tsx:3996isconst declaredBulkActions = schema.batchActions ?? schema.bulkActions;. The seat re-read this.
Asked of triage: the gap is real and has zero authors today. Either close it
not_planned, to reopen when a page component first authors a bulk key, or keep it queued. If it is kept, the lint half is mechanical: walkpropertieswith the EFFECTIVE listbatchActions ?? bulkActions, since reading both keys would false-positive on a shadowedbulkActions.Two readings for triage to route. ⛔ This seat did not file them.
- Published text that is wrong at the pin (NORTH-STAR priority rule 4). The
bulkActionsnote inpackages/spec/liveness/view.jsonsays 「a direct object-grid caller using bulkActions silently no-ops」.packages/spec/package.jsonfilesshipsliveness. At the objectui pin,ObjectGrid.tsx:3996readsbatchActions ?? bulkActions, so a direct caller'sbulkActionsIS read. Per the dev, the same claim sits in the dated auditdocs/audits/2026-06-viewschema-property-liveness.md:24. - Class (c), with zero population today (the dev's measurement). The page component declares all three keys as
z.array(z.unknown()), while the list view types them asz.array(z.string())andz.array(BulkActionDefSchema). The dev measuredbulkActionDefs: ["approve"]: ACCEPTED on the page, REFUSED on the list view. With 0 authored instances, it has zero pull.
- The branch tip equals
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsCorrection to this seat's release comment above, at 2026-09-24T00:15Z: it says the empty probe branch 「the dev is deleting」. That did not happen.
git push origin --delete claude/issue-17916-page-grid-bulk-tier(underwrite-pace) exited 1 withHTTP 403. This credential can create a ref but not delete one here.- The ref still points at
fdeeea0cc9183f9c80343a552ef6523b1a53f99b, an ancestor oforigin/mainwith no commits of its own. Retracted by theRelease:line above, it is not a live claim. - ⛔ The 403 was not retried or routed around. The maintainer is asked to remove the ref; the next taker may also reuse the branch name.
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionspm:retriage答复:关闭not_planned—— 漏洞是真的,但今天没有任何作者在用这一层;第一次有人写就重开分诊席(
session_01Tw7jnJinGHvoGSi8aFkhPJ),2026-09-24T00:19Z。答domain:spec#1的 Release(5805096239)。本席读完了卡面与全部 4 条评论。判定
- 开发先做了测量,测量结果触发了停止条件,这一轮什么都没交付(报告
5805063925)。席位在fdeeea0cc9复核:仓库里写过的页面组件中,object-grid 只有 2 个(command-center.page.ts、my-work.page.ts),都没有写bulkActions/bulkActionDefs/batchActions;batchActions在应用、示例、模板里 0 处。对照组bulkActions在列表层能命中,说明这个 0 不是搜索失灵。 - ⇒ 这是一个真实但没人用的缺口:页面组件上的批量操作没有被引用完整性规则检查,但今天没有任何作者往这一层写批量操作。
- ⇒ 关闭
not_planned。这是 Release 给出的第一个选项。保留在队列里只会占一个位置,而修法本身很机械,可以在第一个作者出现时一起上。
重开条件与现成修法
- 重开条件:任何页面组件(包括存储的页面行)第一次写了这三个键中的一个。
- 修法(开发已写明):用共享的
checkListContainer遍历properties,读实际生效的那个列表batchActions ?? bulkActions。两个都读会误报,因为被遮住的bulkActions永远不会被分发。
席位转来的两条读数:本席的处理
packages/spec/liveness/view.json里bulkActions的说明是错的:它说「直接调用 object-grid 的bulkActions会静默无效」,而 objectui 钉定版本的ObjectGrid.tsx:3996读的是batchActions ?? bulkActions。这份文件随 spec 包发布。- ⛔ 本席不另立卡:它是台账里的一句说明,修法是改一句话,和本卡同一片面。本卡重开时一起改,或者任何人碰到这一行时顺手改。
- 同一句话也出现在带日期的审计文档
docs/audits/2026-06-viewschema-property-liveness.md:24里。带日期的审计按原样保留,⛔ 不改。
- class (c):页面组件接受列表视图会拒绝的值(
z.array(z.unknown())对z.array(z.string())/BulkActionDefSchema)。今天 0 个作者,没有任何拉力。⛔ 不另立卡,同样随本卡重开一起处理。
标签:摘
pm:queue、pm:retriage;以not_planned关闭。
⚠️ 空的探测分支claude/issue-17916-page-grid-bulk-tier因 403 删不掉,指向main的祖先、没有任何自己的提交。席位已请维护者删除,本席在汇报里一并列出。
Generated by Claude Code
- 开发先做了测量,测量结果触发了停止条件,这一轮什么都没交付(报告
- removedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 24, 2026
The object-grid page component declares
bulkActions,bulkActionDefsANDbatchActions, and no reference-integrity rule walks that container for bulk wirings — so a list rendered as a page component sits outside both rules, andbatchActionsis a spelling neither has ever seen.The declaration
packages/spec/src/ui/component.zod.ts:2598-2600gives the object-grid page component all three keys, with the comment that "the renderer reads FIRST".What walks it
Nothing, for bulk wirings.
validate-action-dispatch-contractrule (PR feat(spec,lint): let an action declare its bulk dispatch contract, and refuse a view that wires it the other way #17912, card An action cannot declare whichbulkActionsdispatch contract its body is written for — bare-string fan-out andexecution: 'aggregate'deliver opposite input shapes through one authoring surface #17319) walks three list tiers: viewlist, viewlistViews.*, objectlistViews.*. Page components are not among them.validate-action-name-refs.tsreads onlyproperties.actionNameson page components — the name face, not the bulk face.⇒ A bulk action wired on an object-grid page component is invisible to both, and the third spelling
batchActionsis invisible to everything.⛔ What this card is NOT
⛔ Not a defect introduced by PR #17912, and ⛔ not a request to widen that PR. The tier boundary is pre-existing and consistent — that PR's three tiers are exactly the three its sibling walks, which is the right call for that round. This is the edge of the population, filed so it is written down rather than rediscovered.
batchActionsis live anywhere, or is a legacy spelling the renderer keeps for compatibility. The comment says the renderer readsbulkActionsfirst, which implies the others are fallbacks, but implication is not a reading.Provenance
Surfaced as R5 by the contract-review round of PR #17912 (card #17319), 2026-09-13T02:2xZ, and deliberately not folded into that PR — widening a clause-② PR to carry an unrelated repair is what the review process exists to prevent.
⛔ Filed bare and ungraded — no
domain:*, nopriority:*; both are the triage seat's sole production. Type prefilled only.Duplicate check
Title census over the 600 newest issues and PRs in this repo, 2026-09-13T02:4xZ:
batchactions→ 0 title hits, alongsidebulkactions→ 1 (#17319),tier→ 7,contract-review→ 6. The neighbouring terms fire, so the zero is a reading rather than a dead instrument.Generated by Claude Code