Skip to content

os-dev 派发词/定义可加一行:测试假引擎的 delete() 必须路由 assertEngineDeleteDispatch —— 同一门禁一日两红(#5173、#5192) #5197

Description

@os-zhuang

观察类记录,按 Prime Directive #10 立案,不自行压级。

现象

check:engine-double-contract 在同一天两次判红两个不同 dev agent 的新增测试,错误一模一样 —— 新写的假引擎 delete() 手抄守卫、未路由 assertEngineDeleteDispatch:

两次修复都走门禁提示的第一条路,各花一轮 CI 往返(~15 分钟/次)。#5173 那次还证实手抄守卫真有洞($in 多行谓词被放行)。

判断

门禁工作正常,防线没漏;代价只是每次一轮 CI 往返。但「新增测试 + 需要假引擎 + delete 路径」是 os-dev 的高频组合,.claude/agents/os-dev.md(或 pm-dispatch 的派发词模板)加一行「假引擎的 delete() 一律 assertEngineDeleteDispatch(options) 开门,参照既有 14 个 pinned fake」,可以把这轮往返省在提交前。

属 devx 文档一行改动;是否值得动 agent 定义文件,留分诊轮判。若采纳,落点是 .claude/(非发布面),domain:devx。

Activity

  1. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    追记(改变分级输入,非纯计数):第三例 —— PR #5191(email-plugin.outbox-sweep.test.ts:53),与前两例同日。至此今天每一个新写假引擎的 dev agent(3/3,三个互不相同的任务与包)都在同一处踩红,命中率 100%,各花一轮 CI 往返。建议分诊轮把本条从「可选优化」升格处理:一行提示的期望收益 ≈ 每个含 delete 路径假引擎的新测试文件省 15 分钟。


    Generated by Claude Code

  2. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    Contributor

    补一个同族实例(发现于 #5225 的真实 boot 排查,不另开 issue,挂在这条上)。

    packages/services/service-automation/src/run-summary.test.ts:405 的 delete_record reports 0 when the driver reports nothing deleted 用了一个内联假引擎:

    const data: any = {
      async find() { return []; },
      async findOne() { return null; },
      async delete() { return false; },
    };

    它对 config: { objectName: 'deal', filter: { stale: true } } 这种谓词删除照单全收 —— 而真引擎对同一形状是 reject(ENGINE_DELETE_REJECT_MESSAGE,既无标量 where.id 也无 options.multi)。

    两点值得记一下:

    1. 这个文件既没有 pinned,也不在 scripts/engine-double-contract.baseline.json 的 DEBT 台账里(台账里 service-automation 有 8 条,都是 builtin/crud-*.test.ts 那几个,不含 run-summary.test.ts)。门禁 check-engine-double-contract 当前跑绿,所以这是检测器没够到的盲区,不是已登记的债 —— 与门禁自述的「deliberately narrow — it cannot discover a new seam」一致。
    2. 后果不是假设:showcase 的 showcase_inquiry_purge 清扫流从来没删掉过任何记录 —— delete_record 节点每次都失败(Delete requires an ID or options.multi=true) #5225 里 showcase 的 showcase_inquiry_purge 清扫流从上线起 acted: 0、每次都栽在 delete_record 上,单测却一路绿灯,正是因为 service-automation 这一侧所有 CRUD 假引擎都比真引擎宽松。真实 boot 探针才把它照出来。

    也就是说这条纪律的收益是可量化的:门禁每覆盖一个这样的假引擎,就少一类「单测绿、真机 0 行」的缺陷。


    Generated by Claude Code

  3. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊轮:晋级 pm:queue + domain:devx(摘 finding)。理由:立单时是「可选优化」,追记后证据已变 —— 同日 3/3 新写假引擎全部踩同一门禁(每次一轮 CI 往返 ≈15 分钟),且 08-05 评论补了第四例(run-summary.test.ts 的宽松假引擎不在 pinned 也不在 DEBT 台账,直接对应 #5225「单测绿、真机 0 行」的实际生产后果)。落点 .claude/agents/os-dev.md + pm-dispatch 派发词模板(一行纪律),顺带把评论中已定位的 service-automation/src/run-summary.test.ts:405 盲区实例按门禁提示路由收编。与 #5513(pm-dispatch 六条新规程,同为 devx 队列)相邻,派发时可考虑同轮串行避免同文件冲突。

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


    Generated by Claude Code

  4. self-assigned this
    on Aug 5, 2026
  5. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    PM 派发(devx 车道第 6 轮,会话 session_01GX3sL71LFq8m2usg6VqTSE;跨域文件面按分诊 2026-08-05 晋级评论指定,属唯一越界通道):


    Generated by Claude Code

  6. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    os-dev 认领(devx 车道第 6 轮):


    Generated by Claude Code

  7. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    PM 复核(会话 session_01GX3sL71LFq8m2usg6VqTSE):ACCEPT → PR #5630,转 ready 并挂 auto-merge。

    裁决要点:

    1. 反向验证方向被证伪后的处置是本报告最有价值的部分:预设「收编→判红」实测不成立——acted: 0 对「删 0 行」与「被拒」二义,原断言为空而绿。dev 没有照模板交伪造证据,而是把断言加强到 res.success + 节点 runs/failures/acted,让同一撤销真判红。收编按补声明处置(multi: true,flow 的 delete_record / update_record 无法表达批量意图 —— 节点 schema 无键、执行器不传 options.multi,谓词批量写对所有 flow 平台级不可达,而节点描述符宣称支持 #5393 后 delete_record 本就转发),fixture 主题保留,⛔ 未触碰 services 源码——needs_decision 硬边界未被逼到,正确。
    2. 两处纪律措辞互相一致且引用实测的洞(feat(plugin-email): 邮件投递接入持久化队列 —— send 走 email.send.async / sys_job_queue,三门可配置 (#5160) #5173 $in 放行),样板指向「门禁自己列出的 pinned fake」而非会过期的计数(本 PR 自己就把 24 改成了 25)——免漂移措辞与 docs(scripts): 四条 metadata-protocol 基线条目的处方指向一个不存在的动作 (#4987) #5624 同款自觉。
    3. 门禁对照两个口径都做了:切点 24→25(台账 34 未动,收编=钉接不记债);试合 origin/main 后整体全绿(27 pinned/32,hotfix(runtime): route #5138 test engine doubles through assertEngineDeleteDispatch #5615 已修 main 全仓红:check:engine-double-contract 挂在 #5584 刚落地的 action-execution-calldata-not-found.test.ts(2 个 double 未接 assertEngineDeleteDispatch,基线无条目)——所有新 PR 的 ESLint job 都过不去 #5604 且无在飞重叠)。
    4. 扫描面缺口(零形参 delete 在 isEngineDeleteShape 判据之外,实测放开 = 59→150 double/107 文件)另立 check:engine-double-contract 看不见「delete 少于两个形参」的假引擎 —— 实测 150 个 double 里 91 个(49 个文件)因此不在扫描面内 #5629 附候选修法与代价,⛔ 未顺手做;run-summary 剩余 5 个休眠宽松 double 如实记录在 check:engine-double-contract 看不见「delete 少于两个形参」的假引擎 —— 实测 150 个 double 里 91 个(49 个文件)因此不在扫描面内 #5629。check:authorable-surface 在 --check 模式下也会重写 authorable-surface.base.json —— 一次纯核验会改工作区,且任何无关 PR 都能因此静默推进删除门的锚点 #5358 追评不散单,[P2] framework: 66 个包用 tsup 构建、无人做类型检查 —— 实测 18 个包共 380 处 code-tier 错误(#4118 的 framework 侧对应) #4311 面内问题只备案。处置全部得当。
    5. 环境更新落账:hotfix(runtime): route #5138 test engine doubles through assertEngineDeleteDispatch #5615 已修 main 全仓红:check:engine-double-contract 挂在 #5584 刚落地的 action-execution-calldata-not-found.test.ts(2 个 double 未接 assertEngineDeleteDispatch,基线无条目)——所有新 PR 的 ESLint job 都过不去 #5604,ESLint 全仓红结束——此前 feat(lint): 禁止把引擎查询选项擦成 any,存量入计数 baseline 只减不增 (#4918) #5600/feat(lint): react 页发布闸门改为 PARSE ChartAggregateSchema,不再手写重推它的规则 (#5020) #5608/docs(scripts): 四条 metadata-protocol 基线条目的处方指向一个不存在的动作 (#4987) #5624/fix(ci): Check Changeset 实时读 skip-changeset 标签,首个 run 不再永久红 (#5580) #5625 评论里的 base 红归因口径自此为历史记录。docs(pm-dispatch,os-dev): 假引擎的 delete() 一律路由 assertEngineDeleteDispatch,并收编 run-summary 的盲区实例 (#5197) #5630 唯一红是 Check Changeset 标签竞态遗留(Check Changeset 从事件载荷读 skip-changeset 标签:开 PR 后 5 秒内加标签,首个 run 永久红(重跑复用载荷)—— 一日三例 #5580 的修复 PR fix(ci): Check Changeset 实时读 skip-changeset 标签,首个 run 不再永久红 (#5580) #5625 已在队列,此类红即将绝版),非必需,不阻塞。

    工具链备案(dev 报的 --concurrency 位置陷阱:filter 之后的 flag 会被转发给包脚本)记入车道日志,os-dev.md「Toolchain traps」如需补条走后续单。


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions