@xulthekl/team-flow 0.57.0 → 0.59.0

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 (50) hide show
  1. package/.claude/always/phase-guard.md +1 -1
  2. package/.claude-plugin/marketplace.json +3 -3
  3. package/.claude-plugin/plugin.json +2 -2
  4. package/.codex-plugin/plugin.json +2 -2
  5. package/.cursor-plugin/marketplace.json +2 -2
  6. package/.cursor-plugin/plugin.json +2 -2
  7. package/.github/plugin/marketplace.json +2 -2
  8. package/AGENTS.md +27 -7
  9. package/CHANGELOG.md +86 -0
  10. package/GEMINI.md +1 -1
  11. package/HANDOFF.md +2 -2
  12. package/INSTALL.md +10 -10
  13. package/README.md +9 -7
  14. package/agents/code-reviewer.md +3 -0
  15. package/agents/cross-change-consistency-checker.md +34 -6
  16. package/agents/release-archivist.md +6 -0
  17. package/docs/README_en.md +1 -1
  18. package/docs/platform-matrix.md +1 -1
  19. package/docs/release-checklist.md +1 -1
  20. package/docs/usage-guide.md +2 -2
  21. package/gemini-extension.json +2 -2
  22. package/hooks/session-start +2 -2
  23. package/llms.txt +1 -1
  24. package/package.json +2 -2
  25. package/plugin.json +2 -2
  26. package/scripts/check-version-consistency.mjs +34 -4
  27. package/scripts/guard/checks/dp3-approved.mjs +1 -1
  28. package/scripts/guard/guard.mjs +7 -1
  29. package/scripts/lib/cmd-state.mjs +9 -6
  30. package/skills/architecture-design/templates/conventions/frontend-patterns.md +7 -0
  31. package/skills/build-executor/SKILL.md +2 -0
  32. package/skills/build-executor/implementer-prompt.md +19 -0
  33. package/skills/build-executor/task-reviewer-prompt.md +51 -5
  34. package/skills/clean-code/SKILL.md +116 -0
  35. package/skills/clean-code/references/judgement-cases.md +83 -0
  36. package/skills/clean-code/references/shared-layer-rules.md +50 -0
  37. package/skills/code-reviewer/SKILL.md +10 -0
  38. package/skills/code-reviewer/code-reviewer-prompt.md +68 -2
  39. package/skills/decision-surrogate/SKILL.md +87 -0
  40. package/skills/decision-surrogate/references/decision-points.md +87 -0
  41. package/skills/decision-surrogate/references/onboarding.md +79 -0
  42. package/skills/decision-surrogate/references/protocols.md +116 -0
  43. package/skills/workflow-orchestrator/references/s5-monitoring.md +8 -4
  44. package/skills/workflow-start/SKILL.md +4 -0
  45. package/templates/conventions/glaf4-compliant/java-testing.md +3 -3
  46. package/templates/conventions/js-testing.md +1 -1
  47. package/templates/conventions/python-testing.md +1 -1
  48. package/.zcode/hooks.json +0 -8
  49. package/.zcode/rules/phase-guard.mdc +0 -33
  50. package/.zcode/skills/workflow-start/SKILL.md +0 -175
@@ -46,7 +46,7 @@ For each example in `docs/examples/`:
46
46
  - `node scripts/team-flow.mjs version <version> --dry-run` — reports all files in sync
47
47
  - `node scripts/check-version-consistency.mjs` — exits 0
48
48
  - `node scripts/team-flow.mjs --help` — all subcommands listed
49
- - `node scripts/team-flow.mjs install-workbuddy --dry-run` — finds all 9 skills and target paths
49
+ - `node scripts/team-flow.mjs install-workbuddy --dry-run` — finds all 28 skills and target paths
50
50
  - `npm run test:raw-mode` — packs the current source and runs a canonical runtime in an empty directory with no plugin-root variables or global `tf`.
51
51
  - Run a representative local-installer smoke test.
52
52
  - `team-flow.config.json` absence still works (backward compatible defaults)
@@ -1,6 +1,6 @@
1
1
  # team-flow 使用说明(研发团队版)
2
2
 
3
- > 版本锚点:v0.50.0(26 skills + 17 agents)· 更新日期:2026-09-09
3
+ > 版本锚点:v0.59.0(28 skills + 17 agents)· 更新日期:2026-09-12
4
4
  > 读者:使用 team-flow 做日常研发的工程师。不需要你懂插件内部实现,只需要照着路径走。
5
5
  > 配套文档:安装细节见 [INSTALL.md](../INSTALL.md);状态机细节见 [state-machine.md](state-machine.md);决策点细节见 [decision-points.md](decision-points.md);平台差异见 [platform-matrix.md](platform-matrix.md)。
6
6
 
@@ -36,7 +36,7 @@
36
36
  | 大需求拆成一团乱麻,改 A 坏 B | 产品级编排拆分 change + 依赖 DAG + 跨 change 冲突检测 |
37
37
  | 会话中断后上下文全丢 | 状态持久化在 `.team-flow.yaml`,新会话可无损恢复 |
38
38
 
39
- **规模感知**:24 个 skills(工作流能力)+ 15 个 agents(子代理角色)+ 1 个 `tf` CLI(状态机与门禁运行时)。你日常真正需要记住的入口只有 **3 个**(见第 3 节)。
39
+ **规模感知**:28 个 skills(工作流能力)+ 17 个 agents(子代理角色)+ 1 个 `tf` CLI(状态机与门禁运行时)。你日常真正需要记住的入口只有 **3 个**(见第 3 节)。
40
40
 
41
41
  ### 双层编排架构
42
42
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-flow",
3
- "description": "Unified workflow plugin: team-flow (spec-driven dev) + compound-engineering core subset + architecture-design (4A/DDD) + prototype (local HTML) + business-analysis (independent requirement/scenario artifact). 26 skills, one install.",
4
- "version": "0.57.0",
3
+ "description": "Unified workflow plugin: team-flow (spec-driven dev) + compound-engineering core subset + architecture-design (4A/DDD) + prototype (local HTML) + business-analysis (independent requirement/scenario artifact). 28 skills, one install.",
4
+ "version": "0.59.0",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env bash
2
- # v0.57.0: auto-sync CLI version with plugin version
2
+ # v0.59.0: auto-sync CLI version with plugin version
3
3
  set -e
