@@ -0,0 +1,254 @@
# feature/docker-test-image 任务卡
任务主记录:PR #645 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/645;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git -ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main; R0( initial_base_sha) = 162c5a0160955989608f325b4be30458e3717d16
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image( worktree);分支:feature/docker-test-image
- 分支类型:standalone; root_target: main; immediate_target: main; accepting_requirements: false
- 需求分流:verdict=NEW; selected_initiative=无;requirement_sha256=614aefe70dd97a672de9522beee5fece3da4719ee310d1c7cfc4d13fea081ac2; triage_receipt=/tmp/docker-image-triage.json; receipt_sha256=bc1c9cab074d853273d064a98599c6ef2519aa4022f2272bcc0830d3d97d01c0
- 授权与交付终点:用户直接请求(2026-10-20):为本系统准备 Docker 测试镜像(含系统环境、SSH、无头浏览器),后续测试用该镜像启动容器做隔离测试。终点=镜像定义与构建/验证入口合入 main:docker/ 定义文件 + Makefile image-build/image-verify + docker/README.md,镜像本机构建通过、容器内环境自检通过。未授权事项:不改动 modules/**、CI/治理脚本、部署形态(本仓交付仍非容器化);不发布镜像到外部 registry;不把本镜像用于生产部署。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:一份可重复构建的测试环境镜像定义(docker/),镜像内提供与本机开发一致的工具链(Go 1.27.1、Node 26.10.0、Python 3.14、git、make)、SSH 服务(仅公钥、专用 dev 用户)与无头浏览器(Playwright 1.64.0 chromium,系统级缓存 /opt/ms-playwright),供后续以 `docker run` 启动一次性容器、挂载仓库做隔离测试。
入口/影响:新增 docker/( Dockerfile、entrypoint.sh、verify-env.sh、README.md);根 Makefile 新增 image-build / image-verify 两个目标。不嵌入仓库代码与任何密钥;不改变 `make test` /CI 行为;不引入部署容器化。
非目标:镜像注册表发布、CI 内构建镜像、多架构构建、给镜像装业务代码/子模块、Windows/macOS 镜像。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| docker-test-image | docker/**、Makefile | AGENT-EXECUTION.md( agent-execution/v1) | implementation | cursor→antigravity→pi(紧急 codex) | cursor#a1 (运行 1) | cursor-agent-stable/auto | failed-unknown( cursor 后端连接反复中断,exit 1) | 未发生 | 无 | /tmp/docker-image-unit1-receipt.json;隔离工作区保留于 /tmp/agent-exec-1000/ebd031a7b7be000aca6f401395d70cd1/wt-bb3cf3ec9e85 |
| docker-test-image | 同上(重派发) | 同上 | implementation | 同上 | cursor#a1 (运行 2,重发前已对账+探活) | cursor-agent-stable/auto | failed-unknown( Cursor 月度额度耗尽 ActionRequiredError,非瞬时) | 未发生 | 无 | /tmp/docker-image-unit2-receipt.json;隔离工作区保留于 /tmp/agent-exec-1000/90bc3c29e3ea2d9fbebc9e376461846f/wt-c0358fa94a6b |
| docker-test-image | 同上(误派发) | 同上 | implementation | 同上 | — | — | invalid-config(运行前检出脏:host 对 AGENT-EXECUTION.md 的直接改动被 admit 拒绝后残留,已回滚,未启动任何候选) | 未发生 | 无 | /tmp/docker-image-unit3-receipt.json |
| docker-test-image | 同上(重派发) | AGENT-EXECUTION.md( cursor 停用后,16776aa) | implementation | antigravity→pi(紧急 codex) | agy#a1 (运行 4) | antigravity/auto | failed-unknown(实现与验证全部完成、终态记录已输出,但会话尾部一次后端 API EOF 污染 result 信封,控制器 fail-closed 未建 transport;镜像已建成且 verify-env PASS 经 host 独立复核) | 未发生 | 无 | /tmp/docker-image-unit4-receipt.json;隔离区 /tmp/agent-exec-1000/78f91904001532b603bf0ceeb292b893/wt-3ec6b80250c3(含已验证实现) |
| docker-test-image | 同上(重验证派发) | 同上 | implementation | 同上 | agy#a2 (运行 5,对账后;连续第二次因传输机制的 failed-unknown 重派发,若再失败则回到用户决策,不无限循环) | 待运行 | NOT_RUN | NOT_RUN | NOT_RUN | /tmp/docker-image-unit5-receipt.json |
- 配置摘要来源:AGENT-EXECUTION.md `agent-execution` 块(schema v1; implementation 候选 cursor/agy/pi,每候选至多 3 次,紧急 codex 一次,fallback_to_host=never);运行收据由 scripts/agent-exec run 写出后原样保留在源码外路径。
- 运行 1 对账(2026-10-20):镜像未构建(docker images 无 agent-system-test-*)、无新增容器、规范检出干净;改动仅存在于保留的隔离工作区(Makefile M + docker/ 4 文件);cursor 探活已恢复(探针 exit 0)。据此授权同一单元重新派发(新 run,非同 run 盲重试)。
- 运行 2 对账(2026-10-20):终态原因实为 Cursor Ultra 月度用量额度耗尽(ActionRequiredError,重置日 2026-11-10),属确定性不可用;host 依配置 enabled 机制停用 cursor 时被 pre-commit admit 拒绝(非豁免路径须 transport 来源),路由改动本身又需一次成功运行——死锁,经用户选项 1 解除(见下方决策点)。
- 运行 4 对账(2026-10-20):worker 完成实现且四条验证自报通过,host 独立重跑 `docker run --rm --shm-size=1g agent-system-test-env:dev /usr/local/bin/verify-env.sh` → verify-env: PASS;失败纯属会话尾部 API EOF 污染 result 信封(raw log 尾部 `streamGenerateContent: EOF` ),非内容缺陷。镜像 agent-system-test-env:dev 已在 daemon 中(层缓存可复用)。授权重派发运行 5 作纯重验证;若再因传输机制失败,停止并回用户决策。
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 测试环境镜像定义:docker/ 内 Dockerfile 固定 ubuntu:24.04( amd64) + Go 1.27.1 + Node 26.10.0 + Python 3.14( deadsnakes) + git/make/openssh-server/sudo + Playwright 1.64.0 chromium( /opt/ms-playwright) | 与本机开发工具链版本一致(实测:go1.27.1 / v26.10.0 / 3.14.8 / playwright 1.64.0),避免测试行为漂移 | 高 | `docker build -t agent-system-test-env:dev docker/` 退出 0 | 无 | 已确认 |
| R2 | SSH 就绪:容器以 root 入口前台跑 sshd; PermitRootLogin no、PasswordAuthentication no; dev 用户(UID 1000、NOPASSWD sudo);host key 首启生成;authorized_keys 运行时只读挂载注入 | 隔离测试需要经 SSH 进入容器;公钥注入避免镜像携带凭据 | 高 | 容器内 `sshd -t` 通过;dev 存在且 sudo NOPASSWD;镜像内无任何私钥/secret | R1 | 已确认 |
| R3 | 无头浏览器可用:镜像内预装 playwright 1.64.0 chromium 及系统依赖,ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright | frontend e2e( @playwright/test ^1.50.1,解析 1.64.0)容器内可直接跑;版本对齐避免浏览器 revision 漂移 | 高 | verify-env.sh 中 chromium --headless --dump-dom about:blank 输出 HTML | R1 | 已确认 |
| R4 | 构建/验证入口与文档:Makefile image-build / image-verify; docker/README.md 覆盖构建、启动(端口映射、--shm-size、公钥挂载、仓库挂载 /workspace)、容器内跑 e2e 示例与安全边界 | 用户后续直接用这两个入口启动隔离测试容器 | 中 | `make image-build` 、`make image-verify` 可用;README 含最小可复现命令 | R1– R3 | 已确认 |
## 方案与计划
- 方案引用:本卡「目标与非目标」+ 单元包 /tmp/unit-docker-test-image.json( digest 由运行收据记录);固定版本事实:go1.27.1、node v26.10.0、python 3.14.8、playwright 1.64.0(本机实测于 2026-10-20)
- 实施计划引用:单单元 docker-test-image( docker/** + Makefile 内聚小任务,合为一个包)
- 测试计划引用:R1–R4 验收条件 = worker 窄检查(docker build + 容器内 verify-env.sh);host 权威验证在 apply 后本仓重跑同两命令
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | R0=162c5a0160 | 已完成 | host 主模型 | 2026-10-20 | AGENTS.md 路由 + policy/delivery.md |
| 需求评估 | R0=162c5a0160 | 已完成 | host 主模型 | 2026-10-20 | 本卡需求表 R1– R4 |
| 需求表确认 | R0=162c5a0160 | 已完成 | 用户直接请求即授权 | 2026-10-20 | 授权与交付终点节 |
| 方案设计 | R0=162c5a0160 | 已完成 | host 主模型 | 2026-10-20 | 见方案与计划 |
| 实施计划 | R0=162c5a0160 | 已完成 | host 主模型 | 2026-10-20 | 单元 docker-test-image(单元包 /tmp/unit-docker-test-image.json) |
| 实施与自检 | de3d3aff( transport de3d3aff285e0dcfd185c9904a3a9b01af34e2fa) | 已完成 | agy worker(运行 4 实现、运行 5 重验证)→ host apply | 2026-10-20 | /tmp/docker-image-unit5-receipt.json;运行 1– 5 详见收据表 |
| 正式测试与验收 | de3d3aff | 已完成(SELF; GATE 待 CI) | host 主模型 | 2026-10-20 | make image-build / image-verify 证据入卡;CI 待验 |
| 代码 Review | de3d3aff | 进行中 | host 主模型(policy 允许,独立于实施会话) | 2026-10-20 | 见合入与清理节 Review 记录 |
| 合入 | de3d3aff | 待执行 | host(授权范围内) | — | 按 policy/delivery.md 合入流程 |
| 合入核验与收口 | — | 待执行 | host | — | — |
### 决策点(2026-10-20,已闭合)
implementation/repair 角色首候选 cursor 因月度额度耗尽必然失败,且路由配置无法由 host/worker 合规变更。选项及结果:
1. **已采纳(用户 2026-10-20 选定选项 1) ** :用户以自身授权在任务 worktree 编辑 AGENT-EXECUTION.md 将 cursor profile `enabled: false` (附注释,额度重置后恢复),并亲自 `git commit --no-verify` 提交为 16776aa(配置 diff 已在决策菜单中预告并经用户选择,validate 通过)。host 据此重派发,路由落到探活正常的 antigravity。额度重置后应恢复 enabled: true。
2. 用户在 Cursor 提高 Spend Limit(未采用)。
3. 等待 2026-11-10 重置(未采用)。
4. host 以 role=test 派发(未采用,角色标签与工作性质不符)。
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| I1 | docker/ 镜像定义可构建、容器内自检通过 | 单一交付 | build+verify 通过即停,不做镜像优化迭代 | 授权与交付终点节 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 162c5a0160955989608f325b4be30458e3717d16 | 162c5a0160955989608f325b4be30458e3717d16 | 2026-10-20T02:39:22Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:docker/ 测试环境镜像定义(Dockerfile + entrypoint.sh + verify-env.sh + README.md)与根 Makefile image-build/image-verify 目标已由 worker 交付、host apply 入分支(de3d3aff)。镜像 ubuntu:24.04 + Go 1.27.1 + Node 26.10.0 + Python 3.14( deadsnakes) + Playwright 1.64.0 chromium( /opt/ms-playwright) + sshd(仅公钥、dev 用户 NOPASSWD sudo、root 登录关闭)。
- 验证:`make image-build` exit=0( SELF,证据块);`make image-verify` exit=0 且 verify-env: PASS( SELF);worker 四条自检通过;R1–R4 验收条件全部满足。已知非阻塞项:Dockerfile `FROM --platform=linux/amd64` 触发 buildkit 一条 lint 警告(有意钉住 amd64,不改)。CI GATE 与 Review 见合入与清理节。
- 影响与剩余项:仅新增 docker/ 与 Makefile 两个目标,不触碰 modules/CI/治理脚本;镜像不发布外部 registry。剩余:PR CI、独立 Review、合入与回收。
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:PASS( host 主模型独立 Review,非实施会话;对象 base=origin/main/d2035c76 head=b9c0fc3)。范围核对:7 文件全部在授权内(docker/ 4 文件 + Makefile 增量 + 任务卡 + AGENT-EXECUTION.md 路由调整 16776aa);Go/CI/脚本/modules 零触碰;secret 扫描无命中(仅 task-start 等词的 sk- 误报);Makefile 除 .PHONY 一行外纯增量。非阻塞观察:① FROM --platform=linux/amd64 触发 buildkit lint 警告(有意钉 amd64,接受);② sshd_config 追加式覆盖依赖 stock ubuntu 默认(测试镜像可接受,verify-env 已断言 sshd -t)。
- 冲突记录:main 前进至 d2035c7(含 #644 )后合并 origin/main( merge commit b9c0fc3),无冲突;新 gitlink 物化后 make test-worktree 递归核对通过;modules/frontend 仍解析 @playwright/test ^1.50.1(镜像内浏览器 1.64.0 对齐不变)。
- CI 记录:CI_SUCCESS @ b9c0fc3fa1817812295394e069b457cc098e1f24( ci / test、test-pg、svc-realcombo 全绿,runs 4360)。过程备注:首候选 HEAD 8e062ca 的 test-pg 首跑 TestArtifactFacadeCard 失败(伴随 database is closed 收尾噪音),重跑同 job 即 success,判偶发;b9c0fc3 的 test 首跑为 npm EIDLETIMEOUT 网络抖动,重跑 success。两次均非本 PR 内容缺陷(本 PR 未触碰 Go/npm 依赖)。
- 合入记录:待执行(合入后回填)
- 清理记录:待执行(合入后回填)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
``` json
{
"summary_schema" : 1 ,
"source" : "SELF" ,
"timestamp" : "2026-10-20T02:38:25.695061+00:00" ,
"command" : "make precheck" ,
"exit_code" : 0 ,
"cwd" : "/home/weichen/projects/Agent-System-Dev" ,
"before_head" : "162c5a0160955989608f325b4be30458e3717d16" ,
"after_head" : "162c5a0160955989608f325b4be30458e3717d16" ,
"branch" : "main" ,
"target_branch" : "main" ,
"target_head" : "162c5a0160955989608f325b4be30458e3717d16" ,
"root_target" : "main" ,
"immediate_target" : "main" ,
"before_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"after_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"output_tail" : [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'" ,
"[repo] branch=main head=162c5a0160" ,
"[remote] origin/main=162c5a0160 ahead=0 behind=0" ,
"[tree] clean submodules_drift=0 uninit=0" ,
"[worktrees] linked=6" ,
"[initiatives] local cards (not authoritative): none" ,
"[hooks] core.hooksPath=scripts/hooks( pre-commit/post-merge 实际接线)" ,
"[facts] policy/facts.md 6 条事实均在有效期内" ,
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md" ,
"[R0] 162c5a0160(完整:162c5a0160955989608f325b4be30458e3717d16) " ,
"[worktree] before-sync: recursive component checks passed" ,
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch" ,
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
] ,
"output_sha256" : "9e1904b7470a27857bd0243bc42faff0a9eb9cafc6916ad823fb1ccfea32f3b3" ,
"receipt_sha256" : "838d0ce05fc8661b279c5ccd7696cbe4712cd582b3bf39411ede4265e314a7f1" ,
"receipt_path" : "/home/weichen/.cache/agent-system-dev/evidence/838d0ce05fc8661b279c5ccd7696cbe4712cd582b3bf39411ede4265e314a7f1.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
``` json
{
"summary_schema" : 1 ,
"source" : "SELF" ,
"timestamp" : "2026-10-20T04:24:06.218569+00:00" ,
"command" : "make image-build" ,
"exit_code" : 0 ,
"cwd" : "/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image" ,
"before_head" : "de3d3aff285e0dcfd185c9904a3a9b01af34e2fa" ,
"after_head" : "de3d3aff285e0dcfd185c9904a3a9b01af34e2fa" ,
"branch" : "feature/docker-test-image" ,
"target_branch" : "main" ,
"target_head" : "d2035c76dc1cb15e01d2c184af5155d9d773cd9f" ,
"root_target" : "main" ,
"immediate_target" : "main" ,
"before_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"after_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"output_tail" : [
"#10 CACHED" ,
"" ,
"#11 exporting to image" ,
"#11 exporting layers done" ,
"#11 exporting manifest sha256:1b70b78c47f81555bca6525d04f8fefa836eb817d37bd018fcd71632c9cce13b done" ,
"#11 exporting config sha256:af4c14981be06d79e082e1685dd6f5aac947bc2f08022de3efdb8a158d656ffb done" ,
"#11 exporting attestation manifest sha256:bebc178b5c4328c737af45858184422a642deb66ac627d6cc80d6ec3c003f246 done" ,
"#11 exporting manifest list sha256:b9244ca7c49a4192b6beee8cb66ea148f2b07d6c26e613f3661aba4e569b6fa4 done" ,
"#11 naming to docker.io/library/agent-system-test-env:dev done" ,
"#11 unpacking to docker.io/library/agent-system-test-env:dev done" ,
"#11 DONE 0.0s" ,
"" ,
" \u001b[33m1 warning found (use docker --debug to expand):" ,
"\u001b[0m - FromPlatformFlagConstDisallowed: FROM --platform flag should not use constant value \"linux/amd64\" (line 1)" ,
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image'"
] ,
"output_sha256" : "9d5d28f761a75ec302f735b181d53f3a31893b29a7db1417da0b580d39a6ede9" ,
"receipt_sha256" : "10c826d7803683685c0fe49e99b8a86a04e0d675b14aad637f50220a48b13d58" ,
"receipt_path" : "/home/weichen/.cache/agent-system-dev/evidence/10c826d7803683685c0fe49e99b8a86a04e0d675b14aad637f50220a48b13d58.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
``` json
{
"summary_schema" : 1 ,
"source" : "SELF" ,
"timestamp" : "2026-10-20T04:24:15.223285+00:00" ,
"command" : "make image-verify" ,
"exit_code" : 0 ,
"cwd" : "/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image" ,
"before_head" : "de3d3aff285e0dcfd185c9904a3a9b01af34e2fa" ,
"after_head" : "de3d3aff285e0dcfd185c9904a3a9b01af34e2fa" ,
"branch" : "feature/docker-test-image" ,
"target_branch" : "main" ,
"target_head" : "d2035c76dc1cb15e01d2c184af5155d9d773cd9f" ,
"root_target" : "main" ,
"immediate_target" : "main" ,
"before_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"after_tracked_diff_sha256" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
"output_tail" : [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image'" ,
"docker run --rm --shm-size=1g agent-system-test-env:dev /usr/local/bin/verify-env.sh" ,
"verify-env: PASS" ,
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-docker-test-image'"
] ,
"output_sha256" : "4e670ae97df841f706396291f73ef43e7702f9fd60cfe163b37699ca5968804a" ,
"receipt_sha256" : "3c69f4644d10998f86733da4486b1967e49c310aad4a932aa13a7bddaf387265" ,
"receipt_path" : "/home/weichen/.cache/agent-system-dev/evidence/3c69f4644d10998f86733da4486b1967e49c310aad4a932aa13a7bddaf387265.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #645 ( https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/645)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。