@modus-ai/modus 0.2.4 → 0.2.6

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 (75) hide show
  1. package/README.md +100 -42
  2. package/dist/cli/index.js +2 -2
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/config.d.ts.map +1 -1
  5. package/dist/commands/config.js +9 -8
  6. package/dist/commands/config.js.map +1 -1
  7. package/dist/commands/global.js +1 -1
  8. package/dist/commands/global.js.map +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +37 -7
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/status.js +2 -2
  13. package/dist/generators/claude.d.ts.map +1 -1
  14. package/dist/generators/claude.js +1 -37
  15. package/dist/generators/claude.js.map +1 -1
  16. package/dist/generators/codebuddy.d.ts.map +1 -1
  17. package/dist/generators/codebuddy.js +3 -1
  18. package/dist/generators/codebuddy.js.map +1 -1
  19. package/dist/generators/codex.d.ts +10 -0
  20. package/dist/generators/codex.d.ts.map +1 -0
  21. package/dist/generators/codex.js +178 -0
  22. package/dist/generators/codex.js.map +1 -0
  23. package/dist/generators/copilot.d.ts.map +1 -1
  24. package/dist/generators/copilot.js +0 -1
  25. package/dist/generators/copilot.js.map +1 -1
  26. package/dist/generators/cursor.d.ts.map +1 -1
  27. package/dist/generators/cursor.js +36 -7
  28. package/dist/generators/cursor.js.map +1 -1
  29. package/dist/generators/custom.d.ts +55 -0
  30. package/dist/generators/custom.d.ts.map +1 -0
  31. package/dist/generators/custom.js +166 -0
  32. package/dist/generators/custom.js.map +1 -0
  33. package/dist/generators/index.d.ts +1 -0
  34. package/dist/generators/index.d.ts.map +1 -1
  35. package/dist/generators/index.js +10 -0
  36. package/dist/generators/index.js.map +1 -1
  37. package/dist/utils/config.d.ts +38 -1
  38. package/dist/utils/config.d.ts.map +1 -1
  39. package/dist/utils/config.js +10 -2
  40. package/dist/utils/config.js.map +1 -1
  41. package/dist/utils/file-system.d.ts.map +1 -1
  42. package/dist/utils/file-system.js +2 -1
  43. package/dist/utils/file-system.js.map +1 -1
  44. package/package.json +1 -1
  45. package/schemas/harness-schema.yaml +178 -53
  46. package/schemas/knowledge-schema.yaml +111 -1
  47. package/templates/agents/modus-analyst.md +1 -1
  48. package/templates/behavior-guard.md +165 -0
  49. package/templates/commands/auto.md +61 -25
  50. package/templates/commands/commit.md +63 -0
  51. package/templates/commands/harness.md +97 -30
  52. package/templates/commands/init.md +43 -10
  53. package/templates/commands/modus.md +55 -28
  54. package/templates/commands/plan.md +60 -18
  55. package/templates/commands/spec.md +69 -25
  56. package/templates/commands/upgrade.md +54 -0
  57. package/templates/commands/vibe.md +56 -6
  58. package/templates/knowledge-catalog.md +74 -32
  59. package/templates/skills/modus-agents/analyst/SKILL.md +18 -3
  60. package/templates/skills/modus-agents/deployer/SKILL.md +114 -62
  61. package/templates/skills/modus-agents/designer/SKILL.md +104 -92
  62. package/templates/skills/modus-agents/developer/SKILL.md +107 -66
  63. package/templates/skills/modus-agents/perf-auditor/SKILL.md +98 -61
  64. package/templates/skills/modus-agents/reviewer/SKILL.md +61 -11
  65. package/templates/skills/modus-agents/security-auditor/SKILL.md +111 -67
  66. package/templates/skills/modus-agents/skill-creator/SKILL.md +30 -12
  67. package/templates/skills/modus-agents/tester/SKILL.md +100 -54
  68. package/templates/skills/modus-auto/SKILL.md +581 -109
  69. package/templates/skills/modus-design-brief/SKILL.md +45 -19
  70. package/templates/skills/modus-harness/SKILL.md +150 -85
  71. package/templates/skills/modus-init/SKILL.md +1145 -319
  72. package/templates/skills/modus-plan/SKILL.md +125 -48
  73. package/templates/skills/modus-platform/SKILL.md +271 -0
  74. package/templates/skills/modus-spec/SKILL.md +175 -331
  75. package/templates/skills/modus-vibe/SKILL.md +256 -55
