Skip to content

trigger-record-change 的 input.doc 防御性 alias 读的是一个没有生产者的键(引擎只建 input.data) #5671

Description

@os-zhuang

在 #5273(PR #5668)核对 HookContext.input 契约表时发现,PD #10 单独记录。观察类(finding):今天没有用户会撞上,它是一条永不命中的兜底分支。

事实(对 origin/main 核实)

packages/triggers/trigger-record-change/src/record-change-trigger.ts:295-300:

const inputDoc =
    input.data && typeof input.data === 'object'
        ? input.data
        : input.doc && typeof input.doc === 'object'
          ? input.doc
          : undefined;

input.doc 这条分支在任何引擎路径上都不可达:

该文件自己的注释其实已经写明了真值:

objectql lifecycle hooks carry the written row under input.data (insert / update payload); id is on update. (doc kept only as a defensive alias.)

packages/spec 的契约表当时确实把 insert 写成 { doc: Record, options } —— 那是假的,已由 PR #5668 改成 { data, options } 并加 pin。所以这条 alias 现在连「文档这么说」的依据也没有了。

分级说明

标 finding:纯休眠代码,行为上零影响。但它是 AGENTS.md PD #12 点名的那类消费端 ?? 兜底——「a tolerant fallback fossilizes the wrong convention into a second de-facto contract」——而且是为一个从来不存在的生产者留的。严重程度请分诊轮判。

建议

删掉 input.doc 分支与类型里的 doc?: 声明,只读 input.data;真值已被 packages/objectql/src/hook-input-shape-contract.test.ts(PR #5668 新增,断言 insert 上下文有 data、无 doc)钉住。

顺带:packages/spec/src/data/hook.test.ts:422 与 packages/services/service-storage/src/attachment-lifecycle.test.ts:159 的 fixture 也拼的是 input: { doc: … }。两处都只喂开放形状的 z.record,不会因此变红,但它们是照旧契约表写的,清理时应一并按引擎真值重拼(fixture 三分法里的「re-spell」)。

关联

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions