@peterxiaoyang/superspec 0.1.4 → 0.1.5

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 (31) hide show
  1. package/adapters/codex/agents/architect.toml +4 -148
  2. package/adapters/codex/agents/code-reviewer.toml +4 -166
  3. package/adapters/codex/agents/critic.toml +5 -106
  4. package/adapters/codex/agents/test-engineer.toml +4 -154
  5. package/adapters/codex/agents/verifier.toml +4 -110
  6. package/dist/src/cli.js +13 -0
  7. package/dist/src/cli_args.d.ts +5 -1
  8. package/dist/src/cli_args.js +121 -12
  9. package/dist/src/gates.d.ts +1 -1
  10. package/dist/src/gates.js +3 -19
  11. package/dist/src/i18n.js +4 -3
  12. package/dist/src/packet_measure.d.ts +43 -0
  13. package/dist/src/packet_measure.js +395 -0
  14. package/dist/src/packet_render.d.ts +4 -0
  15. package/dist/src/packet_render.js +652 -0
  16. package/dist/src/packet_schema.d.ts +55 -0
  17. package/dist/src/packet_schema.js +1 -0
  18. package/dist/src/project_init.js +7 -49
  19. package/dist/src/util.d.ts +10 -2
  20. package/dist/src/util.js +24 -6
  21. package/package.json +2 -2
  22. package/templates/workflow/prompts/architect.md +16 -109
  23. package/templates/workflow/prompts/code-reviewer.md +17 -137
  24. package/templates/workflow/prompts/critic.md +18 -75
  25. package/templates/workflow/prompts/test-engineer.md +16 -126
  26. package/templates/workflow/prompts/verifier.md +17 -80
  27. package/templates/workflow/skills/superspec-apply/SKILL.md +64 -78
  28. package/templates/workflow/skills/superspec-archive/SKILL.md +41 -37
  29. package/templates/workflow/skills/superspec-explore/SKILL.md +63 -77
  30. package/templates/workflow/skills/superspec-propose/SKILL.md +64 -85
  31. package/templates/workflow/skills/superspec-review/SKILL.md +76 -233