4
4
 
5
5
  # ═══════════════════════════════════════════════════════════════
6
6
  # Plugin version (update this when releasing new versions)
7
7
  # ═══════════════════════════════════════════════════════════════
8
- PLUGIN_VERSION="0.57.0"
8
+ PLUGIN_VERSION="0.59.0"
9
9
 
10
10
  # ═══════════════════════════════════════════════════════════════
11
11
  # Step 1: Auto-sync CLI version with plugin version
package/llms.txt CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Overview
4
4
  spec-superflow is a self-contained workflow integration plugin for Claude Code, Cursor, OpenAI Codex CLI/App, GitHub Copilot CLI, Gemini CLI, OpenCode, WorkBuddy, and Trae. It merges spec-driven planning artifacts (proposal, specs, design, tasks) with disciplined execution guardrails (TDD, review gates, controlled handoff) into one unified workflow.
5
5
 
6
- Current version: v0.57.0.
6
+ Current version: v0.59.0.
7
7
 
8
8
  ## Key Documents
9
9
  - README.md: Chinese homepage with full usage guide and FAQ
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xulthekl/team-flow",
3
- "version": "0.57.0",
4
- "description": "Unified plugin (26 skills + 17 agents) integrating team-flow, compound-engineering, architecture-design, prototype, design-system, workflow-orchestrator, workflow-bootstrap, e2e, session-handoff, workflow-feedback, business-analysis for multi-agent coding tools.",
3
+ "version": "0.59.0",
4
+ "description": "Unified plugin (28 skills + 17 agents) integrating team-flow, compound-engineering, architecture-design, prototype, design-system, workflow-orchestrator, workflow-bootstrap, e2e, session-handoff, workflow-feedback, business-analysis for multi-agent coding tools.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "team-flow",
3
- "version": "0.57.0",
4
- "description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking) + business-analysis (independent requirement/scenario artifact) + design-system (design tokens + component contract + AI primer + showcase) + test-strategy (test strategy design) + project-initialize (new service onboarding). 26 skills + 17 agents, one install.",
3
+ "version": "0.59.0",
4
+ "description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking) + business-analysis (independent requirement/scenario artifact) + design-system (design tokens + component contract + AI primer + showcase) + test-strategy (test strategy design) + project-initialize (new service onboarding). 28 skills + 17 agents, one install.",
5
5
  "author": {
6
6
  "name": "LT"
7
7
  },
