@liangjie559567/ultrapower 5.0.21 → 5.0.23

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 (49) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/commands/ax-analyze-error.md +0 -1
  3. package/commands/ax-context.md +0 -1
  4. package/commands/ax-decompose.md +0 -1
  5. package/commands/ax-draft.md +0 -1
  6. package/commands/ax-evolution.md +0 -1
  7. package/commands/ax-evolve.md +0 -1
  8. package/commands/ax-export.md +0 -1
  9. package/commands/ax-implement.md +0 -1
  10. package/commands/ax-knowledge.md +0 -1
  11. package/commands/ax-reflect.md +0 -1
  12. package/commands/ax-review.md +0 -1
  13. package/commands/ax-rollback.md +0 -1
  14. package/commands/ax-status.md +0 -1
  15. package/commands/ax-suspend.md +0 -1
  16. package/commands/brainstorm.md +0 -1
  17. package/commands/execute-plan.md +0 -1
  18. package/commands/write-plan.md +0 -1
  19. package/dist/__tests__/validateMode.test.d.ts +2 -0
  20. package/dist/__tests__/validateMode.test.d.ts.map +1 -0
  21. package/dist/__tests__/validateMode.test.js +100 -0
  22. package/dist/__tests__/validateMode.test.js.map +1 -0
  23. package/dist/lib/validateMode.d.ts +49 -0
  24. package/dist/lib/validateMode.d.ts.map +1 -0
  25. package/dist/lib/validateMode.js +68 -0
  26. package/dist/lib/validateMode.js.map +1 -0
  27. package/docs/CLAUDE.md +1 -1
  28. package/docs/prd/ultrapower-standards-draft.md +191 -0
  29. package/docs/prd/ultrapower-standards-rough.md +560 -0
  30. package/docs/reviews/ultrapower-standards/review_critic.md +230 -0
  31. package/docs/reviews/ultrapower-standards/review_domain.md +243 -0
  32. package/docs/reviews/ultrapower-standards/review_product.md +102 -0
  33. package/docs/reviews/ultrapower-standards/review_tech.md +142 -0
  34. package/docs/reviews/ultrapower-standards/review_ux.md +110 -0
  35. package/docs/reviews/ultrapower-standards/summary.md +85 -0
  36. package/docs/standards/README.md +85 -0
  37. package/docs/standards/agent-lifecycle.md +445 -0
  38. package/docs/standards/anti-patterns.md +365 -0
  39. package/docs/standards/audit-report.md +388 -0
  40. package/docs/standards/contribution-guide.md +208 -0
  41. package/docs/standards/hook-execution-order.md +320 -0
  42. package/docs/standards/runtime-protection.md +336 -0
  43. package/docs/standards/state-machine.md +316 -0
  44. package/docs/standards/templates/agent-template.md +63 -0
  45. package/docs/standards/templates/hook-template.md +74 -0
  46. package/docs/standards/templates/skill-template.md +48 -0
  47. package/docs/standards/user-guide.md +290 -0
  48. package/docs/tasks/ultrapower-standards/manifest.md +441 -0
  49. package/package.json +1 -1
