@andyqiu/codeforge 0.5.1 → 0.5.2

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.
@@ -16,7 +16,7 @@ allowed_tools:
16
16
  - smart_search
17
17
  # 故意不给 save_chat_insight:challenger 是过程角色,不沉淀
18
18
  # 故意不给 task:物理禁止派子 agent(避免嵌套对抗)
19
- # 故意不给 pending_changes:零写权
19
+ # 故意不给 edit/write:零写权(worktree 也不允许写)
20
20
  model: openai/gpt-5.5
21
21
  model_category: ultrabrain
22
22
  tier: deep
@@ -60,7 +60,7 @@ fallback_models:
60
60
  - "方向是对的,不过..."
61
61
  - ❌ 禁止只夸不挑 —— 如果真的全对,必须明示"我没找到问题"并列出**已检查的维度清单**(让 discover 看到你确实查过 7 项)
62
62
  - ❌ 禁止派子 agent(工具未给 `task`,物理禁止)
63
- - ❌ 禁止 stage / apply 任何文件(工具未给 `pending_changes`)
63
+ - ❌ 禁止写任何文件(工具未给 `edit` / `write`)
64
64
  - ❌ 禁止 `save_chat_insight`(你是过程角色,沉淀由 discover 做)
65
65
  - ❌ 报告里**不允许**出现「伪需求」三字(包括 红旗 reasons 字段)
66
66
 
@@ -10,14 +10,14 @@ permission:
10
10
  webfetch: deny
11
11
  # CodeForge 自描述字段(phase1:check 校验复数 + 列表形态)
12
12
  permissions:
13
- edit: deny
14
13
  bash: deny
15
14
  webfetch: deny
16
15
  allowed_tools:
17
16
  - read
17
+ - write
18
+ - edit
18
19
  - smart_search
19
20
  - save_chat_insight
20
- - pending_changes
21
21
  - task
22
22
  - skill
23
23
  model: anthropic/claude-opus-4-7
@@ -71,14 +71,15 @@ fallback_models:
71
71
  - 数值范围:`当前` ∈ [0.0, 1.0],`加权` = `当前 × 权重`(保留 2 位小数)。**违反格式 = 违反硬约束**。
72
72
  - **评分表前必须先输出 1 行 Phase 进度提示**(C5 dogfooding 用户反馈:全程看不到红旗 YES/NO,等价于看不到自己处于哪个 Phase)。模板见附录 D。
73
73
  - 进入 Phase E 出 PRD 草稿前**强制展示一次**评分表(让用户拍板)
74
- - 所有产物必须通过 `pending_changes.stage` 暂存到 `.codeforge/specs/<slug>/`,**不允许** apply
74
+ - 所有产物(PRD.md / handoff.yaml)**直接 `write` session worktree** 的 `.codeforge/specs/<slug>/` 下;session-worktree-guard 隔离主仓,最终由用户 `/merge` 拍板合并
75
75
  - 开始新对话时**必须** `smart_search` 三轮并发(业务领域 / 团队历史类似需求 / 反模式清单)
76
76
  - 每个 Phase 结束时**必须** `save_chat_insight` 沉淀阶段结论
77
77
 
78
78
  ### MUST NOT
79
79
 
80
80
  - ❌ 永不向用户提及以下术语(即便用户先说):`JTBD` / `Jobs-to-be-Done` / `EARS` / `Pre-mortem` / `Socratic Self-Refine` / `Affinity clustering` / `Divergent phase` / `Convergent phase` / `5 维加权打分` / `Sycophancy` / `Devil's Advocate` / `Example Mapping` / `ambiguity-gate` / **`伪需求`**(红旗用「关键前提未证实」表达,绝不说这三个字)
81
- - ❌ 不允许出现"按 X 框架"/"用 Y 方法论"/"做一次 Pre-mortem"等领字句式;不允许跳过 pending-changes 直接写文件;不允许调用 `task()` 派出 discover-challenger 以外的任何 agent;不允许 apply / apply_all(用户拍板)
81
+ - ❌ 不允许出现"按 X 框架"/"用 Y 方法论"/"做一次 Pre-mortem"等领字句式;不允许写到 worktree 之外(session-worktree-guard 会拒);不允许调用 `task()` 派出 discover-challenger 以外的任何 agent;不允许擅自跳过用户 `/merge` 直接动主仓
82
+ - ❌ **不允许 `edit` / `write` 除 `.codeforge/specs/<slug>/PRD.md` 和 `.codeforge/specs/<slug>/handoff.yaml` 之外的任何路径**;禁止修改源码、配置和工作流文件(discover 的产出仅限 spec 两份产物)
82
83
  - ❌ 用户说「别给我看分了 / 静默模式 / 不要表格」后,**永久**不再输出评分表(连 Phase E 也不展示)
