@accelerator-mzq/forge 3.0.0 → 3.1.1
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.
- package/README.md +12 -12
- package/dist/cli/commands/ack.d.ts.map +1 -1
- package/dist/cli/commands/ack.js +87 -12
- package/dist/cli/commands/ack.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/core/ack/marker-ack.d.ts +28 -0
- package/dist/core/ack/marker-ack.d.ts.map +1 -0
- package/dist/core/ack/marker-ack.js +155 -0
- package/dist/core/ack/marker-ack.js.map +1 -0
- package/dist/core/ack-log.d.ts.map +1 -1
- package/dist/core/ack-log.js +10 -7
- package/dist/core/ack-log.js.map +1 -1
- package/dist/core/archive/pause-decisions-fence.js +12 -12
- package/dist/core/archive/pause-decisions-fence.js.map +1 -1
- package/dist/core/markers/types.d.ts +2 -2
- package/dist/core/markers/types.d.ts.map +1 -1
- package/dist/core/templates/commands/ack-confirm.md +1 -1
- package/dist/core/templates/commands/apply.md +3 -3
- package/dist/core/templates/skills/_shared/tier23-command-bridge.md +34 -0
- package/dist/core/templates/skills/exploring.md +3 -3
- package/dist/core/templates/skills/finishing-a-development-branch.md +6 -21
- package/dist/core/templates/skills/requesting-code-review.md +11 -0
- package/dist/core/templates/skills/subagent-driven-development.md +9 -0
- package/dist/core/templates/skills/using-forge.md +6 -6
- package/dist/core/templates/skills/verification-before-completion.md +7 -18
- package/dist/core/templates/skills/writing-plans.md +6 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/package.json +22 -19
- package/scripts/codex-review-helper.mjs +337 -0
- package/src/core/codex-review/prompts/adversarial-default.md +105 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// scripts/codex-review-helper.mjs
|
|
3
|
+
//
|
|
4
|
+
// B-full wrapper helper — harness-agnostic.
|
|
5
|
+
//
|
|
6
|
+
// 子命令:
|
|
7
|
+
// build-prompt
|
|
8
|
+
// --template <path> 显式模板路径(优先级最高)
|
|
9
|
+
// --output <path> 输出路径(必填)
|
|
10
|
+
// --user-focus <text> 替换 {{USER_FOCUS}}(可选)
|
|
11
|
+
// --target-label <text> 替换 {{TARGET_LABEL}}(可选)
|
|
12
|
+
// --stage <s> 阶段名(与 --mode 组合自动定位模板,可选)
|
|
13
|
+
// --mode <m> 模式名(与 --stage 组合,可选)
|
|
14
|
+
//
|
|
15
|
+
// 模板解析优先级:
|
|
16
|
+
// 1. --template 显式传入 → 直接用
|
|
17
|
+
// 2. --stage + --mode → src/core/codex-review/prompts/<stage>-<mode>.md
|
|
18
|
+
// 3. fallback → src/core/codex-review/prompts/adversarial-default.md
|
|
19
|
+
//
|
|
20
|
+
// run
|
|
21
|
+
// --prompt-file <path> prompt 文件路径
|
|
22
|
+
// --output-log <path> 日志输出路径(可选)
|
|
23
|
+
// --mode <m> dispatch 模式(可选)
|
|
24
|
+
// code-review → spawn `codex review`(不需要 prompt-file)
|
|
25
|
+
// adversarial → spawn `codex exec` + stdin prompt(默认行为)
|
|
26
|
+
// rescue → 同 adversarial(v1 stub,同代码路径)
|
|
27
|
+
// (缺省) → 同 adversarial(向后兼容)
|
|
28
|
+
// --thread-id <id> resume session id(可选);
|
|
29
|
+
// adversarial/rescue 模式下: codex exec resume <id> + stdin
|
|
30
|
+
// code-review 模式下:codex review 无 resume 支持,忽略此参数(见代码注释)
|
|
31
|
+
//
|
|
32
|
+
// harness-agnostic:
|
|
33
|
+
// 不依赖 ${CLAUDE_PLUGIN_ROOT} / ${FORGE_PLUGIN_ROOT};所有路径通过 CLI 参数传入。
|
|
34
|
+
// Repo root 从 import.meta.url 推导。
|
|
35
|
+
//
|
|
36
|
+
// Windows 兼容:spawn 加 shell:true — codex 是 .cmd wrapper,
|
|
37
|
+
// 不加会 ENOENT(沿 forge-repo execFileSync 同模式)。
|
|
38
|
+
|
|
39
|
+
import { spawn } from 'node:child_process';
|
|
40
|
+
import fs from 'node:fs';
|
|
41
|
+
import path from 'node:path';
|
|
42
|
+
import process from 'node:process';
|
|
43
|
+
import { fileURLToPath } from 'node:url';
|
|
44
|
+
|
|
45
|
+
// 从 import.meta.url 推导 repo root(helper 位于 <repo>/scripts/ 下)
|
|
46
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
47
|
+
const REPO_ROOT = path.resolve(path.dirname(__filename), '..');
|
|
48
|
+
|
|
49
|
+
// 默认 fallback 模板(B-full adversarial-default)
|
|
50
|
+
const DEFAULT_TEMPLATE = path.join(
|
|
51
|
+
REPO_ROOT,
|
|
52
|
+
'src',
|
|
53
|
+
'core',
|
|
54
|
+
'codex-review',
|
|
55
|
+
'prompts',
|
|
56
|
+
'adversarial-default.md',
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// 解析 CLI 参数(轻量,不依赖 commander — 避免引入 deps)
|
|
60
|
+
function parseArgs(argv) {
|
|
61
|
+
const args = {};
|
|
62
|
+
for (let i = 0; i < argv.length; i++) {
|
|
63
|
+
const a = argv[i];
|
|
64
|
+
if (a.startsWith('--')) {
|
|
65
|
+
const key = a.slice(2);
|
|
66
|
+
const next = argv[i + 1];
|
|
67
|
+
if (next && !next.startsWith('--')) {
|
|
68
|
+
args[key] = next;
|
|
69
|
+
i++;
|
|
70
|
+
} else {
|
|
71
|
+
args[key] = true;
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
// positional passthrough
|
|
75
|
+
args._ = args._ || [];
|
|
76
|
+
args._.push(a);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return args;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function exitWithError(msg, code = 1) {
|
|
83
|
+
process.stderr.write(`❌ codex-review-helper: ${msg}\n`);
|
|
84
|
+
process.exit(code);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ============================================================
|
|
88
|
+
// 子命令 1:build-prompt
|
|
89
|
+
// ============================================================
|
|
90
|
+
function buildPrompt(args) {
|
|
91
|
+
const {
|
|
92
|
+
template,
|
|
93
|
+
output,
|
|
94
|
+
'user-focus': userFocus,
|
|
95
|
+
'target-label': targetLabel,
|
|
96
|
+
stage,
|
|
97
|
+
mode,
|
|
98
|
+
} = args;
|
|
99
|
+
|
|
100
|
+
if (!output) {
|
|
101
|
+
// --output 是必填;--template 是可选的(可用 --stage/--mode 自动推导或 fallback)
|
|
102
|
+
exitWithError('build-prompt 需要 --output <path>');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 模板解析优先级:
|
|
106
|
+
// 1. --template 显式 → 直接用(向后兼容)
|
|
107
|
+
// 2. --stage + --mode → <stage>-<mode>.md(若文件存在)
|
|
108
|
+
// 3. fallback → adversarial-default.md
|
|
109
|
+
let templatePath;
|
|
110
|
+
if (template) {
|
|
111
|
+
// 优先级 1:显式 --template
|
|
112
|
+
templatePath = path.resolve(template);
|
|
113
|
+
} else if (stage && mode) {
|
|
114
|
+
// 优先级 2:stage+mode 自动定位
|
|
115
|
+
const candidate = path.join(
|
|
116
|
+
REPO_ROOT,
|
|
117
|
+
'src',
|
|
118
|
+
'core',
|
|
119
|
+
'codex-review',
|
|
120
|
+
'prompts',
|
|
121
|
+
`${stage}-${mode}.md`,
|
|
122
|
+
);
|
|
123
|
+
if (fs.existsSync(candidate)) {
|
|
124
|
+
templatePath = candidate;
|
|
125
|
+
} else {
|
|
126
|
+
// 文件不存在则降级 fallback
|
|
127
|
+
process.stderr.write(
|
|
128
|
+
`⚠️ 模板 ${stage}-${mode}.md 不存在,fallback → adversarial-default.md\n`,
|
|
129
|
+
);
|
|
130
|
+
templatePath = DEFAULT_TEMPLATE;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
// 优先级 3:fallback
|
|
134
|
+
// 若只给了 --stage 或只给了 --mode(未成对),提示用户避免静默 fallback
|
|
135
|
+
if (stage || mode) {
|
|
136
|
+
process.stderr.write(
|
|
137
|
+
`⚠️ --stage / --mode 需成对提供,已忽略,fallback → adversarial-default.md\n`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
templatePath = DEFAULT_TEMPLATE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// --template 显式时,若找不到文件报错(维持原有行为)
|
|
144
|
+
// fallback / auto-resolve 时,若连 default 也不存在则报错
|
|
145
|
+
if (!fs.existsSync(templatePath)) {
|
|
146
|
+
exitWithError(`模板文件不存在:${templatePath}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let content = fs.readFileSync(templatePath, 'utf-8');
|
|
150
|
+
|
|
151
|
+
// 变量替换 — 当前支持 {{USER_FOCUS}} / {{TARGET_LABEL}}
|
|
152
|
+
// 未提供变量默认 (none)
|
|
153
|
+
content = content.replace(/\{\{USER_FOCUS\}\}/g, userFocus || '(none provided)');
|
|
154
|
+
content = content.replace(/\{\{TARGET_LABEL\}\}/g, targetLabel || 'current branch');
|
|
155
|
+
|
|
156
|
+
// 检查未替换的 {{VAR}}(可能是模板更新但 helper 没跟上)
|
|
157
|
+
const unreplaced = content.match(/\{\{[A-Z_]+\}\}/g);
|
|
158
|
+
if (unreplaced) {
|
|
159
|
+
process.stderr.write(
|
|
160
|
+
`⚠️ 未替换的变量(可能模板有新变量,helper 待更新):${unreplaced.join(', ')}\n`,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 确保 output 目录存在
|
|
165
|
+
const outputPath = path.resolve(output);
|
|
166
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
167
|
+
fs.writeFileSync(outputPath, content, 'utf-8');
|
|
168
|
+
|
|
169
|
+
process.stdout.write(`✓ prompt written to ${outputPath}\n`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ============================================================
|
|
173
|
+
// 子命令 2:run
|
|
174
|
+
// ============================================================
|
|
175
|
+
function runCodex(args) {
|
|
176
|
+
const { 'prompt-file': promptFile, 'output-log': outputLog, mode, 'thread-id': threadId } = args;
|
|
177
|
+
|
|
178
|
+
// --mode code-review:spawn `codex review`,不需要 prompt-file
|
|
179
|
+
const isCodeReview = mode === 'code-review';
|
|
180
|
+
|
|
181
|
+
if (!isCodeReview && !promptFile) {
|
|
182
|
+
exitWithError('run 需要 --prompt-file <path>');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let promptPath = null;
|
|
186
|
+
let promptContent = null;
|
|
187
|
+
|
|
188
|
+
if (!isCodeReview) {
|
|
189
|
+
promptPath = path.resolve(promptFile);
|
|
190
|
+
if (!fs.existsSync(promptPath)) {
|
|
191
|
+
exitWithError(`prompt 文件不存在:${promptPath}`);
|
|
192
|
+
}
|
|
193
|
+
promptContent = fs.readFileSync(promptPath, 'utf-8');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 准备 output-log(tee 目标)
|
|
197
|
+
let logStream = null;
|
|
198
|
+
if (outputLog) {
|
|
199
|
+
const logPath = path.resolve(outputLog);
|
|
200
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
201
|
+
logStream = fs.createWriteStream(logPath, { flags: 'w', encoding: 'utf-8' });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// codex passthrough args(除了 helper 自己消化的参数)
|
|
205
|
+
const passthrough = args._ || [];
|
|
206
|
+
|
|
207
|
+
// 构造 codex 调用参数
|
|
208
|
+
// mode dispatch:
|
|
209
|
+
// code-review → codex review [passthrough]
|
|
210
|
+
// adversarial | rescue | (默认) → codex exec [resume <threadId>] [passthrough]
|
|
211
|
+
//
|
|
212
|
+
// thread-id resume:
|
|
213
|
+
// adversarial/rescue: codex exec resume <threadId> — 通过子命令 resume 续接 session
|
|
214
|
+
// code-review: codex review 无 resume 子命令/选项(已验证 codex review --help),
|
|
215
|
+
// 忽略 --thread-id 并输出警告
|
|
216
|
+
let codexArgs;
|
|
217
|
+
if (isCodeReview) {
|
|
218
|
+
// code-review 模式:spawn `codex review`
|
|
219
|
+
codexArgs = ['review', ...passthrough];
|
|
220
|
+
|
|
221
|
+
// codex review 不支持 resume(无 session 概念),忽略 --thread-id
|
|
222
|
+
if (threadId) {
|
|
223
|
+
process.stderr.write(
|
|
224
|
+
`⚠️ --thread-id 在 code-review 模式下被忽略:codex review 不支持 session resume\n`,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
// adversarial / rescue / 默认:spawn `codex exec` + stdin prompt
|
|
229
|
+
if (threadId) {
|
|
230
|
+
// codex exec resume <sessionId> — 续接指定 session,prompt 通过 stdin 传入
|
|
231
|
+
codexArgs = ['exec', 'resume', threadId, ...passthrough];
|
|
232
|
+
} else {
|
|
233
|
+
// 无 resume:新会话
|
|
234
|
+
codexArgs = ['exec', ...passthrough];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
process.stderr.write(`▶ spawning: codex ${codexArgs.join(' ')}\n`);
|
|
239
|
+
if (promptPath) {
|
|
240
|
+
process.stderr.write(` prompt: ${promptPath}\n`);
|
|
241
|
+
}
|
|
242
|
+
if (outputLog) {
|
|
243
|
+
process.stderr.write(` log: ${path.resolve(outputLog)}\n`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// shell: true — 跨平台兼容:Windows 下 codex 是 .cmd wrapper,
|
|
247
|
+
// 不加 shell:true 会 spawn ENOENT(沿 forge-repo execFileSync 同模式)
|
|
248
|
+
//
|
|
249
|
+
// 用「单条已转义命令字符串 + shell:true」而非「args 数组 + shell:true」:
|
|
250
|
+
// 1. Node 22+ 对「args 数组 + shell:true」会发 DEP0190 弃用警告(污染 stderr,
|
|
251
|
+
// 下游 Task 5 runner 会解析 stderr)
|
|
252
|
+
// 2. 每个 arg 显式加双引号并转义内部双引号,中和 threadId 等参数里
|
|
253
|
+
// 可能含 shell 元字符导致的注入
|
|
254
|
+
const stdinMode = isCodeReview ? 'inherit' : 'pipe';
|
|
255
|
+
const quoted = codexArgs.map((a) => `"${String(a).replace(/"/g, '\\"')}"`).join(' ');
|
|
256
|
+
const codex = spawn(`codex ${quoted}`, {
|
|
257
|
+
stdio: [stdinMode, 'pipe', 'inherit'],
|
|
258
|
+
shell: true,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// adversarial/rescue/默认:喂 prompt 到 stdin
|
|
262
|
+
if (!isCodeReview && codex.stdin) {
|
|
263
|
+
codex.stdin.write(promptContent);
|
|
264
|
+
codex.stdin.end();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// stdout 透传 + tee
|
|
268
|
+
codex.stdout.on('data', (chunk) => {
|
|
269
|
+
process.stdout.write(chunk);
|
|
270
|
+
if (logStream) logStream.write(chunk);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
codex.on('close', (code) => {
|
|
274
|
+
if (logStream) logStream.end();
|
|
275
|
+
process.stderr.write(`\n${code === 0 ? '✓' : '❌'} codex exited with code ${code}\n`);
|
|
276
|
+
process.exit(code);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
codex.on('error', (err) => {
|
|
280
|
+
exitWithError(
|
|
281
|
+
`spawn codex failed: ${err.message}\n (是否装了 codex CLI?跑 \`codex --version\` 确认)`,
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ============================================================
|
|
287
|
+
// Main dispatcher
|
|
288
|
+
// ============================================================
|
|
289
|
+
const [subcmd, ...rest] = process.argv.slice(2);
|
|
290
|
+
|
|
291
|
+
if (!subcmd || subcmd === '--help' || subcmd === '-h') {
|
|
292
|
+
process.stdout.write(`
|
|
293
|
+
codex-review-helper — stage-extensions wrapper for codex review
|
|
294
|
+
|
|
295
|
+
Usage:
|
|
296
|
+
node scripts/codex-review-helper.mjs build-prompt \\
|
|
297
|
+
[--template <path>] --output <path> \\
|
|
298
|
+
[--stage <stage>] [--mode <mode>] \\
|
|
299
|
+
[--user-focus "<text>"] [--target-label "<text>"]
|
|
300
|
+
|
|
301
|
+
node scripts/codex-review-helper.mjs run \\
|
|
302
|
+
[--prompt-file <path>] [--output-log <path>] \\
|
|
303
|
+
[--mode code-review|adversarial|rescue] \\
|
|
304
|
+
[--thread-id <id>] \\
|
|
305
|
+
[-- codex passthrough args]
|
|
306
|
+
|
|
307
|
+
build-prompt template priority:
|
|
308
|
+
1. --template <path> explicit path (highest)
|
|
309
|
+
2. --stage + --mode auto-resolve <stage>-<mode>.md
|
|
310
|
+
3. fallback adversarial-default.md
|
|
311
|
+
|
|
312
|
+
run --mode dispatch:
|
|
313
|
+
code-review → codex review (no prompt-file needed)
|
|
314
|
+
adversarial → codex exec + stdin prompt
|
|
315
|
+
rescue → codex exec + stdin prompt (v1 stub)
|
|
316
|
+
(default) → codex exec + stdin prompt (backward compat)
|
|
317
|
+
|
|
318
|
+
Notes:
|
|
319
|
+
- harness-agnostic:不依赖 \${CLAUDE_PLUGIN_ROOT} / \${FORGE_PLUGIN_ROOT};
|
|
320
|
+
所有路径通过 CLI 参数传入。
|
|
321
|
+
- --thread-id 在 code-review 模式下被忽略(codex review 不支持 resume)。
|
|
322
|
+
`);
|
|
323
|
+
process.exit(0);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const args = parseArgs(rest);
|
|
327
|
+
|
|
328
|
+
switch (subcmd) {
|
|
329
|
+
case 'build-prompt':
|
|
330
|
+
buildPrompt(args);
|
|
331
|
+
break;
|
|
332
|
+
case 'run':
|
|
333
|
+
runCodex(args);
|
|
334
|
+
break;
|
|
335
|
+
default:
|
|
336
|
+
exitWithError(`未知子命令:${subcmd}(可用:build-prompt | run)`);
|
|
337
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<role>
|
|
2
|
+
You are Codex performing an adversarial software review.
|
|
3
|
+
Your job is to break confidence in the change, not to validate it.
|
|
4
|
+
</role>
|
|
5
|
+
|
|
6
|
+
<task>
|
|
7
|
+
Review the provided focus area as if you are trying to find the strongest reasons this should not ship yet.
|
|
8
|
+
Focus: {{USER_FOCUS}}
|
|
9
|
+
Target: {{TARGET_LABEL}}
|
|
10
|
+
</task>
|
|
11
|
+
|
|
12
|
+
<operating_stance>
|
|
13
|
+
Default to skepticism.
|
|
14
|
+
Assume the change can fail in subtle, high-cost, or user-visible ways until the evidence says otherwise.
|
|
15
|
+
Do not give credit for good intent, partial fixes, or likely follow-up work.
|
|
16
|
+
If something only works on the happy path, treat that as a real weakness.
|
|
17
|
+
</operating_stance>
|
|
18
|
+
|
|
19
|
+
<attack_surface>
|
|
20
|
+
Prioritize the kinds of failures that are expensive, dangerous, or hard to detect:
|
|
21
|
+
|
|
22
|
+
For design / spec / plan artifacts (forge brainstorm / propose / apply stages):
|
|
23
|
+
|
|
24
|
+
- Hidden assumptions in design / scope decisions / approach selection
|
|
25
|
+
- Missing edge cases / error paths / failure modes not documented
|
|
26
|
+
- Inconsistencies between artifacts (proposal / spec / design / tasks)
|
|
27
|
+
- Scope drift / out-of-scope items not explicitly marked
|
|
28
|
+
- Vague success criteria / missing measurable DoD
|
|
29
|
+
- Type / API / data flow inconsistencies across tasks
|
|
30
|
+
- Hidden technical debt the change is creating
|
|
31
|
+
|
|
32
|
+
For code-level artifacts (forge review / verify stages):
|
|
33
|
+
|
|
34
|
+
- auth, permissions, tenant isolation, and trust boundaries
|
|
35
|
+
- data loss, corruption, duplication, and irreversible state changes
|
|
36
|
+
- rollback safety, retries, partial failure, and idempotency gaps
|
|
37
|
+
- race conditions, ordering assumptions, stale state, and re-entrancy
|
|
38
|
+
- empty-state, null, timeout, and degraded dependency behavior
|
|
39
|
+
- version skew, schema drift, migration hazards, and compatibility regressions
|
|
40
|
+
- observability gaps that would hide failure or make recovery harder
|
|
41
|
+
</attack_surface>
|
|
42
|
+
|
|
43
|
+
<review_method>
|
|
44
|
+
Actively try to disprove the change.
|
|
45
|
+
Look for violated invariants, missing guards, unhandled failure paths, and assumptions that stop being true under stress.
|
|
46
|
+
Trace how bad inputs, retries, concurrent actions, or partially completed operations move through the code or the proposal.
|
|
47
|
+
If the user supplied a focus area, weight it heavily, but still report any other material issue you can defend.
|
|
48
|
+
</review_method>
|
|
49
|
+
|
|
50
|
+
<finding_bar>
|
|
51
|
+
Report only material findings with concrete evidence.
|
|
52
|
+
Do not include style feedback, naming feedback, low-value cleanup, or speculative concerns without evidence.
|
|
53
|
+
|
|
54
|
+
A finding should answer:
|
|
55
|
+
|
|
56
|
+
1. What can go wrong?
|
|
57
|
+
2. Why is this code / design path vulnerable?
|
|
58
|
+
3. What is the likely impact?
|
|
59
|
+
4. What concrete change would reduce the risk?
|
|
60
|
+
</finding_bar>
|
|
61
|
+
|
|
62
|
+
<severity_scale>
|
|
63
|
+
Use the forge severity scale (4 levels):
|
|
64
|
+
|
|
65
|
+
- **BLOCKER**: Ship-blocking. Concrete evidence of failure mode that will cause production incident or correctness violation. Must be fixed before merge.
|
|
66
|
+
- **MAJOR**: Significant risk or design flaw. Likely to cause incident under realistic load / edge case. Should be fixed before merge or have explicit ack with rationale.
|
|
67
|
+
- **MINOR**: Real issue but not ship-blocking. Nice-to-have improvement. Can be deferred to backlog.
|
|
68
|
+
- **NIT**: Style / minor cleanup / preference. Non-actionable beyond drive-by fix.
|
|
69
|
+
|
|
70
|
+
Map to confidence:
|
|
71
|
+
|
|
72
|
+
- BLOCKER / MAJOR should have confidence >= 0.8 (you're confident this is real)
|
|
73
|
+
- MINOR / NIT may have confidence 0.5-0.8
|
|
74
|
+
</severity_scale>
|
|
75
|
+
|
|
76
|
+
<output_format>
|
|
77
|
+
Return Markdown with these sections:
|
|
78
|
+
|
|
79
|
+
## Summary
|
|
80
|
+
|
|
81
|
+
2-3 sentences capturing the overall verdict and main risks.
|
|
82
|
+
|
|
83
|
+
## Findings
|
|
84
|
+
|
|
85
|
+
List each finding as:
|
|
86
|
+
|
|
87
|
+
### [SEVERITY] Title
|
|
88
|
+
|
|
89
|
+
**Location**: `file:line` or `section name` (if applicable)
|
|
90
|
+
**Confidence**: 0.0-1.0
|
|
91
|
+
|
|
92
|
+
**Body**:
|
|
93
|
+
What's wrong and why it matters.
|
|
94
|
+
|
|
95
|
+
**Recommendation**:
|
|
96
|
+
Concrete change that would address the finding.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Verdict
|
|
101
|
+
|
|
102
|
+
One of: `approve` | `needs-attention`
|
|
103
|
+
|
|
104
|
+
Brief rationale (1-2 sentences).
|
|
105
|
+
</output_format>
|