fix(spec): make the bulk-action option item's openness deliberate, not accidental (#4001) - #4909
Merged
Merged
Conversation
…t accidental (#4001) `BulkActionParamSchema`'s `options[]` entry was bare default-strip while the strictness ledger's prose called it and its parent "both deliberately open" — one intent, two postures, found by the #4001 2026-08-03 re-measure (#4852). Per the maintainer's verdict A the code moves to the prose: `.passthrough()` on the option item. Verified before writing, since the prose itself had just been proven able to drift — objectui's option TYPE is closed (`Array<{ label; value }>`, `packages/types/src/objectql.ts:271`), but the type is not what an authored option meets: `bulkParamToField` SPREADS every entry (`packages/plugin-grid/src/components/bulkParamToField.ts:131`) into the field metadata, whose vocabulary is `SelectOptionMetadata` (`packages/types/src/field-types.ts:288`) — `color` / `icon` / `disabled` / `visibleWhen` beyond the pair, and read (`packages/fields/src/index.tsx:1089`). So the strip was deleting widget config the renderer would have honoured. The new test states the openness is deliberate and names the evidence, so a future strict-ification sweep stops there instead of "fixing" it. Ledger: `ui/bulk-action.zod.ts` reaches zero strip sites, so its remaining-strip row is deleted and the header arithmetic reconciled (124 → 123 of 198). Both directions of that gate were driven red before the green was believed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
`gen:docs` renders a passthrough object inside an array as `Record<string,
any>[]`, so the reference page lost the `{ label, value }` shape the moment the
entry opened — an author-facing surface reading "shapeless" for something that
still has two required keys, which is the strip-era smell pointed the other way.
The declared pair now lives in the key's own `.describe()`, which the generator
renders verbatim, along with WHY the entry is open and which extra keys the
widget actually reads. Regenerated `content/docs/references/ui/bulk-action.mdx`
accordingly (the one artifact `check:generated` proved stale — not the set).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
xuyushun441-sys
marked this pull request as ready for review
August 3, 2026 16:18
xuyushun441-sys
pushed a commit
that referenced
this pull request
Aug 3, 2026
批 9 (#4925) landed the same automation/ ledger section. Both waves deleted their own rows and decremented the section header by their own count, so git merged the ROWS cleanly and conflicted only on the header — while the authorable subtotal one line below, which conflicted with nothing, merged clean while being wrong on both branches. Header recomputed from the surviving rows (42 strip of 75, authorable 16 of 42) rather than resolved in favour of either side; check:strictness-ledger's header arithmetic is the arbiter and reads 45 open files / 299 strip sites. os-regen four-step run: merge -> checkout origin/main for every path in .gitattributes -> wholesale regenerate -> assert siblings survived. 批 9's three reference pages and #4909's bulk-action page are byte-identical to origin/main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #4001
执行 2026-08-03 11:42Z 维护者裁决第 ② 项(方案 A):给
BulkActionParamSchema的options条目补.passthrough(),让代码与旁边那句散文一致。裁决不再重议,本 PR 只负责执行 + 交出裁决要求的先验证据。先验证据(裁决的执行前提)
裁决明确要求先核 objectui 侧兜底确实存在——因为台账散文本身刚被证明会漂。核完的结论是:兜底存在,但不在裁决预期的那一层,所以这里把实测贴全,而不是只回一句「已确认」。
packages/types/src/objectql.ts:271options?: Array< { label: string; value: string | number | boolean } >—— 封闭,没有索引签名packages/plugin-grid/src/components/bulkParamToField.ts:131options?.map(o => ({ ...o, value: String(o.value) }))—— 展开,每个多余键原样存活packages/types/src/field-types.ts:288SelectOptionMetadata在label/value之外声明color/icon/disabled/visibleWhen而且落点的键确实被读:
option?.color见 objectuipackages/fields/src/index.tsx:1089(dot 外观)与:1101(badge 配色)。所以裁决的业务论据成立,且比预期更强:被 strip 掉的不是「可能有人想写的自由字段」,而是渲染器会真的读、真的画出来的 widget 配置。作者写下
color: '#8B5CF6'只会得到一个默认色的徽章,没有任何提示。一处必须如实说明的偏差:裁决措辞是「核 objectui 侧那个
[key: string]: unknown兜底确实存在」。在 param 这一层它确实存在(objectql.ts:293,注释写明 min/max/step/format 转发给字段渲染器);但在 option 条目这一层没有——那一层的类型是封闭的,开放性来自展开 + 落点类型。结论不变(passthrough仍是对的姿态,且与运行时一致),但依据换成了实测事实。这条类型/运行时不一致已按 Prime Directive #10 单独归档为 objectstack-ai/objectui#3309,未在本 PR 修改 objectui(该仓本次只读)。改动
packages/spec/src/ui/bulk-action.zod.ts:option 条目.passthrough();模块头 rationale 块补一条,按本文件惯例写清为什么这一层是开的,并带上上表的 file:line。color/icon/disabled/visibleWhen存活),并在注释里明说这是刻意开放,连同证据,好让下一轮 strict 化扫荡走到这里停住而不是「顺手修好」。另加一条反向断言——开放 ≠ 无形状,label缺失仍然报错。ui/bulk-action.zod.tsstrip 归零 → 按 fix(spec): #4001 重测 —— 实测剩余站点清单,并修好测量它的那把尺 #4852 的反向闸删除其 remaining-strip 行,表头124 → 123 of 198,并把 triage 行那句「both deliberately open」改成如实描述(原文正是漂移本身)。.describe()那笔是被动修补:gen:docs把数组里的 passthrough 对象渲染成Record< string, any >[],一开放就把{ label, value }的形状从参考页上抹掉了——一个仍有两个必填键的东西在作者面前显示成「无形状」,正是 strip 时代那股味道反过来。形状与开放理由因此写进该键自己的.describe(),生成器会原样渲染。验证
先证红,再信绿(战役自定规矩),台账闸门两个方向都诱发过:
两个控制组都恢复后:
基数从 51 文件 / 325 站点降到 50 / 324,与本单预期恰好一致。
其余闸门(
packages/spec全部 check,build 先行):近邻消费者
@objectstack/lint+@objectstack/metadata-protocoltypecheck 通过(首次报Cannot find module '@objectstack/formula'是未构建依赖,即 AGENTS.md §9 那个陷阱,补构建后即Done,与本改动无关)。本改动是放宽,只会多接受、不会少接受,消费者均以 loose record 读bulkActionDefs。os-regen 同步
git merge origin/main(未 rebase、未 force),git checkout origin/main --全部merge=os-regen路径后整体重生成。结果:工作区与本分支提交逐字节一致,且七类生成物对origin/main的差集仅content/docs/references/ui/bulk-action.mdx一行——即兄弟 PR 的条目全部存活。🤖 Generated with Claude Code
https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
Generated by Claude Code