83
84
  - ❌ 输出文档里**禁止**出现「伪需求」三字;允许的替代措辞:「带红旗交付」/「风险标记」/「关键前提未证实」/「多轮反对未回应」
84
85
 
@@ -163,7 +164,7 @@ fallback_models:
163
164
  - **不允许**把所有 high-risk-unknown 全塞为 blocker —— 只挑「不解除会导致 coder 实施时翻车或返工」的真阻断点;细节追踪用 `open_issues` 即可
164
165
  - 老 v1.1 spec 缺该字段:下游 coder fallback 从 assumptions+open_issues+red_flags 推断;新生成 spec 必走 v1.2.0
165
166
  7. **禁止手填 `created_at` 和 `discover_session_id`**:这两个字段由工具运行时注入,留空即可(schema 已 optional)
166
- 8. `pending_changes.stage` 两份产物到 `.codeforge/specs/<slug>/PRD.md` 和 `handoff.yaml`,列 pending id 给用户审批
167
+ 8. `write` 工具把两份产物落到 `.codeforge/specs/<slug>/PRD.md` 和 `handoff.yaml`(worktree 内直写,session-worktree-guard 隔离主仓),告诉用户已写入 session worktree,由用户后续 `/merge` 拍板
167
168
 
168
169
  **人话外壳模板**(递交时):
169
170
 
@@ -403,4 +404,4 @@ related_artifacts: { prd: "PRD.md", transcript: "transcript.md" }
403
404
 
404
405
  - 用户中途说"算了不做了":保留 transcript,`save_chat_insight` 沉淀已澄清部分,结束
405
406
  - challenger 召唤失败(task 超时 / 模型不可用):fallback 到 self-critique 模板,并明示用户"对抗这一环降级了"
406
- - pending_changes.stage 失败:汇报具体错误,**不要直接写文件绕过**
407
+ - `write` 工具失败(例如 worktree-guard 拒绝路径):汇报具体错误,**不要绕过 worktree 写到主仓**
package/bin/codeforge.mjs CHANGED
@@ -285,6 +285,52 @@ function cmdRollback(args) {
285
285
  return 0
286
286
  }
287
287
 
288
+ // ────────────────────────────────────────────────────────────────────
289
+ // 子命令:upgrade —— 升级到 npm latest 并重新 install --global
290
+ // ────────────────────────────────────────────────────────────────────
291
+ function cmdUpgrade(args) {
292
+ const dryRun = !!args.flags["dry-run"] || !!args.flags.dryRun
293
+ const currentVersion = getVersion()
294
+
295
+ log(`CodeForge upgrade`)
296
+ log(` 当前版本 : ${currentVersion}`)
297
+ log(` dry-run : ${dryRun}`)
298
+ hr()
299
+
300
+ const npmCmd = "npm"
301
+ const npmArgs = ["install", "-g", "@andyqiu/codeforge@latest"]
302
+ log(`步骤 1/2:${npmCmd} ${npmArgs.join(" ")}`)
303
+
304
+ if (!dryRun) {
305
+ const r = spawnSync(npmCmd, npmArgs, { stdio: "inherit", shell: true })
306
+ if (r.status !== 0) {
307
+ err(`npm install 失败 (exit=${r.status ?? 1})`)
308
+ err(`提示:可手动跑 npm install -g @andyqiu/codeforge@latest`)
309
+ return 1
310
+ }
311
+ } else {
312
+ log(`[dry-run] 跳过 npm install`)
313
+ }
314
+
315
+ hr()
316
+ log(`步骤 2/2:codeforge install --global`)
317
+
318
+ if (!dryRun) {
319
+ const code = installOpencode({ scope: "global", dryRun: false, extraArgs: [] })
320
+ if (code !== 0) {
321
+ err(`install --global 失败 (exit=${code})`)
322
+ return 1
323
+ }
324
+ } else {
325
+ log(`[dry-run] 跳过 install --global`)
326
+ }
327
+
328
+ hr()
329
+ ok(`升级完成!运行 codeforge -v 查看新版本`)
330
+ ok(`重启 opencode 后新版本生效`)
331
+ return 0
332
+ }
333
+
288
334
  // ────────────────────────────────────────────────────────────────────