@@ -1,91 +1,216 @@
1
- # Modus Harness Schema
1
+ # Modus Harness Schema v2.0
2
2
  # 定义 /modus:harness 双 Loop 多智能体流程的产出物及调度规则
3
+ # 与 modus-harness/SKILL.md 保持完全一致(9 个 SubAgent:SA00~SA08)
4
+ # 更新时间:2026-05-18
5
+
3
6
  name: harness
4
- description: 双 Loop 多智能体 Harness — 全自动需求分析、开发、测试、评审、部署流程
7
+ version: "2.0"
8
+ description: 双 Loop 多智能体 Harness — 全自动需求分析、设计、开发、测试、评审、部署流程
9
+ schema_version: "1.1" # HANDOFF 协议版本(见 docs/protocol.md)
10
+
11
+ # 产物根目录(v3.2)
12
+ directories:
13
+ harness: "modus/stories/{story-id}/harness/"
14
+ knowledge: "modus/knowledge/"
15
+ sessions: "modus/sessions/"
5
16
 
17
+ # SubAgent 清单(SA00~SA08,共 9 个)
18
+ # 命名偏移说明:SA02(设计)对应 Skill modus-harness-01-5-design(插入在 01 和 02 之间),
19
+ # 导致后续 Skill 文件名编号比 SubAgent ID 少 1。HANDOFF agent 值以 SubAgent ID 为基准。
6
20
  subAgents:
21
+
22
+ - id: "00"
23
+ skill: modus-harness-00-skills-builder
24
+ handoff_agent: "00-skills-builder"
25
+ name: 知识注入/提取(Skills Builder)
26
+ generates:
27
+ - "Skill 文件(modus/knowledge/biz-*/SKILL.md)"
28
+ - "modus/knowledge-catalog.md"
29
+ requires: []
30
+ loop: 1
31
+ modes:
32
+ - "A: 新建 Skill"
33
+ - "B: 增量更新 Skill"
34
+ - "C: 知识批量写回"
35
+ - "D: ARCHIVE 知识提取"
36
+ notes: "INIT 阶段调用模式 B 更新知识,ARCHIVE 阶段调用模式 D 提取知识"
37
+
7
38
  - id: "01"
8
- skill: modus-analyst
39
+ skill: modus-harness-01-analysis
40
+ handoff_agent: "01-analysis"
9
41
  name: 需求分析
10
- generates: 01-analysis.md
11
- requires: []
42
+ generates: ["modus/stories/{story-id}/harness/01-analysis.md"]
43
+ requires: ["00-INIT"]
12
44
  loop: 1
45
+ gateAfter: A0 # Gate A0: 检查 01-analysis.md HANDOFF gate_status = "passed"
46
+ max_retry: 2 # Gate A0 失败时最多重入 2 次
13
47
 
14
48
  - id: "02"
15
- skill: modus-developer
16
- name: 代码开发
17
- generates: 02-sprint-contract.md
49
+ skill: modus-harness-01-5-design
50
+ handoff_agent: "02-design"
51
+ name: 设计方案生成
52
+ generates: ["modus/stories/{story-id}/harness/02-design-brief.md"]
18
53
  requires: ["01"]
19
54
  loop: 1
20
- gateAfter: compile # Gate A: 编译验证
55
+ human_checkpoint: true # 架构决策确认 ⏸️ 人工交互节点
56
+ gateAfter: A05 # Gate A0.5: 检查 02-design-brief.md HANDOFF gate_status ∈ {passed, warning}
57
+ max_retry: 2
21
58
 
22
59
  - id: "03"
23
- skill: modus-tester
24
- name: 代码测试
25
- generates: 03-test-report.md
60
+ skill: modus-harness-02-dev
61
+ handoff_agent: "03-dev"
62
+ name: 代码开发
63
+ generates: ["modus/stories/{story-id}/harness/03-sprint-contract.md"]
26
64
  requires: ["02"]
27
65
  loop: 1
28
- parallel: ["03", "04", "05"] # 04/05 并行
66
+ gateAfter: A # Gate A: 执行 constitution.build_command,exit code = 0
67
+ max_retry: 3 # Gate A 失败时最多重入 3 次(含 Loop 2 精准重入)
29
68
 
