Claude Cursor Skill

release-gate-loop

发版前自动验证闸门——V 验证 + F 修复循环(verdict FAIL → F 改代码 → 跑 audit → V 重验),最大 3 轮直到 PASS。纯只读验证 + 最小修复。

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download KongFangXun-sofagent-FORGE_SKILL_release-gate-loop-b8c9032.zip · 46 KB
Part of kongfangxun/sofagent — 15 skills

Install

skills CLI npx skills add https://github.com/KongFangXun/sofagent/tree/main/FORGE/SKILL/release-gate-loop
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install kongfangxun-sofagent@llmmart
Git git clone https://github.com/KongFangXun/sofagent.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole kongfangxun/sofagent collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

release-gate-loop · 发版闸门循环定义

V 验证 FAIL 后触发 F 修复循环——F 读 verdict → 改代码 → 跑 audit → V 重验,最大 3 轮。

这是什么

一套可复用的发版前自动验证闸门 + 自动修复。它描述:谁来做(V = 验证者 + F = 修复者)、怎么走(V 5 步验证 + F 3 步修复循环)、产物放哪(runs/release-gate-loop/YYYY-MM-DD/run-NN/round-N/)。

  • V = 验证者:跑 acceptance-test.sh、跑 regression-checklist、做覆盖率交叉检查、合并报告、出裁决。
  • F = 修复者:V 裁决 FAIL 后,F 读 verdict 报告 → 定位根因 → 改代码 → driver 自动跑 audit → 回到 V 重验。
  • driver(Node 编排进程,非 agent):在步骤间中转、维护 runs/ 文件、复制报告到桌面。由用户手动新开的执行 session 启动(见下「执行载体铁律」)。

怎么用

  1. 读 loop.md 拿到完整 SOP(角色 / 步骤协议 / 产物 schema)。
  2. 5 步的行为指令在 prompts/(acceptance / regression / coverage / consolidate / verdict)。
  3. F 步骤指令在 prompts/(f-diagnose / f-fix)+ driver 自动执行 f-audit。
  4. 跨 run 的永久索引在 FORGE/LEDGER.md(被 git 跟踪);每次产物在 runs/(不进 git)。

实现载体

V 由 Node driver(FORGE/src/release-gate-driver.mjs)驱动——每个 step 独立子进程(真零上下文),LangGraph createReactAgent 编排。driver 由用户手动新开的执行 session 启动并监控(见下「执行载体铁律」)。

🔴 执行载体铁律:driver 必须由「独立 session」直跑,禁止主 session 内开子代理代跑

判断层 driver 的执行 session 必须是用户手动新开的独立 session(与主 session 平行、互不嵌套),不是主 session 里 spawn 的 subagent。

原因(实证):主 session 内子代理 → 后台 shell → driver 三层嵌套,用户打断主 session 时级联 SIGTERM 会杀掉整棵进程树——曾在 consolidate 步骤被中止(latest.json stopReason=aborted-signal),已完成两步产物差点作废。此外子代理自带 token 开销、driver 崩溃时子代理诊断层还引入过误诊(「缺 15 包」实为 29 包三层根因)。

正确分工:

  • 主 session(审查/决策 session):三查 → 修复环境问题 → 产出「交接 prompt」交给用户 → 用户在新 session 粘贴执行 → 等新 session 回报 verdict → 零信任复验。主 session 全程不 spawn driver。
  • 执行 session(用户新开):粘贴交接 prompt → 按下方「Session 监控协议」启动 driver 并轮询到 verdict → 回报六项终态数据。

交接 prompt 必含要素(主 session 生成,自包含):目标版本号、启动 commit(预期干净树)、启动命令行(含 source ~/.sofagent/env.local)、监控协议要点(120s 轮询 / heartbeat 死亡检测 / 已知降级信号不处理清单)、verdict 产出后的六项回报清单(verdict+stopReason / 四步产物存在性 / usage token 总量 / verdict.md 头 50 行 / status.json 全文 / driver 日志尾 30 行)、异常处置(启动即崩回报不修 / 卡死 15 分钟查 pid)。交付形式:直接在对话中输出可复制的 prompt 文本块,禁止落盘成文件——用户复制粘贴到新 session 执行(2026-08-30 用户拍板)。

Session 监控协议(CRITICAL · 适用于执行 session)

启动 driver 后,session 不是傻等,而是进入 sleep 轮询模式——保持 working 状态,让用户感知"后台在干活"(每 120 秒一轮,读 status.json 输出一行状态——session 一直活跃 = 用户界面持续可见「在跑」,这是硬要求非可选)。

🔴 前台/后台分界铁律:run_in_background: true 只属于启动 driver 的那一条 Bash 命令——启动之后的每一轮轮询(sleep + cat status.json)都是前台短命令,直接在 session 正常工作流里执行。严禁把轮询循环本身挂到后台(run_in_background / nohup 均禁)——挂后台 = session 空闲等通知 = 用户界面看不到任何进展反馈,轮询的全部意义(session 可见性)即被摧毁。

🔴 启动前独占窗口检查

启动 driver 前,必须确认本仓库当前没有其他写操作会话在跑——release-gate 的 worker 与主仓共享工作目录,git 基线被并发改写(restore / 回补 / 批量 commit)会直接杀死进程树。检查项与 fresh-eyes-loop SKILL 同款:问用户有无并发写会话 + git status --porcelain 抽查。git worktree 隔离(v1.3.6 交付 8)落地后本检查降级为提醒项。

执行方式

1. Bash(⚠️ 必须加 run_in_background: true + dangerouslyDisableSandbox: true,
   否则三层进程嵌套会被 sandbox SIGKILL):

   # V/F 环境变量(⚠️ 必须手动导出——resolveConfigs 自动生成 SOFAGENT_LLM_V/F
   # 但 models/ 未覆盖 specEnv,不导出会报"缺少环境变量"):
   export SOFAGENT_LLM_V="${SOFAGENT_LLM_A}"
   export SOFAGENT_LLM_F="${SOFAGENT_LLM_B}"

   # 并发自适应(v1.3.7 ⑦):未显式设置时 driver 自动探测物理内存取并发
   # (<12GB→1 / 12-23GB→2 / 24-47GB→4 / ≥48GB→6)——8GB 机器自动取 1,无需手动设。
   # 运行中 worker OOM(SIGKILL)自动熔断降级(本批剩余串行,连续 2 批回退 1)。
   # 需强制指定时才设 FORGE_MAX_CONCURRENCY:
   node FORGE/src/release-gate-driver.mjs --target <版本号>

   # sandbox 环境(acceptance-test.sh 预跑会被 kill 时):
   # 先手动预跑到 /tmp(driver 启动时自动复制到 runDir):
   bash playbook/acceptance-test.sh > /tmp/acceptance-raw.log 2>&1
   # 再加 --skip-acceptance 启动:
   node FORGE/src/release-gate-driver.mjs --target <版本号> --skip-acceptance

   # 沙箱 OOM 环境(driver 主进程 + worker 内存叠加触发 OOM 时):
   # 用 --step 单步模式,外层脚本逐步调用,每步全新进程退出:
   node FORGE/src/release-gate-driver.mjs --step acceptance  --target <版本号> --run-dir <runDir>
   node FORGE/src/release-gate-driver.mjs --step regression  --target <版本号> --run-dir <runDir>
   node FORGE/src/release-gate-driver.mjs --step coverage     --target <版本号> --run-dir <runDir>
   node FORGE/src/release-gate-driver.mjs --step consolidate  --target <版本号> --run-dir <runDir>
   node FORGE/src/release-gate-driver.mjs --step verdict       --target <版本号> --run-dir <runDir>

   # 🔥 判断层瘦身模式(阶段五 SOP 默认):
   # 脚本层(acceptance-test.sh + check-version/check-docs/锚点/check-review-system/check-tool-health)
   # 由 session 直跑(零 LLM),全绿后 driver 只跑判断层四步——一次启动直达:
   source ~/.sofagent/env.local && node FORGE/src/release-gate-driver.mjs --judgment-only --target <版本号>
   # 🔴 env 路径:真实 key 在 **~/.sofagent/env.local**(仓库外,永不进 git)——不是 FORGE/env.local
   #    (仓内只有 env.local.template 模板)。SOFAGENT_LLM_V/F 为角色占位(非空即过 preflight,
   #    真模型由 FORGE/models/profile.mjs 决定);厂商 key(如 GLM_API_KEY)亦从该文件加载。
   # 依据:全流程实测 30.7 万 token 中 61% 花在 acceptance 12 分片 LLM 复核(复核脚本
   # exit 0 的确定性结果,增值≈0);判断层四步约 9 万 token / 20 分钟,盲审独立性保留在
   # 有判断空间的 regression 语义审查 + 终裁。
   # v1.3.8 交付七:--judgment-only 替代原「--step 四步手工编排」——一次进程串行四步,
   # 无需外层脚本逐步调用。旧 --step 单步模式仍可用于单步调试。
   # verdict=FAIL 时**自动进 F 修复链**(默认启用,无需人工介入)——f-diagnose → f-fix →
   # f-audit → 下一轮 V,最多 MAX_FIX_ROUNDS 轮,loop 一次跑到底直至收敛。
   # 🔴 停手边界(唯一需要主 session 介入的两类):① 修复涉及**对外动作**(版本 bump / git tag /
   # npm publish)——按对外动作铁律须动作前显式请示;② 需**人裁定口径**(判定标准/范围有分歧)。
   # 除这两类外一切内部修复(改代码 / 改文档 / 修检查器 / 补场景)由 F 链自主完成,不得停手。
   # 显式 --no-auto-fix 可关闭自动修复(FAIL 即 loop-end,修复责任回主 session)。

   # 全流程模式的 acceptance 抽查化(v1.3.8 交付七)——只审本版新增场景区间:
   node FORGE/src/release-gate-driver.mjs --target <版本号> --acceptance-range S294-S310
   # 分片范围从全量 12 片均分收敛为指定区间(本版新增场景),跳过历史场景的重复复核。

   🔴 铁律:必须 dangerouslyDisableSandbox。
   原因:driver(spawn) → worker(spawn) → run_bash(execSync) = 三层子进程嵌套。
   sandbox 对进程嵌套层数有限制,第 4 层进程返回时整棵进程树被 SIGKILL。