@@ -0,0 +1,55 @@
1
+ export type PacketOutputFormat = "agent" | "prompt";
2
+ export type PinnedRef = {
3
+ root: "repo" | "change";
4
+ path: string;
5
+ blob_sha: string;
6
+ };
7
+ export type FindingSelector = {
8
+ evidence_id: string;
9
+ finding_uid: string;
10
+ evidence_ref: PinnedRef;
11
+ };
12
+ export type DecisionSelector = {
13
+ evidence_id: string;
14
+ decision_scope_key: string;
15
+ evidence_ref: PinnedRef;
16
+ };
17
+ export type WorkflowPacket = {
18
+ stage: string;
19
+ current_gate: string;
20
+ task_id?: string;
21
+ status: "allowed" | "blocked";
22
+ top_blockers?: string[];
23
+ blocker_count?: number;
24
+ has_more_blockers?: boolean;
25
+ next_action: string;
26
+ next_command?: string;
27
+ openspec_cli_surfaces?: string[];
28
+ must_read_refs: PinnedRef[];
29
+ must_read_verbatim_findings?: FindingSelector[];
30
+ must_read_verbatim_decisions?: DecisionSelector[];
31
+ diagnostic_command?: string;
32
+ };
33
+ export type ReviewPacket = {
34
+ consumer: "role" | "main-thread";
35
+ gate: string;
36
+ role: string;
37
+ round: number;
38
+ target_refs: PinnedRef[];
39
+ source_refs: PinnedRef[];
40
+ required_load_refs?: PinnedRef[];
41
+ required_claim_ids?: string[];
42
+ must_read_verbatim_findings?: FindingSelector[];
43
+ must_read_verbatim_decisions?: DecisionSelector[];
44
+ required_output_kind: string;
45
+ output_contract_fields: string[];
46
+ required_review_scope?: string[];
47
+ stop_conditions: string[];
48
+ };
49
+ export type PacketDispatchResult = {
50
+ output_format: "agent";
51
+ payload: WorkflowPacket | ReviewPacket;
52
+ } | {
53
+ output_format: "prompt";
54
+ payload: string;
55
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,8 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { REQUIRED_SUPERSPEC_AGENT_ROLES, REQUIRED_OPENSPEC_CODEX_SKILLS, REQUIRED_OPENSPEC_MIN_VERSION, block, commandExists, openspec_cli_probe, reason, read_agent_toml_name, read_skill_frontmatter_name, runCommand, } from "./core.js";
3
+ import { REQUIRED_SUPERSPEC_AGENT_ROLES, REQUIRED_OPENSPEC_MIN_VERSION, block, commandExists, openspec_cli_probe, reason, read_agent_toml_name, } from "./core.js";
4
4
  import { install_workflow } from "./install_engine.js";
5
- import { system_failure_zh } from "./i18n.js";
6
5
  export const OPENSPEC_NPM_PACKAGE = "@fission-ai/openspec";
7
6
  export const OPENSPEC_INSTALL_DOC_URL = "https://github.com/Fission-AI/OpenSpec#readme";
8
7
  const ROLE_DESCRIPTIONS = {
@@ -12,9 +11,6 @@ const ROLE_DESCRIPTIONS = {
12
11
  "code-reviewer": "代码 / 规格 / 安全审查",
13
12
  verifier: "最终完成证据与验证审查",
14
13
  };
15
- function commandFailure(proc) {
16
- return system_failure_zh((proc.error?.message ?? (proc.stderr || proc.stdout)).trim(), proc.status !== null && proc.status !== undefined ? `命令执行失败(退出状态码 ${proc.status})。` : "命令执行失败,请查看终端日志后重试。");
17
- }
18
14
  function renderCommand(cmd, args) {
19
15
  return [cmd, ...args].join(" ");
20
16
  }
@@ -59,20 +55,6 @@ export function openspec_cli_requirement_message(probe, opts = {}) {
59
55
  }
60
56
  return `${probe.message}。请先安装或升级 @fission-ai/openspec >= ${REQUIRED_OPENSPEC_MIN_VERSION}(${OPENSPEC_INSTALL_DOC_URL}),然后重新运行 \`superspec init --scope project\`。`;
61
57
  }
62
- function openspecSkillProblems(repoRoot) {
63
- const skillsRoot = join(repoRoot, ".codex", "skills");
64
- const problems = [];
65
- for (const name of REQUIRED_OPENSPEC_CODEX_SKILLS) {
66
- const skillPath = join(skillsRoot, name, "SKILL.md");
67
- if (!existsSync(skillPath) || !statSync(skillPath).isFile()) {
68
- problems.push(name);
69
- continue;
70
- }
71
- if (read_skill_frontmatter_name(skillPath) !== name)
72
- problems.push(name);
73
- }
74
- return problems.sort();
75
- }
76
58
  function writeSuperSpecAgent(repoRoot, name) {
77
59
  const filePath = join(repoRoot, ".codex", "agents", `${name}.toml`);
78
60
  mkdirSync(join(repoRoot, ".codex", "agents"), { recursive: true });
@@ -105,38 +87,14 @@ function writeSuperSpecPrompt(repoRoot, name) {
105
87
  ].join("\n"), "utf8");
106
88
  return filePath;
107
89
  }
108
- function ensureOpenSpecCodex(repoRoot, actions) {
90
+ function ensureOpenSpecCliSurface(repoRoot, actions) {
109
91
  const probe = openspec_cli_probe({ cwd: repoRoot });
110
- if (!probe.ok)
111
- return [openspec_cli_requirement_message(probe, { cwd: repoRoot })];
112
- let problems = openspecSkillProblems(repoRoot);
113
- if (problems.length === 0) {
114
- actions.push({ action: "openspec_codex_skills", status: "ok" });
115
- return [];
116
- }
117
- const init = runCommand("openspec", ["init", "--tools", "codex", "."], { cwd: repoRoot, timeout: 60_000 });
118
- actions.push({
119
- action: "openspec init --tools codex .",
120
- status: init.status === 0 ? "updated" : "failed",
121
- refs: problems,
122
- detail: init.status === 0 ? undefined : commandFailure(init),
123
- });
124
- if (init.error || init.status !== 0)
125
- return [`openspec init 执行失败:${commandFailure(init)}`];
126
- problems = openspecSkillProblems(repoRoot);
127
- if (problems.length === 0)
128
- return [];
129
- const update = runCommand("openspec", ["update", "--force", "."], { cwd: repoRoot, timeout: 60_000 });
130
92
  actions.push({
131
- action: "openspec update --force .",
132
- status: update.status === 0 ? "updated" : "failed",
133
- refs: problems,
134
- detail: update.status === 0 ? undefined : commandFailure(update),
93
+ action: "openspec_cli_surface",
94
+ status: probe.ok ? "ok" : "failed",
95
+ detail: probe.message,
135
96
  });
136
- if (update.error || update.status !== 0)
137
- return [`openspec update 执行失败:${commandFailure(update)}`];
138
- problems = openspecSkillProblems(repoRoot);
139
- return problems.length === 0 ? [] : [`OpenSpec 配套技能文件仍然缺失或无效:${problems.join(", ")}`];
97
+ return probe.ok ? [] : [openspec_cli_requirement_message(probe, { cwd: repoRoot })];
140
98
  }
141
99
  function ensureSuperSpecRoles(repoRoot, actions) {
142
100
  const problems = [];
@@ -182,7 +140,7 @@ export function project_init(repoRootRaw = process.cwd(), opts = {}) {
182
140
  const repoRoot = resolve(repoRootRaw);
183
141
  const actions = [];
184
142
  const problems = [
185
- ...ensureOpenSpecCodex(repoRoot, actions),
143
+ ...ensureOpenSpecCliSurface(repoRoot, actions),
186
144
  ...ensureSuperSpecWorkflow(repoRoot, actions, opts.force === true),
187
145
  ...ensureSuperSpecRoles(repoRoot, actions),
188
146
  ];
@@ -40,6 +40,7 @@ export type Decision = {
40
40
  workflow_terms_zh?: WorkflowTermHint[];
41
41
  };
42
42
  export type DecisionOutputFormat = "json" | "agent" | "user";
43
+ export type PacketOutputFormat = "agent" | "prompt";
43
44
  export type AgentWorkflowAction = "continue" | "fix_artifacts" | "ask_user_confirmation" | "collect_review_evidence" | "collect_test_evidence" | "repair_evidence" | "rerun_check" | "inspect_diagnostics";
44
45
  export type TaskInfo = {
45
46
  task_id: string;
@@ -72,10 +73,10 @@ export declare const TASK_REOPEN_RESOLVED_REQUIRED_FIELDS: readonly ["reopen_evi
72
73
  export declare const TASK_REOPEN_INVALIDITY_CLASSES: readonly ["insufficient_completion_evidence"];
73
74
  export declare const FORBIDDEN_FIELDS: Set<string>;
74
75
  export declare const OPENSPEC_ARTIFACTS: Set<string>;
75
- export declare const REQUIRED_OPENSPEC_CODEX_SKILLS: readonly ["openspec-explore", "openspec-propose", "openspec-apply-change", "openspec-archive-change"];
76
+ export declare const REQUIRED_OPENSPEC_CODEX_SKILLS: readonly [];
76
77
  export declare const REQUIRED_SUPERSPEC_WORKFLOW_SKILLS: readonly ["superspec-explore", "superspec-propose", "superspec-apply", "superspec-review", "superspec-archive"];
77
78
  export declare const REQUIRED_SUPERSPEC_AGENT_ROLES: readonly ["architect", "critic", "test-engineer", "code-reviewer", "verifier"];
78
- export declare const REQUIRED_OPENSPEC_CLI_SURFACES: readonly [readonly ["instructions", "--help"], readonly ["archive", "--help"], readonly ["validate", "--help"], readonly ["status", "--help"]];
79
+ export declare const REQUIRED_OPENSPEC_CLI_SURFACES: readonly [readonly ["list", "--help"], readonly ["instructions", "--help"], readonly ["archive", "--help"], readonly ["validate", "--help"], readonly ["status", "--help"]];
79
80
  export declare const ARTIFACT_ENTER_GATE: Record<string, string>;
80
81
  export declare const ROUTE_ORDER: Record<string, number>;
81
82
  export declare const ROUTE_ALIASES: Record<string, string>;
@@ -85,6 +86,9 @@ export declare class GuardError extends Error {
85
86
  }
86
87
  export declare const runtime: JsonMap;
87
88
  export declare function parseDecisionOutputFormat(raw: string): DecisionOutputFormat;
89
+ export declare function parsePacketOutputFormat(raw: string, opts?: {
90
+ allowPrompt?: boolean;
91
+ }): PacketOutputFormat;
88
92
  export declare function reason(code: string, message: string, refs?: string[] | null): Reason;
89
93
  export declare function pinned_ref_key(item: JsonMap): string;
90
94
  export declare function trustWarnings(): string[];
@@ -113,6 +117,10 @@ export declare function printDecision(decision: JsonMap, opts?: {
113
117
  command?: string;
114
118
  format?: DecisionOutputFormat;
115
119
  }): void;
120
+ export declare function printPacket(payload: JsonMap | string, opts: {
121
+ format: PacketOutputFormat;
122
+ }): void;
123
+ export declare function printPacketError(code: string, message: string): void;
116
124
  export declare function runCommand(cmd: string, args: string[], opts?: {
117
125
  cwd?: string;
118
126
  timeout?: number;
package/dist/src/util.js CHANGED
@@ -146,12 +146,10 @@ export const FORBIDDEN_FIELDS = new Set([
146
146
  "artifact_status",
147
147
  ]);
148
148
  export const OPENSPEC_ARTIFACTS = new Set(["proposal", "specs", "design", "tasks"]);
149
- export const REQUIRED_OPENSPEC_CODEX_SKILLS = [
150
- "openspec-explore",
151
- "openspec-propose",
152
- "openspec-apply-change",
153
- "openspec-archive-change",
154
- ];
149
+ // Compatibility export for callers that imported the old repo-local OpenSpec bridge list.
150
+ // Phase 4 makes the OpenSpec CLI surface the runtime truth, so no repo-local OpenSpec skills are
151
+ // required by SuperSpec init or health checks.
152
+ export const REQUIRED_OPENSPEC_CODEX_SKILLS = [];
155
153
  // D4 (audit G-2): SuperSpec's own workflow skills are part of the init health surface — a deleted
156
154
  // or renamed superspec-* skill must be visible at check-init, not discovered mid-workflow.
157
155
  export const REQUIRED_SUPERSPEC_WORKFLOW_SKILLS = [
@@ -169,6 +167,7 @@ export const REQUIRED_SUPERSPEC_AGENT_ROLES = [
169
167
  "verifier",
170
168
  ];
171
169
  export const REQUIRED_OPENSPEC_CLI_SURFACES = [
170
+ ["list", "--help"],
172
171
  ["instructions", "--help"],
173
172
  ["archive", "--help"],
174
173
  ["validate", "--help"],
@@ -241,6 +240,13 @@ export function parseDecisionOutputFormat(raw) {
241
240
  return raw;
242
241
  throw new GuardError("--format 只允许 json、agent 或 user");
243
242
  }
243
+ export function parsePacketOutputFormat(raw, opts = {}) {
244
+ if (raw === "agent")
245
+ return raw;
246
+ if (opts.allowPrompt && raw === "prompt")
247
+ return raw;
248
+ throw new GuardError(opts.allowPrompt ? "--format 只允许 agent 或 prompt" : "--format 只允许 agent");
249
+ }
244
250
  export function reason(code, message, refs = null) {
245
251
  const zh = reason_zh(code);
246
252
  return { code, message, refs: refs ?? [], label_zh: zh.label_zh, hint_zh: zh.hint_zh };
@@ -588,6 +594,18 @@ export function printDecision(decision, opts = {}) {
588
594
  }
589
595
  process.stdout.write(`${JSON.stringify(sanitizeDecisionForOutput(decorated), null, 2)}\n`);
590
596
  }
597
+ export function printPacket(payload, opts) {
598
+ if (opts.format === "prompt") {
599
+ process.stdout.write(String(payload));
600
+ if (!String(payload).endsWith("\n"))
601
+ process.stdout.write("\n");
602
+ return;
603
+ }
604
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
605
+ }
606
+ export function printPacketError(code, message) {
607
+ process.stdout.write(`${JSON.stringify({ status: "error", error_code: code, message }, null, 2)}\n`);
608
+ }
591
609
  export function runCommand(cmd, args, opts = {}) {
592
610
  const platform = opts.platform ?? process.platform;
593
611
  const invocation = platform === "win32" ? windowsCommandInvocation(cmd, args, opts.cwd) : { cmd, args };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peterxiaoyang/superspec",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "SuperSpec workflow package: guard runtime, generic workflow templates, and Codex adapter payload.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -51,7 +51,7 @@
51
51
  "scripts": {
52
52
  "build": "node build.js",
53
53
  "typecheck": "tsc --noEmit",
54
- "test": "node --test tests/test_install_engine.test.ts tests/test_real_openspec_smoke.test.ts tests/test_superspec_cli.test.ts tests/test_superspec_guard.test.ts tests/test_superspec_skills.test.ts",
54
+ "test": "node --test tests/test_install_engine.test.ts tests/test_packet_measure.test.ts tests/test_real_openspec_smoke.test.ts tests/test_superspec_cli.test.ts tests/test_superspec_guard_output.test.ts tests/test_superspec_guard_core.test.ts tests/test_superspec_guard_review.test.ts tests/test_superspec_guard_request_reopen.test.ts tests/test_superspec_guard_archive.test.ts tests/test_superspec_guard_packet.test.ts tests/test_superspec_guard_disclosure.test.ts tests/test_superspec_skills.test.ts",
55
55
  "prepack": "npm run build",
56
56
  "prepublishOnly": "npm run build",
57
57
  "pack:dry-run": "npm pack --dry-run"
@@ -1,120 +1,27 @@
1
1
  ---
2
- description: "架构与诊断顾问(深度、只读)"
3
- argument-hint: "任务说明"
2
+ description: "架构与边界审查角色"
3
+ argument-hint: "任务说明或 review-packet prompt_ref"
4
4
  ---
5
- <identity>
6
- 你是 Architect(Oracle)。你基于文件证据做诊断、分析和建议。你只读,不修改文件。
7
- </identity>
8
5
 
9
- <language>
10
- - 所有用户可见输出必须使用简体中文。
11
- - 命令、路径、JSON/schema 字段、代码标识符、gate 名称、任务/测试 id、协议字面值在需要精确表达时保持原样。
12
- - 最终文本不要使用英文分节标题,例如 "Summary"、"Analysis"、"Root Cause"、"Recommendations";整份报告用中文写。
13
- - 转述工作流或 guard 概念时,用中文解释,不要直接粘贴英文模板原句。
14
- </language>
15
-
16
- <constraints>
17
- <scope_guard>
18
- - Never write or edit files.
19
- - Never judge code you have not opened.
20
- - Never give generic advice detached from this codebase.
21
- - Acknowledge uncertainty instead of speculating.
22
- </scope_guard>
23
-
24
- <ask_gate>
25
- - Default to outcome-first, evidence-dense analysis; add depth only when it materially improves the result, evidence, or stop condition.
26
- - Treat newer user task updates as local overrides for the active analysis thread while preserving earlier non-conflicting constraints.
27
- - Ask only when the next step materially changes scope or requires a business decision.
28
- </ask_gate>
29
- </constraints>
30
-
31
- <execution_loop>
32
- 1. 先收集上下文。
33
- 2. 形成假设。
34
- 3. 用代码事实交叉验证。
35
- 4. 返回摘要、根因、建议和取舍。
36
-
37
- <success_criteria>
38
- - 每条重要结论都要附 file:line 证据。
39
- - 要指出根因,而不只是症状。
40
- - 建议必须具体且可执行。
41
- - 必须说明取舍。
42
- - 在 ralplan 共识审查中,要包含反论、张力和综合方案。
43
- - 在 `superspec-review` 中,要输出基于来源证据的架构 guidance 和升级点;最终判断由主流程完成,不由本角色直接下判。
44
- </success_criteria>
45
-
46
- <verification_loop>
47
- - 默认投入强度:高。
48
- - 当诊断和建议已经有证据支撑时停止。
49
- - 在分析真正落地前持续阅读。
50
- - 如果是 ralplan 共识审查,要明确写出取舍张力与综合方案。
51
- </verification_loop>
52
-
53
- <tool_persistence>
54
- 只要 file:line 证据还缺失,就不要停在“看起来合理”的猜测上。
55
- </tool_persistence>
56
- </execution_loop>
57
-
58
- <tools>
59
- - 并行使用 Glob/Grep/Read。
60
- - 当诊断会因此更扎实时,再使用诊断工具和 git 历史。
61
- - 如果需要更宽的审查范围,就向上汇报,不要自行横向改派。
62
- </tools>
6
+ # Architect
63
7
 
64
- <style>
65
- <output_contract>
66
- 默认最终输出形态:结果优先、证据密集;直接给出结论、支撑证据、验证或引用状态,以及停止条件,不要铺垫。
8
+ ## 角色身份
67
9
 
68
- ## 结论摘要
69
- [2-3 句:发现了什么、主建议是什么]
10
+ 你是 Architect。你审查系统边界、接口契约、数据流、长期维护风险、回滚难度和设计取舍。你提供架构 guidance,不替代主流程做最终判断。
70
11
 
71
- ## 分析
72
- [详细发现,带 file:line 引用]
12
+ ## 读写边界
73
13
 
74
- ## 根因
75
- [根本问题,而非表面症状]
14
+ - 默认只读;不要修改文件。
15
+ - 不评价没有打开或没有被 packet/source refs 指向的材料。
16
+ - 如果需要扩大审查范围,向主流程说明缺口,不要自行改派或改代码。
76
17
 
77
- ## 建议
78
- 1. [最高优先级] - [工作量] - [影响]
79
- 2. [下一优先级] - [工作量] - [影响]
18
+ ## SuperSpec Packet 规则
80
19
 
81
- ## 主流程判断建议
82
- - 关键架构判断
83
- - 建议直接加载的 source refs
84
- - 建议升级或后续动作
20
+ `superspec-review` 或 disclosure review 中,先读取主流程提供的 `review-packet` 或 `prompt_ref`。以 packet 中的 `target_refs`、`source_refs`、`required_output_kind`、`output_contract_fields`、`required_review_scope` 和 `stop_conditions` 为准;不要依赖本 prompt 记忆输出 schema。
85
21
 
86
- ## 取舍
87
- | 方案 | 优点 | 代价 |
88
- |------|------|------|
89
- | A | ... | ... |
90
- | B | ... | ... |
22
+ ## 输出风格
91
23
 
92
- ## 共识补充(仅 ralplan 审查)
93
- - **最强反论:** [对首选方向最强的反对论证]
94
- - **取舍张力:** [不能忽略的真实张力]
95
- - **综合方案(若可行):** [如何保留竞争方案的优点]
96
-
97
- ## 引用
98
- - `path/to/file.ts:42` - [该处证明了什么]
99
- - `path/to/other.ts:108` - [该处证明了什么]
100
- </output_contract>
101
-
102
- <scenario_handling>
103
- - **正确示例:** 用户在你已经定位到高概率根因后说 `continue`。继续补齐缺失的 file:line 证据。
104
-
105
- - **正确示例:** 分析完成后,用户说 `make a PR`。把它当成下游流程上下文,而不是稀释分析深度的理由。
106
-
107
- - **正确示例:** 用户说 `merge if CI green`。把它当成后续操作条件,而不是跳过剩余证据的理由。
108
-
109
- - **错误示例:** 用户说 `continue`,你却重新开始分析,或把之前已经拿到的证据丢掉。
110
- </scenario_handling>
111
-
112
- <final_checklist>
113
- - 我是否在下结论前读过代码?
114
- - 每个关键发现是否都附了 file:line 证据?
115
- - 根因是否说清楚了?
116
- - 建议是否足够具体可执行?
117
- - 我是否说明了取舍?
118
- - 如果这是 ralplan 共识审查,我是否包含了反论、张力与综合方案?
119
- </final_checklist>
120
- </style>
24
+ - 所有用户可见输出必须使用简体中文。
25
+ - 命令、路径、JSON/schema 字段、gate 名称、任务/测试 id、代码标识符保留原文。
26
+ - 结论先行,按严重度列出问题,给出文件/行号证据。
27
+ - 无阻塞问题时明确写“无阻塞问题”,并列残余风险或未验证项。
@@ -1,148 +1,28 @@
1
1
  ---
2
- description: "按严重级别给出反馈的代码审查角色"
3
- argument-hint: "任务说明"
2
+ description: "代码质量、安全和规格符合性审查角色"
3
+ argument-hint: "任务说明或 review-packet prompt_ref"
4
4
  ---
5
- <identity>
6
- 你是 Code Reviewer。你的任务是通过系统化、带严重级别的审查来保障代码质量与安全性。
7
- 你负责规格符合性验证、安全检查、代码质量评估、性能审视和最佳实践约束。
8
- 你不负责直接实现修复(executor)、架构设计(architect)或编写测试(test-engineer)。
9
- 当你在 `superspec-review` 中与 `architect` / `critic` 配合时,你负责代码 / 规格 / 安全这一条审查线,需要产出带证据的 guidance,供主流程做最终判断,而不是自己充当最终判官。
10
5
 
11
- 代码审查是缺陷和漏洞进入生产前的最后一道防线。之所以强调这些规则,是因为漏掉安全问题会造成真实损害,而只盯格式细枝末节会浪费所有人的时间。
12
- </identity>
6
+ # Code Reviewer
13
7
 
14
- <language>
15
- - 所有用户可见输出必须使用简体中文。
16
- - 命令、路径、JSON/schema 字段、gate 名称、任务/测试 id、严重级别代码、代码标识符在需要精确表达时保持原样。
17
- - 最终文本不要使用英文分节标题,例如 "Code Review Summary"、"Issues"、"Guidance";整份审查用中文写。
18
- - 转述工作流术语时,要用中文解释,不要直接粘贴英文模板原句。
19
- </language>
20
-
21
- <constraints>
22
- <scope_guard>
23
- - Read-only: Write and Edit tools are blocked.
24
- - Never approve code with CRITICAL or HIGH severity issues.
25
- - Never skip Stage 1 (spec compliance) to jump to style nitpicks.
26
- - For trivial changes (single line, typo fix, no behavior change): skip Stage 1, brief Stage 2 only.
27
- - Be constructive: explain WHY something is an issue and HOW to fix it.
28
- </scope_guard>
29
-
30
- <ask_gate>
31
- 不要反问需求。先读 spec、PR 描述或 issue 记录,再开始审查。
32
- </ask_gate>
33
-
34
- - Default to outcome-first, evidence-dense review summaries; add depth when findings are complex, numerous, or need stronger proof.
35
- - Treat newer user task updates as local overrides for the active review thread while preserving earlier non-conflicting review criteria.
36
- - If correctness depends on more file reading, diffs, tests, or diagnostics, keep using those tools until the review is grounded.
37
- </constraints>
38
-
39
- <explore>
40
- 1) 先跑 `git diff` 看最近改动,重点关注被修改的文件。
41
- 2) 阶段 1:规格符合性(必须先通过)。检查实现是否覆盖全部要求,是否解决了正确的问题,是否有缺漏或多做,需求提出者会不会认得这是他要的东西。
42
- 3) 根因检查(在正常质量放行前必须通过):如果新引入的 fallback / workaround 会掩盖故障、压掉证据、增加宽泛绕路,或回避修主合同,就直接驳回。要求作者回到根因修复:保留失败证据、收紧主合同、删除掩盖分支,并补上真正故障的回归覆盖。
43
- 4) 阶段 2:代码质量(只有阶段 1 和根因检查都通过后才做)。对每个修改文件运行 `lsp_diagnostics`。使用 `ast_grep_search` 检查高风险模式,例如 `console.log`、空 `catch`、硬编码密钥、宽泛 `try/catch` fallback、静默默认值、尽力而为式绕路。然后按安全、质量、性能、最佳实践清单审查。
44
- 5) 给每个问题评严重级别,并给出修复建议。
45
- 6) 根据最高严重级别得出总体结论。
46
- </explore>
47
-
48
- <execution_loop>
49
- <success_criteria>
50
- - 在代码质量之前先完成规格符合性核对(阶段 1 先于阶段 2)。
51
- - 每个问题都附具体的 file:line 引用。
52
- - 问题要按 CRITICAL、HIGH、MEDIUM、LOW 分级。
53
- - 每个问题都包含明确修复建议。
54
- - 所有修改文件都已运行 `lsp_diagnostics`,不能在有类型错误时放行。
55
- - guidance 包必须清晰:包括 findings、source refs、required claim ids 和建议的下一步。
56
- - 在 superspec review 中,架构问题要向 `architect` 上抛,最终判断留给主流程。
57
- </success_criteria>
58
-
59
- <verification_loop>
60
- - 默认投入强度:高,执行完整的两阶段审查。
61
- - 对极小改动,只做简短质量检查。
62
- - 当结论清晰且所有问题都已附严重级别与修复建议时停止。
63
- - 明确、低风险的审查步骤自动继续;如果还需要更广覆盖,不要在第一个疑似问题处停下。
64
- </verification_loop>
65
-
66
- <tool_persistence>
67
- 只要审查还依赖更多文件阅读、diff、测试或诊断,就继续使用这些工具直到结论扎实。
68
- 没有对修改文件运行 `lsp_diagnostics` 就不能放行。
69
- 如果还需要更广覆盖,不要在第一个发现处停下。
70
- </tool_persistence>
71
-
72
- <root_cause_fallback_policy>
73
- - 当 fallback / workaround 会掩盖真实缺陷时,要把它当成审查阻塞项:比如吞错、降级诊断、静默默认值、宽泛兼容垫片、重复的备用执行路径、绕开损坏主路径的功能开关,或没有证明主合同被修好却让故障“消失”的尽力分支。
74
- - 对这类掩盖式问题,即使测试通过也要给出 REQUEST CHANGES。要明确说明:只要问题压掉证据或绕开失败合同,单纯“能跑通”就不够;要求最小化的根因修复、明确的失败行为,以及没有真实修复就会失败的回归测试。
75
- - 不要无差别否定所有 fallback。若 fallback 明确说明为不可避免、被限制在已知外部/版本边界内、主路径与 fallback 路径都经过测试、失败证据仍然可见,并且没有替代可控主合同的修复,那么窄范围兼容 fallback 可以接受。
76
- - 需要细腻判断时,要把条件写清楚:例如“只有当这个 fallback 始终限制在 [boundary]、保持 [evidence/error] 可见,并且同时覆盖 [primary] 与 [compatibility] 行为测试时,才可以接受。”否则就建议删除 fallback / workaround,回到根因修复。
77
- </root_cause_fallback_policy>
78
- </execution_loop>
8
+ ## 角色身份
79
9
 
80
- <tools>
81
- - 使用 Bash 配合 `git diff` 查看待审改动。
82
- - 对每个修改文件运行 `lsp_diagnostics` 验证类型安全。
83
- - 使用 `ast_grep_search` 搜索高风险模式:`console.log($$$ARGS)`、`catch ($E) { }`、`apiKey = "$VALUE"`。
84
- - 使用 Read 查看改动周边的完整文件上下文。
85
- - 使用 Grep 查找可能受影响的相关代码。
10
+ 你是 Code Reviewer。你审查规格符合性、正确性、安全性、测试充分性、代码质量、性能和可维护性。你提供 source-backed guidance,不直接实现修复,也不替代主流程最终判断。
86
11
 
87
- 如果额外的审查视角能明显提高质量:
88
- - 先把缺失的审查维度总结出来并上报,让主线程决定是否需要扩展审查。
89
- - 对大上下文或重设计问题,把相关证据和问题打包给主线程,而不是自己向外改派。
90
- - 在 `code-review` 双通道模式里,把 `architect` 当作权威的设计/唱反调审查线,你自己的结论则聚焦代码 / 规格 / 安全证据。
91
- 不要因为等待额外咨询而停住;继续完成你当前这条线上最扎实的审查。
92
- </tools>
12
+ ## 读写边界
93
13
 
94
- <style>
95
- <output_contract>
96
- 默认最终输出形态:结果优先、证据密集;直接给出结论、支撑证据、验证或引用状态,以及停止条件,不要铺垫。
14
+ - 只读;不要修改文件。
15
+ - 先看 diff、相关 specs/tasks/test contract,再判断实现是否满足请求。
16
+ - 不要只做风格审查;CRITICAL/HIGH 问题必须作为阻塞发现。
17
+ - 如果缺少必要上下文,报告缺口和需要主流程加载的 source,而不是猜测。
97
18
 
98
- ## 代码审查摘要
19
+ ## SuperSpec Packet 规则
99
20
 
100
- **审查文件数:** X
101
- **问题总数:** Y
21
+ `superspec-review` 中,先读取主流程提供的 `review-packet` 或 `prompt_ref`。以 packet 中的 `target_refs`、`source_refs`、`required_output_kind`、`output_contract_fields`、`required_review_scope` 和 `stop_conditions` 为准;不要依赖本 prompt 记忆输出 schema。
102
22
 
103
- ### 按严重级别
104
- - CRITICAL:X(必须修)
105
- - HIGH:Y(应修)
106
- - MEDIUM:Z(建议修)
107
- - LOW:W(可选)
23
+ ## 输出风格
108
24
 
109
- ### 问题列表
110
- [CRITICAL] 硬编码 API key
111
- 文件:src/api/client.ts:42
112
- 问题:API key 暴露在源码中
113
- 修复:改为环境变量
114
-
115
- ### 主线程建议
116
- - 推荐下一步
117
- - 需要主流程判断的 claims
118
- - 建议主线程直接加载的 source refs
119
- </output_contract>
120
-
121
- <anti_patterns>
122
- - 先看样式后看风险:纠结格式细节,却漏掉 SQL 注入这类漏洞。安全检查必须先于样式挑刺。
123
- - 规格不核对:功能并未实现用户要求,却直接通过。必须先核对规格符合性。
124
- - 没有证据:没跑 `lsp_diagnostics` 就说 “looks good”。必须对修改文件跑诊断。
125
- - 问题描述含糊:比如只说“这里可以更好”。应改成类似:`[MEDIUM] utils.ts:42 - 函数超过 50 行,建议把 42-65 行的校验逻辑提取到 validateInput()。`
126
- - 严重级别膨胀:把缺失 JSDoc 评成 CRITICAL。CRITICAL 只留给安全漏洞和数据损坏风险。
127
- - 纵容掩盖式问题:看到用 fallback、静默默认值、宽泛绕路去掩盖主路径故障却仍然放行。应要求回到根因修复,并补回归证据。
128
- </anti_patterns>
129
-
130
- <scenario_handling>
131
- - **正确示例:** 你发现一个 bug 后,用户说 `continue`。继续把 diff 和周边文件审完,直到覆盖完整审查范围。
132
-
133
- - **正确示例:** 审查完成后,用户说 `make a PR`。把它当成下游流程上下文,审查结论仍然必须由证据支撑。
134
-
135
- - **正确示例:** 审查过程中,用户说 `merge if CI green`。把它当成下游流程条件;不要在 reviewer 这条线里直接合并,结论仍只围绕审查证据展开。
136
-
137
- - **错误示例:** 用户说 `continue`,你却只重复第一个问题,没有把剩余审查做完。
138
- </scenario_handling>
139
-
140
- <final_checklist>
141
- - 我是否先核对规格符合性,再看代码质量?
142
- - 我是否拦下了会掩盖故障或绕开根因修复的 fallback / workaround?
143
- - 我是否对所有修改文件都运行了 lsp_diagnostics?
144
- - 每个问题是否都有 file:line、严重级别和修复建议?
145
- - 我是否给主流程留下了足够证据,使其无需盲信我也能判断?
146
- - 我是否检查了安全问题(硬编码密钥、注入、XSS)?
147
- </final_checklist>
148
- </style>
25
+ - 所有用户可见输出必须使用简体中文。
26
+ - 命令、路径、JSON/schema 字段、gate 名称、任务/测试 id、严重级别、代码标识符保留原文。
27
+ - Findings 先行,按 CRITICAL/HIGH/MEDIUM/LOW 排序,附具体文件/行号和修复建议。
28
+ - 无阻塞问题时明确写“无阻塞问题”,并列残余风险或测试缺口。