289
335
  // 子命令:runtime —— 转发到 codeforge-runtime-info.mjs
290
336
  // ────────────────────────────────────────────────────────────────────
@@ -390,6 +436,7 @@ function cmdHelp() {
390
436
  codeforge list
391
437
  codeforge version
392
438
  codeforge rollback [--target=<path>] [--dry-run] # 恢复最近 backup(auto_install 失败救场)
439
+ codeforge upgrade [--dry-run] # 升级到 npm latest 并重新 install --global
393
440
  codeforge runtime where [<path>] # 打印当前项目的全局运行时目录
394
441
  codeforge adr-init [--force] [--dry-run] [--write-prepare] [--no-pre-push]
395
442
  # 把 ADR 校验体系(hooks + scripts + 模板)下发到当前 git 项目
@@ -453,6 +500,8 @@ async function main() {
453
500
  return 0
454
501
  case "rollback":
455
502
  return cmdRollback(args)
503
+ case "upgrade":
504
+ return cmdUpgrade(args)
456
505
  case "runtime":
457
506
  return cmdRuntime(args)
458
507
  case "adr-init":
@@ -4,7 +4,7 @@ description: 查看当前 session worktree 的改动(文件列表+统计,或
4
4
 
5
5
  <!--
6
6
  codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析):
7
- name: diff
7
+ name: changes
8
8
  version: 1.0.0
9
9
  requires_human_approval: false
10
10
  说明:底层调用 session_merge 工具的 action=diff
@@ -14,9 +14,9 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
14
14
  -->
15
15
 
16
16
 
17
- # /diff — 查看当前 session worktree 改动
17
+ # /changes — 查看当前 session worktree 改动
18
18
 
19
- **ADR: worktree-session-isolation Phase 3**
19
+ **ADR: worktree-session-isolation Phase 3** <!-- ADR:worktree-session-isolation -->
20
20
 
21
21
  快速查看当前 session worktree 中的代码改动,无需触发 merge 或 review 流程。
22
22
 
@@ -27,23 +27,23 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
27
27
  ## 用法
28
28
 
29
29
  ```
30
- /diff # 显示改动文件列表 + 统计(git diff --stat 风格)
31
- /diff --full # 显示完整 diff 内容
30
+ /changes # 显示改动文件列表 + 统计(git diff --stat 风格)
31
+ /changes --full # 显示完整 diff 内容
32
32
  ```
33
33
 
34
34
  ## 行为说明
35
35
 
36
36
  | 模式 | 触发条件 | 输出内容 |
37
37
  |------|----------|----------|
38
- | **stat 模式**(默认) | `/diff` | 改动文件列表 + 增删行数统计 |
39
- | **full 模式** | `/diff --full` | 完整 diff 内容(含每行改动) |
38
+ | **stat 模式**(默认) | `/changes` | 改动文件列表 + 增删行数统计 |
39
+ | **full 模式** | `/changes --full` | 完整 diff 内容(含每行改动) |
40
40
  | **无 worktree** | session 无写操作 | 友好提示:当前 session 没有写操作,无 worktree 改动 |
41
41
 
42
42
  ## 底层调用
43
43
 
44
44
  ```
45
- /diff → session_merge(action="diff", stat=true)
46
- /diff --full → session_merge(action="diff", stat=false)
45
+ /changes → session_merge(action="diff", stat=true)
46
+ /changes --full → session_merge(action="diff", stat=false)
47
47
  ```
48
48
 
49
49
  ## 何时使用
@@ -56,7 +56,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
56
56
 
57
57
  | 命令 | 用途 |
58
58
  |------|------|
59
- | `/diff` | 本命令:只读查看 worktree 改动,不触发任何合并 |
59
+ | `/changes` | 本命令:只读查看 worktree 改动,不触发任何合并 |
60
60
  | `/merge` | 触发 review-fix-review 审批闭环后 squash merge 入主仓 |
61
61
  | `/discard-session` | 放弃当前 session 所有改动(不可恢复) |
62
62
  | `session_merge action=status` | 查看 worktree 绑定状态(非 diff 内容) |
package/commands/debug.md CHANGED
@@ -8,7 +8,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  version: 1.0.0
9
9
  trigger_workflow: bugfix
10
10
  requires_human_approval: true
11
- allowed_tools: smart_search, save_chat_insight, pending-changes, repo-map, ast-edit, nav-find, nav-goto, bash
11
+ allowed_tools: smart_search, save_chat_insight, repo-map, ast-edit, nav-find, nav-goto, bash, edit, write
12
12
  说明:入口 agent 由 workflow 控制(先取证用 reviewer,后续步骤切换)
13
13
  ADR-0008(gstack 单 markdown skill)/ ADR-0010(plan-act 模式分离)
14
14
  -->
@@ -50,8 +50,8 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
50
50
  | 2. 假设 | planner | 出最多 3 个根因假设 + 验证方法 | 否 |
51
51
  | 3. 复现 | coder | 写最小测试用例(应红)| 风险动作自动审批 |
52
52
  | 4. 修复 | coder | 改代码让复现测试变绿 | 风险动作自动审批 |
53
- | 5. 审阅 | reviewer | pending + 跑全量测试 | 否 |
54
- | 6. 落地 | coder | `pending-changes apply_all` | **必审批** |
53
+ | 5. 审阅 | reviewer | worktree diff + 跑全量测试 | 否 |
54
+ | 6. 落地 | 用户 | 跑 `/merge` 触发 review-fix-review 闭环合并 session worktree 到主仓 | **必审批** |
55
55
  | 7. 沉淀 | reviewer | `save_chat_insight category=bugfix` | 否(写失败 skip) |
56
56
 
57
57
  ## 与 /ship 的差异
@@ -79,7 +79,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
79
79
  | step 3 (复现) | retry 1 次。仍失败 → abort(也许不是真 bug) |
80
80
  | step 4 (修复) | retry 2 次。仍失败 → abort(假设可能错了) |
81
81
  | step 5 (审阅 BLOCK) | abort:reviewer 否决,回 step 2 重新假设 |
82
- | step 6 (apply 漂移) | abort:pending-changes 拒绝脏覆盖 |
82
+ | step 6 (/merge 失败) | abort:review-fix-review 闭环未通过或主仓冲突 |
83
83
  | step 7 (save_chat_insight) | skip |
84
84
 
85
85
  ## 上下文注入
package/commands/deep.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 临时把当前任务的 agent 模型升到 deep 档(Opus + 大 thinking);改动 stage pending-changes 等待用户审批
2
+ description: 临时把当前任务的 agent 模型升到 deep 档(Opus + 大 thinking);改动直接写入 session worktree,由用户 /merge 拍板
3
3
  agent: planner
4
4
  ---
5
5
 
@@ -8,8 +8,8 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  name: deep
9
9
  version: 1.0.0
10
10
  trigger_workflow: null
11
- allowed_tools: model_chain, ast_edit, pending_changes
12
- 说明:方案 A 用户显式 override 入口;与 /quick 对称;与 /model-switch 共享 ast_edit + pending_changes 落地路径
11
+ allowed_tools: model_chain, ast_edit
12
+ 说明:方案 A 用户显式 override 入口;与 /quick 对称;与 /model-switch 共享 ast_edit 落地路径(写入 session worktree,由用户 /merge 拍板)
13
13
  ADR-0060(model-tier-three-layer-escalation,Phase 2d)
14
14
  -->
15
15
 
@@ -17,7 +17,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
17
17
  # /deep — 临时升档到 deep(Opus + 大 thinking)
18
18
 
19
19
  把指定 agent 的模型临时升到 `deep` 档(默认 `anthropic/claude-opus-4-7` + 大 thinking budget)。
20
- 改动会 stage pending-changes,**由用户审批后 apply 才会真正生效**。
20
+ 改动会直接写入当前 session worktree(由 session-worktree-guard 隔离主仓),**由用户 `/merge` 拍板合并到主仓后才会真正生效**。
21
21
 
22
22
  ## 输入
23
23
 
@@ -45,11 +45,11 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
45
45
  - 若当前已是 `ultra` 档(更高档)→ 提示「<agent> 当前是 ultra 档(比 deep 更高),如确需降到 deep 请显式确认」,**不 stage**
46
46
  - 否则进入切换流程
47
47
 
48
- 4. **执行切换**(复用 `/model-switch` 的等价路径,不直接调它,按 ast_edit + pending_changes 标准模式自行 stage):
48
+ 4. **执行切换**(复用 `/model-switch` 的等价路径,不直接调它,按 ast_edit 标准模式直接写入 session worktree):
49
49
  1. 从 `codeforge.json` 的 `models.categories.deep`(或 `models.tiers.deep`,若已落地 Phase 2a)读出目标 model id 和 thinking 配置
50
50
  2. 用 `ast_edit` 修改 `codeforge.json`:把 `models.agents.<agent>.model` 改为 deep 档 model;旧主模型自动 prepend 到该 agent 的 fallback 链头部(避免重启后被切回去)
51
- 3. 改动用 `pending_changes.stage` 暂存;**不调 apply**
52
- 4. 输出 pending-changes ID 给用户审批
51
+ 3. `ast_edit` 直接写入 session worktree(session-worktree-guard 隔离主仓,不影响主工作区)
52
+ 4. 告诉用户改动已落到 session worktree,跑 `/merge` 触发 review-fix-review 闭环合并
53
53
 
54
54
  5. **审批后提示**:用户 apply 之后,主动提示跑 `npm run sync:models` 把新配置同步到 `agents/<agent>.md` 的 frontmatter
55
55
 
@@ -65,15 +65,15 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
65
65
 
66
66
  - `/quick` ←→ `/deep`:完全对称,方向相反
67
67
  - `/model-switch agent <model-id>`:底层通用切换;`/deep` 是它的「按档位语义糖」,自动算出 deep 档 model 不用用户记 id
68
- - 三者最终都走相同的 `ast_edit + pending_changes` 路径,没有"另一套"写文件机制
68
+ - 三者最终都走相同的 `ast_edit` 写入 session worktree 路径,没有"另一套"写文件机制
69
69
 
70
70
  ## 安全约束
71
71
 
72
- - ❌ 禁止直接 apply pending-changes(必须用户审批)
72
+ - ❌ 禁止绕过 `/merge` 直接把改动写进主仓(必须用户拍板)
73
73
  - ❌ 禁止改 `codeforge.json` 之外的文件
74
74
  - ❌ 禁止在没有 `models.categories.deep`(或 `models.tiers.deep`)配置时硬编码 model id —— 必须从配置读
75
- - ✅ stage 完一定要输出 pending id 给用户
76
- - ✅ apply 后一定要提示 `npm run sync:models`
75
+ - ✅ 写入 session worktree 后,明确告知用户「改动已落到 session worktree,请跑 `/merge`」
76
+ - ✅ `/merge` 后一定要提示 `npm run sync:models`
77
77
 
78
78
  ## 失败回退
79
79
 
@@ -8,8 +8,8 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  name: model-switch
9
9
  version: 1.0.0
10
10
  trigger_workflow: null
11
- allowed_tools: model_chain, ast_edit, pending_changes, repo_map
12
- 说明:单 agent 命令,不触发 workflow;切换走 ast_edit + pending_changes 暂存
11
+ allowed_tools: model_chain, ast_edit, repo_map
12
+ 说明:单 agent 命令,不触发 workflow;切换走 ast_edit 直接写入 session worktree(由用户 /merge 拍板)
13
13
  ADR-0008(gstack 单 markdown skill)
14
14
  -->
15
15
 
@@ -39,10 +39,10 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
39
39
  - **只给 agent 名** → 输出该 agent 的链 + 当前主模型 + 完整 fallback 顺序
40
40
  - **agent + model id** → 校验目标 model 在该 agent 的 chain 里,然后:
41
41
  1. 用 `ast_edit` 把 `codeforge.json` 中 `models.agents.<name>.model` 改成新值(旧主模型自动追加到 fallback 链头部,避免下次重启又被切回去)
42
- 2. `pending_changes` 暂存改动,**等用户确认**
42
+ 2. `ast_edit` 直接写入 session worktree(session-worktree-guard 隔离主仓),**告知用户跑 `/merge` 拍板**
43
43
  3. 提示用户跑 `npm run sync:models` 把新配置同步到 `agents/<name>.md`
44
44
  - **agent + `next`** → 调用 `model_chain({agent, current})`,拿到下一档后等同于第 3 种用法
45
- 3. **永远不直接写文件**:所有切换都走 `pending_changes`
45
+ 3. **永远不直接写主仓**:所有切换都走 session worktree,最终由用户 `/merge` 合并
46
46
 
47
47
  ## 何时用
48
48
 
package/commands/quick.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 临时把当前任务的 agent 模型降到 quick 档(Sonnet/Haiku 档,省 token);改动 stage pending-changes 等待用户审批
2
+ description: 临时把当前任务的 agent 模型降到 quick 档(Sonnet/Haiku 档,省 token);改动直接写入 session worktree,由用户 /merge 拍板
3
3
  agent: planner
4
4
  ---
5
5
 
@@ -8,8 +8,8 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  name: quick
9
9
  version: 1.0.0
10
10
  trigger_workflow: null
11
- allowed_tools: model_chain, ast_edit, pending_changes
12
- 说明:方案 A 用户显式 override 入口;与 /deep 对称;与 /model-switch 共享 ast_edit + pending_changes 落地路径
11
+ allowed_tools: model_chain, ast_edit
12
+ 说明:方案 A 用户显式 override 入口;与 /deep 对称;与 /model-switch 共享 ast_edit 落地路径(写入 session worktree,由用户 /merge 拍板)
13
13
  ADR-0060(model-tier-three-layer-escalation,Phase 2d)
14
14
  -->
15
15
 
@@ -17,7 +17,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
17
17
  # /quick — 临时降档到 quick(Sonnet/Haiku 档,省 token)
18
18
 
19
19
  把指定 agent 的模型临时降到 `quick` 档(默认 `anthropic/claude-sonnet-4-5` 或更轻量的 Haiku,按 `codeforge.json` 配置)。
20
- 改动会 stage pending-changes,**由用户审批后 apply 才会真正生效**。
20
+ 改动会直接写入当前 session worktree(由 session-worktree-guard 隔离主仓),**由用户 `/merge` 拍板合并到主仓后才会真正生效**。
21
21
 
22
22
  ## 输入
23
23
 
@@ -49,11 +49,11 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
49
49
  - 若用户降的是 `planner` 或 `reviewer`,额外提示「⚠️ <agent> 是质量关键节点,降档可能导致方案/评审失误」
50
50
  - 仍按用户意图执行 stage(提示是软约束,不阻断)
51
51
 
52
- 5. **执行切换**(复用 `/model-switch` 的等价路径,按 ast_edit + pending_changes 标准模式自行 stage):
52
+ 5. **执行切换**(复用 `/model-switch` 的等价路径,按 ast_edit 标准模式直接写入 session worktree):
53
53
  1. 从 `codeforge.json` 的 `models.categories.quick`(或 `models.tiers.quick`,若已落地 Phase 2a)读出目标 model id 和 thinking 配置
54
54
  2. 用 `ast_edit` 修改 `codeforge.json`:把 `models.agents.<agent>.model` 改为 quick 档 model;旧主模型自动 prepend 到该 agent 的 fallback 链头部(避免重启后被切回去,方便升回去)
55
- 3. 改动用 `pending_changes.stage` 暂存;**不调 apply**
56
- 4. 输出 pending-changes ID 给用户审批
55
+ 3. `ast_edit` 直接写入 session worktree(session-worktree-guard 隔离主仓,不影响主工作区)
56
+ 4. 告诉用户改动已落到 session worktree,跑 `/merge` 触发 review-fix-review 闭环合并
57
57
 
58
58
  6. **审批后提示**:用户 apply 之后,主动提示跑 `npm run sync:models` 把新配置同步到 `agents/<agent>.md` 的 frontmatter
59
59
 
@@ -69,16 +69,16 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
69
69
 
70
70
  - `/deep` ←→ `/quick`:完全对称,方向相反
71
71
  - `/model-switch agent <model-id>`:底层通用切换;`/quick` 是它的「按档位语义糖」,自动算出 quick 档 model 不用用户记 id
72
- - 三者最终都走相同的 `ast_edit + pending_changes` 路径,没有"另一套"写文件机制
72
+ - 三者最终都走相同的 `ast_edit` 写入 session worktree 路径,没有"另一套"写文件机制
73
73
 
74
74
  ## 安全约束
75
75
 
76
- - ❌ 禁止直接 apply pending-changes(必须用户审批)
76
+ - ❌ 禁止绕过 `/merge` 直接把改动写进主仓(必须用户拍板)
77
77
  - ❌ 禁止改 `codeforge.json` 之外的文件
78
78
  - ❌ 禁止在没有 `models.categories.quick`(或 `models.tiers.quick`)配置时硬编码 model id —— 必须从配置读
79
79
  - ✅ 降档前必须输出质量风险提示
80
- - ✅ stage 完一定要输出 pending id 给用户
81
- - ✅ apply 后一定要提示 `npm run sync:models`
80
+ - ✅ 改动写入 session worktree 后,明确告知用户「已落到 session worktree,请跑 `/merge`」
81
+ - ✅ `/merge` 后一定要提示 `npm run sync:models`
82
82
 
83
83
  ## 失败回退
84
84
 
@@ -9,7 +9,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
9
9
  version: 1.0.0
10
10
  trigger_workflow: refactor
11
11
  requires_human_approval: true
12
- allowed_tools: smart_search, save_chat_insight, pending-changes, repo-map, nav-find, nav-goto, bash
12
+ allowed_tools: smart_search, save_chat_insight, repo-map, nav-find, nav-goto, bash, edit, write
13
13
  说明:workflow-engine 看到 trigger_workflow=refactor 拦截 /refactor 触发对应 YAML
14
14
  -->
15
15
 
@@ -45,7 +45,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
45
45
  | 3. 确认覆盖 | reviewer | 确认测试覆盖待重构代码路径 | 否 |
46
46
  | 4. 重构 | coder | 实施重构,每步保证测试仍绿 | 否,auto_feedback 自纠 |
47
47
  | 5. 审阅 | reviewer | 确认行为不变 + 代码更清晰 | 否 |
48
- | 6. 落地 | coder | `pending-changes apply_all` | **必审批**(YAML 写死) |
48
+ | 6. 落地 | 用户 | 跑 `/merge` 触发 review-fix-review 闭环合并 session worktree 到主仓 | **必审批**(YAML 写死) |
49
49
  | 7. 沉淀 | reviewer | `save_chat_insight` 把经验回写 KH | 否(写失败 skip) |
50
50
 
51
51
  ## 与 /tdd 的区别
@@ -8,14 +8,14 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  name: review
9
9
  version: 1.0.0
10
10
  trigger_workflow: code-review
11
- allowed_tools: smart_search, save_chat_insight, pending-changes, bash, repo-map, nav-find
11
+ allowed_tools: smart_search, save_chat_insight, bash, repo-map, nav-find
12
12
  说明:workflow-engine 看到 trigger_workflow=code-review 拦截 /review 触发对应 YAML
13
13
  -->
14
14
 
15
15
 
16
16
  # /review — 代码审阅工作流
17
17
 
18
- 触发 `workflows/code-review.yaml`。**只读流程**:不 stage 任何改动,不 apply 任何 pending。
18
+ 触发 `workflows/code-review.yaml`。**只读流程**:不写任何文件、不触发 `/merge`。
19
19
 
20
20
  ## 输入
21
21
 
package/commands/ship.md CHANGED
@@ -8,7 +8,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
8
8
  version: 1.0.0
9
9
  trigger_workflow: feature-dev
10
10
  requires_human_approval: true
11
- allowed_tools: smart_search, save_chat_insight, pending-changes, repo-map, nav-find, nav-goto, bash
11
+ allowed_tools: smart_search, save_chat_insight, repo-map, nav-find, nav-goto, bash, edit, write
12
12
  说明:workflow-engine 看到 trigger_workflow=feature-dev 拦截 /ship 触发对应 YAML
13
13
  -->
14
14
 
@@ -39,15 +39,15 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
39
39
  | 步骤 | Agent | 动作 | 是否需审批 |
40
40
  |------|------|------|-----------|
41
41
  | 1. 规划 | planner | smart_search + repo-map → 出方案 | 否 |
42
- | 2. 执行 | coder | 按方案 stage 改动到 `.codeforge/pending/` | 风险动作自动审批 |
43
- | 3. 审阅 | reviewer | pending + 跑测试 + 给 APPROVE/REQUEST_CHANGES | 否 |
44
- | 4. 落地 | coder | `pending-changes apply_all` | **必审批**(YAML 写死) |
42
+ | 2. 执行 | coder | 按方案直接写入 session worktree(session-worktree-guard 隔离主仓) | 风险动作自动审批 |
43
+ | 3. 审阅 | reviewer | worktree diff + 跑测试 + 给 APPROVE/REQUEST_CHANGES | 否 |
44
+ | 4. 落地 | 用户 | 跑 `/merge` 触发 review-fix-review 闭环合并 session worktree 到主仓 | **必审批**(YAML 写死) |
45
45
  | 5. 沉淀 | reviewer | `save_chat_insight` 把会话经验回写 KH | 否(写失败 skip) |
46
46
 
47
47
  ## 自主度(AGENTS.md C18)
48
48
 
49
49
  `/ship` 默认 `semi` 模式:
50
- - 风险动作(pending-changes apply / bash / write)自动弹审批
50
+ - 风险动作(bash / 写到 worktree 外)自动弹审批;最终合并由用户跑 `/merge`
51
51
  - planner / reviewer 的只读动作不打扰
52
52
 
53
53
  要全自动跑,启动 opencode 时加 `--mode=full`,**且必须开 worktree 隔离**(自动启用)。
@@ -69,7 +69,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
69
69
  | step 1 (planner) | abort:方案出不来,后续没意义 |
70
70
  | step 2 (coder) | retry 1 次,仍失败则 abort |
71
71
  | step 3 (reviewer) BLOCK | abort:用户决定要不要继续 |
72
- | step 4 (apply) hash 漂移 | abort:避免脏覆盖(pending-changes 会拒) |
72
+ | step 4 (/merge 失败) | abort:review-fix-review 闭环未通过或主仓冲突 |
73
73
  | step 5 (save_chat_insight) | skip:KH 写失败不能让用户已 ship 的功能"看起来失败" |
74
74
 
75
75
  ## 与 /plan 的关系
package/commands/tdd.md CHANGED
@@ -9,7 +9,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
9
9
  version: 1.0.0
10
10
  trigger_workflow: tdd
11
11
  requires_human_approval: true
12
- allowed_tools: smart_search, save_chat_insight, pending-changes, repo-map, nav-find, nav-goto, bash
12
+ allowed_tools: smart_search, save_chat_insight, repo-map, nav-find, nav-goto, bash, edit, write
13
13
  说明:workflow-engine 看到 trigger_workflow=tdd 拦截 /tdd 触发对应 YAML
14
14
  -->
15
15
 
@@ -46,7 +46,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
46
46
  | 4. 最小实现-GREEN | coder | 写最小实现让测试变绿(不超出需要) | 否,auto_feedback 自纠 |
47
47
  | 5. 重构-REFACTOR | coder | 可选 refactor,测试必须仍绿 | 否,可 skip |
48
48
  | 6. 审阅 | reviewer | 确认三步全做 + 测试覆盖核心 | 否 |
49
- | 7. 落地 | coder | `pending-changes apply_all` | **必审批**(YAML 写死) |
49
+ | 7. 落地 | 用户 | 跑 `/merge` 触发 review-fix-review 闭环合并 session worktree 到主仓 | **必审批**(YAML 写死) |
50
50
 
51
51
  ## TDD 三色循环
52
52
 
@@ -82,7 +82,7 @@ codeforge 元数据(opencode 不读,由 plugins / workflow-engine 解析)
82
82
  | step 4 (最小实现) | auto_feedback 5 轮 |
83
83
  | step 5 (REFACTOR 失败) | skip:refactor 是可选 |
84
84
  | step 6 (审阅 REQUEST_CHANGES) | 回 step 2,max_loops=5 |
85
- | step 7 (apply) | hash 漂移则拒 |
85
+ | step 7 (/merge) | review-fix-review 闭环未通过或主仓冲突则拒 |
86
86
 
87
87
  ## 元数据
88
88