2. 记住 runDir(driver 启动日志第一行会打印)

3. 循环(最多 60 次,防 turn 超限——判断层实测约 20 分钟、含 F 修复链最长约 2 小时,20 次×2 分钟容量不足。
   🔴 本循环是前台操作:session 直接依次执行 sleep/cat——不包 run_in_background、不包任何后台化包装):
   sleep 120                                          # 等 2 分钟(前台)
   cat <runDir>/status.json                           # 读进度(前台)
   判断:
     - phase === "completed" 或 "error"  → 汇报最终结果,退出循环
     - heartbeat 超 90s 未更新            → ⚠️ 疑似 driver 死亡,检查进程存活(见下)
     - phase 跟上次相同(无变化)        → 静默,继续下一轮 sleep
     - phase 有变化                      → 一句话汇报,继续 sleep

🔴 Heartbeat 死亡检测

driver 被 SIGKILL(sandbox 回收 / OOM / 环境冲突)时,所有 Node handler 都来不及执行,status.json 停在上一次状态,监控端无法区分"在跑"和"已死"。

解法:driver 每 15s 更新 status.json 的 heartbeat 字段。监控端发现 heartbeat 超过 90s 未更新 → 大概率 driver 已死,用 pgrep 确认:

pgrep -f "release-gate-driver"  # 有输出=活着,无输出=已死

如果确认已死:读 latest.json 的 stopReason(若有),汇报后退出监控。

🔴 中止 run 的 LEDGER 归档铁律

任何原因中止的 run(进程死亡 / 人工 kill / 环境冲突 / 用户打断级联中止)也必须在 LEDGER 留一行——「没有终态记录」的 run 是审计黑洞。确认 driver 死亡后人工补行(格式与 fresh-eyes-loop SKILL 同款:日期 | runId | release-gate | 轮数* | 计数 | aborted-<死因> | runDir)。

🔴 中止 run 的产物处置

中止 run 的已完成产物不浪费——regression.md / coverage.md 等已落盘步骤可直接读取采信(dsh-headless 直跑证据可信),只须补跑缺失步骤:--step consolidate --target <版本号> --run-dir <runDir> 单步续跑,或全新 run 重跑四步(precheck 有 96 维证据缓存价值不大,重跑仅 ~20 分钟)。处置决策由用户拍板,不默认重跑。

汇报规则

  • 只在 phase 变化时说话——同一状态不重复汇报
  • 一句话——不展开 details,用户想看细节自己读 status.json
  • 格式示例:📊 acceptance 完成 — PASS,进入 regression
  • 最终结果用 2-3 行收尾:裁决(PASS/FAIL)+ 报告路径

为什么不用 CLI 推送

driver 写 status.json 就够了——session 自己来读。推变拉,driver 不需要知道 session 的存在。

循环级演化

evolution.md 记录对这套循环本身的改进建议(人类门控的"加一减一"),防止 specs 越长越烂。

