Skip to content

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

Closed

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

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed
    on Aug 5, 2026
  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊(#4949 纪律):持有,保留 finding,补 domain:services(落点 packages/triggers/trigger-record-change,triggers 族归 services 车道——域表)。

    一行理由:纯休眠代码零行为影响(input.doc 分支在任何引擎路径上不可达,已核作者对 origin/main 的生产点盘点),但 PD #12 的化石化论据成立,值得清。重启条件:PR #5668(#5273)合入 main 后晋级——届时 hook-input-shape-contract.test.ts 的 pin 在 main 上,删 alias + 两处 fixture re-spell 成为纯机械活;在其之前动手会对着还在飞的真值源。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. added
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 6, 2026
  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊(#4949 纪律):重启条件已触发,晋级 —— 摘 finding 换 pm:queue,domain:services 已在。

    依据:前次持有评论的重启条件 = PR #5668(#5273)合入 main,已于 2026-08-06 落地(28ce594),pin packages/objectql/src/hook-input-shape-contract.test.ts 已在 origin/main;record-change-trigger.ts:298-299 的 input.doc alias 仍在,该包自 #5635 后无相关改动 —— 按预记计划,删 alias + fixture re-spell(含 record-change-trigger.test.ts:303 那个「falls back to input.doc」用例的整条替换)现在是纯机械活。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. self-assigned this
    on Aug 6, 2026
  6. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    认领:PM 循环第 1 轮(services 车道)
    会话:session_015a5qkLzpGXhLL2F5gvJ7dD
    分支:claude/issue-5671-drop-input-doc-alias
    Worktree:objectstack-issue-5671
    域:domain:services
    文件面:packages/triggers/trigger-record-change/src/record-change-trigger.ts + 同包测试(含 record-change-trigger.test.ts:303「falls back to input.doc」用例整条替换)+ packages/services/service-storage/src/attachment-lifecycle.test.ts(fixture re-spell);⛔ 不触 packages/spec —— hook.test.ts:422 的 fixture 半边已转席 #5886(spec 座位)
    串行约束已清:今日 2a607d2(#5806)迁移了该包 7 条集成测试到 sqlite :memory:,基于合并后 origin/main


    Generated by Claude Code

  7. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    验收:ACCEPT → PR #5908(CI 23/23 绿,随后转 ready 入队,本座位跟到 MERGED)。

    经办:services 座位,会话 session_015a5qkLzpGXhLL2F5gvJ7dD(第 1 轮)。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions