Skip to content

primaryField 不是可声明键(ObjectSchema 以 unrecognized_keys 拒收),但两条 lint 规则与 objectstack-data 技能文档都把它当作合法 name 面 #6326

Description

@hotlong

#6108(object/missing-name-field 谓词补读 nameField)实施过程中量到的相邻事实,按 Prime Directive #10 单独立单,不在那条 PR 里修。

量到的事实

primaryFieldpackages/spec 的对象 Zod schema 里根本不存在。全仓检索(排除 node_modules / dist)只有 4 处提及,没有一处是 schema 声明:

位置 用法
packages/lint/src/data-model-rules.ts object/missing-name-field 谓词的一支:!!obj.primaryField
packages/lint/src/validate-semantic-roles.ts:190 标题解析链 [obj.nameField, obj.primaryField, obj.displayNameField]
skills/objectstack-data/SKILL.md:1001 规则表:「an object with no name/title field or primaryField
packages/spec/src/shared/suggestions.test.ts:100 仅作为 camelCase 拼写建议语料里的一个字符串

实测(packages/spec dist,17.0.0-rc.5):

const { ObjectSchema } = require('@objectstack/spec/data');
ObjectSchema.safeParse({ name: 'probe_obj', label: 'Probe', primaryField: 'code',
                         fields: { code: { type: 'text', label: 'Code' } } });
// => success: false
// => issues: [{ code: 'unrecognized_keys', keys: ['primaryField'], path: [] }]

ObjectSchema.create(/* 同上 */);
// => throws: ObjectSchema.create('probe_obj'): unknown key(s) — primaryField.

对照组 nameField: 'code' 同一形状 safeParse 通过。

为什么这不只是「死代码」

两个方向各有一个可达面:

  1. 文档面(作者会照做) —— skills/objectstack-data/SKILL.md 是 AI 编写元数据时读的技能文档,它明说 primaryField 是这条规则的合法逃逸口。照它写的对象在 ObjectSchema.create() 上被 ADR-0032「不静默丢弃未知键」的闸硬拒。文档说可以写,schema 说不能写。
  2. 规则面(判定永不成立) —— 反过来,!!obj.primaryFieldvalidate-semantic-roles 的那一项对任何 schema 收得下的对象都恒为 false,属于 validateOrgAxisRedLines 读的 sharing-rule 键是 spec 拒收的:ADR-0105 D6 ① 在 criteria 路径上从不触发 #4984 家族的死支:它看起来在保护什么,实际什么都判不到,而覆盖它的既有断言(packages/cli/test/data-model-rules.test.ts:138)喂的是一个 schema 会拒收的 fixture,所以绿得没有意义。

两面同源:primaryField 从来没有(或已经不再)是可声明面,而三处消费者没跟上。

建议的处置方向(未定,交分诊)

要么在 spec 里补声明 primaryField(若它确有业务面),要么按 ADR-0049 enforce-or-remove 把三处消费者一起摘掉并改 SKILL.md。倾向后者:nameField 已是 ADR-0079 的规范主标题指针,再留一个平行指针与「One Zod source per metadata type」相悖;但这是公共作者面的取舍,不自行裁定。

发现现场:#6108 / PR(谓词修正)。那条 PR 只做了两件事以避免夹带——保留 primaryField 支不动(行为不变),并把该规则新的提示文案收敛为只点名真实可声明面(nameField 与 name-like 字段),不再向作者广告一个会被拒收的键。

查重:已按 primaryField / unrecognized_keys / phantom 在本仓 open issues 检索,无既有单。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions