
审查发现的竞态条件,按原因退回的停滞作业
两个案例:一个的规范与提交写明由 Claude 实现、Codex 审查;另一个让停滞作业变得可诊断。
May 19, 2026
配额耗尽即停止的变更,连同审查发现的竞态条件,在同一个 PR 中修复
人人
行动配额耗尽时停止花费 · 不做自动回退
- 交接实现约束→ 实现检查点 · halt · 手动恢复 (Claude)
编程智能体Claude
行动实现检查点 · halt · 手动恢复
- 交接同一 PR 内审查→ 审查意见:竞态条件 · 重复的状态转换 (Codex)
审查 · 验证Codex
观测 · 审查意见审查意见:竞态条件 · 重复的状态转换
- 退回竞态 · 幂等性→ 在同一 PR 中:行锁 · 唯一评分键 · 原子转换 (同一 PR)
产物同一 PR
产物在同一 PR 中:行锁 · 唯一评分键 · 原子转换
- 交接→ 本地 fixture · 数据库集成检查记录 (同一 PR)
产物同一 PR
产物本地 fixture · 数据库集成检查记录
- 不是记录在案的执行已检查的范围→ 未收集新的 CI 或生产部署结果 (同一 PR)
产物同一 PR
规范 · 未确认未收集新的 CI 或生产部署结果
- 背景
- 人设定的条件是:配额耗尽时停止花费,不做自动回退。Claude 实现了检查点、halt 和手动恢复,经项目 MCP 运行的 Codex 审查发现了状态转换中的竞态条件和重复。
- 结果
- 进入与恢复的状态转换在锁内执行,评判分数带唯一键以防重复,并划定了事务边界。这并不意味着已消除所有竞态条件。
- 局限
- 提交中写的是 140 项检查,之后的集成 CHANGELOG 写的是 160 项,因此未合并为同一个运行数。按规范,Codex 审查是可选的本地步骤,因此这并不意味着过去每个 PR 都经过了它。
依据与尚存的局限
- 规范记录了顺序:Claude 实现,Codex 经项目 MCP 在本地审查,审查结果附在 PR 上,意见分歧时与 Claude 的审查智能体一同调查。CI 中的自动 Codex 审查当时已被推迟。
- 开发检查使用 fixture 和 mock,真实模型调用需要单独划定范围。审查意见并入同一个 PR,并以 feature → main 方式 squash 合并。
May 26, 2026
让停滞作业可诊断,并按原因退回
开发对象翻译 worker · 队列
观测 · 审查意见停留在 draft 的作业 · 尝试次数耗尽
- 交接观测值→ 比对 failedReason · 退出码 · draft 状态 (开发者)
人开发者
行动比对 failedReason · 退出码 · draft 状态
- 交接→ 原因:继承的 NODE_OPTIONS 在子进程中冲突 (开发者)
人开发者
观测 · 审查意见原因:继承的 NODE_OPTIONS 在子进程中冲突
- 退回继承选项冲突→ 移除 NODE_OPTIONS · 每进程并发上限 (代码变更)
工作会话代码变更
行动移除 NODE_OPTIONS · 每进程并发上限
- 交接→ 队列状态:waiting · active · failed · stale (代码变更)
工作会话代码变更
行动队列状态:waiting · active · failed · stale
- 交接→ 停滞巡检:区分不在队列中与尝试用尽,按有无结果分支 (代码变更)
工作会话代码变更
行动停滞巡检:区分不在队列中与尝试用尽,按有无结果分支
- 交接一个周期→ 开发环境巡检:200 个候选 → 106 个转移 · 2 个重新入队 · 0 个错误 (产物)
产物产物
产物开发环境巡检:200 个候选 → 106 个转移 · 2 个重新入队 · 0 个错误
- 不是记录在案的执行解读的边界→ 这 106 个并非翻译成功 (产物)
产物产物
规范 · 未确认这 106 个并非翻译成功
- 背景
- 比对 BullMQ 的 failedReason、子进程退出码以及停留在 draft 的作业,发现继承的 NODE_OPTIONS 在子进程中发生冲突。此后,同样的情况可以作为队列状态看到。
- 结果
- 停滞作业分为不在队列中的和尝试次数用尽的;后者依据是否有结果,带着原因移入 needs_review 或 needs_credential。人工审核保持不变。
- 局限
- 并发上限按进程计。审阅的材料中没有原始运行日志;由于未记录当时请求的模型和 effort,延迟数据从略。仅有构建与发布代码,不能作为公开部署的依据。
依据与尚存的局限
- CHANGELOG 记录了一个并行 adapter 分支的提议,但未将其当作实际并行执行的记录。
- 200 个中的其余部分在此记录中未细分。