30
69
  - id: "04"
31
- skill: modus-perf-auditor
32
- name: 性能审计
33
- generates: 04-perf-report.md
34
- requires: ["02"]
70
+ skill: modus-harness-03-test
71
+ handoff_agent: "04-test"
72
+ name: 代码测试(单元测试)
73
+ generates: ["modus/stories/{story-id}/harness/04-test-report.md"]
74
+ requires: ["03"]
35
75
  loop: 1
36
- parallel: ["03", "04", "05"]
76
+ parallel: ["04", "05", "06"] # 与 SA05/SA06 并行执行
77
+ gateAfter: B # Gate B: 三份报告全部 artifact_status=complete
78
+ max_retry: 2
37
79
 
38
80
  - id: "05"
39
- skill: modus-security-auditor
40
- name: 安全审计
41
- generates: 05-security-report.md
42
- requires: ["02"]
81
+ skill: modus-harness-04-perf
82
+ handoff_agent: "05-perf"
83
+ name: 性能审计
84
+ generates: ["modus/stories/{story-id}/harness/05-perf-report.md"]
85
+ requires: ["03"]
43
86
  loop: 1
44
- parallel: ["03", "04", "05"]
87
+ parallel: ["04", "05", "06"]
88
+ gateAfter: B
89
+ max_retry: 2
45
90
 
46
91
  - id: "06"
47
- skill: modus-reviewer
48
- name: 代码评审
49
- generates: cr-report.md
50
- requires: ["03", "04", "05"] # Gate B: 等待 03/04/05 全部完成
51
- loop: 2
92
+ skill: modus-harness-05-security
93
+ handoff_agent: "06-security"
94
+ name: 安全审计
95
+ generates: ["modus/stories/{story-id}/harness/06-security-report.md"]
96
+ requires: ["03"]
97
+ loop: 1
98
+ parallel: ["04", "05", "06"]
99
+ gateAfter: B # Gate B 额外条件:安全报告无严重/高危未修复问题(强制拦截)
100
+ max_retry: 2
52
101
 
53
102
  - id: "07"
54
- skill: modus-deployer
103
+ skill: modus-harness-06-review
104
+ handoff_agent: "07-review"
105
+ name: 代码评审(CR)
106
+ generates: ["modus/stories/{story-id}/harness/cr-report.md"]
107
+ requires: ["04", "05", "06"] # Gate B 通过后触发
108
+ loop: 1 # CR 在 Loop 1 执行;Loop 2 是对 SA03 的精准重入,非 CR 重跑
109
+ gateAfter: C # Gate C: cr-report.md HANDOFF issues 为空或全为 P3
110
+
111
+ - id: "08"
112
+ skill: modus-harness-07-deploy
113
+ handoff_agent: "08-deploy"
55
114
  name: 部署发布
56
- generates: 07-deploy-status.md
57
- requires: ["06"]
58
- loop: 2
59
- gateAfter: noPnPProblems # Gate C: cr-report.md 无 P1/P2
115
+ generates: ["modus/stories/{story-id}/harness/08-deploy-status.md"]
116
+ requires: ["07"] # Gate C 通过后触发
117
+ loop: 1
118
+ human_checkpoint: true # prd 环境等待人工确认
60
119
 
120
+ # Gate 规则(强制,不可跳过)
61
121
  gates:
62
- compile:
63
- description: 编译验证
64
- condition: "项目构建工具编译,exit code = 0"
122
+ A0:
123
+ description: "需求分析质量门"
124
+ checkFile: "01-analysis.md"
125
+ checkField: "gate_status"
126
+ condition: "gate_status = \"passed\""
127
+ onFail: retrySubAgent01
128
+ maxRetry: 2
129
+
130
+ A05:
131
+ description: "设计方案确认门(Gate A0.5)"
132
+ checkFile: "02-design-brief.md"
133
+ checkField: "gate_status"
134
+ condition: "gate_status ∈ {passed, warning}"
65
135
  onFail: retrySubAgent02
66
- maxRetry: 3
136
+ maxRetry: 2
67
137
 
68
- noPnPProblems:
69
- description: 代码评审质量门
70
- condition: "cr-report.md 中 P1 和 P2 问题数量为 0"
71
- onFail: retryFromSubAgent02
138
+ A:
139
+ description: "编译验证门"
140
+ checkMethod: "execute constitution.build_command"
141
+ condition: "exit_code = 0"
142
+ onFail: retrySubAgent03
72
143
  maxRetry: 3
73
144
 
145
+ B:
146
+ description: "并行审计完成门"
147
+ checkFiles:
148
+ - "04-test-report.md"
149
+ - "05-perf-report.md"
150
+ - "06-security-report.md"
151
+ checkField: "artifact_status"
152
+ condition: "三份报告 artifact_status 均为 complete,且各 gate_status ≠ failed"
153
+ extraCondition: "06-security-report.md 中无严重/高危未修复问题(强制拦截)"
154
+ onFail: "继续等待(文件未齐);gate_status=failed 则重入对应 SubAgent(最多 2 次);超时 30 分钟上报用户"
155
+ timeout: "30m"
156
+
157
+ C:
158
+ description: "代码评审质量门"
159
+ checkFile: "cr-report.md"
160
+ checkField: "issues"
161
+ condition: "issues 数组为空,或全部 level 为 P3"
162
+ onFail: triggerLoop2
163
+ maxLoop2Retries: 3
164
+
165
+ # Loop 2 精准重入规则
74
166
  loop2:
75
- trigger: "cr-report.md 中存在 P1 或 P2 问题"
76
- action: "定位涉及的 Sprint,精准重入 SubAgent 02(非全量重跑)"
77
- rerunPath: ["02", "Gate A", "03+04+05", "06"]
78
- maxLoops: 3
79
- onMaxLoopsReached: "暂停流程,上报用户,请求人工介入"
167
+ trigger: "Gate C 失败(cr-report.md HANDOFF issues 含 P1 或 P2"
168
+ sprintLocating:
169
+ primary: "issues[].affected_sprint 字段(整数,如 Sprint 2)"
170
+ fallback: "affected_sprint 缺失或为 0 时,重跑全量 Sprint(保守策略)"
171
+ multiple: "多个 issue 指向不同 Sprint 时,取编号并集一并重跑"
172
+ rerunPath: ["03(受影响 Sprint)", "Gate A", "04+05+06(并行)", "07"]
173
+ maxRetries: 3
174
+ onMaxRetriesReached: "暂停流程,上报用户,请求人工介入,写入 .harness-state.yaml"
80
175
 
81
- finalReview:
82
- trigger: "Gate C 通过(cr-report.md 无 P1/P2)"
83
- action: "等待人工 Final Review,确认后合入主干"
176
+ # ARCHIVE 阶段(SA08 完成后触发,进入 Human Final Review 等待前执行)
177
+ archive:
178
+ trigger: "SA08 部署完成(08-deploy-status.md artifact_status=complete)"
179
+ callSubAgent: "00(模式 D:知识提取)"
180
+ sourceArtifacts:
181
+ - "01-analysis.md"
182
+ - "02-design-brief.md" # 提取架构决策 [decision] 知识
183
+ - "03-sprint-contract.md"
184
+ - "04-test-report.md"
185
+ - "05-perf-report.md"
186
+ - "06-security-report.md"
187
+ - "cr-report.md"
188
+ - "08-deploy-status.md"
189
+ knowledgeTypes:
190
+ - "[decision] - 来自 02-design-brief.md/03-sprint-contract.md 的技术选型"
191
+ - "[guideline] - 来自 08-deploy-status.md 的上线操作规范"
192
+ - "[pitfall] - 来自 cr-report.md P2/P3 和 04/05 报告高风险项"
193
+ - "[process] - 来自 01-analysis.md 的业务流程"
194
+ - "[invariant] - 来自 cr-report.md 和 01-analysis.md 的业务约束"
84
195
 
196
+ # 断点续跑状态文件
197
+ stateFile:
198
+ path: "modus/stories/{story-id}/harness/.harness-state.yaml"
199
+ fields:
200
+ story_id: "string"
201
+ loop: "integer(1 或 2)"
202
+ completed_agents: "string[](已完成的 SubAgent ID 列表)"
203
+ current_agent: "string(当前正在执行的 SubAgent,空=全部完成)"
204
+ loop2_triggers: "Issue[](Loop 2 触发的 P1/P2 问题列表)"
205
+ last_updated: "ISO 8601 时间戳"
206
+
207
+ # 超时配置
85
208
  timeout:
86
- perSubAgent: 15m
209
+ perSubAgent: "15m"
210
+ parallelGroup: "30m(SA04/05/06 并行组整体超时)"
87
211
  action: "汇报卡点,询问用户是否重试"
88
212
 
89
- directories:
90
- active: modus/plans/active
91
- archive: modus/plans/archive
213
+ # Human Final Review
214
+ finalReview:
215
+ trigger: "Gate C 通过 + ARCHIVE 完成"
216
+ action: "输出推荐 Commit Message,等待人工确认合入主干"
@@ -4,6 +4,49 @@
4
4
  name: knowledge
5
5
  description: 知识体系 schema — 知识目录索引、Skill frontmatter、知识条目类型
6
6
 
7
+ # ─────────────────────────────────────────
8
+ # config.yaml scanRules 结构
9
+ # ─────────────────────────────────────────
10
+ scan_rules:
11
+ description: |
12
+ /modus:init Step 2 执行代码扫描时的规则配置,遵循公式:
13
+ 最终扫描文件 = (include_extensions 匹配的文件) - (exclude_patterns 排除的路径)
14
+ 各规则来源叠加计算(类似 .gitignore 的分层覆盖机制)。
15
+ location: "modus/config.yaml → scanRules 字段"
16
+ fields:
17
+ - name: include_extensions
18
+ type: list[string]
19
+ description: 要扫描的文件后缀名列表。默认值覆盖主流后端/前端语言。
20
+ default: [".java", ".kt", ".py", ".ts", ".tsx", ".js", ".go", ".rs", ".php", ".rb", ".swift", ".scala"]
21
+
22
+ - name: exclude_patterns
23
+ type: list[string]
24
+ description: |
25
+ glob 格式的排除模式,支持 ** 通配符。
26
+ 默认已排除:构建产物(target/、build/、dist/)、IDE 配置(.idea/、.vscode/)、
27
+ 依赖目录(node_modules/)、生成代码(generated/、*Generated.java)。
28
+ 用户可在 config.yaml 中追加项目特有的排除模式。
29
+ default:
30
+ - "target/**"
31
+ - "build/**"
32
+ - "dist/**"
33
+ - "node_modules/**"
34
+ - ".idea/**"
35
+ - ".vscode/**"
36
+ - "generated/**"
37
+ - "**/*Generated.java"
38
+ - "*.lock"
39
+
40
+ - name: include_paths
41
+ type: list[string]
42
+ required: false
43
+ description: 额外需要扫描的目录,默认扫描项目 src/ 下全部内容。用于将 plugins/、extensions/ 等非标准目录纳入扫描。
44
+
45
+ - name: exclude_domain_patterns
46
+ type: list[string]
47
+ required: false
48
+ description: 强制排除的包名 glob 模式(如 "com.example.legacy.**"),用于将不希望被 modus 管理的历史代码排除在域识别之外。
49
+
7
50
  # ─────────────────────────────────────────
8
51
  # knowledge-catalog.md 结构
9
52
  # ─────────────────────────────────────────
@@ -94,6 +137,38 @@ skill_frontmatter:
94
137
  description: 知识层级(仅 team-conventions 和 tech-wiki 需要填写)
95
138
  values: ["0-T", "1"]
96
139
 
140
+ - name: upstream_skills
141
+ type: list
142
+ required: false
143
+ description: |
144
+ 本 Skill 依赖的上游 Skill 列表(仅填写直接依赖,不递归填写传递依赖)。
145
+ 当上游 Skill 的 last_hash 发生变化或 maturity 降级时,本 Skill 的 stale_cascade 自动置为 true。
146
+ 格式:["modus-biz-order", "modus-biz-user"]
147
+ default: []
148
+
149
+ - name: stale_cascade
150
+ type: boolean
151
+ required: false
152
+ description: |
153
+ 联动失效标记。当任一 upstream_skills 中的 Skill 发生 hash 变更或 maturity 降级时,
154
+ 由 vibe/plan 的防腐机制自动将此字段置为 true。
155
+ 置为 true 后,引用本 Skill 前须先执行 /modus:refresh 验证依赖链是否仍然有效,
156
+ 确认无误后由 skill-creator 模式 B 将此字段重置为 false。
157
+ default: false
158
+
159
+ - name: external_deps
160
+ type: map
161
+ required: false
162
+ description: |
163
+ 本 Skill 的规范依赖外部库的版本范围。当 pom.xml / package.json 中对应库发生
164
+ 跨大版本升级(major version 变化)时,自动触发 stale 降级。
165
+ 格式:key 为库名,value 为 semver 范围(如 "~2.7"、">=3.0 <4.0")
166
+ example:
167
+ spring-boot: "~2.7"
168
+ mybatis-plus: ">=3.5"
169
+ dubbo: "~3.1"
170
+ default: {}
171
+
97
172
  # ─────────────────────────────────────────