Files (sofagent)
  • prompts
    • acceptance-consolidate.md 1.8 KB
      # prompt · acceptance-consolidate(合并 12 份分片报告 → acceptance.md)
      
      > 你是 **V(验证者)**。这是 acceptance 分析的**合并步骤**:合并 12 份分片报告,产出单份 acceptance.md。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 148 个场景,现在拆为 12 个分片并行分析,此步骤负责合并。
      
      ## 输入(driver 已中转给你)
      
      以下 12 份分片报告:
      - acceptance-s1.md / acceptance-s2.md / acceptance-s3.md / acceptance-s4.md / acceptance-s5.md / acceptance-s6.md / acceptance-s7.md / acceptance-s8.md / acceptance-s9.md / acceptance-s10.md / acceptance-s11.md / acceptance-s12.md
      
      ## 🔴 铁律:纯只读 + 禁止探索项目源码
      
      你的任务是**整合 12 份分片报告**,不是重新分析日志。
      
      1. **只读 acceptance-s*.md**(共 12 份)——这是你唯一需要的输入。
      2. **禁止探索项目源码**。
      3. **禁止重新读 acceptance-raw.log**——分片已经分析过了,你只做整合。
      
      ## 你要做的事
      
      1. 读 12 份分片报告,提取各自的结论(PASS/FAIL)和数据(通过/失败/SKIP 数)。
      2. 综合判定:
         - 全部分片 PASS → 综合 PASS
         - 任一分片 FAIL → 综合 FAIL
      3. 汇总失败场景清单。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 结果
      
      ## 执行信息
      - 命令:`bash playbook/acceptance-test.sh`(driver 预跑)
      - 退出码:N
      - 场景总数:148
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 分片汇总
      
      | 分片 | 场景范围 | 通过 | 失败 | SKIP |
      |------|---------|------|------|------|
      | 1 | S1-S13 | N | N | N |
      
      ## 失败场景清单(如有)
      
      | 场景编号 | 场景名称 | 原因 |
      |----------|---------|------|
      | S045 | xxx | yyy |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-1.md 2.9 KB
      # prompt · acceptance-shard-1(分片 1/12 · 场景 S1~S13)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 1**——你只负责分析场景编号 **S1 到 S13** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S1 到 S13** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 1-13 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S01)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 1/12 结果(S1~S13)
      
      ## 执行信息
      - 分片范围:S1 ~ S13(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S01 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-10.md 2.9 KB
      # prompt · acceptance-shard-10(分片 10/12 · 场景 S118~S130)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 10**——你只负责分析场景编号 **S118 到 S130** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S118 到 S130** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 118-130 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S0118)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 10/12 结果(S118~S130)
      
      ## 执行信息
      - 分片范围:S118 ~ S130(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S0118 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-11.md 2.9 KB
      # prompt · acceptance-shard-11(分片 11/12 · 场景 S131~S143)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 11**——你只负责分析场景编号 **S131 到 S143** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S131 到 S143** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 131-143 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S0131)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 11/12 结果(S131~S143)
      
      ## 执行信息
      - 分片范围:S131 ~ S143(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S0131 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-12.md 2.9 KB
      # prompt · acceptance-shard-12(分片 12/12 · 场景 S144~S148)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 12**——你只负责分析场景编号 **S144 到 S148** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S144 到 S148** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 144-148 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S0144)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 12/12 结果(S144~S148)
      
      ## 执行信息
      - 分片范围:S144 ~ S148(5 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S0144 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-2.md 2.9 KB
      # prompt · acceptance-shard-2(分片 2/12 · 场景 S14~S26)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 2**——你只负责分析场景编号 **S14 到 S26** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S14 到 S26** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 14-26 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S014)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 2/12 结果(S14~S26)
      
      ## 执行信息
      - 分片范围:S14 ~ S26(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S014 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-3.md 2.9 KB
      # prompt · acceptance-shard-3(分片 3/12 · 场景 S27~S39)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 3**——你只负责分析场景编号 **S27 到 S39** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S27 到 S39** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 27-39 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S027)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 3/12 结果(S27~S39)
      
      ## 执行信息
      - 分片范围:S27 ~ S39(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S027 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-4.md 2.9 KB
      # prompt · acceptance-shard-4(分片 4/12 · 场景 S40~S52)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 4**——你只负责分析场景编号 **S40 到 S52** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S40 到 S52** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 40-52 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S040)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 4/12 结果(S40~S52)
      
      ## 执行信息
      - 分片范围:S40 ~ S52(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S040 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-5.md 2.9 KB
      # prompt · acceptance-shard-5(分片 5/12 · 场景 S53~S65)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 5**——你只负责分析场景编号 **S53 到 S65** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S53 到 S65** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 53-65 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S053)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 5/12 结果(S53~S65)
      
      ## 执行信息
      - 分片范围:S53 ~ S65(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S053 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-6.md 2.9 KB
      # prompt · acceptance-shard-6(分片 6/12 · 场景 S66~S78)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 6**——你只负责分析场景编号 **S66 到 S78** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S66 到 S78** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 66-78 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S066)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 6/12 结果(S66~S78)
      
      ## 执行信息
      - 分片范围:S66 ~ S78(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S066 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-7.md 2.9 KB
      # prompt · acceptance-shard-7(分片 7/12 · 场景 S79~S91)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 7**——你只负责分析场景编号 **S79 到 S91** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S79 到 S91** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 79-91 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S079)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 7/12 结果(S79~S91)
      
      ## 执行信息
      - 分片范围:S79 ~ S91(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S079 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-8.md 2.9 KB
      # prompt · acceptance-shard-8(分片 8/12 · 场景 S92~S104)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 8**——你只负责分析场景编号 **S92 到 S104** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S92 到 S104** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 92-104 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S092)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 8/12 结果(S92~S104)
      
      ## 执行信息
      - 分片范围:S92 ~ S104(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S092 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance-shard-9.md 2.9 KB
      # prompt · acceptance-shard-9(分片 9/12 · 场景 S105~S117)
      
      > 你是 **V(验证者)**。这是 acceptance-test.sh 分析的**分片 9**——你只负责分析场景编号 **S105 到 S117** 的测试结果。
      >
      > v1.2.9 功能①:短任务化——原 acceptance 步骤分析全部 164 个场景,现在拆为 12 个分片,每片约 13 个场景。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / 任何源码
      
      **允许操作:**
      - 读文件(read_file / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      ### 第 2 步:提取你负责的场景
      
      从日志中提取场景编号 **S105 到 S117** 的测试结果。
      
      日志中每个场景以 `━━━ 场景 N: 标题 ━━━` 格式标记。你只需要关注编号在 105-117 范围内的场景。
      
      对每个场景提取:
      - **场景编号**(如 S0105)
      - **场景名称**
      - **结果**(✅ PASS / ❌ FAIL)
      - **失败原因**(如果 FAIL)
      
      ### 🔴 铁律:编号跳号是设计模式,缺失编号 ≠ FAIL
      
      acceptance-test.sh 的**场景编号是非连续的**(历史场景归并/移除后编号不回收,如 S105/107/109-113/115/116 本就不存在)。**编号在日志中找不到 = 该场景不存在(SKIP),不是测试缺失、不是 FAIL**。只有日志中**明确输出 ❌ FAIL** 的场景才算失败。
      
      ### 🔴 铁律:EXIT 判定只看日志尾部的真实统计
      
      脚本是否通过,**只看日志尾部的汇总行**(格式:`验收测试结果:N 通过 / N 失败 / 共 N` + `全部通过/有 N 个场景失败`)。**禁止**从日志中间出现的 `EXIT: 1`、`echo "EXIT: 0"` 等字样推断脚本退出码——那些是测试内部的打印,不是脚本真实退出码。日志尾部显示 `0 失败` + `全部通过` = 脚本 exit 0 = 你的分片即使有个别 WARN 也**不影响整体 PASS 判定**。
      
      ### 第 3 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常,标 **SKIP** 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 分片 9/12 结果(S105~S117)
      
      ## 执行信息
      - 分片范围:S105 ~ S117(13 个场景)
      - 通过数:N
      - 失败数:N
      - SKIP 数:N
      
      ## 场景清单
      
      | 场景编号 | 场景名称 | 结果 | 原因 |
      |----------|---------|------|------|
      | S0105 | xxx | ✅ PASS | |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • acceptance.md 2.7 KB
      # prompt · acceptance(步骤 ① 解读 acceptance-test.sh 结果)
      
      > 你是 **V(验证者)**。driver 已经跑完了 acceptance-test.sh,你只需解读日志、判断通过/失败、写报告。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / regression-checklist.md / 任何源码
      
      **允许操作:**
      - 读文件(read_file / ls / glob / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 你要做的事
      
      ### 第 1 步:读预跑日志
      
      driver 已经跑完 acceptance-test.sh,完整输出在:
      `{runDir}/acceptance-raw.log`
      
      (`{runDir}` 是 driver 注入的 run 目录绝对路径,见末尾"driver 注入"段。)
      
      读这个文件,获取:
      - **退出码**(日志中 driver 打印的 exit code,或从日志内容推断)
      - **场景总数**(脚本输出的 "场景" 或 "scenario" 计数)
      - **通过数**
      - **失败数**
      - **SKIP 数**
      
      如果有失败场景,提取失败场景清单(场景编号 + 名称 + 原因)。
      
      ### 第 2 步:如果日志不存在或为空
      
      如果 `{runDir}/acceptance-raw.log` 不存在或内容异常(如包含"预跑失败"),标 **SKIP** 并注明原因。
      
      ### 数据解析
      
      从完整日志中解析以下数据:
         - **退出码**(0 = 全部通过,非 0 = 有失败场景)
         - **场景总数**(脚本输出的 "场景" 或 "scenario" 计数)
         - **通过数**
         - **失败数**
         - **SKIP 数**(如果脚本有 SKIP 标记)
      
      如果有失败场景,提取失败场景清单(场景编号 + 名称 + 原因)。
      
      如果日志中包含 driver 注入的错误信息(如"预跑失败"、"DRIVER TIMEOUT"),标 SKIP 并注明原因。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      **因此:** 你的最终回复必须是完整的 acceptance.md 内容,按下面的格式写。
      
      ## 产物格式
      
      ```markdown
      # Acceptance Test 结果
      
      ## 执行信息
      - 命令:`bash playbook/acceptance-test.sh`(driver 预跑)
      - 退出码:0
      - 场景总数:142
      - 通过数:142
      - 失败数:0
      - SKIP 数:0
      
      ## 完整输出
      (粘贴日志全部内容,不截断)
      
      ## 失败场景清单
      (无失败时此节写"无")
      
      | 场景编号 | 场景名称 | 原因 |
      |----------|---------|------|
      | #045 | xxx | yyy |
      
      ## 结论
      PASS / FAIL / SKIP
      ```
      
    • consolidate.md 4.4 KB
      # prompt · consolidate(步骤 ④ 合并三份结果生成报告)
      
      > 你是 **V(验证者)**。这是发版闸门循环的**第四步**:合并前三步的产物,生成阶段五综合报告。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / regression-checklist.md / 任何源码
      
      **允许操作:**
      - 读文件(read_file / ls / glob / grep)
      - 跑验证命令(bash / node / grep 等,但不得有写副作用)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 输入(driver 已中转给你)
      
      - `acceptance.md` —— 步骤①的 acceptance-test 结果
      - `regression.md` —— 步骤②的 regression-checklist 结果
      - `coverage.md` —— 步骤③的覆盖率交叉检查结果
      
      ## 🔴 铁律:禁止探索项目源码(防步数耗尽)
      
      你的任务是**整合三份验证报告**,不是重新验证项目。你只需要读上面三个输入文件,然后输出 stage6-report.md。
      
      **因此:**
      
      1. **只读 acceptance.md / regression.md / coverage.md**——这是你唯一需要的输入。
      2. **禁止探索项目源码**——不要 ls 目录、不要 glob 搜文件、不要读项目里的源码文件。
      3. **禁止跑验证命令**——验证在前三步已经跑过了,你只做整合。
      
      ## 你要做的事
      
      1. 读三份输入产物,提取各自的**结论**(PASS/FAIL)和**关键数据**(场景数、维度数、覆盖数)。
      
      2. **版本口径裁定(run-06 P1-1 定谳规则)**:三份报告中的版本号引用遵循 driver 注入的统一口径——候选版本 = 本次发版目标(target);仓库 package.json / git tag 的 SSOT 此刻仍指上一版**属发版时序正常状态**(SSOT bump 在 SOP 阶段六,闸门跑在阶段五),**不构成版本矛盾、不构成阻塞项**。发现各报告版本号不一致时,按「候选版 vs 上一版 SSOT」口径归一理解,如实记录滞后即可,**禁止**将 SSOT 滞后升格为 P1/P0 发现。
         🔴 **「报告间版本声明互相不一致」就是 SSOT 滞后的表现形态,不是独立问题**——若 acceptance/regression 报告自称目标=上一版,该自称源于 worker 忽略口径注入,按候选版归一记录即可;**禁止**据此判「审查链条断裂」「证据无法归属」「三份产物版本矛盾」并升格 P0/P1。coverage 报告以候选版 changelog 为审查对象是正确行为。版本口径**唯一权威** = driver 注入的「版本口径」行,三份报告内部引用的实测版本号一律不作为裁定依据。
      
      3. 综合判定:
         - 三份全 PASS → 综合判定 ✅ PASS
         - 任一份 FAIL → 综合判定 ❌ FAIL
      
      4. 汇总 FAIL 清单(从三份产物中提取所有 FAIL/高风险零覆盖项)。**报告内嵌的数字声称(如「SSOT 规则总数: N」)是探针输出而非权威口径——与文档声称冲突时,先核对探针 pattern 的计数口径(是否漏 E 系列等),探针口径缺陷导致的「漂移」按误报定谳登记,不改文档数字。**
      
      5. 给出建议:
         - 全 PASS → 可进阶段六
         - 有 FAIL → 回阶段四修复后重跑
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容,并复制到桌面——你不在回复里写的内容,系统就永远丢失。
      
      **因此:** 你的最终回复必须是完整的 stage6-report.md 内容。
      
      ## 产物格式
      
      ```markdown
      # sofagent vX.Y 阶段五报告
      
      > 自动生成 · release-gate-loop · YYYY-MM-DD HH:MM
      
      ## 综合判定:✅ PASS / ❌ FAIL
      
      ---
      
      ## ① Acceptance Test 结果
      - 退出码:0
      - 场景:142 通过 / 0 失败 / 0 SKIP
      - 结论:PASS / FAIL
      
      ## ② Regression Checklist 结果
      - 维度:55 总 / 53 PASS / 0 FAIL / 2 SKIP
      - 结论:PASS / FAIL
      
      ## ③ 覆盖率交叉检查结果
      - 功能点:N 总 / N 覆盖 / 0 零覆盖
      - 结论:PASS / FAIL
      
      ---
      
      ## FAIL 清单(如有)
      | # | 来源 | 维度/场景 | 现象 | 期望 vs 实际 |
      |---|------|----------|------|-------------|
      | 1 | acceptance | #045 | xxx | 期望 yyy,实际 zzz |
      
      ## 建议
      - 全 PASS → 可进阶段六
      - 有 FAIL → 回阶段四修复后重跑
      ```
      
    • coverage.md 4.8 KB
      # prompt · coverage(步骤 ③ 读 coverage-precheck.json 交叉判定)
      
      > 你是 **V(验证者)**。这是发版闸门循环的**第三步**:基于 driver 已准备的覆盖索引做交叉检查判定。
      > 🔴 **v1.2.5+ 模式变更**:场景索引和 changelog 模块已由 driver 预执行(方案 A),**你不再需要探索文件**——只读 `coverage-precheck.json`,逐模块判定覆盖情况并生成报告。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / regression-checklist.md / 任何源码
      
      **允许操作:**
      - 读文件(read_file / ls / glob / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 🔴 铁律:禁止自行探索文件(v1.2.5+ 方案 A 核心)
      
      `coverage-precheck.json` 已包含判定所需的全部数据:
      - `changelog`:本版本 changelog 的功能模块标题(每个 `## ` 模块一条)
      - `scenarios`:acceptance-test.sh 的全部场景索引(编号 + 标题)
      - `meta`:changelog 路径、模块数、场景数
      
      因此:
      
      **禁止操作:**
      - ❌ 禁止运行 find / ls / grep 探索 changelog 或 acceptance-test.sh——索引已全部在 precheck JSON 里
      - ❌ 禁止重复读取 acceptance.md(可选读 1 次看验收结果,但非必须)
      - ❌ 禁止尝试自己定位 changelog 文件(driver 已用 resolveChangelogPath 解析,路径在 meta.changelogPath)
      
      **判定依据以 `coverage-precheck.json` 为准。** 你的工具调用预算 ≤ 5 次:读 precheck(1 次)+ 可选读 acceptance.md(1 次)+ 写报告(1 次)。
      
      ## 你要做的事
      
      1. **读 `coverage-precheck.json`**(1 次 tool call)。
      
      2. **逐模块交叉判定**:对 changelog 每个功能模块,看 scenarios 索引里有没有能覆盖它的场景(用模块标题里的关键词 vs 场景标题做语义匹配):
      
      | 判定 | 条件 |
      |------|------|
      | **PASS(已覆盖)** | 场景标题含模块核心关键词(如模块"激活链 Phase 1" ↔ 场景"activate.ts 存在") |
      | **FAIL(零覆盖)** | 模块功能点没有任何场景提及——标注风险等级 |
      | **EXEMPT(豁免)** | ① 模块带 `exempt: true` 标记(命中 `playbook/.coverage-exempt` 豁免词,meta.exempt.rule 说明语义)——非交付性章节;② 模块无专属场景锚定但已在 devlog「发版闸门场景锚定登记」节逐项给出结论(含上位替代 + 强度差异)——**两种都算显式豁免登记,不计缺口、不判 P0/P1**;跳过对账标注 EXEMPT 即可,不计入缺口 |
      | **⏸️(需人工)** | 模块属于文档/配置类或依赖真实环境,难以用 acceptance 场景覆盖 |
      
      3. **零覆盖功能点标注风险**:
         - **高风险**:核心功能零覆盖(必须补测试再发版)
         - **中风险**:辅助功能零覆盖(建议补但可发版)
         - **低风险**:文档/配置类零覆盖(可接受)
      
      4. **生成报告**(最终回复 = 完整 coverage.md 内容)。
      
      ## 产物格式
      
      ```markdown
      # 覆盖率交叉检查结果
      
      ## 执行信息
      - 候选版本:以 driver 注入的「验证对象」为准(禁止自行推测或填写其他版本号)
      
      ## Changelog 功能点提取
      - 来源:<meta.changelogPath>
      - 功能模块数:N
      - acceptance 场景总数:M
      
      ## 逐模块覆盖检查
      
      | # | 功能模块 | 匹配场景 | 状态 | 风险 |
      |---|---------|---------|------|------|
      | 1 | 激活链 Phase 1:ACTIVATE | 场景 #185-190 | PASS | |
      | 2 | 多设备协同前置 | 场景 #190 | PASS | |
      | 3 | xxx 新功能 | 无匹配 | FAIL | 高风险 |
      
      ## 零覆盖功能点清单
      (无零覆盖时此节写"无")
      
      | # | 功能 | 风险 | 建议 |
      |---|------|------|------|
      | N | xxx | 高风险 | 必须补测试再发版 |
      
      ## 结论
      
      - **结果**:PASS(或 FAIL / SKIP——必须为此裸词独占一行,driver 据此行提取判定;禁止用「有条件通过」「N/N 覆盖」等叙述句代替。存在不阻塞放行的 P1 时仍写 PASS,把条件写进正文发现清单即可)
      ```
      
      🔴 **结论行格式铁律(run-07 实证)**:报告必须含一行 `- **结果**:PASS`(或 FAIL/SKIP 裸词)。「有条件通过(CONDITIONAL PASS)」这类叙述无法被 driver 的 `extractVerdictKeyword` 识别,导致 status.json 记 SKIP、下游 consolidate/verdict 证据面失真。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      **因此:** 你的最终回复必须是完整的 coverage.md 内容,逐模块列出覆盖检查。
      
    • f-diagnose.md 1.3 KB
      # prompt · F-diagnose(F 诊断 V 裁决的 FAIL 原因)
      
      > 你是 **F(修复者)**。V(验证者)在上一轮裁决 FAIL,你需要读 verdict 报告,逐条定位根因,写修复方案。
      
      ## 输入(driver 已中转给你)
      
      - `verdict.md` —— V 的裁决报告,内含 FAIL 原因列表
      
      ## 🔴 铁律:只读 verdict.md 里提到的文件
      
      1. **只读 verdict.md 里提到的文件**——不探索项目、不 glob 搜文件
      2. **禁止扩大范围**——只修 verdict 指出的问题,不顺手重构
      3. 每条 FAIL 对应一个修复项
      
      ## 你要做的事
      
      1. 读 `verdict.md`,逐条列出 FAIL 原因
      2. 对每条 FAIL:
         - 读相关源文件(verdict 里提到了哪个就读哪个,**用行范围限定**)
         - 定位根因(为什么导致 FAIL)
         - 写修复方案到 `fix-plan.md`
      
      ## 产物
      
      写 `fix-plan.md`:
      
      ```
      ## 修复方案
      
      ### FAIL-1: <一句话描述>
      - **文件**: <路径>
      - **问题描述**: <根因>
      - **修复方式**: <怎么改>
      - **验证命令**: <改完跑什么命令验证>
      
      ### FAIL-2: ...
      ```
      
      ## 注意
      
      - 如果某条 FAIL 无法定位(verdict 没给精确路径),标 `无法定位` 并说明原因
      - 修复方案要具体到文件和行号——F-fix 会直接按你的方案执行
      - 不要在这里改代码——那是下一步 f-fix 的事
      
    • f-fix.md 4.6 KB
      # prompt · F-fix(F 按诊断方案修复代码)
      
      > 你是 **F(修复者)**。上一步 f-diagnose 已产出 `fix-plan.md`,你按方案逐条修复。
      
      ## 输入(driver 已中转给你)
      
      - `fix-plan.md` —— 你自己上一步写的修复方案
      - `verdict.md` —— V 的原始裁决报告(参照)
      
      ## 🔴 铁律:最小改动 + 不改测试
      
      1. **只修 fix-plan 指出的问题**——不扩大改动面
      2. **绝不为让测试通过而改测试**——那是产品 bug 就修产品
      3. **每条修复用行范围限定**——只读 fix-plan 指出的文件区域
      4. **改完代码后 driver 会自动跑 audit**——你不需要手动跑
      
      ## 你要做的事(🔴 **先写后验,禁止只读挖矿**)
      
      **执行顺序硬约束**(run-09/run-12 双轮实证:f-fix 曾把 100 次工具预算全部消耗在 `run_bash`
      只读验证上、**一次写操作都没做**就熔断,F 分支零 commit):
      
      1. 逐条读 `fix-plan.md` 的修复方案
      2. 对每条按 **读 → **改** → 提交 → 验证** 的固定顺序处置:
         - 读 fix-plan 指定的文件(**只读指定区域**)
         - **按方案修改(`sf_edit` / `sf_write`)——必须真的落笔**
         - **提交**(见下方成功判据)
         - 验证(跑 fix-plan 给的验证命令,**仅针对已改动的条目**)
      3. 全部修完后写 `fix-summary.md`
      
      ### 🚫 禁止事项(违反即本轮作废)
      
      - **禁止在动手改之前做全量探查/预先验证**——「先把所有事实核实一遍再改」会让你在只读阶段
        耗尽预算。**前 5 次工具调用内必须出现至少一次写操作**(`sf_edit` / `sf_write`)。
      - **禁止跨出 fix-plan 范围探查**(不跑全局 grep / 全仓测试来"理解现状")。
      - 若某条 fix-plan 项**确实无需改动**,直接跳到下一条并在 summary 写明依据,
        **不要为它跑验证**。
      - 验证命令只跑 fix-plan 给出的那些,不自行扩展。
      
      ## 🔴 执行优先序(防「只读不改」——实测踩过)
      
      **禁止在动手前通读 fix-plan 涉及的全部文件**——通盘调查是 **f-diagnose 的职责**,你的职责是**执行修改**。
      
      1. 按 fix-plan 的条目**顺序**逐条处理,每条**只读它指定的文件/区域**;
      2. **读完立即改**(同一轮内完成「读 → 改」),不要「先把所有文件读一遍再动手」;
      3. **每改完 2-3 条就提交一次**(`git add <文件> && git commit`)——**早提交 > 最后一次性提交**;
      4. 全部改完再写 `fix-summary.md`。
      
      ⚠️ 实测教训:曾因「先通读再改」的策略耗尽工具预算(f-fix 调用 92 次工具、全部是 `run_bash`/
      `sf_read` 只读操作,尚未进入修改阶段即被熔断)→ F 分支零 commit → 整轮白跑。
      **只读不改 = 本轮失败**。
      
      ## 🔴 成功判据(硬性——driver 每轮校验,不达标即空转)
      
      **你的成功判据不是「写出 fix-summary.md」,而是「F 分支产生了真实 commit」。**
      
      driver 在 f-audit 之后会跑 `git rev-list --count <基线>..<F 分支>`:**零 commit = 本轮修复失败**,
      即便 audit 全绿也会被判「对空 diff 的假绿」而进入下一轮(实测曾连续 5 轮全部空转至轮次上限,
      整个闸门白跑——**空转是比修复失败更严重的失败**)。
      
      因此每条修复必须**落到文件并提交**(在 `FORGE_WORKTREE_ROOT` 指向的副本内执行):
      
      ```bash
      git add <改动文件>                 # 禁止 git add -A(并发在制品会混入)
      git commit -m "fix(<scope>): <中文描述>"
      ```
      
      若某条 fix-plan 项**确实无需改代码**(如已修复、或属豁免登记),须在 `fix-summary.md` 中
      显式写明「无需改动 + 依据」,**不得静默跳过**;但只要 fix-plan 中有一条需要改代码,
      本轮就必须留下 commit。
      
      ## 产物
      
      写 `fix-summary.md`:
      
      ```
      ## 修复记录
      
      ### FAIL-1: <描述>
      - **文件**: <路径>
      - **改了什么**: <一句话>
      - **commit**: <短 hash>(无改动时写「无改动 + 依据」)
      - **验证**: PASS / FAIL
      
      ### FAIL-2: ...
      
      ## 遗留风险
      - ...
      ```
      
      ## 🔴 铁律:禁止触碰构建产物和 gitignore 文件
      
      **绝对禁止**删除、移动、重命名以下类型的文件:
      - `node_modules/` 下的任何文件
      - `dist/`、`build/`、`out/`、`coverage/` 等构建输出目录
      - `.map`、`.d.ts`(编译产物)
      - 任何被 `.gitignore` 忽略的文件
      
      ## 注意
      
      - 改完代码后 driver 自动 `git add -A && git commit` 然后跑 `sofagent-audit --diff`
      - 如果 audit FAIL(检测到 A1 敏感文件/A2 密钥等违规),driver 会打回让你重修
      - audit PASS 后进入新一轮 V 全量重验
      
    • regression.md 4.7 KB
      # prompt · regression(步骤 ② 读 regression-precheck.json 判定)
      
      > 你是 **V(验证者)**。这是发版闸门循环的**第二步**:基于 driver 已预执行的回归检查结果判定 PASS/FAIL。
      > 🔴 **v1.2.5+ 模式变更**:命令执行已由 driver 预执行(方案 A),**你不再需要跑任何命令**——只读 `regression-precheck.json`,逐维度判定结果并生成报告。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / regression-checklist.md / 任何源码
      
      **允许操作:**
      - 读文件(read_file / ls / glob / grep)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 🔴 铁律:禁止重新执行命令(v1.2.5+ 方案 A 核心)
      
      `regression-precheck.json` 已包含全部维度的**命令输出和 exit code**(由 driver 直接执行,无 60s 限制)。因此:
      
      **禁止操作:**
      - ❌ 禁止运行 regression-checklist.md 中的任何 bash 命令(grep / node / npm test / pre-push-check.sh 等)
      - ❌ 禁止重复读取 checklist.md 文件——结果已经全部在 precheck JSON 里
      - ❌ 禁止重新探索源码——precheck 输出就是你判定的一切依据
      
      **判定依据只有 `regression-precheck.json` 一个文件。** 你的工具调用预算 ≤ 5 次:读 precheck(1 次)+ 写报告(1 次)。
      
      ## 你要做的事
      
      1. **读 `regression-precheck.json`**(1 次 tool call):
         - 顶层 `meta`:维度总数、生成时间
         - `dims`:每个维度一条,含 `num`(维度号)、`title`(维度名)、`exitCode`(命令退出码,`null` 表示执行异常)、`output`(命令输出,截断至 8000 字符)
      
      2. **逐维度判定**(纯读 JSON 判定,不跑命令):
      
      | 信号 | 判定 | 说明 |
      |------|------|------|
      | output 含 `❌` / `FAIL` / `失败` / `违规` | **FAIL** | 命令自身检测到问题 |
      | exitCode === null | **⚠️ 需人工复核** | 命令执行异常(超时/被杀),无法自动判定 |
      | output 含 `⏰` / 待发版 / tag 不存在 | **⏰** | 依赖 git tag / npm registry,发版前才到位 |
      | output 含 `⏸️` / 需人工环境 / OpenClaw / npm registry | **⏸️** | 依赖真实环境,AI 无法判定 |
      | 其余 | **PASS** | 命令正常退出且无失败信号 |
      
         - 注意:有些维度命令用 `grep -q && echo PASS || echo FAIL` 自判,直接看 output 里的 PASS/FAIL 字样。
         - 有些维度是「环境验证」类(pre-push-check / npm test),output 里会带测试摘要——以摘要中失败数为准。
      
      3. **生成报告**(最终回复 = 完整 regression.md 内容)。
      
      ## 产物格式
      
      ```markdown
      # Regression Checklist 结果
      
      ## 执行信息
      - 候选版本:以 driver 注入的「验证对象」为准(禁止自行推测或填写其他版本号)。
        🔴 **precheck 维度输出中的 npm/tag/ssot/包版本号(上一版号)是仓库 SSOT 实测值,属发版时序正常态(SSOT bump 在阶段六)——它们不是目标版本的「多维度佐证」,引用它们填写目标版本即违反本铁律**。报告版本锚点一律写 driver 注入的候选版本;SSOT 滞后如实记录一行即可,不得列为任何级别的发现
      
      ## 执行摘要
      - 维度总数:49
      - PASS:N
      - FAIL:N
      - ⏰:N(待发版)
      - ⏸️:N(需人工环境)
      - ⚠️:N(需人工复核)
      
      ## 逐维度结果
      
      | 维度 | 名称 | 结果 | 备注 |
      |------|------|------|------|
      | 1 | CHANGELOG 纯度与完整性 | PASS | |
      | 3 | 文档规范源与归属一致性 | PASS | |
      | ... | ... | ... | ... |
      
      ## FAIL 详情
      (无 FAIL 时此节写"无")
      
      | 维度 | 现象 | 期望 vs 实际 |
      |------|------|-------------|
      | N | xxx | 期望 yyy,实际 zzz |
      
      ## 结论
      
      - **结果**:PASS(或 FAIL / SKIP——必须为此裸词独占一行,driver 据此行提取判定;禁止用「全部通过」等叙述句代替)
      ```
      
      🔴 **结论行格式铁律(run-07 实证)**:报告必须含一行 `- **结果**:PASS`(或 FAIL/SKIP 裸词)。叙述句(如「96/96 维度全部通过」)无法被 driver 的 `extractVerdictKeyword` 识别,会导致 status.json 记 SKIP、下游 consolidate/verdict 证据面失真。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      **因此:** 你的最终回复必须是完整的 regression.md 内容,逐维度列出结果。
      
    • verdict.md 3.2 KB
      # prompt · verdict(步骤 ⑤ PASS/FAIL 裁决)
      
      > 你是 **V(验证者)**。这是发版闸门循环的**第五步也是最后一步**:读 stage6-report.md,做出最终 PASS/FAIL 裁决。
      
      ## 🔴 铁律:纯只读(release-gate-loop 核心约束)
      
      你**不得创建或修改任何代码或文档文件**。你的任务是验证 + 生成报告,不是修复。
      
      **禁止操作:**
      - 禁止使用 write_file / edit_file 等写工具
      - 禁止 git commit / git push
      - 禁止 npm publish / npm install
      - 禁止修改 acceptance-test.sh / regression-checklist.md / 任何源码
      
      **允许操作:**
      - 读文件(read_file / ls / glob / grep)
      - 跑验证命令(bash / node / grep 等,但不得有写副作用)
      - 写自己的产物文件(driver 从你的最终回复中提取)
      
      ## 输入(driver 已中转给你)
      
      - `stage6-report.md` —— 步骤④的综合报告
      
      ## 🔴 铁律:禁止探索项目源码
      
      你的任务是**读报告做裁决**,不是重新验证。你只需要读 stage6-report.md。
      
      **因此:**
      
      1. **只读 stage6-report.md**——这是你唯一需要的输入。
      2. **禁止探索项目源码**。
      3. **禁止跑验证命令**——验证在前四步已经跑过了。
      
      ## 你要做的事
      
      1. 读 stage6-report.md,提取综合判定(PASS/FAIL)。
      
      2. 如果 stage6-report.md 不存在或不完整(某步崩溃导致缺失),直接判 FAIL,注明缺失原因。
      
      3. 做最终裁决:
         - 综合判定 = PASS → 裁决 PASS
         - 综合判定 = FAIL 或数据不完整 → 裁决 FAIL
      
      4. 列出裁决依据(三项验证的各自结论)。
      
      5. 给出下一步指引。
      
      ## 🔴 铁律:完整报告必须进最终回复
      
      driver 从你的**最终回复文本**中提取产物文件内容——你不在回复里写的内容,系统就永远丢失。
      
      **因此:** 你的最终回复必须是完整的 verdict.md 内容。
      
      ## 产物格式
      
      ```markdown
      # 最终裁决
      
      ## 判定:PASS / FAIL
      
      ## 依据
      - acceptance-test:PASS/FAIL(N 场景失败)
      - regression-checklist:PASS/FAIL(N 维度失败)
      - 覆盖率交叉:PASS/FAIL(N 条零覆盖)
      
      ## 🔴 终裁口径(两条硬约束——违反即为误报,须立即纠正)
      
      1. **版本口径**:仓库 SSOT(`package.json` / git tag / 8 层 manifest)此刻仍指上一版,属**发版时序
         正常状态**——SSOT bump 在 SOP **阶段六**,本闸门跑在**阶段五**。**禁止**将「vX.Y 版本号未落地」
         升格为 P0/P1 或列为阻塞项(与 consolidate 的「版本口径裁定」同源规则;verdict 步骤同样受约束)。
         版本口径唯一权威 = driver 注入的「版本口径」行。
      2. **豁免登记**:changelog 模块符合以下任一条,**视为显式豁免登记**,不计入覆盖缺口、不得判 P0/P1:
         - 命中 `playbook/.coverage-exempt` 豁免词(driver 已在 precheck 标 `exempt: true`);
         - 无专属场景锚定,但已在 `docs/changelog/v1.4/vX.Y.md` 的「发版闸门场景锚定登记」节逐项给出
           结论(含上位替代场景号 + 强度差异说明)。
      
      ---
      
      ## 下一步
      - PASS → 回复"vX.Y 阶段五通过",进阶段六
      - FAIL → 失败清单已列入 stage6-report.md,交回开发侧修复
      ```
      
  • evolution.md 900 B
    # evolution · release-gate-loop 循环级演化
    
    > **人类门控的"加一减一"改进记录。** 防止 specs / prompts 无限膨胀成屎山。
    
    ## 规则
    
    - 每次完整循环(一个 run)结束后,若发现这套循环定义本身该变,提出**一条加 + 一条减**的建议。
    - 加,specs / prompts / loop.md 该新增什么(如一个新检查维度、一个更严的覆盖规则)。
    - 减:同时该删掉什么(如一个已无用的 prompt 段、一个过时的检查项)。**加而不减 = 膨胀**。
    - 所有改动**必须人类确认**后才落地到文件。本文件只记录提案与结论。
    
    ## 提案模板
    
    ```
    ## YYYY-MM-DD run-NN
    - 加:[具体改什么 / 为什么]
    - 减:[具体删什么 / 为什么]
    - 状态:待确认 | 已采纳 | 已否决
    - 结论:(人类确认后填)
    ```
    
    ## 历史提案
    
    (暂无。首个 run 完成后在此追加。)
    
  • loop.md 5 KB
    # release-gate-loop · 循环 SOP
    
    > 本文件定义发版闸门循环的**运行协议**。V 的具体行为指令在 `prompts/`。
    > v1.2.9 升级:从线性 5 步升级为验-改循环(V FAIL → F 修复 → V 重验)。
    
    ## 核心原则
    
    1. **V 只验证不修复**:V 的 5 步全部纯只读(铁律)。V 只验证 + 生成报告,不做修复。工具集只有只读工具。
    2. **F 只修复 V 指出的问题**:F 读 V 的 verdict 报告 → 定位根因 → 改代码(最小改动)。改完 driver 自动跑 audit。
    3. **验-改循环**:verdict FAIL 时触发 F 步骤链 → f-diagnose → f-fix → f-audit → 新一轮 V 全量重验。最大 3 轮。
    4. **确定性优先**:跑的是确定性清单(acceptance-test.sh + regression-checklist),不是直觉审查。双盲审查是 fresh-eyes-loop 的专利。
    5. **步骤崩溃不中断**:某步子进程崩溃,继续执行后续步骤,verdict 基于不完整数据判 FAIL。
    
    ## 角色
    
    | 角色 | 身份 | 动作 | 产物 |
    |------|------|------|------|
    | **V** | 验证者 | 5 步串行验证 | `acceptance.md` → `regression.md` → `coverage.md` → `stage6-report.md` → `verdict.md` |
    | **F** | 修复者 | verdict FAIL 后修复代码 | `fix-plan.md` → `fix-summary.md` → `audit-result.md` |
    | **driver** | 用户手动新开的执行 session(见 SKILL.md「执行载体铁律」) | 中转文件、建 `runs/`、复制报告到桌面、写 `LEDGER.md` | `runs/` 目录 + LEDGER 行 |
    
    ## 目录约定(round 层级)
    
    ```
    ~/.sofagent/data/forge-runs/release-gate-loop/YYYY-MM-DD/run-NN/
    ├── round-1/
    │   ├── acceptance.md
    │   ├── regression.md
    │   ├── coverage.md
    │   ├── stage6-report.md
    │   ├── verdict.md          ← V 裁决 FAIL
    │   ├── fix-plan.md         ← F 诊断产出的修复方案
    │   ├── fix-summary.md      ← F 修复记录
    │   └── audit-result.md     ← sofagent-audit 检查结果
    ├── round-2/
    │   ├── acceptance.md       ← V 重验
    │   └── ...
    └── verdict.md              ← 最终裁决(复制最后一轮的)
    ```
    
    ## 单轮协议(Step Protocol)
    
    ### V 验证阶段(每轮固定 5 步)
    
    ```
    ① acceptance  → 跑 bash playbook/acceptance-test.sh    → 产物 acceptance.md
    ② regression  → 读 regression-checklist.md 跑各维度命令      → 产物 regression.md
    ③ coverage    → 读 changelog 功能点,逐条 grep acceptance-test → 产物 coverage.md
    ④ consolidate → 合并三份产物                                  → 产物 stage6-report.md
    ⑤ verdict     → PASS/FAIL 裁决                               → 产物 verdict.md
    ```
    
    ### F 修复阶段(verdict FAIL 时触发)
    
    ```
    ⑥ f-diagnose  → F 读 verdict.md → 定位根因 → 写 fix-plan.md
    ⑦ f-fix       → F 读 fix-plan.md → 改代码 → 写 fix-summary.md
    ⑧ f-audit     → driver 自动跑 sofagent-audit --diff HEAD~1..HEAD
                    audit PASS → 进入 round N+1(新一轮 V 全量重验)
                    audit FAIL → 打回 f-fix 重修
    ```
    
    ### 收敛判定
    
    ```
    verdict = PASS → 出 loop,可以发版 ✅
    verdict = FAIL 且 round < MAX_FIX_ROUNDS → **自动**触发 F 步骤链(默认启用,无需人工)
                                            → f-diagnose → f-fix → f-audit → round N+1
    verdict = FAIL 且 round ≥ MAX_FIX_ROUNDS → 输出"轮次耗尽"报告 ❌ → 出 loop
    
    **停手边界**(唯一需要主 session 介入的两类,其余一律自主修复):
    1. 修复涉及**对外动作**——版本 bump / git tag / npm publish(按对外动作铁律须动作前显式请示);
    2. 需**人裁定口径**——判定标准、范围、豁免是否成立存在分歧。
    
    除这两类外的全部内部修复(改代码 / 改文档 / 修检查器 / 补场景 / 对齐锚点)由 F 链自主完成,
    **不得停手等人工**——「每轮 FAIL 都停下来交主 session 修」会使 loop 无法一次跑到底。
    ```
    
    ## 产物 Schema
    
    | 文件 | 步骤 | 内容 |
    |------|------|------|
    | `acceptance.md` | ① | acceptance-test.sh 执行结果 |
    | `regression.md` | ② | regression-checklist 逐维度结果 |
    | `coverage.md` | ③ | changelog 功能点 vs acceptance-test 交叉覆盖 |
    | `stage6-report.md` | ④ | 合并报告 |
    | `verdict.md` | ⑤ | PASS/FAIL 裁决 |
    | `fix-plan.md` | ⑥ v1.2.8 | F 诊断的修复方案 |
    | `fix-summary.md` | ⑦ v1.2.8 | F 修复记录 |
    | `audit-result.md` | ⑧ v1.2.8 | sofagent-audit 检查结果 |
    
    ## createReactAgent 实现提示
    
    - V 用 `REVIEWER_TOOLS`(只读工具集);F 用 `ENGINEER_TOOLS`(含 write/edit)。
    - F 由 Node driver spawn 独立子进程(与 B 共用 engineer skill)。
    - f-audit 是 driver 步骤(role: null),不调 LLM,driver 直接执行 `runAuditGate()`。
    
    ## 循环级演化(evolution.md)
    
    `evolution.md` 是人类门控的"加一减一"改进记录:每次循环后若发现 specs/prompts 该增删,提出**一条加 + 一条减**的建议,由人类确认后才落地。防止 specs 无限膨胀成"屎山"。
    
  • SKILL.md 12 KB
    ---
    name: release-gate-loop
    description: 发版前自动验证闸门——V 验证 + F 修复循环(verdict FAIL → F 改代码 → 跑 audit → V 重验),最大 3 轮直到 PASS。纯只读验证 + 最小修复。
    emoji: 🚪
    color: "#F59E0B"
    version: 1.5.2
    ---
    
    # release-gate-loop · 发版闸门循环定义
    
    > **V 验证 FAIL 后触发 F 修复循环——F 读 verdict → 改代码 → 跑 audit → V 重验,最大 3 轮。**
    
    ## 这是什么
    
    一套可复用的发版前自动验证闸门 + 自动修复。它描述:谁来做(V = 验证者 + F = 修复者)、怎么走(V 5 步验证 + F 3 步修复循环)、产物放哪(`runs/release-gate-loop/YYYY-MM-DD/run-NN/round-N/`)。
    
    - **V** = 验证者:跑 acceptance-test.sh、跑 regression-checklist、做覆盖率交叉检查、合并报告、出裁决。
    - **F** = 修复者:V 裁决 FAIL 后,F 读 verdict 报告 → 定位根因 → 改代码 → driver 自动跑 audit → 回到 V 重验。
    - **driver(Node 编排进程,非 agent)**:在步骤间中转、维护 `runs/` 文件、复制报告到桌面。由**用户手动新开的执行 session** 启动(见下「执行载体铁律」)。
    
    ## 怎么用
    
    1. 读 `loop.md` 拿到完整 SOP(角色 / 步骤协议 / 产物 schema)。
    2. 5 步的行为指令在 `prompts/`(acceptance / regression / coverage / consolidate / verdict)。
    3. F 步骤指令在 `prompts/`(f-diagnose / f-fix)+ driver 自动执行 f-audit。
    4. 跨 run 的永久索引在 `FORGE/LEDGER.md`(被 git 跟踪);每次产物在 `runs/`(不进 git)。
    
    ## 实现载体
    
    V 由 **Node driver**(`FORGE/src/release-gate-driver.mjs`)驱动——每个 step 独立子进程(真零上下文),LangGraph `createReactAgent` 编排。driver 由用户手动新开的执行 session 启动并监控(见下「执行载体铁律」)。
    
    ## 🔴 执行载体铁律:driver 必须由「独立 session」直跑,禁止主 session 内开子代理代跑
    
    **判断层 driver 的执行 session 必须是用户手动新开的独立 session**(与主 session 平行、互不嵌套),不是主 session 里 spawn 的 subagent。
    
    原因(实证):主 session 内子代理 → 后台 shell → driver 三层嵌套,**用户打断主 session 时级联 SIGTERM 会杀掉整棵进程树**——曾在 consolidate 步骤被中止(latest.json stopReason=aborted-signal),已完成两步产物差点作废。此外子代理自带 token 开销、driver 崩溃时子代理诊断层还引入过误诊(「缺 15 包」实为 29 包三层根因)。
    
    **正确分工**:
    - 主 session(审查/决策 session):三查 → 修复环境问题 → 产出「交接 prompt」交给用户 → 用户在新 session 粘贴执行 → 等新 session 回报 verdict → 零信任复验。主 session 全程不 spawn driver。
    - 执行 session(用户新开):粘贴交接 prompt → 按下方「Session 监控协议」启动 driver 并轮询到 verdict → 回报六项终态数据。
    
    **交接 prompt 必含要素**(主 session 生成,自包含):目标版本号、启动 commit(预期干净树)、启动命令行(含 source ~/.sofagent/env.local)、监控协议要点(120s 轮询 / heartbeat 死亡检测 / 已知降级信号不处理清单)、verdict 产出后的六项回报清单(verdict+stopReason / 四步产物存在性 / usage token 总量 / verdict.md 头 50 行 / status.json 全文 / driver 日志尾 30 行)、异常处置(启动即崩回报不修 / 卡死 15 分钟查 pid)。**交付形式**:直接在对话中输出可复制的 prompt 文本块,禁止落盘成文件——用户复制粘贴到新 session 执行(2026-08-30 用户拍板)。
    
    ## Session 监控协议(CRITICAL · 适用于执行 session)
    
    **启动 driver 后,session 不是傻等,而是进入 sleep 轮询模式**——保持 working 状态,让用户感知"后台在干活"(**每 120 秒一轮,读 status.json 输出一行状态**——session 一直活跃 = 用户界面持续可见「在跑」,这是硬要求非可选)。
    
    > 🔴 **前台/后台分界铁律**:`run_in_background: true` **只属于启动 driver 的那一条 Bash 命令**——启动之后的每一轮轮询(sleep + cat status.json)都是**前台短命令**,直接在 session 正常工作流里执行。**严禁把轮询循环本身挂到后台**(run_in_background / nohup 均禁)——挂后台 = session 空闲等通知 = 用户界面看不到任何进展反馈,轮询的全部意义(session 可见性)即被摧毁。
    
    ### 🔴 启动前独占窗口检查
    
    **启动 driver 前,必须确认本仓库当前没有其他写操作会话在跑**——release-gate 的 worker 与主仓共享工作目录,git 基线被并发改写(restore / 回补 / 批量 commit)会直接杀死进程树。检查项与 fresh-eyes-loop SKILL 同款:问用户有无并发写会话 + `git status --porcelain` 抽查。git worktree 隔离(v1.3.6 交付 8)落地后本检查降级为提醒项。
    
    ### 执行方式
    
    ```
    1. Bash(⚠️ 必须加 run_in_background: true + dangerouslyDisableSandbox: true,
       否则三层进程嵌套会被 sandbox SIGKILL):
    
       # V/F 环境变量(⚠️ 必须手动导出——resolveConfigs 自动生成 SOFAGENT_LLM_V/F
       # 但 models/ 未覆盖 specEnv,不导出会报"缺少环境变量"):
       export SOFAGENT_LLM_V="${SOFAGENT_LLM_A}"
       export SOFAGENT_LLM_F="${SOFAGENT_LLM_B}"
    
       # 并发自适应(v1.3.7 ⑦):未显式设置时 driver 自动探测物理内存取并发
       # (<12GB→1 / 12-23GB→2 / 24-47GB→4 / ≥48GB→6)——8GB 机器自动取 1,无需手动设。
       # 运行中 worker OOM(SIGKILL)自动熔断降级(本批剩余串行,连续 2 批回退 1)。
       # 需强制指定时才设 FORGE_MAX_CONCURRENCY:
       node FORGE/src/release-gate-driver.mjs --target <版本号>
    
       # sandbox 环境(acceptance-test.sh 预跑会被 kill 时):
       # 先手动预跑到 /tmp(driver 启动时自动复制到 runDir):
       bash playbook/acceptance-test.sh > /tmp/acceptance-raw.log 2>&1
       # 再加 --skip-acceptance 启动:
       node FORGE/src/release-gate-driver.mjs --target <版本号> --skip-acceptance
    
       # 沙箱 OOM 环境(driver 主进程 + worker 内存叠加触发 OOM 时):
       # 用 --step 单步模式,外层脚本逐步调用,每步全新进程退出:
       node FORGE/src/release-gate-driver.mjs --step acceptance  --target <版本号> --run-dir <runDir>
       node FORGE/src/release-gate-driver.mjs --step regression  --target <版本号> --run-dir <runDir>
       node FORGE/src/release-gate-driver.mjs --step coverage     --target <版本号> --run-dir <runDir>
       node FORGE/src/release-gate-driver.mjs --step consolidate  --target <版本号> --run-dir <runDir>
       node FORGE/src/release-gate-driver.mjs --step verdict       --target <版本号> --run-dir <runDir>
    
       # 🔥 判断层瘦身模式(阶段五 SOP 默认):
       # 脚本层(acceptance-test.sh + check-version/check-docs/锚点/check-review-system/check-tool-health)
       # 由 session 直跑(零 LLM),全绿后 driver 只跑判断层四步——一次启动直达:
       source ~/.sofagent/env.local && node FORGE/src/release-gate-driver.mjs --judgment-only --target <版本号>
       # 🔴 env 路径:真实 key 在 **~/.sofagent/env.local**(仓库外,永不进 git)——不是 FORGE/env.local
       #    (仓内只有 env.local.template 模板)。SOFAGENT_LLM_V/F 为角色占位(非空即过 preflight,
       #    真模型由 FORGE/models/profile.mjs 决定);厂商 key(如 GLM_API_KEY)亦从该文件加载。
       # 依据:全流程实测 30.7 万 token 中 61% 花在 acceptance 12 分片 LLM 复核(复核脚本
       # exit 0 的确定性结果,增值≈0);判断层四步约 9 万 token / 20 分钟,盲审独立性保留在
       # 有判断空间的 regression 语义审查 + 终裁。
       # v1.3.8 交付七:--judgment-only 替代原「--step 四步手工编排」——一次进程串行四步,
       # 无需外层脚本逐步调用。旧 --step 单步模式仍可用于单步调试。
       # verdict=FAIL 时**自动进 F 修复链**(默认启用,无需人工介入)——f-diagnose → f-fix →
       # f-audit → 下一轮 V,最多 MAX_FIX_ROUNDS 轮,loop 一次跑到底直至收敛。
       # 🔴 停手边界(唯一需要主 session 介入的两类):① 修复涉及**对外动作**(版本 bump / git tag /
       # npm publish)——按对外动作铁律须动作前显式请示;② 需**人裁定口径**(判定标准/范围有分歧)。
       # 除这两类外一切内部修复(改代码 / 改文档 / 修检查器 / 补场景)由 F 链自主完成,不得停手。
       # 显式 --no-auto-fix 可关闭自动修复(FAIL 即 loop-end,修复责任回主 session)。
    
       # 全流程模式的 acceptance 抽查化(v1.3.8 交付七)——只审本版新增场景区间:
       node FORGE/src/release-gate-driver.mjs --target <版本号> --acceptance-range S294-S310
       # 分片范围从全量 12 片均分收敛为指定区间(本版新增场景),跳过历史场景的重复复核。
    
       🔴 铁律:必须 dangerouslyDisableSandbox。
       原因:driver(spawn) → worker(spawn) → run_bash(execSync) = 三层子进程嵌套。
       sandbox 对进程嵌套层数有限制,第 4 层进程返回时整棵进程树被 SIGKILL。
    
    2. 记住 runDir(driver 启动日志第一行会打印)
    
    3. 循环(最多 60 次,防 turn 超限——判断层实测约 20 分钟、含 F 修复链最长约 2 小时,20 次×2 分钟容量不足。
       🔴 本循环是前台操作:session 直接依次执行 sleep/cat——不包 run_in_background、不包任何后台化包装):
       sleep 120                                          # 等 2 分钟(前台)
       cat <runDir>/status.json                           # 读进度(前台)
       判断:
         - phase === "completed" 或 "error"  → 汇报最终结果,退出循环
         - heartbeat 超 90s 未更新            → ⚠️ 疑似 driver 死亡,检查进程存活(见下)
         - phase 跟上次相同(无变化)        → 静默,继续下一轮 sleep
         - phase 有变化                      → 一句话汇报,继续 sleep
    ```
    
    ### 🔴 Heartbeat 死亡检测
    
    driver 被 SIGKILL(sandbox 回收 / OOM / 环境冲突)时,所有 Node handler 都来不及执行,status.json 停在上一次状态,监控端无法区分"在跑"和"已死"。
    
    **解法**:driver 每 15s 更新 status.json 的 `heartbeat` 字段。监控端发现 heartbeat 超过 90s 未更新 → 大概率 driver 已死,用 `pgrep` 确认:
    
    ```
    pgrep -f "release-gate-driver"  # 有输出=活着,无输出=已死
    ```
    
    如果确认已死:读 `latest.json` 的 stopReason(若有),汇报后退出监控。
    
    ### 🔴 中止 run 的 LEDGER 归档铁律
    
    **任何原因中止的 run(进程死亡 / 人工 kill / 环境冲突 / 用户打断级联中止)也必须在 LEDGER 留一行**——「没有终态记录」的 run 是审计黑洞。确认 driver 死亡后人工补行(格式与 fresh-eyes-loop SKILL 同款:`日期 | runId | release-gate | 轮数* | 计数 | aborted-<死因> | runDir`)。
    
    ### 🔴 中止 run 的产物处置
    
    中止 run 的已完成产物**不浪费**——regression.md / coverage.md 等已落盘步骤可直接读取采信(dsh-headless 直跑证据可信),只须补跑缺失步骤:`--step consolidate --target <版本号> --run-dir <runDir>` 单步续跑,或全新 run 重跑四步(precheck 有 96 维证据缓存价值不大,重跑仅 ~20 分钟)。处置决策由用户拍板,不默认重跑。
    
    ### 汇报规则
    
    - **只在 phase 变化时说话**——同一状态不重复汇报
    - **一句话**——不展开 details,用户想看细节自己读 status.json
    - 格式示例:`📊 acceptance 完成 — PASS,进入 regression`
    - 最终结果用 2-3 行收尾:裁决(PASS/FAIL)+ 报告路径
    
    ### 为什么不用 CLI 推送
    
    driver 写 status.json 就够了——session 自己来读。推变拉,driver 不需要知道 session 的存在。
    
    ## 循环级演化
    
    `evolution.md` 记录对这套循环本身的改进建议(人类门控的"加一减一"),防止 specs 越长越烂。
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related