@@ -71,6 +71,9 @@ const TEXT_CHECKS = [
71
71
  { file: 'llms.txt', extract: /Current version: v(\d+\.\d+\.\d+)\./ },
72
72
  { file: '.claude/always/phase-guard.md', extract: /# team-flow v(\d+\.\d+\.\d+) \|/ },
73
73
  { file: 'GEMINI.md', extract: /# team-flow v(\d+\.\d+\.\d+) \|/ },
74
+ // v0.59.0:新增 usage-guide 版本锚点(此前不在扫描面内,0.58.0 与 0.59.0 两次发版均靠人工改;
75
+ // P3-15 ② 半项闭合——**检出**已覆盖,本段仍无 --fix 分支,自动修复待做)
76
+ { file: 'docs/usage-guide.md', extract: /版本锚点:v(\d+\.\d+\.\d+)/ },
74
77
  ];
75
78
 
76
79
  for (const check of TEXT_CHECKS) {
@@ -103,9 +106,19 @@ const skillDirs = readdirSync(skillsDir, { withFileTypes: true })
103
106
  const ACTUAL_SKILL_COUNT = skillDirs.length;
104
107
 
105
108
  // JSON manifests: extract the "N skills" number from the description field.
109
+ // v0.59.0:扫描面扩展至全部含计数的宿主 manifest——此前仅覆盖 2 个 JSON + 2 个 md,
110
+ // 其余 10+ 处靠人工,是「计数漂移反复发生」的根因(0.58.0 漏 13+ 处、0.59.0 又漏
111
+ // INSTALL.md / platform-matrix.md / usage-guide.md 共 3 文件)。path 支持嵌套与数组下标。
106
112
  const SKILL_COUNT_JSON_CHECKS = [
107
113
  { file: 'plugin.json', path: ['description'], extract: /(\d+) skills/ },
108
114
  { file: '.claude-plugin/plugin.json', path: ['description'], extract: /(\d+) skills/ },
115
+ { file: '.claude-plugin/marketplace.json', path: ['description'], extract: /(\d+) skills/ },
116
+ { file: '.claude-plugin/marketplace.json', path: ['plugins', '0', 'description'], extract: /(\d+) skills/ },
117
+ { file: '.cursor-plugin/plugin.json', path: ['description'], extract: /(\d+) skills/ },
118
+ { file: '.cursor-plugin/marketplace.json', path: ['plugins', '0', 'description'], extract: /(\d+) skills/ },
119
+ { file: '.codex-plugin/plugin.json', path: ['interface', 'longDescription'], extract: /(\d+) skills/ },
120
+ { file: 'gemini-extension.json', path: ['description'], extract: /(\d+) skills/ },
121
+ { file: 'package.json', path: ['description'], extract: /(\d+) skills/ },
109
122
  ];
110
123
 
111
124
  for (const check of SKILL_COUNT_JSON_CHECKS) {
@@ -123,11 +136,20 @@ for (const check of SKILL_COUNT_JSON_CHECKS) {
123
136
  errors.push({ file: `${check.file} [${check.path.join('.')}]`, found: 'PATTERN_NOT_MATCHED', expected: ACTUAL_SKILL_COUNT });
124
137
  } else if (Number(match[1]) !== ACTUAL_SKILL_COUNT) {
125
138
  if (AUTO_FIX) {
126
- // Auto-fix: update skill count in JSON
139
+ // Auto-fix: update skill count in JSON.
140
+ // v0.59.0 修复:原实现只写顶层键(把 path[0] 直接赋成新值),对嵌套路径
141
+ // (plugins[0].description、interface.longDescription)会把父级整体覆盖成字符串 → 毁文件。
142
+ // 改为按完整路径回溯写回,并在路径不可写时显式报错而非静默跳过。
127
143
  const newVal = val.replace(check.extract, `${ACTUAL_SKILL_COUNT} skills`);
128
- obj[check.path[0]] = newVal;
129
- writeFileSync(fp, JSON.stringify(obj, null, 2) + '\n', 'utf-8');
130
- fixes.push(`${check.file}: ${match[1]} → ${ACTUAL_SKILL_COUNT}`);
144
+ let target = obj;
145
+ for (let i = 0; i < check.path.length - 1; i += 1) target = target?.[check.path[i]];
146
+ if (target && typeof target === 'object') {
147
+ target[check.path[check.path.length - 1]] = newVal;
148
+ writeFileSync(fp, JSON.stringify(obj, null, 2) + '\n', 'utf-8');
149
+ fixes.push(`${check.file}: ${match[1]} → ${ACTUAL_SKILL_COUNT}`);
150
+ } else {
151
+ errors.push({ file: `${check.file} [${check.path.join('.')}]`, found: 'FIX_PATH_UNWRITABLE', expected: ACTUAL_SKILL_COUNT });
152
+ }
131
153
  } else {
132
154
  errors.push({ file: `${check.file} [${check.path.join('.')}]`, found: match[1], expected: ACTUAL_SKILL_COUNT });
133
155
  }
@@ -138,9 +160,17 @@ for (const check of SKILL_COUNT_JSON_CHECKS) {
138
160
  }
139
161
 
140
162
  // Text files: extract the documented skill count.
163
+ // v0.59.0:新增 usage-guide / platform-matrix / INSTALL.md(后者 3 条精确规则——不能用全局
164
+ // 「N 个 skill」替换,因为 :797 的「其余 27 个」是 count-1,会被误改)。
141
165
  const SKILL_COUNT_TEXT_CHECKS = [
142
166
  { file: 'README.md', extract: /(\d+) skills/, replace: (content, count) => content.replace(/(\d+) skills/, `${count} skills`) },
143
167
  { file: 'AGENTS.md', extract: /Skills 索引((\d+) 个)/, replace: (content, count) => content.replace(/Skills 索引((\d+) 个)/, `Skills 索引(${count} 个)`) },
168
+ { file: 'docs/usage-guide.md', extract: /(\d+) 个 skills/, replace: (content, count) => content.replace(/(\d+) 个 skills/, `${count} 个 skills`) },
169
+ { file: 'docs/platform-matrix.md', extract: /(\d+) 个 skill 部署/, replace: (content, count) => content.replace(/(\d+) 个 skill 部署/, `${count} 个 skill 部署`) },
170
+ { file: 'INSTALL.md', extract: /应有 (\d+) 个 skill 目录/, replace: (content, count) => content.replace(/(\d+) 个 skill 目录/g, `${count} 个 skill 目录`) },
171
+ { file: 'INSTALL.md', extract: /包含 (\d+) 个 skill、/, replace: (content, count) => content.replace(/(\d+) 个 skill、/, `${count} 个 skill、`) },
172
+ { file: 'INSTALL.md', extract: /← (\d+) 个 skill(/, replace: (content, count) => content.replace(/← (\d+) 个 skill(/, `← ${count} 个 skill(`) },
173
+ { file: 'docs/release-checklist.md', extract: /all (\d+) skills/, replace: (content, count) => content.replace(/all (\d+) skills/, `all ${count} skills`) },
144
174
  ];
145
175
 
146
176
  for (const check of SKILL_COUNT_TEXT_CHECKS) {
@@ -7,7 +7,7 @@ export function checkDp3Approved(changeDir) {
7
7
  if (!decision) {
8
8
  return {
9
9
  pass: false,
10
- failures: ['DP-3 (dp_3_result) is not recorded — minimal contract approval is required before hotfix build'],
10
+ failures: ['DP-3 (dp_3_result) is not recorded — contract approval is required before build'],
11
11
  };
12
12
  }
13
13
 
@@ -33,7 +33,13 @@ const TRANSITION_CHECKS = {
33
33
  //(arch_baseline 缺失 → WARN 不 FAIL,项目级豁免)。
34
34
  'exploring:specifying': ['arch-design', 'arch-readiness'],
35
35
  'specifying:bridging': ['artifacts-exist', 'schema-valid'],
36
- 'bridging:approved-for-build': ['artifacts-exist', 'schema-valid', 'contract-fresh', 'dp-gate-passed'],
36
+ // v0.59.0(decision-surrogate P4 审查发现):**dp3-approved 新增**——原状 full 该转换只查
37
+ // dp-gate-passed(仅要求 dp_3_result 非空),而取值严格校验的 dp3-approved 只挂在 hotfix
38
+ // (见下方 WORKFLOW_TRANSITION_CHECKS)→ **安全档位倒置**:更重要的 full 用弱校验。后果是
39
+ // 任何能写 dp_3_result 的主体(含夜间替身的 HOLD 落盘)都能让 change 呈现"已批准"假象,
40
+ // 从而在无真实批准的前提下跨过 DP-3 硬门。本维度要求取值以 "approved" 开头
41
+ // (判据实现见 checks/dp3-approved.mjs)。
42
+ 'bridging:approved-for-build': ['artifacts-exist', 'schema-valid', 'contract-fresh', 'dp-gate-passed', 'dp3-approved'],
37
43
  // v0.13 §49:test-matrix-ready 门禁前移——full 模式进入 executing 前强制测试准备度
38
44
  //(矩阵存在非空 OR 显式 skip 附理由;legacy 豁免)。hotfix/tweak 沿用 §45.3 豁免,不挂。
39
45
  'approved-for-build:executing': ['artifacts-exist', 'contract-fresh', 'dp-gate-passed', 'execution-plan-ready', 'test-matrix-ready'],
@@ -18,15 +18,18 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
18
18
  const SETTABLE_FIELDS = [
19
19
  'workflow', 'batches_completed', 'spec_merged',
20
20
  'dp_0_decisions', 'dp_0_confirmed', 'dp_0_timestamp', 'dp_0_result',
21
- 'dp_1_result', 'dp_1_timestamp', 'dp_1_decisions', 'dp_1_confirmed',
22
- 'dp_2_result', 'dp_2_timestamp', 'dp_2_decisions', 'dp_2_confirmed',
23
- 'dp_3_result', 'dp_3_timestamp', 'dp_3_decisions', 'dp_3_confirmed',
21
+ // v0.59.0(P4 实测):dp_{1,2,3,5,6,7}_decisions / _confirmed 共 12 个字段已移除——
22
+ // 它们虽在旧白名单内,但 writeState 无对应序列化分支,tf state set 会**回显成功却零写入**
23
+ // (静默假成功;全仓零消费者)。dp_0_decisions / dp_0_confirmed 保留(二者确有序列化分支)。
24
+ 'dp_1_result', 'dp_1_timestamp',
25
+ 'dp_2_result', 'dp_2_timestamp',
26
+ 'dp_3_result', 'dp_3_timestamp',
24
27
  // v2.1 §6.6/§6.7:GLAF4 委托决策与状态位(dp_4_result 仍由 tf execution plan --confirm 程序化写入,不在列表)
25
28
  'dp_4_glaf4_mode', 'dp_4_write_set_hash',
26
29
  'delegation_status', 'delegation_retry_count', 'delegation_partial_writes',
27
- 'dp_5_result', 'dp_5_timestamp', 'dp_5_decisions', 'dp_5_confirmed',
28
- 'dp_6_result', 'dp_6_timestamp', 'dp_6_decisions', 'dp_6_confirmed',
29
- 'dp_7_result', 'dp_7_timestamp', 'dp_7_decisions', 'dp_7_confirmed',
30
+ 'dp_5_result', 'dp_5_timestamp',
31
+ 'dp_6_result', 'dp_6_timestamp',
32
+ 'dp_7_result', 'dp_7_timestamp',
30
33
  // Architecture design gate (v0.9 §26, v0.22.5 评审修复 F02)
31
34
  'arch_design_decision', 'arch_design_reason',
32
35
  'arch_design_timestamp', 'arch_design_artifacts',
@@ -10,6 +10,13 @@ date: 2026-07-31
10
10
  > 本文件由 team-flow 被动式自动沉淀机制维护(v0.11 §33)。
11
11
  > 请勿手动编辑模板——此文件作为参考模板,实际项目规范在 `.team-flow/conventions/frontend-patterns.md` 中维护。
12
12
 
13
+ ## 魔法值(v0.58.0)
14
+
15
+ - **数值 / 字符串字面量 MUST NOT 散落在模板与脚本中**——收敛到 `src/constants/` 下的常量模块,或组件内具名常量。
16
+ - 判据归属:`clean-code` skill 的「魔法值(前端)」判据,分级 **Critical**(与后端「不允许魔法常量」对齐;此前前端无任何等价约束)。
17
+ - 可豁免:结构性索引(如 `arr[0]`)、CSS 取值、仅出现一次且语义自明的字面量。
18
+ - 背景:v1 实测中前端因无约束,同一 change 内出现 21 处硬编码业务码与状态值,被审查降级为 Minor。
19
+
13
20
  ## 框架选型
14
21
  - (项目级规范在此补充,如:Vue 2 Options API)
15
22
 
@@ -72,6 +72,8 @@ RED (write test, see it fail) → GREEN (write minimal code, see it pass) → RE
72
72
  ### Law 3: Review Before Drift
73
73
  Block on: logic defects, spec violations, missing required tests, unintended scope expansion.
74
74
 
75
+ **Structural criteria(clean-code,v0.58.0)**:魔法值(未命名字面量)= Critical;函数长度 / 嵌套深度 / 参数个数 / 命名形式 = Minor;单一职责与 DRY 为审查必答项(无阈值)。**执行处是三个派发模板**(`implementer-prompt.md` / `task-reviewer-prompt.md` / `code-reviewer-prompt.md`)——它们各自内联了完整判据,因为由模板派发的子代理读不到 skill。本摘要仅供编排参考;判据真相源见 `clean-code` skill。
76
+
75
77
  ### Law 4: Rewind on Contract Break
76
78
  Return to `specifying` or `bridging` if: new behavior appears, interfaces change materially, design assumptions fail, artifacts no longer define intended implementation.
77
79
 
@@ -130,6 +130,25 @@ Subagent (general-purpose):
130
130
  - Are names clear and accurate (match what things do, not how they work)?
131
131
  - Is the code clean and maintainable?
132
132
 
133
+ **Structural criteria** — apply to every function this change adds or modifies:
134
+
135
+ - **Magic values** (unnamed numeric/string literals): name them as constants or enums.
136
+ This is **Critical** — do not ship unnamed literals. Applies to front-end code too.
137
+ - **Function length** >20 lines, **nesting depth** >2 levels, parameters >3,
138
+ **naming form** (constants SCREAMING_SNAKE; booleans `is`/`has`/`can` prefix):
139
+ Minor. When counting nesting, exclude try/catch's own level and guard-clause
140
+ `return`/`continue` levels; framework-fixed signatures are exempt from the
141
+ parameter rule.
142
+ - **Single responsibility**: can the function name cover ALL steps in the body?
143
+ If not, split it — or state in your report which steps it cannot cover.
144
+ - **DRY**: is there a structurally equivalent logic block elsewhere in THIS repository
145
+ (ignore comments, whitespace, identifier names)? If the duplicate lives in the same
146
+ shared publish unit (same package / module / directory), extract a shared layer
147
+ rather than copying — if you judge copying is right, say why in your report.
148
+ - **Pre-existing code**: these criteria apply only to what this change touches. A hit
149
+ inside a function that already existed is Minor — register it in your report as
150
+ `存量待整改` rather than restructuring outside your task scope.
151
+
133
152
  **Discipline:**
134
153
  - Did I avoid overbuilding (YAGNI)?
135
154
  - Did I only build what was requested?
@@ -100,6 +100,40 @@ Subagent (general-purpose):
100
100
  - DRY without premature abstraction?
101
101
  - Edge cases handled?
102
102
 
103
+ **Structural criteria (clean-code) — mechanical thresholds:**
104
+ - **Magic values** (unnamed numeric/string literals) → **Critical**. Front-end code too.
105
+ - Function length >20 lines / nesting depth >2 levels / parameters >3 / naming form
106
+ (constants SCREAMING_SNAKE; booleans `is`/`has`/`can` prefix) → Minor. When counting
107
+ nesting, exclude try/catch's own level and guard-clause `return`/`continue` levels;
108
+ framework-fixed signatures are exempt from the parameter rule.
109
+
110
+ **Incremental boundary — applies to ALL criteria above and below**: judge only the code
111
+ units this diff adds or modifies. When a hit sits inside a function that already existed
112
+ before this change, downgrade it to **Minor** and register it as `存量待整改` in your
113
+ report — never ask for a rewrite outside the task scope.
114
+
115
+ **Structural criteria — mandatory answers** (no threshold: answer AND justify):
116
+ - **Single responsibility**: can the function name cover ALL steps in the body?
117
+ - **DRY**: is there a structurally equivalent logic block within this diff OR this
118
+ repository (ignore comments, whitespace, identifier names)? Answer "yes" only when
119
+ you cite BOTH `file:line` sides.
120
+ - Disposition: same shared publish unit (same package / module / directory) →
121
+ **Critical**, extract a shared layer. Cross-repo duplication is NOT judgeable
122
+ here (your worktree is single-repo).
123
+
124
+ **Judgement cases** — when a structural hit is genuinely not blocking, cite it as
125
+ `judgement-exception: <id>` **plus the structural similarity** (e.g. "all guard clauses,
126
+ no nesting"). Match by **structural features, not line count** — the numbers below
127
+ illustrate the case, they are not thresholds. Available ids:
128
+ - `P1` — long function (≈37 lines) whose body is all guard clauses, one abstraction level → not blocking
129
+ - `P2` — cross-repo isomorphic fix, no shared publish unit → not blocking
130
+ - `N1` — long function (≈54 lines) that is guard clauses + one switch, no nesting → not blocking
131
+ - `N2` — deep nesting arising from try/catch + guard-clause `continue` → already covered
132
+ by the nesting rule (cite only if that rule's intent is disputed)
133
+ - `N4` — ≈35 lines, single abstraction level (error mapping) → advisory only
134
+ - Magic-value exemptions beyond the criterion's list: no id needed — apply the criterion's
135
+ own test ("does changing this value change behavior?") and state your reasoning.
136
+
103
137
  **Tests:**
104
138
  - Do the new and changed tests verify real behavior, not mocks?
105
139
  - Are the task's edge cases covered?
@@ -127,12 +161,12 @@ Subagent (general-purpose):
127
161
  Categorize issues by actual severity. Not everything is Critical.
128
162
  Important means this task cannot be trusted until it is fixed: incorrect
129
163
  or fragile behavior, a missed requirement, or maintainability damage you
130
- would block a merge over — verbatim duplication of a logic block,
131
- swallowed errors, tests that assert nothing. "Coverage could be broader"
132
- and polish suggestions are Minor.
164
+ would block a merge over — structurally equivalent duplication of a logic
165
+ block (see Structural criteria), swallowed errors, tests that assert
166
+ nothing. "Coverage could be broader" and polish suggestions are Minor.
133
167
  If the plan or brief explicitly mandates something this rubric calls a
134
- defect (a test that asserts nothing, verbatim duplication of a logic
135
- block), that IS a finding — report it as Important, labeled
168
+ defect (a test that asserts nothing, structurally equivalent duplication
169
+ of a logic block), that IS a finding — report it as Important, labeled
136
170
  plan-mandated. The plan's authorship does not grade its own work; the
137
171
  human decides.
138
172
  Acknowledge what was done well before listing issues — accurate praise
@@ -161,6 +195,18 @@ Subagent (general-purpose):
161
195
  diff alone, and what the controller should check — report alongside the
162
196
  ✅/❌ verdict for everything you could verify]
163
197
 
198
+ ### Structural Criteria (mandatory answers)
199
+
200
+ Answer both; cite `file:line` for each. If you downgrade by citing a judgement
201
+ case, name it here as `judgement-exception: <id>` plus the structural similarity.
202
+
203
+ - **Single responsibility**: [Yes | No — if No, list the steps the function name
204
+ cannot cover, with file:line]
205
+ - **DRY**: [Yes | No — if Yes, cite BOTH `file:line` sides + shared-layer disposition]
206
+
207
+ **存量待整改** (pre-existing hits downgraded to Minor — one per line, or "none"):
208
+ - [e.g. `src/foo/Bar.java:120` — function length >20 lines, pre-existing]
209
+
164
210
  ### Strengths
165
211
  [What's well done? Be specific.]
166
212
 
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: clean-code
3
+ description: 代码结构质量判据 skill——可机械判定项阈值与计数口径、审查必答项、增量归因边界与共享层判定。
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Clean Code
8
+
9
+ 代码结构质量的判据集。判据三分:能机械判定的给阈值;需要判断力的设为「必答项」(不给阈值,但必须回答并给理由);既有的不动。
10
+
11
+ 判例集与判例引用约定见 `references/judgement-cases.md`;共享层判定的完整规则见 `references/shared-layer-rules.md`。
12
+
13
+ > **执行处说明**:本文件是判据**真相源**。实际执行由**派发模板**承载——`skills/build-executor/implementer-prompt.md`(实施自检)、`skills/build-executor/task-reviewer-prompt.md`、`skills/code-reviewer/code-reviewer-prompt.md`(审查)各自内联判据,因为由模板派发的 `general-purpose` 子代理读不到本文件。两侧须保持一致。
14
+
15
+ ## 1. 判据三分
16
+
17
+ | 类型 | 判据 | 处置 |
18
+ |---|---|---|
19
+ | 可机械判定项 | 魔法值、函数长度、嵌套深度、参数个数、命名形式 | 查表 §2 |
20
+ | 审查必答项 | 单一职责、DRY | 必答 §3(不给阈值)|
21
+ | 沿用既有清单项 | 错误处理、边界条件、YAGNI/过度设计 | 本 skill 不涉及,由原清单负责 |
22
+
23
+ 为何不给「单一职责」设阈值:它需要判断力,阈值化会制造查表错觉。实测反证——37 行的 `validateFrontSystemSecret`(通体卫语句、单层抽象)可读性良好;54 行的 `handleDelivery`(三个卫语句 + switch + catch)同样良好。任何「抽象层级计数」规则都无法在这一对同类样本上复现判定,故该规则已废。
24
+
25
+ ## 2. 可机械判定项
26
+
27
+ | 判据 | 阈值 | 分级 | 例外 |
28
+ |---|---|---|---|
29
+ | 魔法值(后端)| 见下方口径 | **Critical** | 见下方豁免 |
30
+ | 魔法值(前端)| 同上 | **Critical** | 同上 |
31
+ | 函数长度 | >20 行 | Minor | 存量代码(§4)|
32
+ | 嵌套深度 | >2 层 | Minor | 见下方计数口径 |
33
+ | 参数个数 | >3 个 | Minor | 框架接口固定签名不适用 |
34
+ | 命名(形式)| 常量非 SCREAMING_SNAKE;布尔非 `is` · `has` · `can` 前缀 | Minor | 仅判形式;命名是否揭示意图属审查者判断,在报告中说明即可 |
35
+
36
+ ### 2.1 魔法值判据口径(真相源)
37
+
38
+ - **定义**:直接出现在逻辑中的数值 / 字符串字面量,**其值变化会改变行为**。典型:业务码、TTL / 超时、阈值、错误消息、键名、URL、正则。
39
+ - **豁免**:结构性索引(`arr[0]`、`list.get(0)`)、算术恒等元(`i + 1`、`x * 1`)、空串 / 空集合判断、CSS 取值、注解参数、日志格式串、测试夹具中自明数据、生成代码。
40
+ - **适用范围**:`src/main` 与前端**运行时**代码。**不适用**于测试代码、构建脚本、SQL 迁移。
41
+ - **交付形态**:命名为常量或枚举(枚举用于有语义集合,纯常量入常量类)。
42
+
43
+ > 项目 conventions 若给出更严或更宽的豁免,以 conventions 为准(§7)。
44
+
45
+ ### 2.2 计数口径
46
+
47
+ - **函数长度**:按**有效行**计——不含空行与纯注释行;**签名行计入**。
48
+ - **嵌套深度**:函数体为第 1 层,每进入一个块(`if` / `for` / `while` / `switch` / `try`)加 1。**排除** `try/catch` 自身一层与卫语句(`return` / `continue`)所在层;`try/catch` 仅排除自身,其体内语句仍计入。
49
+
50
+ 函数长度恒为提示级,不设升级线:曾拟「>50 行升 Important」,但该阈值系从样本反推(过拟合),且会与存量长函数冲突。长度异常的价值由 §3 的必答项综合判断承载。
51
+
52
+ ## 3. 审查必答项(不给阈值,须给理由)
53
+
54
+ | 判据 | 判定要件 | 必答格式 |
55
+ |---|---|---|
56
+ | 单一职责 | 函数名能否概括函数体的全部步骤? | 必须回答「是 / 否」;答「否」须列出无法概括的步骤 + 分级理由。**不单独升级为 Critical** |
57
+ | DRY | 本 diff 内或本仓内是否存在结构等价的逻辑块(忽略注释、空白、标识符命名)? | 必须回答;答「是」须给两侧 `文件:行号` + 结构对比 + 按 §5 判定处置。**同共享发布单元内的重复 = Critical**(见 §5)|
58
+
59
+ 效力边界(诚实声明):必答格式使发现过程可被第三方核对,提升的是发现一致性,不是判定一致性——分级仍由审查者判断,「须给理由」也可能被套用现成话术。故单一职责不单独升 Critical,避免用一条无客观约束的判据制造阻断。
60
+
61
+ 判例引用出口:审查者可在报告中标注 `judgement-exception: <判例编号>`(编号与含义见 `references/judgement-cases.md`,模板侧同步内联)以引用客观例外,须同时写明与该判例的相似点。该机制用于防止用现成话术无边界降级;**机械判定项同样可引用**(判例 `P1` / `N2` / `N4` 即针对长度与嵌套)。
62
+
63
+ ## 4. 增量归因边界
64
+
65
+ 判据只判本次 diff 新增或修改的行所属的代码单元。
66
+
67
+ | 情形 | 处置 |
68
+ |---|---|
69
+ | 新增函数命中 | 按 §2 / §3 正常判定 |
70
+ | 存量函数命中(本次改动前已存在)| 一律降 Minor,并在审查报告中登记「存量待整改」(函数名 + `文件:行号` + 命中判据)|
71
+
72
+ 为何不设「改动占比」阈值:函数总行数不在 diff hunk 内、而审查者被限制读文件,无取证通道;且按次求值可被「两次各改 40%」规避。存量恒为 Minor ⇒ 无豁免判定、无计算需求、无规避动机。台账经审查报告累积。
73
+
74
+ ## 5. 共享层判定(结论)
75
+
76
+ | 步 | 判据 | 判定 |
77
+ |---|---|---|
78
+ | 1 | 复制体是否在同一共享发布单元内(同 npm 包 / 同 Maven 模块 / 同仓同目录)? | **是 → 应抽共享层**(Critical)|
79
+ | 2 | 缺陷是否属同名耦合类(编译期无保护)?若是,横展须逐字节同构并留对端标注 | 附加条件 |
80
+
81
+ **跨仓不可判**:审查者 worktree 为单仓;跨仓 DRY 归横展完整性检查承接。完整规则、判定依据与 v1 实测校验见 `references/shared-layer-rules.md`。
82
+
83
+ ## 6. 取证边界
84
+
85
+ DRY 的取证范围是「本 diff 内或本仓内」,两条派发路径的依据不同:
86
+
87
+ - task 级审查(`skills/build-executor/task-reviewer-prompt.md`):显式授权——「Inspect code outside the diff only to evaluate a concrete risk you can name — one focused check per named risk」
88
+ - wave 级审查(`skills/code-reviewer/code-reviewer-prompt.md`):无禁止性条款(约束仅有 read-only 与 scope 限制)
89
+
90
+ 「须给两侧 `文件:行号`」这一格式要求本身即构成上述条款所要求的「命名的具体风险」。
91
+
92
+ ## 7. 与 conventions 的关系
93
+
94
+ - conventions 优先:项目 conventions 与本 skill 冲突时以项目为准(项目级契约 > 通用缺省)。
95
+ - 追加通道:项目可沉淀「本项目特有的结构约定」,格式参照项目级 `backend-patterns.md` 的 `MUST + 来源 + 证据段` 范式。
96
+ - 引用约定:conventions 引用插件侧 references 时 MUST 写全路径 `skills/<skill>/references/<file>.md`,不得写裸 `references/...`。
97
+ - 参数口径:`test-strategy` 的 `param_count>6` 判测试复杂度,本 skill 的「参数 >3」判可读性——管辖不同,非矛盾。
98
+
99
+ ## 8. 自检口诀
100
+
101
+ 新增函数交付前逐条自查:常量命名了吗?超 20 行了吗?嵌套超 2 层了吗?只做一件事吗?与其他地方重复吗?
102
+
103
+ ## 9. 术语中英对照
104
+
105
+ 本 skill 以中文面向读者;三个派发模板以英文内联执行(受众为 `general-purpose` 子代理)。两侧判据**语义相同**,P4 一致性检查按下表比对:
106
+
107
+ | 中文(本 skill)| English(模板内联)|
108
+ |---|---|
109
+ | 魔法值 | Magic values |
110
+ | 单一职责 | Single responsibility |
111
+ | 结构等价 | structurally equivalent |
112
+ | 共享发布单元 | shared publish unit |
113
+ | 存量待整改 | pre-existing / register as 存量待整改 |
114
+ | 判例引用出口 | judgement-exception |
115
+ | 必答项 | mandatory answers |
116
+ | 增量归因边界 | incremental boundary |
@@ -0,0 +1,83 @@
1
+ # 判例集(Judgement Cases)
2
+
3
+ > **用途**:为「审查必答项」(单一职责 / DRY)提供**客观锚点**,防止判据退化成新的直觉。
4
+ > **全部判例均取自 emp-auth v1 的真实代码**,非虚构。
5
+
6
+ ## 判例引用约定
7
+
8
+ 审查者在报告中对某项判定可标注:
9
+
10
+ ```
11
+ judgement-exception: <P1|P2|N1|N2|N4>
12
+ ```
13
+
14
+ 含义:**该降级属客观例外**(非主观放行)。使用要求:
15
+
16
+ 1. 必须同时写明「本处与所引判例的相似点」(至少一条结构性事实,如"通体卫语句、无嵌套");
17
+ 2. 引用判例**不改变**判据本身的阈值适用——它只解释为何某项判定不阻断;
18
+ 3. 若某处与判例只有表面相似(如"也超 20 行"但结构不同),引用无效,按正常分级处理。
19
+
20
+ **为何需要这个出口**:`task-reviewer-prompt.md` 既有条款 "a stated rationale never downgrades a finding's severity" 约束的是**实施者的自述**;本出口约束的是**审查者的判定**,两者主体不同。判例编号把「判定」从「话术」中分离出来——引用必须有结构性事实支撑。
21
+
22
+ ## 一、判为「Critical(阻断)」的锚点
23
+
24
+ ### N3 — 同一共享单元内的结构等价复制
25
+
26
+ | 项 | 内容 |
27
+ |---|---|
28
+ | **位置** | emp-auth v1-C2 `ui-emp-frame/src/views/iam/relay.vue:19-52`(常量 + `hasControlChar` + `isValidFrontSystem`,其中 `isValidFrontSystem` 在 `:44`)→ v1-C3 同仓 `logout.vue:12-44`(在 `:35`)|
29
+ | **判定** | **Critical**(DRY)|
30
+ | **依据** | §5 步 1「同一共享发布单元内」成立:同一 npm 包、同仓同目录 |
31
+ | **取证** | 两侧同在本仓 → 可达(`code-reviewer-prompt.md` 无禁止性条款;task 级有显式授权)|
32
+ | **要点** | 结构等价判定**忽略注释差异**——两处注释分别为「SP-1 裁定 / design.md D-01」与「与登录入口 relay.vue 同口径」,不作为"非重复"的依据 |
33
+
34
+ ## 二、判为「不阻断」的锚点(防止过度阻断)
35
+
36
+ ### P1 — 长函数但结构清晰
37
+
38
+ | 项 | 内容 |
39
+ |---|---|
40
+ | **位置** | emp-auth v1-C1 `infra-emp-auth` `SysFrontSystemService.java:382-418`(`validateFrontSystemSecret`,37 行)|
41
+ | **判定** | 不阻断(长度属提示级)|
42
+ | **理由** | 通体卫语句早返回、无嵌套、每步有意图注释 |
43
+ | **反面对照价值** | 该函数内含 repository 调用、枚举判断、摘要算法与结果装配 —— **故「抽象层级计数」不可作为判据**(同一规则会把它与 N1 混为一谈,得出相反判定)|
44
+
45
+ ### P2 — 跨单元的必要横展
46
+
47
+ | 项 | 内容 |
48
+ |---|---|
49
+ | **位置** | emp-auth v1-C5 `AuthService.java:47`(两个 BFF 仓各删 1 行 `@Cacheable`)|
50
+ | **判定** | 不阻断 |
51
+ | **依据** | 跨仓、无共享发布单元、无可用共享通道 → 必要横展(见 `shared-layer-rules.md`)|
52
+ | **注意** | 本判例**不在** `clean-code` 的 DRY 判据范围内(跨仓不可判),归 `cross-change-consistency-checker` 的 Dim 5 承接。列此仅为说明「跨单元 ≠ 应抽层」的边界 |
53
+
54
+ ### N1 — 多职责外观但实为单一层次
55
+
56
+ | 项 | 内容 |
57
+ |---|---|
58
+ | **位置** | emp-auth v1-C3 `bff-emp-usersidentification` `AcceptInvalidTokenConsumer.java:57-115`(`handleDelivery`)|
59
+ | **判定** | 不阻断 |
60
+ | **理由** | 三个卫语句早返回 + 一个 switch + catch 兜底,**通体无嵌套** |
61
+ | **历史** | 曾被判「阻断」,理由为「混合域判断/事件解析/规范化/分支/日志」——该描述**不可复现**。其签名 4 个参数亦不适用参数判据(`MessageListener` 框架固定签名)|
62
+
63
+ ### N2 — 深嵌套但来自 try/catch 与卫语句
64
+
65
+ | 项 | 内容 |
66
+ |---|---|
67
+ | **位置** | emp-auth v1-C3 `InvalidTokenInitializer.java:81`(bff)/ `:85-137`(adapter)|
68
+ | **判定** | 提示(嵌套例外已排除)|
69
+ | **理由** | 嵌套层级来自 try/catch 自身一层与卫语句 `continue` 所在层——按 §2 例外规则**不计入深度**|
70
+
71
+ ### N4 — 长度超阈值但单一抽象层级
72
+
73
+ | 项 | 内容 |
74
+ |---|---|
75
+ | **位置** | emp-auth v1-C2 `demo/bff/.../RelayTokenClient.java:51-85`(`redeem`,35 行含 4 个 catch 分支)|
76
+ | **判定** | 提示 |
77
+ | **理由** | 单一抽象层级(错误映射与信封解包);长度超阈值但无职责混杂 |
78
+
79
+ ## 三、判例集维护约定
80
+
81
+ 1. **增补来源**:仅接纳**真实代码**中的判定分歧案例(同一判据在不同审查者间给出不同结论);
82
+ 2. **增补须附**:位置(`文件:行号`)、判定、结构性理由、与该判例易混之处;
83
+ 3. **判例可能被推翻**:若新证据表明某判例的判定有误(如 P1 被证明实为职责混杂),**更新判例本身**并在设计文档版本记录中注明——不得保留错误判例供后续引用。
@@ -0,0 +1,50 @@
1
+ # 共享层判定与跨仓边界
2
+
3
+ > 用途:区分「必要横展」与「应抽共享层」——**两种处置的正确性相反,判错即方向性错误**。
4
+
5
+ ## 一、二判据(顺序判定)
6
+
7
+ | 步 | 判据 | 判定 |
8
+ |---|---|---|
9
+ | 1 | 复制体是否在**同一共享发布单元**内(同 npm 包 / 同 Maven 模块 / 同仓同目录)? | **是 → 应抽共享层**(同单元内复制必然漂移,且抽取成本最低)|
10
+ | 2 | 缺陷是否属**同名耦合类**(编译期无保护,如缓存名、常量名)?若是,横展须**逐字节同构**并留对端标注 | 附加条件,不单独改变步 1 判定 |
11
+
12
+ ### 为何是二判据,而非三判据
13
+
14
+ 早期版本曾有第三条「跨单元时是否存在可用的共享通道(父 POM / 可发公共包 / 已有跨仓契约)」。**该判据已删除**,两个原因:
15
+
16
+ 1. **共线**:跨仓必然无共享单元,第 1 条已隐含"跨单元"的判定,第 3 条只在跨单元时才触发 —— 两条实际只有一条在起作用;
17
+ 2. **不可判定**:审查者被锁定单仓 worktree,无法知道别的仓有无父 POM 依赖或公共包 —— 该判据**无取证通道**(与「跨仓 DRY 不可判」同源)。
18
+
19
+ 删除后本判据**完全在单仓内可判**。
20
+
21
+ ## 二、跨仓边界(重要)
22
+
23
+ **本判据只管单仓内**。下列情形**不在** `clean-code` 的判据范围:
24
+
25
+ | 情形 | 归属 |
26
+ |---|---|
27
+ | 跨仓的同构缺陷(如 v1-C5 修了 2 个 BFF 仓、漏了 2 个 adapter 仓)| `cross-change-consistency-checker` 的 **Dim 5(同构横展完整性)** |
28
+ | 跨仓的重复代码 | 同上(模式驱动扫描全部仓,见 Dim 5)|
29
+
30
+ 理由:审查者的 worktree 为**单仓**(实证:`changes/<name>/.superpowers/sdd/reviews/w*.md` 的 metadata 含 `Target repository: service/<repo>`),跨仓在物理与约定层面均不可达。
31
+
32
+ ## 三、v1 实测校验
33
+
34
+ | 案例 | 步 1 | 判定 | 与实测一致性 |
35
+ |---|---|---|---|
36
+ | C2 `relay.vue` → C3 `logout.vue`(同仓同目录同一 npm 包)| 是 | **应抽共享层** | ✅ 与实测判断一致 |
37
+ | C5 后端两仓(`bff-emp-usersidentification` / `bff-emp-clientsidentification`,跨仓、无共享 jar、hunk md5 相同、同名缓存值类型耦合)| 跨仓 | **不在本判据范围** → Dim 5 承接 | ✅(当时判为必要横展,结论正确但依据不同)|
38
+ | C5 前端三仓(各自独立 npm 包、各修本仓存储封装)| 跨仓 | **不在本判据范围** | 同上 |
39
+
40
+ ## 四、判定为「应抽共享层」后的处置
41
+
42
+ 1. **不要求本次 change 立即重构**(避免范围蔓延)——除非该抽取本身在本次 write_set 内;
43
+ 2. 在审查报告中标注为 **Critical**(DRY 唯一的分级),并给出共享层建议落点(如 `src/utils/`);
44
+ 3. 若项目 conventions 已有对应的共享层约定,以 conventions 为准。
45
+
46
+ ## 五、判定为「必要横展」的处置(由 Dim 5 承接时)
47
+
48
+ 1. 横展须**逐字节同构**(含注释口径),并保留对端来源标注(参照项目级 `backend-patterns.md` 的 §8.1 范式);
49
+ 2. 横展范围须覆盖**全部**同构位置——遗漏即 Dim 5 的 Important 发现(可达时);
50
+ 3. 不可达位置(零调用方)记 Minor,属「预防性一致处置」。