98
173
  # 知识条目类型(五类 MECE)
99
174
  # ─────────────────────────────────────────
@@ -147,10 +222,45 @@ maturity_lifecycle:
147
222
  verified_decay:
148
223
  condition: "verified 且距 last_referenced 超过 6 个月"
149
224
  action: "降为 draft,追加注释 ⚠️ 6个月未引用,可能已过时"
225
+ upstream_cascade_decay:
226
+ condition: "upstream_skills 中任一 Skill 的 last_hash 发生变化,或其 maturity 降级"
227
+ action: "将本 Skill 的 stale_cascade 置为 true,在 knowledge-catalog 中标注 ⚠️ 上游变更待验证"
228
+ external_dep_decay:
229
+ condition: "pom.xml 或 package.json 中,external_deps 里某库的 major version 发生变化"
230
+ action: "将本 Skill maturity 降为 stale,追加注释 ⚠️ 外部依赖 {lib} 升级({old} → {new}),规范需验证"
150
231
 
151
232
  decay_check_trigger:
152
- - "00-skills-builder 模式 D 执行时"
233
+ - "modus-skill-creator(SubAgent 00)模式 D 执行时"
153
234
  - "可手动触发:/modus:init --lint"
235
+ - "vibe/plan Step 3 防腐检查时(仅检查 stale_cascade,不全量扫描)"
236
+ - "modus-init 执行后自动扫描 pom.xml/package.json 版本变化触发 external_dep_decay"
237
+
238
+ # ─────────────────────────────────────────
239
+ # external_deps 自动提取规范
240
+ # ─────────────────────────────────────────
241
+ external_deps_extraction:
242
+ description: |
243
+ /modus:init 生成 Skill 时,自动从构建文件中提取该域依赖的外部库版本,
244
+ 写入 Skill frontmatter 的 external_deps 字段。
245
+ source_files:
246
+ java: "pom.xml(根目录 + 各 module 级别)"
247
+ node: "package.json(各包目录)"
248
+ python: "pyproject.toml / requirements.txt"
249
+ extraction_logic: |
250
+ 1. 扫描该域 key_files 中的 import/require 语句
251
+ 2. 提取引用了 pom.xml/package.json 中声明的第三方库(排除标准库)
252
+ 3. 按引用频次排序,取前 5 个高频库
253
+ 4. 从构建文件中读取对应库的当前版本,转为 semver 范围(固定 major.minor,不锁 patch)
254
+ 5. 写入 frontmatter: external_deps: {lib: version-range}
255
+ version_range_format:
256
+ example_input: "spring-boot-starter 2.7.14"
257
+ example_output: "spring-boot: \"~2.7\""
258
+ rule: "major.minor 相同则用 ~minor,跨 minor 用 >=min <max"
259
+ decay_detection: |
260
+ modus update / /modus:init --lint 执行时:
261
+ 1. 重新读取 pom.xml/package.json 中 external_deps 列出的库的当前版本
262
+ 2. 比对 major version:若发生变化(如 2.x → 3.x),触发 external_dep_decay
263
+ 3. 将受影响的 Skill 降级为 stale,在 knowledge-catalog 中标注 ⚠️
154
264
 
155
265
  # ─────────────────────────────────────────
156
266
  # HANDOFF 块格式(Harness 产物交接协议)
@@ -9,6 +9,6 @@ enabled: true
9
9
 
10
10
  读取并严格遵循 `.codebuddy/skills/modus-analyst/SKILL.md` 中的执行规范。
11
11
 
12
- 产出物路径:`modus/plans/active/{story-id}/01-analysis.md`
12
+ 产出物路径:`modus/stories/{story-id}/harness/01-analysis.md`
13
13
 
14
14
  产出物头部必须包含 HANDOFF 块,包含 `agent`、`story_id`、`domains`、`risk_level`、`key_constraints`、`skill_refs`、`gate_status` 字段。
