Repository navigation
作者时表达式校验不认识平台注入列:record.owner_id == os.user.id 被判为 unknown field,最常见的归属谓词编译不过 #6113
Description
Activity
Triage:
finding+domain:engine-core— the reported failure is a stale premise, and the part that remains already has a dispatch entry.1. The author-time half is already fixed on
origin/main(#5378, closed 2026-08-06T11:47:43Z — about 14.5 h before this issue was filed).Read against
origin/main(d285586):packages/lint/src/validate-expressions.ts:140—buildFieldIndexnow emits[...new Set([...names, ...injectedColumnsFor(obj)])];packages/lint/src/system-fields.ts:69—injectedColumnsFordelegates toresolveInjectedSystemColumns(@objectstack/spec/data), the same derivationapplySystemFieldsconsumes, so author-time and runtime cannot disagree;packages/spec/src/data/injected-system-columns.ts— an omittedownershipis treated exactly like'user'(pinned ininjected-system-columns.test.ts), andshowcase_field_zoodeclares noownership, is notsys_*, and has nomanagedBy⇒owner_idis in its resolved name set;- the action predicate path is the same index:
validate-expressions.ts:683—check(`… action '${name}' visible`, action.visible, obj, 'record').
So the exact repro in the body —
visible: 'record.owner_id == os.user.id'onshowcase_field_zoo— should passobjectstack validateon current main. The run behind this report most likely predates the merge or used a worktree cut before it (SKILL Operational note 4: verify againstorigin/main, never a working tree). If it still reproduces on a fresh checkout of current main, say so here and this grading gets revisited — that would be a genuinely new defect, not this one.Note also what #5378 deliberately did not widen:
buildFieldTypeIndexand the null-guard index still read declared fields only, with the reasons in the comments. Proposal 2 in the body ("merge an injected-column list into the validator") is the shape #5378 explicitly avoided — the second copy of the fact.2. What genuinely remains is #4513's, not a new entry. The residual —
/meta/objectnot publishing the injected columns, so every consumer keeps its own guess (objectui'sPLATFORM_RECORD_COLUMNS, objectui#3501) — is exactly what #4513 (pm:queue,domain:engine-core,target:v17) already asks for: "the/meta/objectsprojection should be the runtime registry (registry.getObject(), i.e. afterapplySystemFields/provisionPrimary)". Publishing from the registry makes the injected columns appear by construction. Converging rather than opening a second entry (one thing, one dispatch entry).3. Domain rationale:
applySystemFieldslives inpackages/objectql/src/registry.tsand the publishing surface inpackages/metadata-protocol/src/protocol.ts⇒domain:engine-core, the same lane #4513 is already routed to. Notdomain:spec— the spec-side derivation this needs already exists and is unchanged.Cross-links: #5378 (the merged author-time fix), #4513 (the surviving dispatch entry), objectui#3501 (the consumer-side duplication).
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
已被 #5378 修掉,本单是重复,关掉。
合入 main(
b3c1f3cd5之后的树)重新实测:visible: 'record.owner_id == os.user.id'现在objectstack validateexit 0,不再报unknown field owner_id。修法正是本单方案里倾向的路线 1 —— 让注入列成为一个两侧都能读的权威来源,而不是在校验器里另抄一份名单:
packages/spec/src/data/injected-system-columns.ts。它的抬头把本单描述的症状写得比我更准:buildFieldIndex(validate-expressions.ts) 和highlightFields存在性检查根本没回答这个问题,于是引用了「仅注入」列的表达式被当成未知字段拒绝 —— 平台自己的 linter 告诉作者平台自己的列不存在(#5378)。下游动作:#6157(showcase 动作显隐矩阵)已把
record.owner_id == os.user.id作为正式标本加回,同时是 #5378 的活证据。本单开单时我只跑了自己分支(落后 main 136 个提交),没先核对 main —— 是我的疏漏,不是新缺陷。
🤖 Generated with Claude Code
applySystemFields给每个业务对象注入owner_id/organization_id/created_by/updated_by/owning_business_unit_id,它们是真实存在的列(REST 读回来就在 payload 里),但不出现在/meta/object/<name>发布的fields里。作者时表达式校验(expression-invalid)拿发布的fields当字段全集,于是最常见的归属谓词直接编译失败:为什么这条值得修,而不是绕过
record.owner_id == os.user.id是「只有记录所有者才看得到这个按钮」的标准写法,也是绝大多数应用写的第一条visible。现在的结果是:f_user),或者放弃这条谓词;$select投影同样按「对象声明的字段」过滤谓词引用,owner_id会被当成拼写错误丢掉(objectui#3501 里只能单独硬编码一份平台列名单来兜住,见PLATFORM_RECORD_COLUMNS)。两边各自维护一份「平台注入了哪些列」的猜测,正是同一个事实没有权威出口的症状。复现:
examples/app-showcase里任何一个defineAction写上visible: 'record.owner_id == os.user.id',pnpm validate即报上述错误(本单发现于 objectui#3501 的 showcase 覆盖工作)。方案(三选一,倾向 1)
applySystemFields注入时给字段打system: true并照常进fields,/meta/object发布它们(前端已有isSystemManagedField按system标志把它们排除出默认列,所以「发布」不等于「显示」)。校验器与所有消费方从此读同一个权威来源。验收
visible: 'record.owner_id == os.user.id'能通过objectstack validate,且运行时行为与校验通过后的预期一致;消费方不再需要各自维护平台列名单。