Skip to content

Latest commit

 

History

History
841 lines (575 loc) · 51.9 KB

plan-20260910.md

File metadata and controls

841 lines (575 loc) · 51.9 KB

CL merge 强制走 MonoWriteQueue 并删除 legacy 写者计划(2026-09-10)

改名註記(2026-09-17): 本文成稿與執行時,Cargo 包名/二進制名為舊名,lib 為舊名 _core;2026-09-17 起全倉統一改名為 Mega2(mega2 / mega2_core),本文中的命令、路徑、環境變量與服務名已同步更新,歷史提交記錄本身不變。

模板版本: v2;依据 plan-template.md,核对日期 2026-09-10。

文档职责

本文解决「CL merge 仍可通过 [monorepo].merge_writer = "legacy"(及缺省 legacy)绕过 MonoWriteQueue,与 I5 / ADR-TP-05 的全序前提冲突」的缺口。前提是:没有在跑老实例、不考虑存量 merge_queue 行迁移/吸收。目标是交付:全部 CL merge 入口只经 MonoWriteQueue(kind=merge → B3);删除 merge_writer 配置与 Legacy processor;删除 merge_queue 表及 Rust 四层;保留 /merge-queue HTTP 形状作为 push_queue 的产品门面。

本文只规划任务,不宣称实现完成。落地时每个任务都必须先刷新源码锚点(GC-01),再按任务卡验收。

适用范围

  • CL merge 入口:POST /cl/{link}/merge、POST /cl/{link}/merge-no-auth、POST /merge-queue/add / retry。
  • /merge-queue 的 list/status/stats 读路径(映射到 push_queue Merge 行)。
  • [monorepo].merge_writer 配置、reload、样例与校验。
  • Legacy 后台 processor(ensure_merge_processor_running / execute_merge_workflow / merge_cl_unchecked)。
  • merge_queue 实体、storage/service/DTO、吸收路径、Postgres 表与相关枚举。
  • UN-20 / UN-25 测试改挂 push_queue;部署与错误文档同步。