@@ -0,0 +1,165 @@
1
+ # Modus Behavior Guard
2
+
3
+ > 安装位置:`modus/behavior-guard.md`(由 `/modus:init` 创建)
4
+ > 加载时机:所有 Modus 命令 Step 0 读取,与 `modus/config.yaml` 同级
5
+ > 来源:直接借鉴 [Andrej Karpathy's LLM coding guidelines](https://x.com/karpathy/status/2015883857489522876),适配 Modus/Java 上下文
6
+
7
+ ---
8
+
9
+ 这是对所有 Modus SubAgent 生效的**全局行为约束**。优先级低于 `constitution.hard_rules`(项目技术规则),高于任何 Skill 中的建议。
10
+
11
+ **权衡声明:** 这些原则偏向谨慎而非速度。对于显然的单步操作,使用判断力。
12
+
13
+ ---
14
+
15
+ ## 1. Think Before Coding
16
+
17
+ **不假设。不隐藏困惑。暴露权衡。**
18
+
19
+ 开始实现前:
20
+ - 明确说出你的假设。如果不确定,问。
21
+ - 如果存在多种解读,呈现它们,不要静默选择。
22
+ - 如果有更简单的方案,说出来。该推回时推回。
23
+ - 如果有不清楚的地方,停下来。说明困惑是什么。问。
24
+
25
+ **modus 场景示例:**
26
+
27
+ ❌ 错误:直接按猜测的域开始生成代码
28
+ ✅ 正确:`[已匹配 order 域 · 置信度 92%]` → 继续;或展示候选列表等待确认
29
+
30
+ ❌ 错误:用户说「做个导出功能」,直接生成完整导出模块
31
+ ✅ 正确:
32
+ ```
33
+ 「导出功能」可能意味着:
34
+ A. 接口返回分页 JSON(最简,当前 Skill 中无导出相关记录)
35
+ B. 后台任务生成文件+邮件通知(需新 MQ Topic)
36
+ C. 前端直接下载 CSV(需 Facade 层新接口)
37
+ 哪种更符合你的期望?
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 2. Simplicity First
43
+
44
+ **最少代码解决问题。没有投机性内容。**
45
+
46
+ - 不实现未被要求的功能。
47
+ - 单次使用的代码不抽象。
48
+ - 未被要求的"灵活性"或"可配置性"不加。
49
+ - 不可能发生的场景不做错误处理。
50
+ - 如果写了 200 行但 50 行能做到,重写。
51
+
52
+ 自我检验:「资深工程师会说这过于复杂吗?」如果是,简化。
53
+
54
+ **modus 场景示例:**
55
+
56
+ ❌ 错误:用户说「加个状态校验」,生成了 Strategy 模式 + 枚举工厂 + 抽象类体系
57
+ ✅ 正确:在 Service 方法头加一行 `if (!order.canTransit(targetStatus)) throw new BizException(...);`
58
+
59
+ ❌ 错误:modus-init 对 50 个文件的项目也跑 5 轮全量扫描 + SubAgent 并行
60
+ ✅ 正确:先读目录结构,按实际发现的域数量决定深度
61
+
62
+ ---
63
+
64
+ ## 3. Surgical Changes
65
+
66
+ **只动必须动的地方。只清理自己的垃圾。**
67
+
68
+ 修改已有代码时:
69
+ - 不「顺手优化」相邻代码、注释或格式。
70
+ - 不重构未损坏的东西。
71
+ - 匹配现有代码风格,即使你会选择不同方式。
72
+ - 发现无关的死代码,提及——不删除。
73
+
74
+ 你的改动产生孤儿时:
75
+ - 删除**你的改动**让其变得无用的 import/变量/方法。
76
+ - 不删除原本就存在的死代码,除非被要求。
77
+
78
+ 检验标准:每一行改动都必须能追溯到用户的请求。
79
+
80
+ **modus 场景示例:**
81
+
82
+ ❌ 错误:用户让修一个 NPE bug,顺便把整个方法改成 Optional 链式 + 加了 log + 补了注释
83
+ ✅ 正确:只加 `if (order == null) throw new BizException(ORDER_NOT_FOUND);`,其余不动
84
+
85
+ ❌ 错误:vibe 编码完成后自动更新 Skill 文件(用户没要求更新文档)
86
+ ✅ 正确:缓冲到 pending-knowledge.yaml,等 git commit 时统一沉淀
87
+
88
+ ---
89
+
90
+ ## 4. Goal-Driven Execution
91
+
92
+ **定义成功标准。循环直到验证通过。**
93
+
94
+ 将任务转化为可验证的目标:
95
+ - 「加个校验」→「为无效输入写测试,然后让测试通过」
96
+ - 「修这个 bug」→「写出能复现的测试,然后让它通过」
97
+ - 「重构 X」→「确保重构前后测试都通过」
98
+
99
+ 多步骤任务,先陈述简短计划:
100
+ ```
101
+ 1. [步骤] → 验证:[检查项]
102
+ 2. [步骤] → 验证:[检查项]
103
+ 3. [步骤] → 验证:[检查项]
104
+ ```
105
+
106
+ 强成功标准让 Agent 独立循环完成。弱标准(「让它能跑」)需要反复澄清。
107
+
108
+ **modus 场景示例:**
109
+
110
+ ❌ 错误:`/modus:vibe 加批量审批` → 直接开始写代码,没有说明"完成"意味着什么
111
+ ✅ 正确:
112
+ ```
113
+ 任务目标:实现批量审批接口,支持最多 50 条订单同时审批
114
+ 完成标准:
115
+ · mvn test -Dtest=BatchApproveServiceTest 通过
116
+ · 并发场景下不产生重复审批(分布式锁验证)
117
+ · 影响范围:仅 OrderService + OrderFacade,不触及其他文件
118
+ ```
119
+
120
+ ---
121
+
122
+ ---
123
+
124
+ ## 5. Token Budget Guard
125
+
126
+ **有意识地使用 token。大操作前声明预算。**
127
+
128
+ Token 是 AI 工作流的核心成本约束。每次命令执行前,应在内部估算本次的 token 消耗范围,避免不必要的全量加载。
129
+
130
+ **Modus 各步骤 token 预算参考:**
131
+
132
+ | 操作 | 估算 token | 说明 |
133
+ |------|-----------|------|
134
+ | Level 1:读 knowledge-catalog | ~200 | 仅目录索引,所有命令必须执行 |
135
+ | Level 2:读 1 个业务 Skill | ~3,000 | 按需加载,不相关的域不读 |
136
+ | Level 3:读 1 个实际代码文件 | ~500–2,000 | 仅在编码时按需读取 |
137
+ | 全量加载(8 个业务 Skill) | ~24,000 | 应避免——三级加载 vs 全量差约 **10×** |
138
+ | behavior-guard + config.yaml | ~500 | Step 0 固定成本 |
139
+ | Design Brief(Simple) | ~200 | 内联生成,不读额外文件 |
140
+ | Design Brief(Medium/Complex) | ~1,000 | 调用 design-brief Skill |
141
+
142
+ **决策规则:**
143
+ - 若任务只涉及 1 个域 → 只读该域 Skill(Level 2 成本 = ~3,000 tokens)
144
+ - 若置信度 < 85% 涉及多域 → 先确认再加载,不预先全量加载
145
+ - 若 Skill 已加载但任务无关 → 不重复读取,复用上下文中已有的内容
146
+
147
+ 自我检验:「本次操作有没有读了不必要的文件?」如果有,下次先匹配域再加载。
148
+
149
+ **modus 场景示例:**
150
+
151
+ ❌ 错误:vibe 任务只涉及 order 域,但读了全部 8 个业务 Skill(~24,000 tokens)
152
+ ✅ 正确:Level 1 读目录 → 匹配 order 域 → Level 2 仅读 order Skill(~3,200 tokens)
153
+
154
+ ❌ 错误:连续 3 次 vibe 都重新读 behavior-guard.md 和 config.yaml
155
+ ✅ 正确:同一 session 中,Step 0 内容已在上下文,不重复读取
156
+
157
+ ---
158
+
159
+ ## 这些原则生效时的表现
160
+
161
+ - **diff 中没有多余改动** — 只有被请求的变更
162
+ - **第一次就写简单代码** — 不因过度设计而返工
163
+ - **澄清问题在实现前提出** — 不是在出错后
164
+ - **干净的 PR,没有顺手重构** — 每行改动都有来源
165
+ - **token 消耗在合理范围** — 三级加载优于全量加载,同 session 不重复读取