@accelerator-mzq/forge 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +12 -12
  2. package/dist/cli/commands/ack.d.ts.map +1 -1
  3. package/dist/cli/commands/ack.js +87 -12
  4. package/dist/cli/commands/ack.js.map +1 -1
  5. package/dist/cli/commands/archive.d.ts +32 -33
  6. package/dist/cli/commands/archive.d.ts.map +1 -1
  7. package/dist/cli/commands/archive.js +339 -667
  8. package/dist/cli/commands/archive.js.map +1 -1
  9. package/dist/cli/commands/legacy-bridge.js +1 -1
  10. package/dist/cli/commands/legacy-bridge.js.map +1 -1
  11. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  12. package/dist/cli/commands/upgrade.js +2 -51
  13. package/dist/cli/commands/upgrade.js.map +1 -1
  14. package/dist/cli/commands/validate.d.ts.map +1 -1
  15. package/dist/cli/commands/validate.js +4 -25
  16. package/dist/cli/commands/validate.js.map +1 -1
  17. package/dist/cli/index.js +0 -9
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/core/ack/marker-ack.d.ts +28 -0
  20. package/dist/core/ack/marker-ack.d.ts.map +1 -0
  21. package/dist/core/ack/marker-ack.js +155 -0
  22. package/dist/core/ack/marker-ack.js.map +1 -0
  23. package/dist/core/ack-log.d.ts.map +1 -1
  24. package/dist/core/ack-log.js +10 -7
  25. package/dist/core/ack-log.js.map +1 -1
  26. package/dist/core/archive/index.d.ts +2 -3
  27. package/dist/core/archive/index.d.ts.map +1 -1
  28. package/dist/core/archive/index.js +7 -5
  29. package/dist/core/archive/index.js.map +1 -1
  30. package/dist/core/archive/pause-decisions-fence.js +12 -12
  31. package/dist/core/archive/pause-decisions-fence.js.map +1 -1
  32. package/dist/core/archive/summary-builder.d.ts +26 -21
  33. package/dist/core/archive/summary-builder.d.ts.map +1 -1
  34. package/dist/core/archive/summary-builder.js +115 -223
  35. package/dist/core/archive/summary-builder.js.map +1 -1
  36. package/dist/core/archive/summary-render.d.ts +5 -3
  37. package/dist/core/archive/summary-render.d.ts.map +1 -1
  38. package/dist/core/archive/summary-render.js +38 -44
  39. package/dist/core/archive/summary-render.js.map +1 -1
  40. package/dist/core/lock.d.ts +46 -0
  41. package/dist/core/lock.d.ts.map +1 -0
  42. package/dist/core/lock.js +98 -0
  43. package/dist/core/lock.js.map +1 -0
  44. package/dist/core/markers/types.d.ts +27 -134
  45. package/dist/core/markers/types.d.ts.map +1 -1
  46. package/dist/core/markers/types.js +10 -1
  47. package/dist/core/markers/types.js.map +1 -1
  48. package/dist/core/migrate/index.js +1 -1
  49. package/dist/core/migrate/index.js.map +1 -1
  50. package/dist/core/monitor/artifact-observer.d.ts.map +1 -1
  51. package/dist/core/monitor/artifact-observer.js +28 -78
  52. package/dist/core/monitor/artifact-observer.js.map +1 -1
  53. package/dist/core/monitor/divergence-map.d.ts.map +1 -1
  54. package/dist/core/monitor/divergence-map.js +9 -7
  55. package/dist/core/monitor/divergence-map.js.map +1 -1
  56. package/dist/core/monitor/health-verdict.d.ts.map +1 -1
  57. package/dist/core/monitor/health-verdict.js +2 -1
  58. package/dist/core/monitor/health-verdict.js.map +1 -1
  59. package/dist/core/monitor/trace-store.d.ts +1 -1
  60. package/dist/core/monitor/trace-store.js +2 -2
  61. package/dist/core/monitor/trace-store.js.map +1 -1
  62. package/dist/core/monitor/types.d.ts +1 -1
  63. package/dist/core/monitor/types.d.ts.map +1 -1
  64. package/dist/core/monitor/types.js +0 -1
  65. package/dist/core/monitor/types.js.map +1 -1
  66. package/dist/core/schemas/archive-summary.d.ts +39 -109
  67. package/dist/core/schemas/archive-summary.d.ts.map +1 -1
  68. package/dist/core/schemas/archive-summary.js +15 -23
  69. package/dist/core/schemas/archive-summary.js.map +1 -1
  70. package/dist/core/templates/commands/ack-confirm.md +1 -1
  71. package/dist/core/templates/commands/apply.md +51 -114
  72. package/dist/core/templates/commands/archive.md +43 -160
  73. package/dist/core/templates/commands/review.md +49 -74
  74. package/dist/core/templates/commands/upgrade.md +21 -40
  75. package/dist/core/templates/commands/verify.md +43 -146
  76. package/dist/core/templates/skills/_shared/tier23-command-bridge.md +34 -0
  77. package/dist/core/templates/skills/exploring.md +3 -3
  78. package/dist/core/templates/skills/finishing-a-development-branch.md +6 -21
  79. package/dist/core/templates/skills/receiving-code-review.md +14 -45
  80. package/dist/core/templates/skills/requesting-code-review.md +11 -0
  81. package/dist/core/templates/skills/subagent-driven-development.md +33 -29
  82. package/dist/core/templates/skills/subagent-driven-discipline.md +28 -28
  83. package/dist/core/templates/skills/using-forge.md +25 -24
  84. package/dist/core/templates/skills/verification-before-completion.md +7 -18
  85. package/dist/core/templates/skills/verifying-three-dimensions.md +93 -169
  86. package/dist/core/templates/skills/writing-plans.md +6 -17
  87. package/dist/core/validate/archive-summary-schema.d.ts +1 -1
  88. package/dist/core/validate/archive-summary-schema.d.ts.map +1 -1
  89. package/dist/core/validate/archive-summary-schema.js +101 -125
  90. package/dist/core/validate/archive-summary-schema.js.map +1 -1
  91. package/dist/core/validate/index.d.ts +0 -1
  92. package/dist/core/validate/index.d.ts.map +1 -1
  93. package/dist/core/validate/index.js +2 -1
  94. package/dist/core/validate/index.js.map +1 -1
  95. package/dist/core/validate/marker-schema.d.ts +12 -4
  96. package/dist/core/validate/marker-schema.d.ts.map +1 -1
  97. package/dist/core/validate/marker-schema.js +98 -605
  98. package/dist/core/validate/marker-schema.js.map +1 -1
  99. package/dist/index.d.ts +1 -1
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +8 -1
  102. package/dist/index.js.map +1 -1
  103. package/package.json +5 -4
  104. package/scripts/codex-review-helper.mjs +337 -0
  105. package/src/core/codex-review/prompts/adversarial-default.md +105 -0
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 派 review subagent 审 [proposal + specs + design + diff],主代理处理反馈,满足三条件打 review-passed YAML
2
+ description: 派 review subagent 审 [proposal + specs + design + diff],主代理处理反馈,满足三条件写 .review-passed v2 marker
3
3
  argument-hint: '[--change-id <id>]'
4
4
  ---
5
5
 
@@ -9,77 +9,55 @@ You are about to handle `/forge:review $ARGUMENTS`.
9
9
 
10
10
  ## 步骤
11
11
 
12
- 1. **必须调用 `forge:requesting-code-review` skill**(主轨)。
13
- 2. **必须调用 `forge:receiving-code-review` skill**(收反馈环节)。
14
- 3. 打包 review 输入:
15
- - `forge/changes/<id>/proposal.md`
16
- - `forge/changes/<id>/specs/*.md`
17
- - `forge/changes/<id>/design.md`
18
- - `git diff <since-tasks-start>..HEAD`(`since-tasks-start` 取 tasks.md 末尾 `applied_commits` 的第一个 commit 的 parent)
19
- 4. 派 fresh review subagent,产出意见列表(每条带:[严重度:阻塞/关键/可改进/建议]、[文件路径]、[问题描述]、[期望修改])。
20
- 5. 主代理对每条意见 **逐条判断接受/拒绝**(参考 forge:receiving-code-review skill 的"用证据反驳"原则,不机械接受)。
21
- 6. 接受的意见 → append 到 `forge/changes/<id>/tasks.md` 末尾作为新 task 条目。
22
- 7. **仅当满足三条件,才打 `forge/changes/<id>/.review-passed`**:
23
- a. 无"已用证据反驳但未存档"的拒绝意见
24
- b. 接受的意见已**全部实现 + 测试通过**(本轮新接受的意见**不算本轮通过**,需下一轮 review)
25
- c. 满足 a+b 时,本轮 review 无新增 task
26
- 7a. **(本 fix 补缺)调 forge evidence record-review 记录 review 事件证据到 staging**
27
-
28
- 主代理在写完 .review-passed YAML 后、freeze 之前,**必须**先调 record-review:
29
-
30
- ```bash
31
- forge evidence record-review <changeId> --task <ref> --implementer-commit <sha>
32
- ```
33
-
34
- 这一步把 review 事件(子代理调用 + 主代理 accept/reject outcomes)写入 `.evidence/process-evidence.staging.yaml`(沿 `src/cli/commands/evidence.ts:474`;helper list 权威 `commands/apply.md:179-182`)。
35
-
36
- 7b. **(本 fix 补缺)调 forge evidence freeze 凝固 process_evidence**
37
-
38
- 7a record-review 后,**必须**调:
39
-
40
- ```bash
41
- forge evidence freeze <changeId> --kind review
42
- ```
43
-
44
- 若漏调 record-review 直接 freeze → exit 1 + 提示 "staging file not found"(代码事实 `evidence.ts:639`)。若漏调 freeze → archive fence 拒签 "[review] v1.0 marker missing process_evidence"(代码事实 `src/core/archive/fence.ts:185`)。
45
-
46
- 8. `.review-passed` YAML schema(spec §3.4)— 含 `pause_decisions` 数组(本 fix 补 lifecycle 注):
47
- ```yaml
48
- schema: forge-review/v1
49
- tasks_hash: <sha256(tasks.md 已勾段)>
50
- content_hash: <sha256(proposal+specs+design)>
51
- reviewed_by: ai-agent # 或 human-override(需 archive --force)
52
- git:
53
- is_git_repo: true
54
- head: <git rev-parse HEAD>
55
- diff_hash: <sha256(git diff against forge/config.yaml code_paths)>
56
- review_outcomes:
57
- - id: 1
58
- severity: blocking
59
- accepted: true
60
- resolved: true
61
- resolution_commit: <hash>
62
- pause_decisions: # apply 阶段累积的 pause 决策在写本 marker 时一并迁移(沿 commands/apply.md "Marker 持久化" 段 lifecycle 说明)
63
- - id: 1
64
- # ... 完整 schema 见 commands/apply.md "Marker 持久化" 段
65
- ```
12
+ 1. **必须调用 `forge:requesting-code-review` skill**(主轨)。
13
+ 2. **必须调用 `forge:receiving-code-review` skill**(收反馈环节)。
14
+ 3. 打包 review 输入:
15
+ - `forge/changes/<id>/proposal.md`
16
+ - `forge/changes/<id>/specs/*.md`
17
+ - `forge/changes/<id>/design.md`
18
+ - `git diff <since-tasks-start>..HEAD`(`since-tasks-start` 取 tasks.md 末尾 `applied_commits` 第一个 commit 的 parent)
19
+ 4. 派 fresh review subagent,产出意见列表(每条带:[严重度]、[文件路径]、[问题描述]、[期望修改])。
20
+ 5. 主代理对每条意见**逐条判断接受/拒绝**(参考 `forge:receiving-code-review` skill 的"用证据反驳"原则,不机械接受)。
21
+ 6. 接受的意见 → append 到 `forge/changes/<id>/tasks.md` 末尾作为新 task 条目,实施 + commit。
22
+ 7. **仅当满足三条件,才写 `.review-passed` v2 marker**:
23
+ - a. 无"已用证据反驳但未存档"的拒绝意见
24
+ - b. 接受的意见已**全部实现 + 测试通过**(本轮新接受的意见**不算本轮通过**,需下一轮 review)
25
+ - c. 满足 a+b 时,本轮 review 无新增 task
26
+
27
+ 8. **`.review-passed` v2 marker 示例**(沿 `src/core/markers/types.ts:ReviewMarker`):
28
+
29
+ ```yaml
30
+ schema: forge-review/v2
31
+ reviewed_at: <ISO 8601 UTC,允许 ms 精度>
32
+ reviewed_by: ai-agent # 或 human-override(需 archive --force)
33
+ pause_decisions: # 可选 — 同 verify marker 的 PauseDecisionSimple
34
+ - paused_at: 2026-05-21T15:00:00Z
35
+ task_ref: tasks.md#task-7
36
+ issue_summary: review subagent 发现 spec 未覆盖的 edge case
37
+ chosen_option: 2
38
+ notes: '加 task 进本轮 tasks.md'
39
+ created_by_tool_version: <FORGE_VERSION>
40
+ ```
41
+
42
+ schema 字段只 5 个,无 hash / git / process_evidence / review_outcomes / evidence 数组。
66
43
 
67
44
  ## 禁止行为
68
45
 
69
- - 不允许跳过 review subagent 直接打 review-passed
70
- - 不允许接受意见但不实现就打 review-passed(违反 b)
71
- - git 项目跳过 git 字段时,review-passed YAML 必须 `is_git_repo: false`(archive --force 才接受)
46
+ - 不允许跳过 review subagent 直接写 .review-passed
47
+ - 不允许接受意见但不实现就写 .review-passed(违反条件 b)
48
+ - 不允许伪造 `reviewed_by` 字段
49
+ - **不允许在 .review-passed 写 v4 已删字段**(`review_outcomes` / `git` / `tasks_hash` / `content_hash` / `process_evidence` — schema 校验会拒)
72
50
 
73
51
  ## (可选)Stage extensions hook — Tier 1 Claude Code only
74
52
 
75
53
  > codex review 集成。AI 主代理在本 stage(`review`)跑多轮收敛协议。
76
54
  > Tier 2/3(Codex/OpenCode)见 [`docs/stage-extensions.md §未来 Tier 2/3 集成`](../docs/stage-extensions.md#未来-tier-23-集成)。
77
55
 
78
- **Step A — 检查是否启用**:读 `forge/config.yaml#stage_extensions.review`。无该字段 / 数组为空 / 全部 entry `enabled: false` → **跳过本段,流程结束**。
56
+ **Step A — 检查是否启用**:读 `forge/config.yaml#stage_extensions.review`。无该字段 / 数组为空 / 全部 entry `enabled: false` → **跳过本段**。
79
57
 
80
58
  **Step B — 对每个 `enabled` entry 跑多轮收敛 loop**:
81
59
 
82
- 初始化 `round = 1`、`threadId = ''`、`roundHistory = []`、`roundLimit = null`(F1-v8 fix:`roundLimit` **不从 config 文件读** —— effective convergence 由 runner 输出,见 Step 3。AI 协议不碰 config 文件解析 / deep-merge,单一数据源是 runner JSON)。循环:
60
+ 初始化 `round = 1`、`threadId = ''`、`roundHistory = []`、`roundLimit = null`。循环:
83
61
 
84
62
  1. **跑单轮 runner**:
85
63
  ```bash
@@ -88,18 +66,15 @@ You are about to handle `/forge:review $ARGUMENTS`.
88
66
  --round <round>${threadId:+ --thread-id $threadId}
89
67
  ```
90
68
  2. **解析 stdout JSON 的 `kind`**:
91
- - `converged` → 该 entry 收敛完成,**break loop**(codex 输出 verbatim 透传给用户)
92
- - `failed` / `config_error` / `no_extension` → 该 entry 放弃,**break loop**(loose,不阻塞主流程)
69
+ - `converged` → break loop(codex 输出 verbatim 透传)
70
+ - `failed` / `config_error` / `no_extension` → break loop(loose)
93
71
  - `unconverged` → 继续 3
94
- 3. **从 unconverged JSON 取状态**(F1-v8 fix:effective config 来自 runner 输出,runner 内 `validateStageExtensionsConfig` 已 normalize):
95
- - `roundHistory.push({ round, block_count: <blockFindings.length> })`;`threadId = <JSON.threadId>`;codex finding verbatim 透传给用户
96
- - 首轮:`roundLimit = <JSON.effectiveConvergence.max_rounds>`(后续轮 `roundLimit` 已设,不覆盖 —— 选项①的 `roundLimit += N` 增量须保留)
97
- 4. **若 `round >= roundLimit`**(F2-v7 fix:用可增长的 `roundLimit`):
98
- - 若 `<JSON.effectiveConvergence.max_rounds_on_exceed>` 为 `force_end` → blockFindings 写 `forge/changes/<id>/.evidence/codex-pending-findings.yaml`(backlog),**break loop**
99
- - 否则跑 `node "${CLAUDE_PLUGIN_ROOT}/scripts/run-forge.mjs" stage-extensions analyze-trend --history '<roundHistory JSON>'` 拿 TrendAdvice,再 `AskUserQuestion` 三选项(默认推 `TrendAdvice.recommended_option`):**①再跑 N 轮**(F2-v7 fix:读用户输入的 `N`,执行 `roundLimit += N`,然后 `round++` 继续 loop —— 后续 `round >= roundLimit` 判定按新上限走,不会立刻又进 Step 4)/ **②放弃 codex**(break loop)/ **③接受当前**(blockFindings 写 backlog,break loop)
100
- 5. **否则(`round < roundLimit`)**:`AskUserQuestion` 三选项(默认推 `<JSON.userInteraction.block_unconverged>`):
101
- - **①auto_fix** → 用 `Task` 工具 dispatch fresh fix subagent 修 blockFindings → `round++`,继续 loop
102
- - **②manual_fix** 等用户改完 → `round++`,继续 loop
103
- - **③give_up** → break loop
104
-
105
- **Step C — loose**:本段任何步骤(runner 调用 / AskUserQuestion / fix dispatch)失败都**不阻塞主流程 fence**。runner 永远 exit 0;AskUserQuestion harness 不支持时降级终端 prompt。
72
+ 3. **从 unconverged JSON 取状态**:
73
+ - `roundHistory.push({ round, block_count: <blockFindings.length> })`;`threadId = <JSON.threadId>`;codex finding verbatim 透传
74
+ - 首轮:`roundLimit = <JSON.effectiveConvergence.max_rounds>`
75
+ 4. **若 `round >= roundLimit`**:
76
+ - 若 `<JSON.effectiveConvergence.max_rounds_on_exceed>` 为 `force_end` → blockFindings 写 `forge/changes/<id>/.evidence/codex-pending-findings.yaml`,break
77
+ - 否则跑 `stage-extensions analyze-trend` 拿 TrendAdvice,AskUserQuestion 三选项:**①再跑 N 轮**(`roundLimit += N`,`round++`)/ **②放弃 codex**(break)/ **③接受当前**(写 backlog,break)
78
+ 5. **否则**:AskUserQuestion 三选项(默认推 `<JSON.userInteraction.block_unconverged>`):**①auto_fix** → dispatch fresh fix subagent → `round++` / **②manual_fix** → 等用户改 → `round++` / **③give_up** → break
79
+
80
+ **Step C loose**:本段任何步骤失败都**不阻塞主流程**。
@@ -1,58 +1,39 @@
1
1
  ---
2
- description: 调 forge upgrade CLI(legacy adapter 清理 + marker resign)
3
- argument-hint: '[--resign-markers <changeId>] [--recover] [--gc] [--dry-run]'
2
+ description: 调 forge upgrade CLI(清理 legacy v0.2 harness adapter 产物)
3
+ argument-hint: '[--dry-run] [--recover] [--gc]'
4
4
  ---
5
5
 
6
6
  # /forge:upgrade
7
7
 
8
- 包装 `forge upgrade` CLI(v0.3 / plan-9j 落地)。
8
+ 包装 `forge upgrade` CLI(v0.3 起)。**仅清理 legacy harness adapter 产物;`forge/` 下 drafts/changes/specs/config 100% 不动**。
9
9
 
10
- ## 用法 / 选项(v6 MINOR 4:option flag 形态,不是 subcommand)
11
-
12
- - `forge upgrade`(无 flag,沿 v0.3):清理 legacy v0.2 harness adapter 产物
13
- - `forge upgrade --resign-markers <changeId>`(plan-9j 新增 option):升级 v0.4 marker 到 v1.0 schema
14
-
15
- ## --resign-markers 用法(plan-9j Task 2 落地)
10
+ ## 用法
16
11
 
17
12
  ```bash
18
- forge upgrade --resign-markers add-oauth-refresh
13
+ forge upgrade # 清理 v0.2 legacy harness adapter 产物
14
+ forge upgrade --dry-run # 只 SHOW DIFF,不 stash
15
+ forge upgrade --recover # 恢复最近 stash(24h 有效期)
16
+ forge upgrade --gc # 删除过期 stash(>24h)
19
17
  ```
20
18
 
21
- 行为:
22
-
23
- - **S 简码** → 自动映射 CRITICAL
24
- - **L 简码** → 自动映射 SUGGESTION
25
- - **C 简码** → 写 pending file 到 `.evidence/pending-acks/`,exit 1 + 提示走 `forge ack confirm`
26
- - **不自动填空** verify_findings / pause_decisions / process_evidence(违反 AI 反向加固)
27
- - 改标 `process_evidence_unavailable_legacy: true` meta 字段
28
- - 写 `ack-log.jsonl` action=resign 行
29
-
30
- 退出码(沿 master §3.12.3):
31
-
32
- - 0:全部 marker resigned 或已是 v1.0
33
- - 1:部分需 C 简码 confirm / 阶段事务失败
34
- - 2:CI 模式拒绝(env CI=true)
35
-
36
- ## C 简码迁移协议(完整流程)
19
+ ## 6 阶段事务
37
20
 
38
- C 简码(clarification)不自动映射(沿 design §2.3.5):用户必须判断目标 severity:
21
+ SCAN(纯只读)→ SHOW DIFF(只读)→ ASK(等用户输入)→ STASH(rename 到 `.forge-upgrade-stash-<ts>/`) VERIFY(hash 比对)→ COMMIT(默认不删 stash,24h 内可 `--recover`)。
39
22
 
40
- 1. `forge upgrade --resign-markers <changeId>` — 若含 C 简码,exit 1 + 写 pending file
41
- 2. 跑 `forge ack confirm <changeId> <findingId> --target-severity WARNING|SUGGESTION`(或走 `/forge:ack-confirm` slash)
42
- 3. 重跑 `forge upgrade --resign-markers <changeId>` 完成 resign
23
+ 任一阶段失败自动反向 rename 回原位。
43
24
 
44
- ## sunset policy
25
+ ## 退出码
45
26
 
46
- `process_evidence_unavailable_legacy: true` v2.0 sunset(沿 design §3.4.4.2):
27
+ - `0`:全部成功 / legacy 产物
28
+ - `1`:STASH/VERIFY 失败(已回滚)/ stash 损坏(hash mismatch / 过期)
47
29
 
48
- - v1.0 / v1.1:合法
49
- - v1.2:warning 加强
50
- - v2.0:拒签,`forge migrate <change-id>` 自动触发 process_evidence 补录
30
+ ## v3 v4 marker 升级路径
51
31
 
52
- ## archive 行为(沿 plan-9j Task 3 / 4)
32
+ v4 BREAKING:**已移除 `--resign-markers` flag**。v0.4 / v1.0 marker → v4 v2 marker 不再有 CLI 自动升级路径;v3 protocol(ack-log / verify_findings / process_evidence / 简码 S/C/L)在 v4 全部消亡。
53
33
 
54
- archive.ts 步骤 3.4 在 evidence 校验之前先跑 legacy-exemption + version-retrograde fence:
34
+ 唯一升级路径(沿 `docs/migration/v3-to-v4.md`):
55
35
 
56
- - legacy marker created_by_tool_version 字段或 `<1.0.0` 走 legacy 路径(13 不变量精确豁免)
57
- - **`legacy=true ⊥ (created_by_tool_version >= 1.0.0 resigned_by_tool_version 缺失)`** 互斥(沿 §3.4.4.1 + v6 选项 C resigned-aware):原生 v1.0 marker 不允许 legacy 标记;resigned 后 marker(含 resigned_by_tool_version 字段)允许 legacy + version 共存
58
- - version retrograde(高版本 低版本)→ 拒签(沿 §3.4.4.3)
36
+ 1. 删除 active change 下的 `.verify-passed` / `.review-passed`(v1 marker)
37
+ 2. stale 残留:`forge/changes/<id>/.evidence/pending-acks/` + `forge/.cache/archive-pause-<id>.json`
38
+ 3. 重跑 `/forge:verify` + `/forge:review`( v2 marker)
39
+ 4. 重跑 `/forge:archive`(v4 校验 v2 schema 通过)
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 跑 forge validate + verification-before-completion + 三维度分析,产 verify_findings 写入 .verify-passed marker
2
+ description: 跑 forge validate + verification-before-completion + 三维度 prose check,写 .verify-passed v2 marker
3
3
  argument-hint: '[--change-id <id>]'
4
4
  ---
5
5
 
@@ -11,158 +11,51 @@ You are about to handle `/forge:verify $ARGUMENTS`.
11
11
 
12
12
  1. **必须调用 `forge:verification-before-completion` skill**(证据先于声称的纪律)。
13
13
 
14
- 2. **跑 `forge validate <change-id>`**(plugin helper 走 `${CLAUDE_PLUGIN_ROOT}/scripts/run-forge.mjs validate`),拿到 validate 结果。validate 已产 `automated=true` CRITICAL `finding_hash`(沿 plan-9d Task 4)
14
+ 2. **跑 `forge validate <change-id>`**(plugin helper 走 `${CLAUDE_PLUGIN_ROOT}/scripts/run-forge.mjs validate`)。
15
15
 
16
- 3. **若 validate 失败(exit 1 — CRITICAL findings 存在)**:
17
- - 根据失败项构造 verify-failed YAML(`forge/changes/<id>/.verify-failed`):
18
- ```yaml
19
- schema: forge-verify-failed/v1
20
- failed_at: <ISO 8601>
21
- reasons:
22
- - <每个 CRITICAL finding 的 message>
23
- fake_completions: []
24
- appended_tasks:
25
- - verify-fix-1
26
- verify_findings: # plan-9d 新增 — validate CLI 产的 automated CRITICAL finding 直接合并
27
- - id: 1
28
- dimension: completeness
29
- check_type: spec-files-missing
30
- severity: CRITICAL
31
- automated: true
32
- finding_hash: <validate 输出的 hash>
33
- evidence: <validate output>
34
- recommendation: <validate output>
35
- resolved: false
36
- ```
37
- - **append 修复 task 到 `forge/changes/<id>/tasks.md`**(沿 v0.4 协议)
38
- - **不要修改原已勾选 task**(维护 spec §3.3 不变量 2)
16
+ 3. **若 validate 失败(exit 1)**:
17
+ - 不写 `.verify-failed` marker(v4 砍掉 failed marker schema)
18
+ - 直接 abort,把错误透传给用户,提示按 validate 错误修代码 / 改 spec 后重跑 `/forge:verify`
39
19
 
40
20
  4. **若 validate 通过(exit 0)**:
41
21
 
42
- 4.1 **跑用户项目测试** — 读 `forge/config.yaml` 的 `test.test_command`,缺省 `pnpm test`,把 stdout 写到 `forge/changes/<id>/.evidence/test-output.log`,计算 `log_hash = sha256(test-output.log)`。**测试 pass 是 Completeness/task-completion 子项**(plan-9d 三维度协议)。字段路径以代码事实为准(`src/core/schema/types.ts:83` + `src/core/archive/fence.ts:146`)。
43
-
44
- 4.2 **三维度分析 — 必须调用 `forge:verifying-three-dimensions` skill**(plan-9d 落地):
45
- - **Completeness**:对 spec 每个 Requirement,grep codebase 找实施证据;完全无证据 → 产 CRITICAL `coverage_gap` finding(automated=true,工具可独立验证;沿 §11.1bis — `evidence_missing` 仅指 evidence.log_path 文件缺失,语义不同)
46
- - **Correctness**:对 spec 每个 Requirement 定位实施 file:line;WHEN/THEN scenario 覆盖检查 → WARNING/SUGGESTION findings(automated=false)
47
- - **Coherence**:design.md `## Decision:` 段比对 codebase;命名 / pattern 比对项目惯例 → WARNING/SUGGESTION findings(automated=false)
48
- - **每个 finding 必须填**:id / dimension / check_type / severity / automated / content_hash / git_head / evidence / recommendation / resolved + finding_hash(JCS SHA256 of 8 字段 payload,沿 9a)
49
- - **`automated=true` 的 finding 必须由工具或 CLI 计算 finding_hash**(直接 grep 命中数等机器判定);AI 不能伪造此类 finding
50
- - **`automated=false` 的 finding 由 AI 产**,需 `forge ack propose` 走两步流程才能降级或带未 ack archive(沿 9a)
51
- - **AI 计算 finding_hash 必须用 `forge finding hash` helper**(v6 M-1 修订 + v7 N-1 修订:沿 plan-9d Task 4 step 12-13)— 防止 AI 自实现 JCS 易出错。示例**用 heredoc 避免单引号 shell 破损**(JSON 内换行 / 单引号 / 中文均安全):
52
-
53
- ```bash
54
- # 把 8 字段 payload 写成 JSON pipe 给 helper,helper 输出 64-hex finding_hash
55
- cat <<'JSON' | forge finding hash
56
- {
57
- "content_hash": "sha256:abc123...",
58
- "git_head": "d4e5f6...",
59
- "dimension": "correctness",
60
- "check_type": "requirement-mapping",
61
- "severity": "WARNING",
62
- "automated": false,
63
- "evidence": "specs/auth/spec.md Requirement #2 在 src/auth/refresh.ts:42 实现 expiryHours=12,spec 默认 24h",
64
- "recommendation": "改 expiryHours=24 或修订 spec"
65
- }
66
- JSON
67
- # 输出:1234abcd5678ef90... (64-hex 裸 hex 沿 9a)
68
- ```
22
+ 4.1 **跑用户项目测试** — 读 `forge/config.yaml` 的 `test.test_command`,缺省 `pnpm test`,失败 abort 让用户修。
69
23
 
70
- **关键约束**:
71
- - **用 `<<'JSON'` heredoc(单引号 quoted)**:JSON 内部含单引号 / `$` / 反引号 / 中文均不会被 shell 解析(v7 N-1 修订:沿 bash heredoc quoted delimiter convention)
72
- - **不能多传 extra keys**(id / resolved / finding_hash 自身)— helper 内部已显式构造 8 字段,extra keys 会被丢弃,但 AI 应该传干净 payload 避免混淆
73
- - **JSON 内换行用真实换行**(不写 `\n`)— heredoc 保留原样换行;若 evidence/recommendation 内文要含 `\n` 字面值则写 `\\n` 双反斜杠(JSON 串 escape)
24
+ 4.2 **三维度 prose check — 必须调用 `forge:verifying-three-dimensions` skill**:
25
+ - **Completeness**:对 spec 每个 Requirement,grep codebase 找实施证据;空 报告给用户
26
+ - **Correctness**:对 spec 每个 Requirement 定位实施 file:line;WHEN/THEN scenario 覆盖检查
27
+ - **Coherence**:design.md `## Decision:` 段比对 codebase;命名 / pattern 比对项目惯例
28
+ - 三维度发现的问题以 prose 形式呈现给用户(对话内 + 必要时改 code 或 spec);**不写 marker 内 fence 字段**(v4 删 `verify_findings` 数组)
74
29
 
75
- 4.3 **写 `forge/changes/<id>/.verify-passed` YAML**(沿 design §2.2.5 schema superset):
30
+ 4.3 **写 `forge/changes/<id>/.verify-passed` v2 marker**(沿 `src/core/markers/types.ts:VerifyMarker`):
76
31
 
77
32
  ```yaml
78
- schema: forge-verify/v1
79
- verified_at: <ISO 8601>
80
- verified_by: ai-agent
81
- tasks_hash: <sha256(tasks.md 已勾段)>
82
- content_hash: <sha256(proposal+specs+design)>
83
- evidence:
84
- - scenario_id: project-tests
85
- test_command: <config.yaml test_command>
86
- test_file: <实际跑的测试范围>
87
- log_path: ./.evidence/test-output.log
88
- log_hash: <log_hash>
89
- pass: true
90
- verify_findings: # plan-9d 新增 — validate CLI 自动 CRITICAL + skill 产 WARNING/SUGGESTION 合并数组
91
- - id: 1
92
- dimension: completeness
93
- check_type: spec-coverage
94
- severity: WARNING
95
- automated: false
96
- content_hash: <sha256>
97
- git_head: <40-hex>
98
- evidence: 'specs/auth/spec.md Requirement #2 在 src/auth/refresh.ts:42 实现 expiryHours=12,spec 默认 24h'
99
- recommendation: '改 expiryHours=24 或修订 spec'
100
- resolved: false
101
- finding_hash: <sha256>
102
- severity_acked_by: null # WARNING 必须 ack 才能 archive(在 archive 阶段走 ack)
103
- severity_acked_at: null
104
- # ... 其他 finding
105
- pause_decisions: # apply 阶段累积的 pause 决策在写本 marker 时一并迁移(本 fix 补 lifecycle 注;沿 commands/apply.md "Marker 持久化" 段)
106
- - id: 1
107
- # ... 完整 schema 见 commands/apply.md "Marker 持久化" 段
108
- ```
109
-
110
- 4.3a **(本 fix 补缺):调 forge evidence record-verify 记录 verify 事件证据到 staging**
111
-
112
- 主代理在写完 .verify-passed YAML 后、freeze 之前,**必须**先调 record-verify 写 staging:
113
-
114
- ```bash
115
- forge evidence record-verify <changeId> --task-refs <list> --scope <type> --report <path>
33
+ schema: forge-verify/v2
34
+ verified_at: <ISO 8601 UTC,允许 ms 精度>
35
+ verified_by: ai-agent # 或 human-override(需 archive --force)
36
+ pause_decisions: # 可选 — apply 阶段累积的 PauseDecisionSimple
37
+ - paused_at: 2026-05-21T14:30:00Z
38
+ task_ref: tasks.md#task-3
39
+ issue_summary: subagent 报告 OAuth refresh edge case
40
+ chosen_option: 3 # 1=扩scope/2=加task/3=转out-of-scope/4=Other
41
+ notes: 'subagent 可跳过该 issue 完成本 task 主体功能'
42
+ created_by_tool_version: <FORGE_VERSION>
116
43
  ```
117
44
 
118
- 这一步把 verify 事件(测试 pass/fail + 三维 findings 总览)写入 `.evidence/process-evidence.staging.yaml`,**freeze 必须前置 staging 才有 source 可以凝固**(沿 `src/cli/commands/evidence.ts:348/639`;helper list 权威 `commands/apply.md:179-182`)。
119
-
120
- 若漏调 record-verify 直接 freeze → exit 1 + 提示 "staging file not found ... 必须先调 forge evidence record-\*"(代码事实 `evidence.ts:639`)。
121
-
122
- 4.4 **(plan-9g 新增):调 forge evidence freeze 凝固 process_evidence**
123
-
124
- 主代理在 4.3a record-verify 后,**必须**调:
125
-
126
- ```bash
127
- forge evidence freeze <changeId> --kind verify
128
- ```
45
+ schema 字段只 5 个,无 hash / git / process_evidence / verify_findings / evidence 数组。
129
46
 
130
- freeze 子命令做:
131
- 1. 读 `.evidence/process-evidence.staging.yaml` + 校验 staging_hash
132
- 2. 复制三数组(tdd_event_chain / verify_invocations / subagent_review_chain)到 marker.process_evidence
133
- 3. 写 marker.process_evidence_staging_hash + ack_log_tail_hash + ack_log_entry_count(五源 cross-check 用)
134
- 4. 算 freeze-time WARNING(不变量 7 + 10)→ 转 VerifyFinding 写 marker.verify_findings
135
- 5. 若 CRITICAL 11/12(tdd_exemption 缺 ack / mode 缺 ack)→ exit 1 + 提示先跑 forge ack
136
- 6. transaction(tmp + rename atomic)落 marker
137
-
138
- 详细 process_evidence 协议见 `skills/process-evidence/SKILL.md`。
139
-
140
- > **Fluid Pause 边界(design §8.3)**:apply 阶段 Fluid Pause 的 `forge pause-capture` 必须在本步 `forge evidence freeze --kind verify` **之前**完成。verify freeze 之后再产生的 pause-capture entry 不被 verify marker 的 `ack_log_tail_hash`/`ack_log_entry_count` 固化,archive 阶段 option=2 强校验会因 ack-log 行数 mismatch 拒签。
141
-
142
- 4.5 **若产任何 WARNING + resolved=false**:提示用户 — archive 阶段必须先 `forge ack propose <finding-id>`(沿 9a 两步流程),否则 archive fence 拒签。
143
-
144
- 4.6 **若产任何 automated=true CRITICAL + resolved=false**:**不能 archive**(沿 design §2.2.4 fence)— 必须先实际修复让 finding resolved=true(改 code + 重跑 verify),不允许 ack 降级。
145
-
146
- ## 禁止行为
147
-
148
- - 不允许在 verify 失败时回去把已勾 task 改回 `[ ]`(违反 spec §3.3 不变量 2)
149
- - 不允许跳过证据 log 写入(verification-before-completion 要求证据先于声称)
150
- - 不允许 pass=true 但 evidence 为空(archive 校验会拒绝)
151
- - **不允许跳维度**(沿 plan-9d skill 红旗清单)— Completeness + Correctness + Coherence 三维度必须全跑,即使测试 pass
152
- - **不允许伪造 automated=true finding**(沿 design §2.3.3 critical_candidate 协议)— automated=true 的 finding 必须由工具/grep 机器判定,不能 AI 自决
153
- - **不允许 vague recommendation**("consider reviewing X" 类)— 必须给 file:line 或 spec:Requirement-id 具体证据(沿 plan-9d skill `## forge-specific 反向加固` §2)
154
- - **不允许在 .verify-passed 写 severity_acked_by = "ai-agent" 自 ack**(必须走 `forge ack propose` 两步流程,沿 9a)
47
+ 4.4 **若三维度发现重大问题**(应改 code / spec 后重跑 verify):**不写 .verify-passed**,直接 abort 让用户先修。AI 不允许"知道问题但仍写 verify-passed"。
155
48
 
156
49
  ## (可选)Stage extensions hook — Tier 1 Claude Code only
157
50
 
158
51
  > codex review 集成。AI 主代理在本 stage(`verify`)跑多轮收敛协议。
159
52
  > Tier 2/3(Codex/OpenCode)见 [`docs/stage-extensions.md §未来 Tier 2/3 集成`](../docs/stage-extensions.md#未来-tier-23-集成)。
160
53
 
161
- **Step A — 检查是否启用**:读 `forge/config.yaml#stage_extensions.verify`。无该字段 / 数组为空 / 全部 entry `enabled: false` → **跳过本段,流程结束**。
54
+ **Step A — 检查是否启用**:读 `forge/config.yaml#stage_extensions.verify`。无该字段 / 数组为空 / 全部 entry `enabled: false` → **跳过本段**。
162
55
 
163
56
  **Step B — 对每个 `enabled` entry 跑多轮收敛 loop**:
164
57
 
165
- 初始化 `round = 1`、`threadId = ''`、`roundHistory = []`、`roundLimit = null`(F1-v8 fix:`roundLimit` **不从 config 文件读** —— effective convergence 由 runner 输出,见 Step 3。AI 协议不碰 config 文件解析 / deep-merge,单一数据源是 runner JSON)。循环:
58
+ 初始化 `round = 1`、`threadId = ''`、`roundHistory = []`、`roundLimit = null`。循环:
166
59
 
167
60
  1. **跑单轮 runner**:
168
61
  ```bash
@@ -171,18 +64,22 @@ You are about to handle `/forge:verify $ARGUMENTS`.
171
64
  --round <round>${threadId:+ --thread-id $threadId}
172
65
  ```
173
66
  2. **解析 stdout JSON 的 `kind`**:
174
- - `converged` → 该 entry 收敛完成,**break loop**(codex 输出 verbatim 透传给用户)
175
- - `failed` / `config_error` / `no_extension` → 该 entry 放弃,**break loop**(loose,不阻塞主流程)
67
+ - `converged` → break loop(codex 输出 verbatim 透传给用户)
68
+ - `failed` / `config_error` / `no_extension` → break loop(loose,不阻塞主流程)
176
69
  - `unconverged` → 继续 3
177
- 3. **从 unconverged JSON 取状态**(F1-v8 fix:effective config 来自 runner 输出,runner 内 `validateStageExtensionsConfig` 已 normalize):
70
+ 3. **从 unconverged JSON 取状态**:
178
71
  - `roundHistory.push({ round, block_count: <blockFindings.length> })`;`threadId = <JSON.threadId>`;codex finding verbatim 透传给用户
179
- - 首轮:`roundLimit = <JSON.effectiveConvergence.max_rounds>`(后续轮 `roundLimit` 已设,不覆盖 —— 选项①的 `roundLimit += N` 增量须保留)
180
- 4. **若 `round >= roundLimit`**(F2-v7 fix:用可增长的 `roundLimit`):
181
- - 若 `<JSON.effectiveConvergence.max_rounds_on_exceed>` 为 `force_end` → 把 blockFindings 写 `forge/changes/<id>/.evidence/codex-pending-findings.yaml`(backlog),**break loop**
182
- - 否则跑 `node "${CLAUDE_PLUGIN_ROOT}/scripts/run-forge.mjs" stage-extensions analyze-trend --history '<roundHistory JSON>'` 拿 TrendAdvice,再 `AskUserQuestion` 三选项(默认推 `TrendAdvice.recommended_option`):**①再跑 N 轮**(F2-v7 fix:读用户输入的 `N`,执行 `roundLimit += N`,然后 `round++` 继续 loop —— 后续 `round >= roundLimit` 判定按新上限走,不会立刻又进 Step 4)/ **②放弃 codex**(break loop)/ **③接受当前**(blockFindings 写 backlog,break loop)
183
- 5. **否则(`round < roundLimit`)**:`AskUserQuestion` 三选项(默认推 `<JSON.userInteraction.block_unconverged>`):
184
- - **①auto_fix** → 用 `Task` 工具 dispatch fresh fix subagent 修 blockFindings → `round++`,继续 loop
185
- - **②manual_fix** 等用户改完 `round++`,继续 loop
186
- - **③give_up** → break loop
187
-
188
- **Step C — loose**:本段任何步骤(runner 调用 / AskUserQuestion / fix dispatch)失败都**不阻塞主流程 fence**。runner 永远 exit 0;AskUserQuestion harness 不支持时降级终端 prompt。
72
+ - 首轮:`roundLimit = <JSON.effectiveConvergence.max_rounds>`
73
+ 4. **若 `round >= roundLimit`**:
74
+ - 若 `<JSON.effectiveConvergence.max_rounds_on_exceed>` 为 `force_end` → 把 blockFindings 写 `forge/changes/<id>/.evidence/codex-pending-findings.yaml`,break loop
75
+ - 否则跑 `stage-extensions analyze-trend` 拿 TrendAdvice,再 AskUserQuestion 三选项:**①再跑 N 轮**(`roundLimit += N` `round++`)/ **②放弃 codex**(break)/ **③接受当前**(blockFindings 写 backlog,break)
76
+ 5. **否则**:AskUserQuestion 三选项(默认推 `<JSON.userInteraction.block_unconverged>`):**①auto_fix**(dispatch fresh fix subagent → `round++`)/ **②manual_fix**(等用户改 → `round++`)/ **③give_up**(break)
77
+
78
+ **Step C loose**:本段任何步骤失败都**不阻塞主流程**。runner 永远 exit 0;AskUserQuestion harness 不支持时降级终端 prompt。
79
+
80
+ ## 禁止行为
81
+
82
+ - 不允许跳过三维度 prose check 就写 .verify-passed
83
+ - 不允许测试 fail 时仍写 .verify-passed(违反 verification-before-completion 纪律)
84
+ - 不允许伪造 `verified_by` 字段(`ai-agent` 表示真跑了流程,`human-override` 表示用户手工签证 — archive 需 `--force`)
85
+ - **不允许在 .verify-passed 写 v4 已删字段**(`verify_findings` / `evidence` / `git` / `tasks_hash` / `content_hash` / `process_evidence` — schema 校验会拒)
@@ -0,0 +1,34 @@
1
+ # Tier 2/3 Command Bridge — 共享替换规则
2
+
3
+ > 被 5 个 stage skill 的「Tier 2/3 Orchestration」段引用。
4
+ > 适用:OpenCode / Codex 等无 `/forge:*` slash 命令的 harness;Claude Code(Tier 1)不走本桥接。
5
+
6
+ ## plugin root 解析(绝对路径字面值)
7
+
8
+ 命令文件与 helper 同在 plugin 仓库根下。先解析出**绝对路径字面值** `<ROOT>`:
9
+
10
+ - OpenCode:从 session bootstrap 文本里的 `forge plugin root: <abs path>` 行取得。
11
+ - Codex:标准安装为 `~/.codex/forge`,把 `~`/`$HOME` 展开成绝对路径。
12
+ - 解析后校验 `<ROOT>/scripts/run-forge.mjs` 与 `<ROOT>/commands/<stage>.md` **同时存在**;
13
+ 任一缺失 → 报错停止(fail closed),提示用户检查安装,**不得静默跳过**。
14
+ - **不得**在 shell 写 `$FORGE_PLUGIN_ROOT`(非运行时环境变量);用绝对路径字面值,
15
+ 或在单条命令内 `FORGE_ROOT="<abs literal>"; node "$FORGE_ROOT/..."`(变量不跨命令)。
16
+
17
+ ## 替换规则
18
+
19
+ 执行 `commands/<stage>.md` 时,按下表把 Tier-1 专属构造换成 Tier 2/3 等价物:
20
+
21
+ | 命令文件里的 | 替换为 |
22
+ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
23
+ | `${CLAUDE_PLUGIN_ROOT}/scripts/run-forge.mjs` | `<ROOT>/scripts/run-forge.mjs` |
24
+ | shell/命令执行上下文中的 forge executable token(裸 `forge <subcmd>`、管道右侧 `… \| forge <subcmd>`) | `node "<ROOT>/scripts/run-forge.mjs" <subcmd> …`;helper 不可达时 fallback `npx -y --package @accelerator-mzq/forge@^4.0.0 -- forge <subcmd>`。**散文/说明文字里的 `forge archive` 等引用不替换** |
25
+ | `$ARGUMENTS` | 从用户自然语言提取 |
26
+ | `AskUserQuestion` | 降级终端 `[1]/[2]/…` 文本 prompt;v4 起无 `forge ack` 协议,确认结果按 v4 marker 写入即可(详见 [`docs/migration/v3-to-v4.md`](../../docs/migration/v3-to-v4.md)) |
27
+ | `Task` 工具派子代理 | 按 `skills/subagent-driven-discipline/references/codex-tools.md`(Codex)/ `opencode-tools.md`(OpenCode)映射 |
28
+ | `## (可选)Stage extensions hook — Tier 1 Claude Code only` 段 | 整段跳过 |
29
+
30
+ 示例:
31
+
32
+ - bash:`node "<ROOT>/scripts/run-forge.mjs" validate add-login`
33
+ - PowerShell:`node "<ROOT>\scripts\run-forge.mjs" validate add-login`
34
+ - 管道(bash):`cat payload.json | node "<ROOT>/scripts/run-forge.mjs" finding hash`
@@ -329,7 +329,7 @@ You: [读 forge/changes/add-oauth-integration/{proposal,design,tasks,specs/oauth
329
329
 
330
330
  **Capture offer**:
331
331
  - 若选 option 2:capture 到 `forge/changes/add-oauth-integration/design.md ## Token Refresh Strategy`(新增段);**注意**:design.md 改后 marker `content_hash` 失效,需要重 verify
332
- - 若决定扩 scope(加 IdP 时钟同步):capture 到 `proposal.md ## What Changes`(扩本 change)
332
+ - 若决定扩 scope(加 IdP 时钟同步):capture 到 `proposal.md ## What`(扩本 change)
333
333
  - 若决定不做(留 v1.1):capture 到 `proposal.md ## Out of Scope` YAML 块(沿 §2.6 schema)
334
334
  ```
335
335
 
@@ -381,7 +381,7 @@ You: forge:exploring 下的对比请求 — 沿 OpenSpec `explore.ts:132` "用
381
381
  User: /forge:explore --change add-oauth-integration
382
382
  我们应不应该顺便加 SAML 支持?
383
383
 
384
- You: [读 add-oauth-integration 现状] proposal.md `## What Changes` 只列了 OAuth
384
+ You: [读 add-oauth-integration 现状] proposal.md `## What` 只列了 OAuth
385
385
  (Google + GitHub),没提 SAML。
386
386
 
387
387
  SAML vs OAuth 是企业级 vs 消费者级路线分支:
@@ -437,7 +437,7 @@ AI 倾向把所有"不做"的项都塞 SUGGESTION 持挂,而不写到 out-of-sco
437
437
  | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
438
438
  | New requirement / Requirement changed | `forge/changes/<id>/specs/<capability>/spec.md` | marker 失效(`content_hash` 变),提示用户重 verify |
439
439
  | Design decision made | `forge/changes/<id>/design.md` | marker 失效,提示重 verify |
440
- | Scope changed(扩本 change) | `forge/changes/<id>/proposal.md ## What Changes` | marker 失效,提示重 propose review |
440
+ | Scope changed(扩本 change) | `forge/changes/<id>/proposal.md ## What` | marker 失效,提示重 propose review |
441
441
  | **Out-of-scope 识别(转 follow-up)** | `forge/changes/<id>/proposal.md ## Out of Scope` / `## Non-Goals` 或 `design.md ## Future Work` YAML 块(沿 §2.6) | 不影响 marker(out-of-scope 不是 change 内容) |
442
442
  | New work identified(本 change 必做) | `forge/changes/<id>/tasks.md` | marker 失效,需重 apply |
443
443
  | Assumption invalidated | 相关 artifact | 看具体 |
@@ -225,27 +225,12 @@ forge 路径下,这一步发生在 `/forge:archive` 之后(archive 已做产物
225
225
 
226
226
  ---
227
227
 
228
- ## forge archive step (Tier 2/3 OpenCode/Codex 路径用,Plan 0a 实测 Variant B PASS)
228
+ ## Tier 2/3 Orchestration(OpenCode / Codex 路径)
229
229
 
230
- **仅 OpenCode + Codex 路径**(Tier 1 Claude Code 路径走 commands.md `/forge:archive` helper)
230
+ 当前 harness `/forge:*` slash 命令时(OpenCode / Codex),你 **MUST** Read 对应 `commands/archive.md` 并**完整执行**其协议 —— 按 `skills/_shared/tier23-command-bridge.md` plugin root 解析与替换规则执行。Claude Code(Tier 1)有 slash 命令,不走本段。
231
231
 
232
- When user says "archive" / "/forge:archive" / "完成归档" or similar, **after** finishing branch tasks(merge / clean / etc),you **MUST** execute:
232
+ 执行完成前核对 archive 硬门槛自检清单:
233
233
 
234
- ```bash
235
- node "${FORGE_HELPER}" archive <change-id>
236
- ```
237
-
238
- (`FORGE_HELPER` 解析见 forge:writing-plans skill 末尾 "CLI validation step" 段)
239
-
240
- forge CLI 内部严格门禁(spec §3.4):
241
-
242
- - `.verify-passed` 存在 + tasks_hash 匹配
243
- - `.review-passed` 存在 + content_hash 匹配 + git.diff_hash 匹配
244
- - specs sync(internal-only,不可绕过)
245
-
246
- **Result handling**:
247
-
248
- - exit 0 → mv 到 `forge/changes/archive/<date>-<id>/`,Tell user "Archive PASS"
249
- - exit 非零 → 报 stderr,**不**重试,提示用户跑缺失 step(`/forge:verify` 或 `/forge:review`)
250
-
251
- **严格门禁不可绕过 — 不要主动加 `--force`**(那是给 maintainer 紧急 escape hatch 用的,不是 AI 自主决策范畴)。
234
+ - `.verify-passed` 与 `.review-passed` 均存在,且 hash(tasks_hash / content_hash / git.diff_hash)新鲜匹配。
235
+ - `forge archive <change-id>` exit 0。
236
+ - 若 archive 步骤 emit sync-check manifest → 按 `commands/archive.md` 的编排步逐项 fulfill。