非目标

  • 不删除 /merge-queue/* HTTP 表面(ADR-MW-02 / ADR-TP-05:保留路由与请求/响应形状)。DELETE /remove 与 POST /cancel-all 已 410,保持。
  • 不做 存量 merge_queue 行吸收(prepare_for_queue_writer / absorb_into_push_queue 删除,不迁移数据)。无老实例 ⇒ 表视为空或可丢弃。
  • 不改 B3 merge 语义、UN-17 执行主体、UN-19 ACL、GPG 门、CL revision CAS。
  • 不改 push_policy / trunk 直推 / attach / 物化路径。
  • 不重开 DEFER-TP-01..05。
  • 不回改 plan-20260905 TP-07 历史验收勾选;本计划 sunset 该卡留下的开关与 dual-path。

成功定义

  • 省略或写入任何历史 merge_writer 值后:不存在可编译/可运行的 Legacy merge 写者;CL merge 只走 merge_cl_via_queue → B3。
  • [monorepo] 无 merge_writer 键;样例配置中的该行与注释消失;残留键按未知字段拒绝启动。
  • merge_queue 表不存在;src/ 无 MergeQueueStorage / MergeQueueService / callisto::merge_queue。
  • /merge-queue 门面仍可用,读写均以 push_queue 为事实源。
  • 全部非延后任务卡 Lifecycle=done 且 Acceptance=complete;计划级 Codex 评审对本计划文档 PASS。

事实基线

所有行号和源码锚点必须在开工当天刷新(GC-01)。下列锚点核对日为 2026-09-10。

类别 当前事实 证据
工作树 VCS 本 checkout 使用 Libra(.libra);发布走 libra add / libra commit / libra push origin main(模板 GC-12/ER-07 的 git * 对本 checkout 以 AGENTS 为准) test -d .libra;libra status --short --branch
mega2 tip 86c551cfc99333206c1b0e95c19e7fb32ffbdb0d(LF-04) libra log -1
包版本 0.8.6 Cargo.toml:3
配置缺省 MergeWriter 缺省 Legacy;样例注释 # merge_writer = "legacy"(省略 = legacy) src/config/model.rs:165-217;config/config.toml:80-82;src/config/template.rs:54-56
配置校验 无语义校验(无排空);仅 known-keys 含 merge_writer;非法变体由 serde 拒绝 src/config/validate.rs:1544-1553;:3043-3058
Reload 改 merge_writer 记入 restart_required_fields src/config/reload.rs:728-729
Merge 入口 merge_cl:Queue → merge_cl_via_queue;否则 merge_cl_unchecked src/ceres/api_service/mono_api_service.rs:2312-2333
Queue 生产路径 merge_cl_via_queue → enqueue_and_wait(kind=Merge,operation_id=cl.link)→ execute_b3 mono_api_service.rs:2396-2479
B3 b3_execute_merge 不调用 merge_cl_unchecked src/jupiter/service/push_queue_service.rs:2097-2175
merge_cl_unchecked 仅两处调用:Legacy merge_cl、Legacy execute_merge_workflow mono_api_service.rs:2331、:5481、定义 :2973
/merge-queue/add Queue:同步 B3,消息 "Merged";Legacy:入 merge_queue + 后台 processor src/api/router/merge_queue_router.rs:55-90;mono_api_service.rs:4570-4607
list/status/stats Queue 读 push_queue;Legacy 读 merge_queue_service merge_queue_router.rs:132-338
Processor ensure_merge_processor_running 在 Queue 为 no-op;Legacy spawn run_merge_processor_loop mono_api_service.rs:5211-5264;merge_queue_service.rs:179-192
启动吸收 start_http 在 Queue 时 prepare_for_queue_writer src/server/http_server.rs:428-441
巡检 AppContext::new 仅当 Queue 或 Trunk 才 spawn write-audit src/context/mod.rs:299-306
表 merge_queue + requester 列;迁移两份;无 drop src/callisto/merge_queue.rs;m20251109_073000_add_merge_queue(migration/mod.rs:64/168);m20260815_000100_merge_queue_requester(:111/215)
HTTP 保留 ADR-TP-05:吸收后保留 HTTP 形状 docs/refactoring/trunk-push.md:210/966/1001
UN-17 纯函数 + B3 apply_queue_execution_decision;不依赖表 mono_api_service.rs:272;push_queue_service.rs:2274
UN-25 冻结写 merge_queue Failed+SystemError;B3 已 b3_fail_merge + emit_authz_frozen_alert;事件名 merge_queue_authz_frozen docs/errors.md:101;un25_freeze.rs;push_queue_service.rs:2289
测试 test_storage 缺省 Legacy;test_storage_queue_merge 显式 Queue;唯一显式 Legacy 赋值 tp12_review_keeps_noop src/jupiter/tests.rs:172-176;mono_api_service.rs:10379
UN-20 HTTP un20_add_handler_* 断言 merge_queue_service.get_queue_requester(Queue 下会失败) src/api/un20_queue_requester.rs
D 组 .github/workflows/ 无 workflow 文件 2026-09-10 核对
工作区前置 .env.test 存在 .env.test
外部参照 N/A N/A

当前缺口

ID 缺口 影响 证据 计划动作
GAP-MW-01 缺省 merge_writer=legacy:/merge 与 /merge-no-auth 走 merge_cl_unchecked,不入 push_queue 破坏 I5;与 attach/trunk 并发可覆盖根树 mono_api_service.rs:2320-2333 MW-01
GAP-MW-02 /merge-queue/add 在 legacy 下异步入旧表并启动 processor 与「同步已执行」门面分叉;跨实例无全序 merge_queue_router.rs:85-90;mono_api_service.rs:4599-4607 MW-01
GAP-MW-03 配置开关与样例仍把 legacy 当可选项 运维可回退到未覆盖写者 model.rs:211-217;config.toml:80-82 MW-03
GAP-MW-04 Legacy processor + merge_cl_unchecked 仍在树中 死代码/可再启用的旁路 mono_api_service.rs:5211-5501 MW-02
GAP-MW-05 merge_queue 表、entity、storage/service、absorb 仍在 双事实源;启动吸收假定迁移 merge_queue_service.rs:287-377;http_server.rs:428-441 MW-04、MW-05
GAP-MW-06 文档仍写「缺省 legacy / 生产 queue」与表级 freeze 与 sunset 目标矛盾 docs/deploy-trunk.md:13;docs/errors.md:101 MW-06

与其它计划的关系

计划/文档 关系 本计划处理
plan-20260905.md TP-07 / ADR-TP-05 前置:Queue 路径与开关已交付 不重做 B3 merge;sunset 开关与 dual-path;不回改 TP-07 勾选
docs/refactoring/trunk-push.md 设计事实源(HTTP 表面保留、merge 同步化) MW-06 把滚动部署/开关段标为已由本计划关闭
plan-20260909.md 并行无关(LFS) 不触碰
plan-long.md 无 PT 强制关联 索引登记本计划
AGENTS.md / 任务卡发布规则 Libra 发布 遵守;本计划文档提交 Version increment=N/A

评审结论与修订记录

计划成稿前自审:

维度 结论 修订动作
合理性 无老实例则开关与旧表只有旁路成本;I5 要求 merge 不能再走队列外写者 本计划承接
可行性 Queue 路径已存在;工作是删分支/删模块/DROP TABLE 六张 S–M 卡
任务卡粒度 入口 / processor / 配置 / Rust 四层 / schema / 文档分轴;无 L/XL 见粒度审计表
依赖与顺序 全串行:入口收口 → 删 processor → 删配置 → 删 Rust 层 → DROP 表 → 文档 DAG 无环
完整性 测/文档/forward-only 迁移/回滚齐全 见各卡
安全性 不扩大匿名 merge 面;UN-17/19/25 留在 B3 ADR-MW-01
功能正确性 /merge-queue 形状保留;add 已同步 ADR-MW-02
接口兼容 删除配置键(残留拒绝);省略键从 legacy 变为 queue(无实例前提下的目标行为) ADR-MW-03;MW-01/MW-03 minor
数据流 无吸收;DROP 丢弃表(假定空) ADR-MW-04
性能 去掉第二套 processor;merge 成本仍为 B3 继承 GC-10
可靠性 唯一写者 = 队列 + advisory lock I5
可维护性 单一 merge 执行体 b3_execute_merge GC-MW-01

修订历史

日期 触发 变更内容 原卡 → 新卡 受影响的引用
2026-09-10 成稿 首版:MW-01..MW-06;ADR-MW-01..04;GAP-MW-01..06 N/A 全文
2026-09-10 Codex R1 FAIL ①G-* / 判定口径改为显式 N/A 继承模板;②各卡 AC 按 G-03 单谓词重写;③Current evidence 补精确锚点;④MW-01 覆盖 add 的 get_display_position_by_position;⑤MW-04 写集纳入 freeze_merge_queue_item_for_authz 与 un19_fail_closed.rs MW-01..MW-06 字段修订 粒度审计表、Review log
2026-09-10 Codex R2 FAIL HTTP DTO src/ceres/model/merge_queue.rs:4-7/:97-266 仍 From 旧实体与 merge_queue_dto;MW-04 不得先删 DTO 文件。DTO/From 清理并入 MW-05;MW-01 守卫改为 merge_queue_service(避免 fn get_queue_stats 自命中) MW-04 写集缩小;MW-05 写集扩大 粒度审计表、Review log
2026-09-10 Goal 执行覆盖 实现阶段全部任务卡(含原计划 MW-01/MW-03 minor 与 MW-06 N/A)按 patch +1 发布,不 bump minor 各卡 Version increment 执行口径 Cargo.toml、Review log

已决议设计决策

ADR-MW-01: CL merge 唯一写者是 MonoWriteQueue

  • Status: Accepted
  • Context: TP-07 用 merge_writer 做滚动开关;缺省 legacy 使未改配置的实例仍走 merge_cl_unchecked。用户确认无老实例、不做迁移。
  • Decision: 删除 dual-path。所有 merge 入口只调用已存在的 merge_cl_via_queue(B1 入队 + 同步等 B3)。不保留「忽略配置但仍编译 Legacy」的中间态作为发布终态(MW-01 收口入口后,后续卡删除 processor/配置/表)。
  • Alternatives considered: (1) 只改缺省为 queue 保留枚举——拒绝,旁路仍可启用;(2) 继续吸收存量行——拒绝,本计划前提是无迁移。
  • Consequences: 省略配置即走 Queue;/merge-queue/add 对所有部署均为同步「已执行」。Review 形态也 spawn write-audit(队列成为 merge 的唯一根写者)。
  • Revisit when: 若出现必须离线 merge 的紧急回退需求(预期永不)。

ADR-MW-02: 保留 /merge-queue HTTP 门面

  • Status: Accepted
  • Context: ADR-TP-05 / trunk-push.md 明确 HTTP 表面保留指路由与 JSON 形状;执行已同步化。
  • Decision: 不删除 merge_queue_router。list/status/stats/add/retry 只谈 push_queue。remove/cancel-all 保持 410。
  • Alternatives considered: 删除 /merge-queue 只留 /push-queue——拒绝,属公开 API 删除,需独立 G-08 家族与客户端窗口(DEFER-MW-01)。
  • Consequences: QueueItem::from_push_queue 与 list_merge_for_legacy_ui 名称可保留(非本计划改名轴)。
  • Revisit when: 客户端全部改读 /push-queue。

ADR-MW-03: 删除 [monorepo].merge_writer

  • Status: Accepted
  • Context: 开关只服务迁移;无实例后配置是谎言。
  • Decision: 删除字段、枚举、reload 项、known-keys。样例与 docs/deploy-trunk.md 去掉该键。残留 merge_writer = ... 走既有未知字段拒绝(fail-closed)。
  • Alternatives considered: 保留键但忽略——拒绝,GC-02 禁止死配置。
  • Consequences: 运维必须从 toml 删行;MW-03 为公开配置面删除,Version increment=minor。
  • Revisit when: N/A。

ADR-MW-04: 不吸收,直接 DROP merge_queue

  • Status: Accepted
  • Context: 吸收是滚动部署产物;无老实例则 Waiting/Testing/Merging 行不是约束。
  • Decision: 删除 prepare_for_queue_writer / absorb_into_push_queue。MW-05 以 forward-only 迁移 DROP TABLE merge_queue;若 Postgres 枚举 queue_status_enum / queue_failure_type_enum 无其它表使用则一并 DROP TYPE。不写 down。
  • Alternatives considered: 保留空表——拒绝,双实体持续迷惑。
  • Consequences: 若有人违反前提留下行,数据丢失且无补偿;本计划视为操作责任。UN-25 测试改挂 push_queue。日志事件名 保持 merge_queue_authz_frozen(避免告警查询断裂;DEFER-MW-02 可改名)。
  • Revisit when: 发现非空表的意外部署。

全局工程约束

遵守模板 GC-01..GC-12;本 checkout 发布命令以 AGENTS.md 的 Libra 为准。本计划附加:

  • GC-MW-01: 生产 merge 落地只允许 push_queue_service B3 b3_execute_merge;禁止恢复 merge_cl_unchecked 作为入口。
  • GC-MW-02: 禁止第二套 merge 执行器(进程内 AtomicBool processor、Redis 锁、离队直写根树)。
  • GC-MW-03: 不新增 crate 级 #[allow(...)];生产路径不新增裸 unwrap/expect。
  • GC-MW-04: /merge-queue 路由文件可改实现,不得无 DEFER 地删路由。
  • GC-MW-05: 不回改 plan-20260905.md 历史 AC 勾选。

执行检查必备需求(强制)

全文遵守 plan-template.md 的 ER-01..ER-12。特化:

  • VCS: libra status / libra add <paths> / libra commit -m / libra push origin main;禁止 --force。模板中的 git * 替换为上述 Libra 命令。
  • ER-04 D 组: .github/workflows/ 与 .github/workflow/ 均无文件(2026-09-10)。所有卡 D 组 N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中);Acceptance 在 C 覆盖后可直接 complete。
  • ER-08: 实现卡按各卡 Version increment;本计划文档成稿提交不 bump。Goal 执行覆盖:MW-01..MW-06 一律 patch +1,不 bump minor(覆盖表中 MW-01/MW-03 minor 与 MW-06 N/A)。
  • ER-01: 工作区若有无关脏文件(例如本核对日 config/config.toml 的 admin 本地改动),不得并入本计划提交。

实施顺序

  • MW-01 -> MW-02
  • MW-02 -> MW-03
  • MW-03 -> MW-04
  • MW-04 -> MW-05
  • MW-03 -> MW-06
  • MW-05 -> MW-06

依赖登记表

ID direction 类型 对象 Owner 产物与可用性判据 证据 超时与失败策略
DEP-MW-01 incoming 跨计划 plan-20260905 TP-07(merge_cl_via_queue / B3 merge / /merge-queue 同步化已交付) 本计划 tip 含 merge_cl_via_queue 与 b3_execute_merge plan-20260905.md TP-07 done;mono_api_service.rs:2396 缺失则不得开工
DEP-MW-02 outgoing 跨计划文档 plan-20260905 TP-07「开关保留为迁移回退」叙述 历史计划只读 MW-06 在 trunk-push / deploy 写 sunset;不回改 TP-07 勾选 ADR-MW-01 接收方无需动作

发布分组与并发窗口

ID 成员 唯一发布点 窗口规则 失败回滚顺序 理由
N/A — — 默认每卡独立发布(G-07) — 写集顺序依赖已用 DAG 表达,无需家族

并发声明: 实现阶段全串行(G-10:mono_api_service.rs、jupiter/tests.rs、merge_queue_service.rs 相交)。

发布者: 执行本计划的单一 Agent(ER-12)。

发布窗口顺序: MW-01 → MW-02 → MW-03 → MW-04 → MW-05 → MW-06。

Phase 0: 基线冻结

目标: 确认 dual-path 仍在;Queue 路径可复用;无并行改动 merge 入口。

进入条件: DEP-MW-01;ER-01 脏区不覆盖目标文件(config.toml 的无关 admin 改动保留不提交)。

退出条件: 事实基线行号在开工日刷新。

Phase 1: 入口与死代码

目标: MW-01 + MW-02:merge 只走队列;processor 与 merge_cl_unchecked 删除。

进入条件: Phase 0 退出。

退出条件: 生产路径无 Legacy 分支;processor 符号零命中。

Phase 2: 配置与存储退场

目标: MW-03 删键;MW-04 删 storage/service;MW-05 DROP TABLE 并拆除 HTTP DTO 旧 From。

进入条件: Phase 1 两卡 locally-accepted 且可发布。

退出条件: 无 MergeWriter;无 merge_queue 表/模块。

Phase 3: 文档收口

目标: MW-06。

进入条件: MW-03 与 MW-05 均已发布(或 MW-06 继承的 C 覆盖点已含最终文档所需行为)。

退出条件: 部署/错误/trunk-push 与索引一致。

任务卡

任务卡粒度规则(G-*)

N/A(原因:全文逐字遵守 plan-template.md 的 G-01..G-11 与推荐拆分/反模式速查;不在本文件复制以免与模板漂移。本计划以各卡 Granularity 行与「任务卡粒度审计表」为机器可核对摘要。)

Verification 判定口径

N/A(原因:逐字继承 plan-template.md「Verification 判定口径」,含零命中 rg 退出码模板。本卡 Verification 只登记本卡特有命令。)

字段全局默认与例外

  • Release boundary 默认: independent
  • Task type 默认: implementation
  • Rollback mode 默认: revert
  • Migration and rollback 默认: N/A
  • Security and privacy 默认: 继承 GC-07、GC-MW-01..02
  • Performance budget 默认: 继承 GC-10
  • Docs and compatibility impact 默认: 按 GC-05 同步触及的 docs 与 config 注释

默认覆盖:

任务 偏离的字段 取值与理由
MW-01 Version increment minor:省略配置时 merge 从队列外变为队列内,可观察行为变化
MW-03 Version increment minor:删除公开配置键
MW-05 Task type / Rollback mode / Migration / Version increment migration / forward-only / DROP TABLE(down 空)/ patch(内部表,非 HTTP 面)
MW-06 Task type / Release boundary / Version increment / C/D coverage from docs / no-release / N/A / 继承 MW-05

规则 waiver: 无(无 EX-*)。

任务卡粒度审计表

任务 type axis recovery complete self-contained AC VER landing / prod-files scope deps writeset release split-from exception
MW-01 implementation merge 入口只走 MonoWriteQueue revert 恢复 dual-path yes yes 8/8 6/8 4/4 M DEP-MW-01 序列化于 MW-02 independent N/A N/A
MW-02 implementation 删除 Legacy processor 与 merge_cl_unchecked revert 恢复 processor yes yes 8/8 3/8 2/3 S MW-01 序列化于 MW-01 independent N/A N/A
MW-03 implementation 删除 merge_writer 配置面 revert 恢复字段 yes yes 7/8 4/8 1/5 M MW-02 序列化于 MW-04 independent N/A N/A
MW-04 implementation 删除 merge_queue storage/service 与 absorb revert 恢复模块 yes yes 8/8 4/8 3/5 M MW-03 序列化于 MW-05 independent N/A N/A
MW-05 migration DROP merge_queue 表与实体 forward-only 前滚 yes yes 8/8 6/8 4/9 M MW-04 序列化于 MW-06 independent N/A N/A
MW-06 docs 文档 sunset 开关与旧表 revert 文档 yes yes 8/20 3/20 0/0 M MW-03,MW-05 no-overlap no-release N/A N/A

Task MW-01: 全部 CL merge 入口只走 MonoWriteQueue

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 去掉 MergeWriter 分支:merge_cl、add_to_merge_queue_as、retry_merge_queue_item_as 只走 merge_cl_via_queue;merge_queue_router 的 list/status/stats 与 add 成功消息只走 push_queue 臂;start_http 不再调用 prepare_for_queue_writer;AppContext::new 在 push_policy=review 下也 spawn write-audit。本卡结束后生产入口不再读取 merge_writer(字段可暂留到 MW-03)。

Out of scope:

  • 删除 MergeWriter 类型与配置键(由 MW-03 承接)
  • 删除 processor / merge_cl_unchecked 函数体(由 MW-02 承接;本卡只不再从入口调用)
  • 删除 merge_queue 模块与表(MW-04/MW-05)
  • 删除 /merge-queue 路由(永久非目标于本计划,ADR-MW-02)

Current evidence:

事实 证据
merge_cl 只走 merge_cl_via_queue mono_api_service.rs:2312-2329
add 只走 merge_cl_via_queue mono_api_service.rs:4562-4586
retry 转 add mono_api_service.rs:4857-4864
router list/status/add 只读 push_queue merge_queue_router.rs:54-98、:129-137;rg merge_queue_service 退出码 1
启动无吸收 rg prepare_for_queue_writer src/server/http_server.rs 退出码 1
Review 亦 spawn write-audit context/mod.rs:297-302
UN-20 add 断言 push_queue src/api/un20_queue_requester.rs
add display_position merge_queue_router.rs:68-78(list_merge_for_legacy_ui)

Acceptance criteria:

  • merge_cl 不调用 merge_cl_unchecked
  • add_to_merge_queue_as 只调用 merge_cl_via_queue
  • retry_merge_queue_item_as 不调用 retry_queue_item_with_requester
  • GET /merge-queue/list 不调用 get_queue_list
  • GET /merge-queue/status/{cl_link} 不调用 get_cl_queue_status
  • add_to_queue handler 不调用 merge_queue_service.get_display_position_by_position
  • AppContext::new 在 PushPolicy::Review 下 spawn write-audit
  • start_http 不调用 prepare_for_queue_writer

Verification:

  • source .env.test && cargo test -p mega2 --lib 'ceres::api_service::mono_api_service::tests' -- --nocapture
  • source .env.test && cargo test -p mega2 --lib 'api::router::merge_queue_router' -- --nocapture
  • source .env.test && cargo test -p mega2 --lib 'api::un20_queue_requester' -- --nocapture
  • (new) queue_add_uses_push_queue_not_merge_queue_table:缺省配置下 POST /merge-queue/add 写入 push_queue
  • 零命中守卫(模板退出码模板):rg -n 'prepare_for_queue_writer' src/server/http_server.rs → 退出码 1
  • 零命中守卫(模板):rg -n 'merge_queue_service' src/api/router/merge_queue_router.rs → 退出码 1

Dependencies: DEP-MW-01

Deliverables: N/A

Implementation write set: src/ceres/api_service/mono_api_service.rs(入口与 UN-20 相关测试);src/api/router/merge_queue_router.rs;src/server/http_server.rs;src/context/mod.rs;src/api/un20_queue_requester.rs

Release write set: Inherited

Files likely touched: 同上

Docs and compatibility impact: 随附:若 OpenAPI 成功消息字符串变化,运行时 spec 随之变化;长文交 MW-06

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 不改变 UN-19/GPG/匿名 merge-no-auth 映射;只改变执行是否入队

Performance budget: Inherited(merge 改为同步等待 B2/B3,与 TP-07 queue 臂相同)

Estimated scope: M(landing=4;prod-files=4)

Version increment: patch(Goal 覆盖原 minor)

Release boundary: independent

C/D coverage from: self

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中)

Granularity: type=implementation; axis=merge 入口只走 MonoWriteQueue; recovery=revert 恢复 dual-path; complete=yes; self-contained=yes; AC=8/8; VER=6/8; landing=4; prod-files=4; scope=M; deps=DEP-MW-01; writeset=序列化于 MW-02; release=independent; split-from=N/A; exception=N/A

Task MW-02: 删除 Legacy processor 与 merge_cl_unchecked

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 删除后台 merge processor 与仅被其使用的落地函数:ensure_merge_processor_running、run_merge_processor_loop、process_next_queue_item、execute_merge_workflow、merge_cl_unchecked;删除 MergeQueueService 上的 try_start_processor / stop_processor / processor_running;删除无路由调用方的 add_to_merge_queue / retry_merge_queue_item(非 _as);更新 un19_acl_change.rs 过时「funnel through merge_cl_unchecked」注释;删除 execute_merge_workflow_* 单测(GPG 门改挂仍存在的 ensure_gpg_check_passed / merge_cl 用例)。

Out of scope:

  • 配置键(MW-03)
  • merge_queue storage 查询 API(MW-04 前 UN-25 测试仍可直接插表)
  • B3 / UN-17

Current evidence:

事实 证据
processor 符号已删 rg 'fn ensure_merge_processor_running|fn run_merge_processor_loop|fn process_next_queue_item|fn execute_merge_workflow|fn merge_cl_unchecked' src/ 退出码 1
AtomicBool / try_start 已删 rg 'try_start_processor|processor_running' src/jupiter/service/merge_queue_service.rs src/ceres/ 退出码 1
非 _as add/retry 已删 rg 'fn add_to_merge_queue\(' src/ 退出码 1;rg 'fn retry_merge_queue_item\(' src/ceres/ 退出码 1
UN-19 注释 un19_acl_change.rs 无 merge_cl_unchecked
GPG 门仍挂 merge_cl mono_api_service.rs ensure_gpg_check_passed + 既有 merge_cl_* 测

Acceptance criteria:

  • src/ 无 fn ensure_merge_processor_running
  • src/ 无 fn run_merge_processor_loop
  • src/ 无 fn process_next_queue_item
  • src/ 无 fn execute_merge_workflow
  • src/ 无 fn merge_cl_unchecked
  • src/ 无 fn try_start_processor
  • src/ 无 fn add_to_merge_queue((不含 _as)
  • un19_acl_change.rs 不含字符串 merge_cl_unchecked

Verification:

  • 零命中守卫(模板):rg -n 'fn merge_cl_unchecked|fn ensure_merge_processor_running|fn execute_merge_workflow' src/ → 退出码 1
  • 零命中守卫(模板):rg -n 'try_start_processor|processor_running|fn retry_merge_queue_item\(' src/jupiter/service/merge_queue_service.rs src/ceres/ → 退出码 1
  • source .env.test && cargo test -p mega2 --lib 'ceres::api_service::' -- --nocapture

Dependencies: MW-01

Deliverables: N/A

Implementation write set: src/ceres/api_service/mono_api_service.rs;src/ceres/api_service/un19_acl_change.rs;src/jupiter/service/merge_queue_service.rs

Release write set: Inherited

Files likely touched: 同上

Docs and compatibility impact: 注释级;用户文档交 MW-06

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: Inherited

Performance budget: N/A(删后台循环)

Estimated scope: S(landing=2;prod-files=3)

Version increment: patch

Release boundary: independent

C/D coverage from: self

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中)

Granularity: type=implementation; axis=删除 Legacy processor 与 merge_cl_unchecked; recovery=revert; complete=yes; self-contained=yes; AC=8/8; VER=3/8; landing=2; prod-files=3; scope=S; deps=MW-01; writeset=序列化于 MW-01; release=independent; split-from=N/A; exception=N/A

Task MW-03: 删除 [monorepo].merge_writer

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 删除 MergeWriter 枚举与 MonoConfig.merge_writer;从 validate known-keys、reload restart-required、config/config.toml 注释、src/config/template.rs 去掉该键;删除 merge_writer_rejects_unknown_value 等「合法变体」测试,改为「残留键未知字段失败」;所有 config.monorepo.merge_writer = ... 赋值删除(含 test_storage_queue_merge、tp11_storage、trunk_storage、tp12_review_keeps_noop)。tp12_review_keeps_noop 只保留 PushPolicy::Review 断言。

Out of scope:

  • DROP TABLE(MW-05)
  • 删除 MergeQueueService 模块(MW-04)
  • deploy-trunk 长文(MW-06;本卡只改样例 toml/template)

Current evidence:

事实 证据
MonoConfig 无字段 src/config/model.rs MonoConfig 止于 max_push_commits
无枚举 rg 'enum MergeWriter' src/ 退出码 1
known-keys validate.rs monorepo 列表无该键
reload reload.rs 无 monorepo.merge_writer
样例/模板 config/config.toml、src/config/template.rs 无该键
残留键 fail-closed config validate 对含 merge_writer = "queue" 的临时 toml 退出 1
tp12_review_keeps_noop 仅 PushPolicy::Review

Acceptance criteria:

  • MonoConfig 无 merge_writer 字段
  • 无 enum MergeWriter
  • monorepo known-keys 无 "merge_writer"
  • restart_required_fields 无 "monorepo.merge_writer"
  • config/config.toml 无 merge_writer
  • src/config/template.rs 无 merge_writer
  • 含 merge_writer = "queue" 的临时 toml 经 config validate 非零退出

Verification:

  • source .env.test && cargo test -p mega2 --lib 'config::' -- --nocapture
  • (new):临时文件带 merge_writer 的 cargo run -p mega2 -- --config <tmp> config validate 非零
  • 零命中守卫(模板):rg -n 'MergeWriter|merge_writer' src/ config/config.toml src/config/template.rs → 退出码 1
  • cargo run -p mega2 -- --config config/config.toml config validate 退出 0(相对已提交样例;勿把工作区无关 admin 脏改当验收树)

Dependencies: MW-02

Deliverables: N/A

Implementation write set: src/config/model.rs;src/config/validate.rs;src/config/reload.rs;src/config/tests.rs;src/config/template.rs;config/config.toml(仅 merge_writer 注释块);测试中赋值 MergeWriter 的 src/jupiter/tests.rs、src/ceres/pack/monorepo.rs、src/ceres/api_service/mono_api_service.rs

Release write set: Inherited

Files likely touched: 同上

Docs and compatibility impact: 公开配置删除;运维删除残留行。长文 MW-06

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 未知字段 fail-closed,禁止静默忽略残留键

Performance budget: N/A

Estimated scope: M(landing=src/config/=1;prod-files=5,不含测试文件计数)

Version increment: patch(Goal 覆盖原 minor)

Release boundary: independent

C/D coverage from: self

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中)

Granularity: type=implementation; axis=删除 merge_writer 配置面; recovery=revert 恢复字段; complete=yes; self-contained=yes; AC=7/8; VER=4/8; landing=1; prod-files=5; scope=M; deps=MW-02; writeset=序列化于 MW-04; release=independent; split-from=N/A; exception=N/A

Task MW-04: 删除 merge_queue storage/service 与 absorb

Task type: implementation

Lifecycle / Acceptance: done / complete

Description: 删除 MergeQueueStorage / MergeQueueService 及 Storage 上的字段与构造;src/jupiter/service/mod.rs / storage/mod.rs 取消对应 mod。把 freeze_merge_queue_item_for_authz(mono_api_service.rs:4830)改写为只写 push_queue(Failed + SystemError + emit_authz_frozen_alert)。改写 un25_freeze.rs 与 un19_fail_closed.rs 中对 merge_queue_service 的调用。删除 absorb 函数及其单测。merge_queue_dto.rs、HTTP DTO 中的 From<Model> / From<merge_queue_dto::QueueStats>、实体文件与 Postgres 表留到 MW-05(HTTP 文件在 MW-04 后仍须能编译)。

Out of scope:

  • DROP TABLE 与 callisto::merge_queue 文件删除(MW-05)
  • 删除 src/jupiter/model/merge_queue_dto.rs 与 HTTP DTO 内 From 旧实体/旧 DTO(MW-05;ADR-MW-02 保留文件)
  • 改事件名(DEFER-MW-02)

Current evidence:

事实 证据
文件已删 无 merge_queue_storage.rs / merge_queue_service.rs
Storage 字段 rg merge_queue_storage|merge_queue_service src/jupiter/ 退出码 1
freeze freeze_merge_for_authz 写 push_queue Failed+SystemError
UN-25 / UN-19 改挂 push_queue_storage
守卫 rg MergeQueueService|MergeQueueStorage|merge_queue_service src/ 退出码 1

Acceptance criteria:

  • 无文件 src/jupiter/storage/merge_queue_storage.rs
  • 无文件 src/jupiter/service/merge_queue_service.rs
  • Storage 无字段 merge_queue_storage
  • Storage 无字段 merge_queue_service
  • src/jupiter/tests.rs 不构造 MergeQueueStorage
  • freeze_merge_queue_item_for_authz 不调用 MergeQueueService
  • un25_freeze.rs 不调用 merge_queue_service
  • un19_fail_closed.rs 不调用 merge_queue_service

Verification:

  • 零命中守卫(模板):rg -n 'MergeQueueService|MergeQueueStorage|merge_queue_service' src/ → 退出码 1
  • source .env.test && cargo test -p mega2 --lib 'ceres::api_service::un25_freeze' -- --nocapture
  • source .env.test && cargo test -p mega2 --lib 'ceres::api_service::un19_fail_closed' -- --nocapture
  • source .env.test && cargo test -p mega2 --lib 'jupiter::' -- --nocapture

Dependencies: MW-03

Deliverables: N/A

Implementation write set: src/jupiter/storage/mod.rs;src/jupiter/storage/merge_queue_storage.rs(删);src/jupiter/service/mod.rs;src/jupiter/service/merge_queue_service.rs(删);src/jupiter/tests.rs;src/ceres/api_service/mono_api_service.rs(freeze_merge_queue_item_for_authz);src/ceres/api_service/un25_freeze.rs;src/ceres/api_service/un19_fail_closed.rs

Release write set: Inherited

Files likely touched: 同上

Docs and compatibility impact: 内部模块;errors.md 表级措辞交 MW-06

Rollback mode: revert

Migration and rollback: N/A(表仍在,直到 MW-05)

Security and privacy: UN-25 冻结语义迁到 push_queue 行,不削弱 fail-closed

Performance budget: N/A

Estimated scope: M(landing=3;prod-files=5)

Version increment: patch

Release boundary: independent

C/D coverage from: self

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中)

Granularity: type=implementation; axis=删除 merge_queue storage/service 与 absorb; recovery=revert 恢复模块; complete=yes; self-contained=yes; AC=8/8; VER=4/8; landing=3; prod-files=5; scope=M; deps=MW-03; writeset=序列化于 MW-05; release=independent; split-from=N/A; exception=N/A

Task MW-05: DROP merge_queue 表与 callisto 实体

Task type: migration

Lifecycle / Acceptance: done / complete

Description: 新增 forward-only 迁移 src/jupiter/migration/m20260910_000100_drop_merge_queue.rs:DROP TABLE IF EXISTS merge_queue;若 queue_status_enum / queue_failure_type_enum 无剩余依赖则 DROP TYPE。删除 src/callisto/merge_queue.rs 及 mod.rs / prelude.rs 注册;从 sea_orm_active_enums.rs 删除仅被该表使用的 QueueStatusEnum / QueueFailureTypeEnum。删除 src/jupiter/model/merge_queue_dto.rs 及 model/mod.rs 注册。在 保留 的 HTTP DTO src/ceres/model/merge_queue.rs 中删除全部旧转换:From<QueueStatusEnum> / From<QueueFailureTypeEnum> / From<merge_queue::Model> / From<Vec<Model>> / From<Option<Model>> / From<merge_queue_dto::QueueStats>(:4-7、:97-266),只留 QueueItem::from_push_queue 与 API 类型。在 migrations() 追加该迁移(保留旧 add_merge_queue 历史文件)。down 空实现。

Out of scope:

  • 文档(MW-06)
  • 删除 HTTP DTO 文件 src/ceres/model/merge_queue.rs(ADR-MW-02:保留路由形状与 from_push_queue)

Current evidence:

事实 证据
建表迁移 src/jupiter/migration/m20251109_073000_add_merge_queue.rs;注册 src/jupiter/migration/mod.rs:64/168
requester src/jupiter/migration/m20260815_000100_merge_queue_requester.rs;src/jupiter/migration/mod.rs:111/215
实体 src/callisto/merge_queue.rs:8-10
实体注册 src/callisto/mod.rs:59
prelude src/callisto/prelude.rs:29
HTTP DTO 仍 From 旧实体与旧 DTO src/ceres/model/merge_queue.rs:4-7;:97-160;:217-266
内部 DTO src/jupiter/model/merge_queue_dto.rs:1-11;src/jupiter/model/mod.rs:7

Acceptance criteria:

  • m20260910_000100_drop_merge_queue 已登记于 migrations() 末尾
  • up 执行 DROP TABLE merge_queue
  • 无其它使用者时 up 删除 type queue_status_enum
  • 无其它使用者时 up 删除 type queue_failure_type_enum
  • 无文件 src/callisto/merge_queue.rs
  • 无文件 src/jupiter/model/merge_queue_dto.rs
  • src/ceres/model/merge_queue.rs 无 use crate::callisto::merge_queue
  • sea_orm_active_enums.rs 无 pub enum QueueStatusEnum

Verification:

  • source .env.test && cargo test -p mega2 --lib 'jupiter::migration::runner::tests::test_apply_migrations' -- --nocapture
  • (new) m20260910_000100_drop_merge_queue::tests:apply_migrations(&db, true) 后 SELECT to_regclass('merge_queue')::text 为 NULL(同 runner::tests::test_drop_chat_and_notes_schema);命令:source .env.test && cargo test -p mega2 --lib 'jupiter::migration::m20260910_000100_drop_merge_queue::tests' -- --nocapture
  • 零命中守卫(模板):rg -n 'callisto::merge_queue|crate::callisto::merge_queue|enum QueueFailureTypeEnum|Entity as MergeQueue' src/ → 退出码 1
  • 零命中守卫(模板):rg -n '\bQueueStatusEnum\b|\bQueueFailureTypeEnum\b|merge_queue::Model|merge_queue_dto' src/ceres/model/merge_queue.rs → 退出码 1
  • 零命中守卫(模板):rg -n 'pub mod merge_queue' src/callisto/mod.rs → 退出码 1
  • 零命中守卫(模板):rg -n 'pub mod merge_queue_dto' src/jupiter/model/mod.rs → 退出码 1

Dependencies: MW-04

Deliverables: N/A

Implementation write set: src/jupiter/migration/m20260910_000100_drop_merge_queue.rs(新);src/jupiter/migration/mod.rs;src/callisto/merge_queue.rs(删);src/callisto/mod.rs;src/callisto/prelude.rs;src/callisto/sea_orm_active_enums.rs;src/jupiter/model/merge_queue_dto.rs(删);src/jupiter/model/mod.rs;src/ceres/model/merge_queue.rs

Release write set: Inherited

Files likely touched: 同上

Docs and compatibility impact: integration.md UN-18 列说明改为历史;MW-06

Rollback mode: forward-only

Migration and rollback: down 空;恢复只能前滚重建表(本计划不提供)。数据不变量:无老实例 ⇒ 无必须保留的行。用户影响:违反前提的残留队列行丢失。

Security and privacy: N/A

Performance budget: N/A(一次性 DDL)

Estimated scope: M(landing=4;prod-files=9)

Version increment: patch

Release boundary: independent

C/D coverage from: self

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件,无 paths 过滤器可命中)

Granularity: type=migration; axis=DROP merge_queue 表与实体; recovery=forward-only 前滚; complete=yes; self-contained=yes; AC=8/8; VER=6/8; landing=4; prod-files=9; scope=M; deps=MW-04; writeset=序列化于 MW-06; release=independent; split-from=N/A; exception=N/A

Task MW-06: 文档 sunset

Task type: docs

Lifecycle / Acceptance: done / complete

Description: 从运维/设计文档删除「merge_writer 缺省 legacy / 生产 queue」与「滚动吸收 merge_queue」作为现行步骤;改为「CL merge 只经 MonoWriteQueue;无该配置键」。docs/errors.md UN-25 段改为冻结落在 push_queue(事件名仍 merge_queue_authz_frozen)。trunk-push.md 滚动开关段标注由 plan-20260910 sunset。更新 docs/plan/README.md 与 plan-long.md 索引状态。docs/refactoring/integration.md UN-18 列说明标为历史表。

Out of scope:

  • 任何 src/ / Cargo.toml 行为改动(发现则 ER-03 重分类)
  • 回改 plan-20260905.md AC 勾选(GC-MW-05)

Current evidence:

事实 证据
deploy 样例仍含 merge_writer docs/deploy-trunk.md:13
freeze 表级措辞 docs/errors.md:101
吸收/开关现行步骤 docs/refactoring/trunk-push.md:968
UN-18 迁移文 docs/refactoring/integration.md:135-158
contract 冻结现行面 docs/refactoring/contract.md:261

Acceptance criteria:

  • docs/deploy-trunk.md 无 merge_writer 键
  • docs/errors.md 写明冻结行在 push_queue
  • docs/refactoring/trunk-push.md:968 标明由 plan-20260910 sunset
  • docs/refactoring/contract.md:261 不再把 merge_queue 表当作现行冻结落库
  • docs/refactoring/integration.md UN-18 段标明为历史表
  • docs/plan/README.md 登记本计划
  • docs/plan/plan-long.md 日期索引含本计划
  • 本卡新增 docs/*.md 链接全部真实存在

Verification:

  • 结构与链接门:上列文件存在且章节完整
  • libra status --short --branch 无 src/ / Cargo.toml 越界(本卡提交)
  • 零悬空:本卡新增链接存在性检查

Dependencies: MW-03,MW-05

Deliverables: docs/deploy-trunk.md;docs/errors.md;docs/refactoring/trunk-push.md(:968 段);docs/refactoring/integration.md(UN-18 历史化);docs/refactoring/contract.md:261;docs/plan/README.md;docs/plan/plan-long.md

Implementation write set: 上列 docs 路径

Release write set: N/A

Files likely touched: 同上

Docs and compatibility impact: 本卡即文档

Rollback mode: revert

Migration and rollback: N/A

Security and privacy: 不改变 503 冻结契约,只改事实源表名

Performance budget: N/A

Estimated scope: M(产物文件 ≤15)

Version increment: patch(Goal 覆盖原 N/A)

Release boundary: no-release

C/D coverage from: MW-05

D-group (ER-04): N/A(本 checkout 无 CI workflow 文件;继承 MW-05 同为 N/A)

Granularity: type=docs; axis=文档 sunset 开关与旧表; recovery=revert 文档; complete=yes; self-contained=yes; AC=8/20; VER=3/20; landing=0; prod-files=0; scope=M; deps=MW-03,MW-05; writeset=no-overlap; release=no-release; split-from=N/A; exception=N/A

测试矩阵

类别 必须覆盖 Target / command
单元 merge 入口只入 push_queue;list/status/stats;UN-17 仍纯函数 --lib 'ceres::api_service::mono_api_service::tests';--lib 'api::router::merge_queue_router'
集成(DB) DROP 后无表;UN-25 冻结合 push_queue --lib 'jupiter::migration';--lib 'ceres::api_service::un25_freeze'
HTTP UN-20 requester 在 add 后可从 push_queue 读出 --lib 'api::un20_queue_requester'
配置 无 merge_writer;残留键失败 --lib 'config::';config validate
迁移 apply_migrations 后无 merge_queue MW-05 (new) 信息架构断言
Git 协议 N/A(不改 receive-pack) N/A
安全 匿名 merge-no-auth / UN-19 回归仍绿 --lib 'ceres::api_service::un19_acl_change' 既有用例
性能 N/A N/A
live/gated N/A N/A

追溯表

任务 来源/证据 mega2 落点 文档/兼容动作 指定测试
MW-01 GAP-MW-01/02 mono_api_service.rs;merge_queue_router.rs;http_server.rs;context/mod.rs OpenAPI 消息字符串 --lib merge/un20
MW-02 GAP-MW-04 mono_api_service.rs;merge_queue_service.rs un19 注释 --lib 'ceres::api_service::'
MW-03 GAP-MW-03 src/config/**;config/config.toml 样例 --lib 'config::'
MW-04 GAP-MW-05 jupiter/storage;jupiter/service;jupiter/tests.rs;ceres/api_service freeze N/A un25 / un19 / jupiter
MW-05 GAP-MW-05 jupiter/migration;callisto;jupiter/model;ceres/model/merge_queue.rs 历史迁移文件保留 migration + 信息架构
MW-06 GAP-MW-06 docs only deploy/errors/trunk-push/integration/plan 索引 链接门

里程碑验收与回滚

里程碑 完成条件 发布/证据 回滚或前滚
M0 计划 Codex PASS;Phase 0 本文件 Review log;libra tip 含本计划 revert 计划文档
M1 MW-01+MW-02 发布 minor+patch;入口/processor 守卫绿 revert 各卡
M2 MW-03..MW-05 发布 无配置键;无表 MW-03 revert;MW-05 只能前滚
M3 MW-06 收口 文档与索引 revert 文档

故障恢复矩阵

故障点 可接受残留 恢复动作 禁止结果
MW-01 已推、MW-02 未推 入口走队列但 processor 符号仍在 继续 MW-02;禁止再从入口调用 重新启用 processor 作为写者
MW-04 已推、MW-05 未推 storage/service 已删;表与 HTTP From 旧类型仍在 尽快 MW-05;禁止再插入 merge_queue 新代码再插入 merge_queue
MW-05 已推后发现非空表被丢 队列行丢失 前滚;从 push_queue/CL 状态恢复意图 声称 down 可回滚
残留 merge_writer 键 进程拒绝启动 从 toml 删行 静默忽略该键

风险登记

风险 影响 缓解 任务
违反「无实例」前提导致 DROP 丢行 高:进行中 merge 丢失 计划前提;MW-05 AC 不吸收;文档声明 MW-05
/merge-queue 客户端仍当异步 中:客户端不等待却已合并 TP-07 已同步化;消息 "Merged";本计划不改形状 MW-01
UN-20 测试未改导致假绿/假红 中 MW-01 改断言 MW-01
未知字段拒绝使带旧键的 toml 起不来 低(预期) 文档 + validate 测试 MW-03/MW-06
HTTP DTO 仍 From 旧实体时先 DROP/删类型 高:MW-05 无法编译 MW-05 写集含 ceres/model/merge_queue.rs;MW-04 暂留 merge_queue_dto.rs MW-05
QueueStatusEnum 仍被其它表引用 中:DROP TYPE 失败 开工日 rg;失败则只 DROP TABLE MW-05

性能与容量摘要

操作 单次成本 累积成本 预算/上限 验证
CL merge 与今日 merge_writer=queue 相同(B1+B2+B3) 与队列深度成正比 不放宽 wait_timeout 既有 queue 测
删除 processor 去掉轮询循环 负成本 N/A 代码审查
DROP TABLE 一次 DDL 空表 O(1) N/A migration 测

兼容与文档收口

本节于 2026-09-15 据实回填勾选;逐条证据取自当前 checkout(各卡 Lifecycle 与 MW-06 的 AC 早已为 done/全勾,仅本计划级清单遗漏)。

  • docs/errors.md 已同步(MW-06)或说明 N/A。 —— docs/errors.md:100 冻结行已改写为落在 push_queue(kind=merge),事件名 merge_queue_authz_frozen 按 AC 保持不变
  • docs/refactoring/trunk-push.md / integration.md / contract.md 已同步或 N/A。 —— trunk-push.md:968 sunset 横幅;integration.md:141 UN-18 标为「历史表」;contract.md:261 冻结落库改述为 push_queue
  • config/config.toml 示例已去掉 merge_writer(MW-03)。 —— rg 'merge_writer' config/ src/ 仅剩 config-storage-only*.toml:173-176 的「该键已删除、残留即拒绝启动」说明性注释,无生效键;src/ 零命中
  • 运行时 OpenAPI:无新路径;add 消息已是 "Merged"(MW-01);无落盘 spec。 —— src/api/router/merge_queue_router.rs:93 为 "Merged"
  • README.md / AGENTS.md:N/A(不改工程约束),除非根 README 提及 merge_writer。 —— rg 'merge_writer' README.md AGENTS.md 零命中,判定 N/A
  • src/callisto/、storage、migrations() 已同步(MW-04/MW-05)。 —— src/callisto/ 无 merge_queue 实体;src/jupiter/migration/mod.rs:120,227 已注册 m20260910_000100_drop_merge_queue
  • 新 docs/*.md 引用真实存在。 —— MW-06 Deliverables 六个 docs 路径逐一存在;docs/deploy-trunk.md:20 的 ./plan/plan-20260910.md 可解析
  • plan-long.md 日期计划索引已登记。 —— docs/plan/plan-long.md:773 行,状态「已完成」,并记 DEFER-MW-01

Review log

Result 只允许 PASS 或 FAIL。

Round Scope Result P0/P1 P2 处置 Evidence
R1 本计划成稿(Codex) FAIL P1:模板 G-* 章节未声明;G-03 欠计;证据锚点不足;漏 get_display_position_by_position / freeze / UN-19 fail-closed 对 merge_queue_service 的依赖 本轮修订关闭 target/tmp/plan-20260910-codex-r1.txt
R2 R1 修订后(Codex) FAIL P1:保留的 HTTP DTO 仍 From callisto::merge_queue::Model / QueueStatusEnum / QueueFailureTypeEnum(:4-7、:97-160),MW-05 删类型后无法编译 本轮把 DTO/From 清理并入 MW-05,且 MW-04 暂留 merge_queue_dto.rs target/tmp/plan-20260910-codex-r2.txt
R3 R2 修订后(Codex) PASS 无 — target/tmp/plan-20260910-codex-r3.txt
R4 MW-01 实现(Codex) PASS 无 入口/router/startup 无 MergeWriter 分支;processor/merge_cl_unchecked 按卡延至 MW-02 target/tmp/mw01-codex-r1.txt
R5 MW-02 实现(Codex) PASS 无 processor/merge_cl_unchecked/AtomicBool 已删;B3 落地保留 target/tmp/mw02-codex-r1.txt
R6 MW-03 实现(Codex) PASS 无 配置面与 src/ 零命中;残留键 fail-closed target/tmp/mw03-codex-r1.txt
R7 MW-04 实现(Codex) PASS 无 storage/service 已删;freeze 写 push_queue;HTTP DTO/merge_queue_dto 留至 MW-05 target/tmp/mw04-codex-r1.txt
R8 MW-05 实现(Codex) PASS 无 DROP TABLE 在 migrations() 末尾;entity/DTO/From 已拆;down 空 target/tmp/mw05-codex-r1.txt
R9 MW-06 实现(Codex) PASS 无 文档 sunset:无配置键;freeze 写 push_queue;UN-18 历史表 target/tmp/mw06-codex-r1.txt

非目标与延后项

ID 延后内容 原因 重启条件 承接位置
DEFER-MW-01 删除 /merge-queue/*,只留 /push-queue 公开 API 删除需 G-08 与客户端窗口 无客户端再依赖 /merge-queue 新日期计划
DEFER-MW-02 重命名 event=merge_queue_authz_frozen 告警查询稳定性 告警侧同步改名 新日期计划
DEFER-MW-03 重命名 list_merge_for_legacy_ui 纯标识符,非行为轴 本计划后清理窗口 可并入无关重构

完成判据

计划只有在以下条件全部满足后才能标记完成:

  • 所有任务卡满足 G-*;粒度审计表已填;无 XL、无未登记合并发布。
  • 所有非延后任务 Lifecycle=done 且 Acceptance=complete。
  • 所有 Verification 已运行并记录。
  • 计划完成门:cargo +nightly fmt --all --check、cargo clippy --all-targets --all-features -- -D warnings 全绿;cargo build 0 错误 0 警告(本卡仅文档;cargo test --all 由各实现卡 VER 覆盖,git-cli IT 环境 137 不削弱用例)。
  • docs/配置/错误契约/测试矩阵已更新。
  • MW-05 Rollback mode=forward-only 已在卡内写明且不可 down。
  • 代码 review(实现阶段每卡 ER-05)最终 PASS;本计划文档 Codex PASS。
  • 发布:MW-01..MW-06 一律 patch +1(Goal 覆盖原 MW-01/MW-03 minor 与 MW-06 N/A)。无 release artifact(N/A:本仓无 tag 流水线)。
  • 修订历史已记录成稿后变更。
  • plan-long.md 索引已同步。