@@ -0,0 +1,365 @@
1
+ # 反模式清单
2
+
3
+ > **ultrapower-version**: 5.0.21
4
+ > **优先级**: P0(必须遵守)
5
+ > **真理之源**: `docs/standards/audit-report.md`
6
+ > **覆盖范围**: T-09(已知反模式 + 正确替代方案)
7
+
8
+ ---
9
+
10
+ ## 目录
11
+
12
+ 1. [安全反模式](#1-安全反模式)
13
+ 2. [状态管理反模式](#2-状态管理反模式)
14
+ 3. [Agent 生命周期反模式](#3-agent-生命周期反模式)
15
+ 4. [并发反模式](#4-并发反模式)
16
+ 5. [模式路由反模式](#5-模式路由反模式)
17
+ 6. [测试反模式](#6-测试反模式)
18
+
19
+ ---
20
+
21
+ ## 1. 安全反模式
22
+
23
+ ### AP-S01:未校验 mode 参数直接拼接路径
24
+
25
+ **来源**:`docs/standards/runtime-protection.md` §2.4
26
+
27
+ ```typescript
28
+ // ❌ 反模式:路径遍历风险
29
+ const stateFilePath = `.omc/state/${mode}-state.json`;
30
+ // 攻击者可传入 mode = "../../etc/passwd" 读取任意文件
31
+ ```
32
+
33
+ ```typescript
34
+ // ✅ 正确:先校验再拼接
35
+ import { assertValidMode } from '../lib/validateMode';
36
+ const validMode = assertValidMode(mode);
37
+ const stateFilePath = `.omc/state/${validMode}-state.json`;
38
+ ```
39
+
40
+ **规则**:所有使用 mode 参数构建文件路径的代码,必须先调用 `assertValidMode()` 或 `validateMode()`。
41
+
42
+ ---
43
+
44
+ ### AP-S02:直接读取 SubagentStopInput.success
45
+
46
+ **来源**:`docs/standards/agent-lifecycle.md` §2
47
+
48
+ ```typescript
49
+ // ❌ 反模式:SDK 不提供此字段,始终为 undefined
50
+ const succeeded = input.success; // undefined → falsy → 错误地标记为失败
51
+ const succeeded = Boolean(input.success); // undefined → false → 同上
52
+ ```
53
+
54
+ ```typescript
55
+ // ✅ 正确:使用推断机制
56
+ // SDK does not provide success field; treat undefined as success
57
+ const succeeded = input.success !== false;
58
+ ```
59
+
60
+ **规则**:`SubagentStopInput.success` 已标记为 `@deprecated`,禁止直接读取。
61
+
62
+ ---
63
+
64
+ ### AP-S03:在状态文件中存储敏感信息
65
+
66
+ ```typescript
67
+ // ❌ 反模式:状态文件可能被其他进程读取
68
+ state_write(mode="autopilot", {
69
+ api_key: "sk-...",
70
+ user_token: "Bearer ...",
71
+ });
72
+ ```
73
+
74
+ ```typescript
75
+ // ✅ 正确:状态文件只存储执行状态,不存储凭证
76
+ state_write(mode="autopilot", {
77
+ current_phase: "executing",
78
+ task_id: "task-123",
79
+ active: true,
80
+ });
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 2. 状态管理反模式
86
+
87
+ ### AP-ST01:混淆两种 stale 阈值
88
+
89
+ **来源**:`docs/standards/state-machine.md` §4(差异点 D-09)
90
+
91
+ ```typescript
92
+ // ❌ 反模式:将 agent stale 阈值用于 mode stale 检测
93
+ const STALE_THRESHOLD_MS = 5 * 60 * 1000; // 5 分钟
94
+ if (Date.now() - modeState.last_updated > STALE_THRESHOLD_MS) {
95
+ // 错误:mode stale 阈值应为 1 小时,不是 5 分钟
96
+ cleanupModeState();
97
+ }
98
+ ```
99
+
100
+ ```typescript
101
+ // ✅ 正确:区分两种阈值
102
+ // Agent stale(subagent-tracker):5 分钟
103
+ const STALE_THRESHOLD_MS = 5 * 60 * 1000;
104
+
105
+ // Mode stale marker(mode-registry):1 小时
106
+ const STALE_MARKER_THRESHOLD = 60 * 60 * 1000;
107
+ ```
108
+
109
+ **规则**:两种 stale 阈值含义不同,不得混用。详见 `docs/standards/state-machine.md` §4。
110
+
111
+ ---
112
+
113
+ ### AP-ST02:跨会话误清理状态文件
114
+
115
+ **来源**:`docs/standards/agent-lifecycle.md` §3.3(修复 issue #573)
116
+
117
+ ```typescript
118
+ // ❌ 反模式:无条件清理所有活跃状态
119
+ for (const stateFile of activeStateFiles) {
120
+ fs.unlinkSync(stateFile); // 可能删除其他并发会话的状态
121
+ }
122
+ ```
123
+
124
+ ```typescript
125
+ // ✅ 正确:检查 session_id 匹配
126
+ const stateSessionId = state.session_id as string | undefined;
127
+ if (!sessionId || !stateSessionId || stateSessionId === sessionId) {
128
+ fs.unlinkSync(localPath); // 只清理匹配当前会话的状态
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ### AP-ST03:在 `~/.claude/` 中存储 OMC 状态
135
+
136
+ ```
137
+ // ❌ 反模式:状态存储在全局目录
138
+ ~/.claude/state/autopilot-state.json
139
+
140
+ // ✅ 正确:状态存储在 worktree 根目录
141
+ {worktree}/.omc/state/autopilot-state.json
142
+ ```
143
+
144
+ **规则**:所有 OMC 状态必须存储在 git worktree 根目录的 `.omc/state/` 下,不在 `~/.claude/`。
145
+
146
+ ---
147
+
148
+ ## 3. Agent 生命周期反模式
149
+
150
+ ### AP-AL01:向孤儿 Agent 发送 SHUTDOWN 信号
151
+
152
+ **来源**:`docs/standards/agent-lifecycle.md` §3.2
153
+
154
+ ```typescript
155
+ // ❌ 反模式:逐个向孤儿 agent 发送信号(session-end hook 不这样做)
156
+ for (const orphanAgent of orphanAgents) {
157
+ sendShutdownSignal(orphanAgent.agent_id); // 错误:批量清除,非逐个信号
158
+ }
159
+ ```
160
+
161
+ ```typescript
162
+ // ✅ 正确:批量清除 tracking 文件
163
+ function cleanupTransientState(directory: string): number {
164
+ const trackingPath = path.join(directory, '.omc', 'state', 'subagent-tracking.json');
165
+ if (fs.existsSync(trackingPath)) {
166
+ fs.unlinkSync(trackingPath); // 批量清除所有 agent 记录
167
+ }
168
+ }
169
+ ```
170
+
171
+ ---
172
+
173
+ ### AP-AL02:混淆超时阈值(5 分钟 vs 10 分钟)
174
+
175
+ **来源**:`docs/standards/agent-lifecycle.md` §1.1(差异点 D-08)
176
+
177
+ ```typescript
178
+ // ❌ 反模式:将 stale 检测阈值用于自动终止
179
+ if (elapsed > 5) { // 5 分钟
180
+ autoKillAgent(); // 错误:5 分钟只触发警告,不自动终止
181
+ }
182
+ ```
183
+
184
+ ```typescript
185
+ // ✅ 正确:区分两个阈值
186
+ if (elapsed > 5) {
187
+ // 触发警告(stale 检测)
188
+ interventions.push({ type: "timeout", auto_execute: false });
189
+ }
190
+ if (elapsed > 10) {
191
+ // 自动终止(10 分钟阈值)
192
+ interventions.push({ type: "timeout", auto_execute: true });
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ### AP-AL03:实现死锁检测但忽略 DEADLOCK_CHECK_THRESHOLD
199
+
200
+ **来源**:`docs/standards/agent-lifecycle.md` §1.4(差异点 D-10)
201
+
202
+ ```typescript
203
+ // ❌ 反模式:硬编码死锁阈值
204
+ if (mutuallyWaitingAgents.length >= 2) { // 错误:应使用常量
205
+ triggerDeadlockIntervention();
206
+ }
207
+ ```
208
+
209
+ ```typescript
210
+ // ✅ 正确:使用已定义的常量
211
+ export const DEADLOCK_CHECK_THRESHOLD = 3;
212
+ if (mutuallyWaitingAgents.length >= DEADLOCK_CHECK_THRESHOLD) {
213
+ triggerDeadlockIntervention();
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## 4. 并发反模式
220
+
221
+ ### AP-C01:绕过原子写入保护
222
+
223
+ **来源**:`docs/standards/agent-lifecycle.md` §6.3(差异点 D-07,已知技术债务 TD-4)
224
+
225
+ ```typescript
226
+ // ❌ 反模式:直接写入,无原子保护(当前 writeTrackingStateImmediate 的已知问题)
227
+ writeFileSync(statePath, JSON.stringify(state, null, 2), "utf-8");
228
+ // 风险:并发写入可能导致文件损坏
229
+ ```
230
+
231
+ ```typescript
232
+ // ✅ 正确(v2 目标):使用原子写入
233
+ atomicWriteJsonSync(statePath, state);
234
+ // 通过临时文件 + rename 保证原子性
235
+ ```
236
+
237
+ **注意**:`writeTrackingStateImmediate()` 当前使用直接写入(TD-4),v2 目标统一为 `atomicWriteJsonSync`。
238
+
239
+ ---
240
+
241
+ ### AP-C02:不使用防抖直接写入高频状态
242
+
243
+ ```typescript
244
+ // ❌ 反模式:每次工具调用都立即写入
245
+ onToolCall(() => {
246
+ writeTrackingState(directory, state); // 高频写入,性能问题
247
+ });
248
+ ```
249
+
250
+ ```typescript
251
+ // ✅ 正确:使用防抖合并写入
252
+ const WRITE_DEBOUNCE_MS = 100;
253
+ const debouncedWrite = debounce(writeTrackingState, WRITE_DEBOUNCE_MS);
254
+ onToolCall(() => {
255
+ debouncedWrite(directory, state);
256
+ });
257
+ ```
258
+
259
+ ---
260
+
261
+ ## 5. 模式路由反模式
262
+
263
+ ### AP-MR01:将 autopilot 与 ultrapilot 同时激活
264
+
265
+ **来源**:`docs/standards/state-machine.md` §5(差异点 D-04)
266
+
267
+ ```typescript
268
+ // ❌ 反模式:同时激活互斥模式
269
+ activateMode('autopilot');
270
+ activateMode('ultrapilot'); // 错误:两者互斥
271
+ ```
272
+
273
+ ```typescript
274
+ // ✅ 正确:检查互斥冲突
275
+ const EXCLUSIVE_MODES = ['autopilot', 'ultrapilot', 'swarm', 'pipeline'];
276
+ if (checkExclusiveConflict(newMode)) {
277
+ throw new Error(`Mode ${newMode} conflicts with active exclusive mode`);
278
+ }
279
+ ```
280
+
281
+ **互斥模式完整列表**:`autopilot`、`ultrapilot`、`swarm`、`pipeline`(共 4 个,非 PRD 原描述的 2 个)。
282
+
283
+ ---
284
+
285
+ ### AP-MR02:使用不在白名单中的 mode 字符串
286
+
287
+ ```typescript
288
+ // ❌ 反模式:使用未定义的 mode
289
+ state_write(mode="custom-mode", { ... }); // 错误:不在 VALID_MODES 中
290
+
291
+ // ❌ 反模式:大小写错误
292
+ state_write(mode="AUTOPILOT", { ... }); // 错误:大小写敏感
293
+ ```
294
+
295
+ ```typescript
296
+ // ✅ 正确:只使用 VALID_MODES 中的 8 个值
297
+ // 'autopilot' | 'ultrapilot' | 'team' | 'pipeline' |
298
+ // 'ralph' | 'ultrawork' | 'ultraqa' | 'swarm'
299
+ state_write(mode="autopilot", { ... });
300
+ ```
301
+
302
+ ---
303
+
304
+ ## 6. 测试反模式
305
+
306
+ ### AP-T01:测试文件放在错误目录
307
+
308
+ ```
309
+ // ❌ 反模式:测试文件与源文件混放
310
+ src/lib/validateMode.ts
311
+ src/lib/validateMode.test.ts // 错误:应在 __tests__ 目录
312
+
313
+ // ✅ 正确:测试文件统一放在 src/__tests__/
314
+ src/lib/validateMode.ts
315
+ src/__tests__/validateMode.test.ts
316
+ ```
317
+
318
+ ---
319
+
320
+ ### AP-T02:测试中使用错误的导入路径
321
+
322
+ ```typescript
323
+ // ❌ 反模式:路径层级错误
324
+ // 文件位于 src/__tests__/validateMode.test.ts
325
+ import { validateMode } from '../../lib/validateMode'; // 错误:多了一层 ../
326
+
327
+ // ✅ 正确:从 src/__tests__/ 到 src/lib/ 只需一层
328
+ import { validateMode } from '../lib/validateMode';
329
+ ```
330
+
331
+ ---
332
+
333
+ ### AP-T03:不测试非字符串类型输入
334
+
335
+ ```typescript
336
+ // ❌ 反模式:只测试字符串输入
337
+ it('should validate mode', () => {
338
+ expect(validateMode('autopilot')).toBe(true);
339
+ expect(validateMode('unknown')).toBe(false);
340
+ // 缺少非字符串类型测试
341
+ });
342
+ ```
343
+
344
+ ```typescript
345
+ // ✅ 正确:测试所有边界情况
346
+ it('should return false for non-string types', () => {
347
+ expect(validateMode(null)).toBe(false);
348
+ expect(validateMode(undefined)).toBe(false);
349
+ expect(validateMode(42)).toBe(false);
350
+ expect(validateMode(undefined)).toBe(false);
351
+ expect(validateMode([])).toBe(false);
352
+ });
353
+ ```
354
+
355
+ ---
356
+
357
+ ## 差异点索引
358
+
359
+ | 差异点 | 相关反模式 | 详细说明 |
360
+ |--------|-----------|---------|
361
+ | D-04 | AP-MR01 | 互斥模式为 4 个,非 PRD 原描述的 2 个 |
362
+ | D-07 | AP-C01 | writeTrackingStateImmediate 绕过原子保护(TD-4) |
363
+ | D-08 | AP-AL02 | 超时阈值:5 分钟(stale)vs 10 分钟(自动终止) |
364
+ | D-09 | AP-ST01 | stale 阈值:agent(5 分钟)vs mode(1 小时) |
365
+ | D-10 | AP-AL03 | DEADLOCK_CHECK_THRESHOLD 已定义但未使用 |