@hongmaple0820/scale-engine 0.47.0 → 0.49.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 (128) hide show
  1. package/README.en.md +8 -2
  2. package/README.md +9 -3
  3. package/dist/agents/evidenceDiscipline.d.ts +7 -0
  4. package/dist/agents/evidenceDiscipline.js +21 -0
  5. package/dist/agents/evidenceDiscipline.js.map +1 -0
  6. package/dist/agents/profiles.js +8 -1
  7. package/dist/agents/profiles.js.map +1 -1
  8. package/dist/agents/types.d.ts +1 -0
  9. package/dist/api/cli.js +975 -6222
  10. package/dist/api/cli.js.map +1 -1
  11. package/dist/artifact/types.d.ts +59 -0
  12. package/dist/artifact/types.js.map +1 -1
  13. package/dist/cli/artifactCrudCommands.d.ts +67 -0
  14. package/dist/cli/artifactCrudCommands.js +182 -0
  15. package/dist/cli/artifactCrudCommands.js.map +1 -0
  16. package/dist/cli/codegraphCommands.d.ts +1 -0
  17. package/dist/cli/codegraphCommands.js +241 -0
  18. package/dist/cli/codegraphCommands.js.map +1 -0
  19. package/dist/cli/contextCommands.d.ts +1 -0
  20. package/dist/cli/contextCommands.js +415 -0
  21. package/dist/cli/contextCommands.js.map +1 -0
  22. package/dist/cli/cortexCommands.d.ts +36 -0
  23. package/dist/cli/cortexCommands.js +76 -4
  24. package/dist/cli/cortexCommands.js.map +1 -1
  25. package/dist/cli/dependencyTddCommands.d.ts +92 -0
  26. package/dist/cli/dependencyTddCommands.js +174 -0
  27. package/dist/cli/dependencyTddCommands.js.map +1 -0
  28. package/dist/cli/diagnoseHuntCommands.d.ts +135 -0
  29. package/dist/cli/diagnoseHuntCommands.js +224 -0
  30. package/dist/cli/diagnoseHuntCommands.js.map +1 -0
  31. package/dist/cli/engineBootstrap.d.ts +39 -0
  32. package/dist/cli/engineBootstrap.js +129 -0
  33. package/dist/cli/engineBootstrap.js.map +1 -0
  34. package/dist/cli/evalCommands.d.ts +1 -0
  35. package/dist/cli/evalCommands.js +273 -0
  36. package/dist/cli/evalCommands.js.map +1 -0
  37. package/dist/cli/evolveDoctorCommands.d.ts +18 -0
  38. package/dist/cli/evolveDoctorCommands.js +59 -0
  39. package/dist/cli/evolveDoctorCommands.js.map +1 -0
  40. package/dist/cli/gateInlineCommands.d.ts +43 -0
  41. package/dist/cli/gateInlineCommands.js +74 -0
  42. package/dist/cli/gateInlineCommands.js.map +1 -0
  43. package/dist/cli/initConfigCommands.d.ts +138 -0
  44. package/dist/cli/initConfigCommands.js +602 -0
  45. package/dist/cli/initConfigCommands.js.map +1 -0
  46. package/dist/cli/metaGovernanceCommands.d.ts +11 -0
  47. package/dist/cli/metaGovernanceCommands.js +55 -0
  48. package/dist/cli/metaGovernanceCommands.js.map +1 -0
  49. package/dist/cli/phaseCommands.d.ts +53 -1
  50. package/dist/cli/phaseCommands.js +317 -22
  51. package/dist/cli/phaseCommands.js.map +1 -1
  52. package/dist/cli/runtimeSkillCommands.d.ts +6 -0
  53. package/dist/cli/runtimeSkillCommands.js +1515 -0
  54. package/dist/cli/runtimeSkillCommands.js.map +1 -0
  55. package/dist/cli/sessionCommands.d.ts +17 -0
  56. package/dist/cli/sessionCommands.js +38 -0
  57. package/dist/cli/sessionCommands.js.map +1 -0
  58. package/dist/cli/toolAgentCommands.d.ts +3 -0
  59. package/dist/cli/toolAgentCommands.js +441 -0
  60. package/dist/cli/toolAgentCommands.js.map +1 -0
  61. package/dist/cli/transitionCommands.d.ts +62 -0
  62. package/dist/cli/transitionCommands.js +174 -0
  63. package/dist/cli/transitionCommands.js.map +1 -0
  64. package/dist/cli/upgradeAssetsCommands.d.ts +44 -0
  65. package/dist/cli/upgradeAssetsCommands.js +933 -0
  66. package/dist/cli/upgradeAssetsCommands.js.map +1 -0
  67. package/dist/cli/workflowEvidenceCommands.d.ts +34 -0
  68. package/dist/cli/workflowEvidenceCommands.js +130 -0
  69. package/dist/cli/workflowEvidenceCommands.js.map +1 -0
  70. package/dist/cortex/InstinctStore.d.ts +32 -1
  71. package/dist/cortex/InstinctStore.js +235 -42
  72. package/dist/cortex/InstinctStore.js.map +1 -1
  73. package/dist/cortex/InstinctValidation.d.ts +9 -0
  74. package/dist/cortex/InstinctValidation.js +55 -0
  75. package/dist/cortex/InstinctValidation.js.map +1 -0
  76. package/dist/cortex/SessionInjector.js +13 -6
  77. package/dist/cortex/SessionInjector.js.map +1 -1
  78. package/dist/eval/BenchmarkPublisher.d.ts +2 -0
  79. package/dist/eval/BenchmarkPublisher.js +43 -0
  80. package/dist/eval/BenchmarkPublisher.js.map +1 -1
  81. package/dist/guardrails/ast/confirmers.d.ts +18 -0
  82. package/dist/guardrails/ast/confirmers.js +69 -0
  83. package/dist/guardrails/ast/confirmers.js.map +1 -0
  84. package/dist/guardrails/ast/parse.d.ts +20 -0
  85. package/dist/guardrails/ast/parse.js +51 -0
  86. package/dist/guardrails/ast/parse.js.map +1 -0
  87. package/dist/output/HTMLDocumentRenderer.d.ts +9 -0
  88. package/dist/output/HTMLDocumentRenderer.js +19 -0
  89. package/dist/output/HTMLDocumentRenderer.js.map +1 -1
  90. package/dist/review/FreshContextVerifier.d.ts +35 -0
  91. package/dist/review/FreshContextVerifier.js +120 -0
  92. package/dist/review/FreshContextVerifier.js.map +1 -0
  93. package/dist/review/JsonLlmClient.d.ts +37 -0
  94. package/dist/review/JsonLlmClient.js +94 -0
  95. package/dist/review/JsonLlmClient.js.map +1 -0
  96. package/dist/review/LlmJudge.d.ts +61 -0
  97. package/dist/review/LlmJudge.js +167 -0
  98. package/dist/review/LlmJudge.js.map +1 -0
  99. package/dist/version.d.ts +1 -1
  100. package/dist/version.js +1 -1
  101. package/dist/workflow/BoundaryEnforcement.d.ts +60 -0
  102. package/dist/workflow/BoundaryEnforcement.js +182 -0
  103. package/dist/workflow/BoundaryEnforcement.js.map +1 -0
  104. package/dist/workflow/EngineeringStandards.js +19 -9
  105. package/dist/workflow/EngineeringStandards.js.map +1 -1
  106. package/dist/workflow/GateCatalog.js +12 -2
  107. package/dist/workflow/GateCatalog.js.map +1 -1
  108. package/dist/workflow/ProfileEnforcement.d.ts +7 -0
  109. package/dist/workflow/ProfileEnforcement.js +12 -0
  110. package/dist/workflow/ProfileEnforcement.js.map +1 -0
  111. package/dist/workflow/ReviewStore.d.ts +10 -0
  112. package/dist/workflow/ReviewStore.js.map +1 -1
  113. package/dist/workflow/SurfaceCoverage.d.ts +19 -0
  114. package/dist/workflow/SurfaceCoverage.js +57 -0
  115. package/dist/workflow/SurfaceCoverage.js.map +1 -0
  116. package/dist/workflow/gates/EnhancedGates.js +2 -0
  117. package/dist/workflow/gates/EnhancedGates.js.map +1 -1
  118. package/dist/workflow/gates/TestIntegrityGate.d.ts +51 -0
  119. package/dist/workflow/gates/TestIntegrityGate.js +175 -0
  120. package/dist/workflow/gates/TestIntegrityGate.js.map +1 -0
  121. package/dist/workflow/types.d.ts +1 -1
  122. package/docs/guides/DEVELOPMENT_WORKFLOW.md +28 -0
  123. package/docs/workflow/E2E_EXAMPLE.md +133 -0
  124. package/docs/workflow/README.md +6 -0
  125. package/docs/workflow/TEMPLATE_GUIDE.md +162 -0
  126. package/docs/workflow/templates/plan.md +26 -0
  127. package/docs/workflow/templates/spec.md +28 -0
  128. package/package.json +3 -1
@@ -0,0 +1,175 @@
1
+ // SCALE Engine — G23 Test Integrity Gate (P1.2, PR-D1)
2
+ // Detects "fake green" test tampering by analysing the test-file diff:
3
+ // assertion count drops, newly introduced skip/only, weakened assertions, and
4
+ // inflated timeouts. PR-D1 ships advisory (warn-only); enforcement + verify→ship
5
+ // hash consistency + coverage regression land in PR-D2.
6
+ import { execSync } from 'node:child_process';
7
+ function createEvidence(input) {
8
+ return {
9
+ id: `EVID-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
10
+ ...input,
11
+ };
12
+ }
13
+ function textEvidence(items) {
14
+ return items.map(item => `${item.label}: ${item.detail}`).join('\n');
15
+ }
16
+ /** Matches test files by filename suffix or by living under a tests/__tests__ dir. */
17
+ const TEST_FILE_PATTERN = /(?:^|\/)(?:__tests__|tests?|specs?)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/;
18
+ /** expect(...) / assert(...) / assert.* / .should / should(...) — line-level assertion signal. */
19
+ const ASSERTION_PATTERN = /\bexpect\s*\(|\bassert\s*\(|\bassert\.|\.should\b|\bshould\s*\(/;
20
+ const SKIP_PATTERN = /\b(?:describe|context|suite|it|test|bench)\.skip\b|\.skip\s*\(|\bx(?:it|describe|test|context)\s*\(/;
21
+ const ONLY_PATTERN = /\b(?:describe|context|suite|it|test|bench)\.only\b|\.only\s*\(|\bf(?:it|describe|test)\s*\(/;
22
+ const WEAKENED_PATTERN = /expect\.any\s*\(|expect\.anything\s*\(|\.toBeTruthy\s*\(|\.toBeFalsy\s*\(|\.toBeDefined\s*\(|\.toBeUndefined\s*\(|\.toBeNull\s*\(/;
23
+ const TIMEOUT_PATTERN = /\b(?:jest|vi)\.setTimeout\s*\(|testTimeout\s*[:=]|\bsetTimeout\s*\(|\btimeout\s*[:=]\s*\d{4,}/;
24
+ function isTestFile(path) {
25
+ return TEST_FILE_PATTERN.test(path);
26
+ }
27
+ /** Parse a unified `git diff` into per-line records limited to test files. */
28
+ export function parseTestDiff(diff) {
29
+ const lines = [];
30
+ let currentFile = '';
31
+ let inTestFile = false;
32
+ for (const raw of diff.split('\n')) {
33
+ if (raw.startsWith('diff --git')) {
34
+ currentFile = '';
35
+ inTestFile = false;
36
+ continue;
37
+ }
38
+ if (raw.startsWith('+++ ')) {
39
+ const path = raw.slice(4).replace(/^b\//, '').trim();
40
+ currentFile = path === '/dev/null' ? currentFile : path;
41
+ inTestFile = isTestFile(currentFile);
42
+ continue;
43
+ }
44
+ if (raw.startsWith('--- ') || raw.startsWith('@@') || raw.startsWith('index '))
45
+ continue;
46
+ if (!inTestFile || !currentFile)
47
+ continue;
48
+ if (raw.startsWith('+'))
49
+ lines.push({ file: currentFile, origin: '+', text: raw.slice(1) });
50
+ else if (raw.startsWith('-'))
51
+ lines.push({ file: currentFile, origin: '-', text: raw.slice(1) });
52
+ else if (raw.startsWith(' '))
53
+ lines.push({ file: currentFile, origin: ' ', text: raw.slice(1) });
54
+ }
55
+ return lines;
56
+ }
57
+ /** Pure heuristic analysis of a unified test diff. Exported for unit testing. */
58
+ export function analyzeTestDiff(diff) {
59
+ const parsed = parseTestDiff(diff);
60
+ const analyzedFiles = [...new Set(parsed.map(line => line.file))].sort();
61
+ // Pre side = context + removed; post side = context + added. Approximates the
62
+ // assertion balance within the changed hunks (whole-file counts arrive with AST in P1.1).
63
+ let preChangeAssertionCount = 0;
64
+ let postChangeAssertionCount = 0;
65
+ for (const line of parsed) {
66
+ const hasAssertion = ASSERTION_PATTERN.test(line.text);
67
+ if (!hasAssertion)
68
+ continue;
69
+ if (line.origin === '-' || line.origin === ' ')
70
+ preChangeAssertionCount++;
71
+ if (line.origin === '+' || line.origin === ' ')
72
+ postChangeAssertionCount++;
73
+ }
74
+ const assertionCountDelta = postChangeAssertionCount - preChangeAssertionCount;
75
+ const findings = [];
76
+ if (assertionCountDelta < 0) {
77
+ findings.push({
78
+ file: analyzedFiles.join(', ') || '(test files)',
79
+ kind: 'assertion-removed',
80
+ severity: 'block',
81
+ detail: `Net assertion count dropped by ${Math.abs(assertionCountDelta)} (pre=${preChangeAssertionCount}, post=${postChangeAssertionCount})`,
82
+ });
83
+ }
84
+ for (const line of parsed) {
85
+ if (line.origin !== '+')
86
+ continue;
87
+ const text = line.text;
88
+ if (SKIP_PATTERN.test(text)) {
89
+ findings.push({ file: line.file, kind: 'skip-added', severity: 'block', detail: `Introduced skipped test: ${text.trim().slice(0, 120)}` });
90
+ }
91
+ if (ONLY_PATTERN.test(text)) {
92
+ findings.push({ file: line.file, kind: 'only-added', severity: 'block', detail: `Introduced focused (.only) test: ${text.trim().slice(0, 120)}` });
93
+ }
94
+ if (WEAKENED_PATTERN.test(text)) {
95
+ findings.push({ file: line.file, kind: 'weakened-assertion', severity: 'warn', detail: `Weakened assertion: ${text.trim().slice(0, 120)}` });
96
+ }
97
+ if (TIMEOUT_PATTERN.test(text)) {
98
+ findings.push({ file: line.file, kind: 'timeout-inflated', severity: 'warn', detail: `Test timeout changed: ${text.trim().slice(0, 120)}` });
99
+ }
100
+ }
101
+ const flaggedPatterns = findings.map(f => `[${f.severity}] ${f.kind}: ${f.detail}`);
102
+ return { analyzedFiles, preChangeAssertionCount, postChangeAssertionCount, assertionCountDelta, findings, flaggedPatterns };
103
+ }
104
+ /**
105
+ * G23 — Test Integrity. Advisory in PR-D1: always PASSED, surfaces heuristic
106
+ * findings as evidence. PR-D2 wires it into verify/ship and flips `block`
107
+ * severity findings into real blockers under the `full`/`ci` profiles (E1).
108
+ */
109
+ export class TestIntegrityGate {
110
+ constructor(options = {}) {
111
+ this.stage = 'G23';
112
+ this.name = 'Test Integrity';
113
+ this.description = 'Detect test weakening (assertion drops, skip/only, weakened matchers, inflated timeouts)';
114
+ this.requiredLevel = 'M';
115
+ this.cwd = options.cwd ?? process.cwd();
116
+ this.baseRef = options.baseRef ?? 'HEAD';
117
+ this.injectedDiff = options.diff;
118
+ this.advisory = options.advisory ?? true;
119
+ }
120
+ collectDiff() {
121
+ if (this.injectedDiff !== undefined)
122
+ return this.injectedDiff;
123
+ try {
124
+ return execSync(`git diff ${this.baseRef}`, { encoding: 'utf-8', stdio: 'pipe', cwd: this.cwd, maxBuffer: 32 * 1024 * 1024 });
125
+ }
126
+ catch {
127
+ return '';
128
+ }
129
+ }
130
+ async execute() {
131
+ const startedAt = Date.now();
132
+ const analysis = analyzeTestDiff(this.collectDiff());
133
+ const evidence = {
134
+ analyzedFiles: analysis.analyzedFiles,
135
+ preChangeAssertionCount: analysis.preChangeAssertionCount,
136
+ postChangeAssertionCount: analysis.postChangeAssertionCount,
137
+ assertionCountDelta: analysis.assertionCountDelta,
138
+ flaggedPatterns: analysis.flaggedPatterns,
139
+ findings: analysis.findings,
140
+ advisory: this.advisory,
141
+ };
142
+ const blockingFindings = analysis.findings.filter(f => f.severity === 'block');
143
+ // PR-D1: advisory — never block. PR-D2 will drive blocking via profile policy.
144
+ const blockers = this.advisory ? [] : blockingFindings.map(f => `${f.kind}: ${f.detail}`);
145
+ const passed = blockers.length === 0;
146
+ const summaryDetail = analysis.analyzedFiles.length === 0
147
+ ? 'No test files changed; nothing to analyse.'
148
+ : `Analyzed ${analysis.analyzedFiles.length} test file(s); assertion delta ${analysis.assertionCountDelta >= 0 ? '+' : ''}${analysis.assertionCountDelta}; ${analysis.findings.length} finding(s)${this.advisory ? ' (advisory)' : ''}.`;
149
+ const evidenceItems = [
150
+ createEvidence({
151
+ kind: 'scan',
152
+ label: 'Test integrity summary',
153
+ passed: passed && blockingFindings.length === 0,
154
+ detail: summaryDetail,
155
+ source: JSON.stringify(evidence),
156
+ }),
157
+ ...analysis.findings.map(finding => createEvidence({
158
+ kind: 'scan',
159
+ label: `Test integrity finding (${finding.kind})`,
160
+ passed: this.advisory ? true : finding.severity !== 'block',
161
+ detail: `[${finding.severity}] ${finding.file}: ${finding.detail}`,
162
+ })),
163
+ ];
164
+ return {
165
+ gate: this.stage,
166
+ status: passed ? 'PASSED' : 'FAILED',
167
+ passed,
168
+ evidence: textEvidence(evidenceItems),
169
+ evidenceItems,
170
+ blockers,
171
+ durationMs: Date.now() - startedAt,
172
+ };
173
+ }
174
+ }
175
+ //# sourceMappingURL=TestIntegrityGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestIntegrityGate.js","sourceRoot":"","sources":["../../../src/workflow/gates/TestIntegrityGate.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export type GateStage = 'G0' | 'G1' | 'G2' | 'G3' | 'G4' | 'G5' | 'G6' | 'G7' | 'G8' | 'G9' | 'G10' | 'G11' | 'G12' | 'G13' | 'G14' | 'G15' | 'G16' | 'G17' | 'G18' | 'G19' | 'G20' | 'G21' | 'G22';
1
+ export type GateStage = 'G0' | 'G1' | 'G2' | 'G3' | 'G4' | 'G5' | 'G6' | 'G7' | 'G8' | 'G9' | 'G10' | 'G11' | 'G12' | 'G13' | 'G14' | 'G15' | 'G16' | 'G17' | 'G18' | 'G19' | 'G20' | 'G21' | 'G22' | 'G23';
2
2
  export type GateStatus = 'PENDING' | 'PASSED' | 'FAILED' | 'BLOCKED';
3
3
  export type ModelTier = 'LOW' | 'MEDIUM' | 'HIGH';
4
4
  export type Verdict = 'APPROVE' | 'ITERATE' | 'REJECT';
@@ -97,3 +97,31 @@ git diff --check
97
97
  - worktree 状态
98
98
  - 截图、trace、缓存
99
99
  - 只对一次任务有意义的中间文件
100
+
101
+ ## Agent 边界约束
102
+
103
+ 这是把 [AGENTS.md](../../AGENTS.md) / [CLAUDE.md](../../CLAUDE.md) 的「工作原则」落到日常执行的硬约束,违反基本都会被对应门禁拦下:
104
+
105
+ - **未验证不得声称**:没有实际运行结果,不说「已通过」;`dry-run` 只代表入口可调度,不代表质量通过。证据写进 `verification.md`(G8)。
106
+ - **不确定显式标记**:拿不准的事实标 `[UNCERTAIN]`,不要用猜测填 `reality-check.md` 的 `## Confirmed`(G2 校验该文件分区)。
107
+ - **最小必要修改**:只改与任务直接相关的文件,不顺手重构、不扩大 diff。未提交文件过多或有大文件会被 G16 拦下。
108
+ - **不覆盖用户改动**:动手前先看 `git status`;不把本地 worktree、缓存、日志、截图混进提交。
109
+ - **行为改动配测试**:改 `src/` 行为原则上同步改 `tests/`,否则 G3 阻断。
110
+ - **规则优先落到物理层**:重要约定要落到脚本、门禁、配置、模板,不只停留在口头或文档;改模板前先读 [模板选择指南](../workflow/TEMPLATE_GUIDE.md) 的双源说明,避免改错一套。
111
+
112
+ ## 长任务检查点模式
113
+
114
+ 跨多次会话、或步骤很多的任务,用检查点把进度落到状态文件,避免上下文丢失后从头再来:
115
+
116
+ ```bash
117
+ make checkpoint PHASE=execute # 记录当前阶段到 .agent/state
118
+ make resume # 恢复:打印当前任务、阶段、下一步
119
+ make status # 等价于 make resume
120
+ ```
121
+
122
+ 实践要点:
123
+
124
+ - **一个阶段一个检查点**:探索→规划→执行→验证→沉淀,每跨一个阶段 `make checkpoint`。
125
+ - **分阶段提交**:长任务拆成多个小提交,别攒成一个巨型提交(同样利于 G16)。
126
+ - **状态与计划同步**:`plan.md` 的 `## Steps with Gates` 勾到哪一步,状态就 checkpoint 到哪一步,恢复时一眼对上。
127
+ - **恢复先 `make resume`**:新会话开始先读当前状态,再继续,不要凭记忆重做。
@@ -0,0 +1,133 @@
1
+ # 端到端示例:从 `make new-task` 到提交
2
+
3
+ 本文走一遍**完整一次任务**:建任务 → 探索 → 规划 → 过工作流门 → 提交。
4
+ 用 **L 级**任务,因为它能覆盖 G2 对「human confirmation」的要求。
5
+
6
+ > 范围说明:本文聚焦 `make new-task → 提交全程`。
7
+ > 关于 FSM Guard(物理阻止「未验证就 COMPLETE」)的**状态机**示例,
8
+ > 见 [../TASK_GUARD_WORKFLOW_DEMO.md](../TASK_GUARD_WORKFLOW_DEMO.md),本文不重复。
9
+ >
10
+ > 模板怎么选见 [TEMPLATE_GUIDE.md](TEMPLATE_GUIDE.md),门禁目录见 [GATES_AND_SCORE.md](GATES_AND_SCORE.md)。
11
+
12
+ 下面每条命令和输出均在本仓库实跑(日期取运行当天,你本地会不同)。
13
+
14
+ ---
15
+
16
+ ## 1. 建任务
17
+
18
+ ```bash
19
+ make new-task NAME=add-dark-mode LEVEL=L
20
+ ```
21
+
22
+ ```text
23
+ bash scripts/workflow/new-task.sh "add-dark-mode" "L"
24
+ [NEW-TASK] created: /.../.planning/tasks/2026-06-11-add-dark-mode
25
+ [NEW-TASK] state: /.../.agent/state/current.json
26
+ [NEW-TASK] next: fill explore.md, runtime.md, and reality-check.md before execution
27
+ ```
28
+
29
+ `new-task` 在 `.planning/tasks/<date>-add-dark-mode/` 一次性生成 9 个核心制品:
30
+ `explore.md`、`mini-prd.md`、`plan.md`、`runtime.md`、`reality-check.md`、
31
+ `resource-cleanup.md`、`verification.md`、`review.md`、`summary.md`。
32
+
33
+ > 需要 `spec.md` / `tasks.md`(深规划)时改用 `make plan NAME=add-dark-mode LEVEL=L`。
34
+
35
+ ---
36
+
37
+ ## 2. 探索(G1)
38
+
39
+ 读至少 3 个相关文件并写清主矛盾:
40
+
41
+ ```bash
42
+ make explore FILES='AGENTS.md docs/workflow/templates/plan.md src/api/cli.ts' \
43
+ MSG='template selection has no guidance'
44
+ ```
45
+
46
+ ```text
47
+ [EXPLORE] recorded 3 files
48
+ [EXPLORE] main contradiction: template selection has no guidance
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 3. 规划(G2)
54
+
55
+ 编辑 `.planning/tasks/<date>-add-dark-mode/plan.md`,把各段的 `TBD` 填成真内容。
56
+ 模板已内置 G2 需要的全部段落(见 [TEMPLATE_GUIDE §4](TEMPLATE_GUIDE.md#4-模板--门禁映射)):
57
+ 范围、异常(≥3 次)、回滚、验收,以及 **L/CRITICAL 的 `## Human Confirmation` 段**。
58
+ 你要做的是**填内容**,而不是补标题。
59
+
60
+ 跑计划门,开箱即过:
61
+
62
+ ```bash
63
+ bash scripts/gates/G2-verify.sh
64
+ ```
65
+
66
+ ```text
67
+ ========================================
68
+ [G2] Plan gate
69
+ ========================================
70
+ [G2] checking: /.../.planning/tasks/2026-06-11-verify-plan-template/plan.md
71
+ [G2] passed
72
+ [G2] exception/error mentions: 6
73
+ ```
74
+
75
+ > `exception/error mentions: 6` 说明异常覆盖 ≥ 3,满足 G2。
76
+ > 若把 `## Human Confirmation` 段删掉,L/CRITICAL 会被 G2 拦下
77
+ > (`[G2] L/CRITICAL plan should record human confirmation requirement`)——
78
+ > 这正是模板默认保留该段的原因。
79
+
80
+ ---
81
+
82
+ ## 4. 执行 + 工作流门(G1/G2/G3/G16)
83
+
84
+ 写代码时记住:改 `src/` 行为要同步改 `tests/`,否则 G3 拦下。改完跑:
85
+
86
+ ```bash
87
+ make gate-workflow
88
+ ```
89
+
90
+ 该聚合命令依次跑 G1、G2、G3、G16。本次因为只动文档/计划、未改 `src/`,
91
+ G3 会跳过(`no source behavior changes detected; skip`)。
92
+
93
+ ---
94
+
95
+ ## 5. 质量门 + 完整验证
96
+
97
+ ```bash
98
+ make gate-quality # G0,G4,G5,G6,G7,G8,G17,G18,G19,G20
99
+ make verify PROFILE=default # 完整 profile 验证
100
+ git diff --check
101
+ ```
102
+
103
+ L 级任务别忘了留审查记录(`.agent/state/review-*.json`),否则 G19 阻断。
104
+
105
+ ---
106
+
107
+ ## 6. 提交
108
+
109
+ 按 [CONTRIBUTING.md](../../CONTRIBUTING.md) 的约定从 `master` 切 `docs/*`、
110
+ `feature/*` 或 `fix/*` 分支,提交信息用 `<type>: <desc>`:
111
+
112
+ ```bash
113
+ git checkout -b feature/add-dark-mode
114
+ git add src/ tests/
115
+ git commit -m "feat: add dark mode toggle"
116
+ ```
117
+
118
+ > `.planning/` 与 `.agent/state/` 已在 `.gitignore` 中,任务制品不会被提交,
119
+ > 它们是给门禁和人审用的过程证据,不进生产代码。
120
+
121
+ ---
122
+
123
+ ## 速查
124
+
125
+ ```text
126
+ make new-task NAME=x LEVEL=L # 建任务 + 生成制品
127
+ make explore FILES='...' MSG='...' # G1:探索 ≥3 文件 + 主矛盾
128
+ # 编辑 plan.md(含 Human Confirmation)
129
+ make gate-workflow # G1,G2,G3,G16
130
+ make gate-quality # G0,G4,G5,G6,G7,G8,G17,G18,G19,G20
131
+ make verify PROFILE=default # 完整验证
132
+ git diff --check
133
+ ```
@@ -52,6 +52,12 @@ See [GATES_AND_SCORE.md](GATES_AND_SCORE.md) for gate catalog visibility, archit
52
52
 
53
53
  See [PROMPT_OPTIMIZATION.md](PROMPT_OPTIMIZATION.md) for the deterministic prompt rewrite layer used by `scale prompt optimize` and `scale define`.
54
54
 
55
+ ## 模板与示例
56
+
57
+ - 不知道一个任务该用哪些模板、模板和哪个门禁挂钩,先读 [TEMPLATE_GUIDE.md](TEMPLATE_GUIDE.md)(按等级 + 按改动类型的选择矩阵,含模板↔门禁映射)。
58
+ - 想看从 `make new-task` 到提交的完整一遍真实命令,读 [E2E_EXAMPLE.md](E2E_EXAMPLE.md)。
59
+ - FSM Guard(物理阻止「未验证就 COMPLETE」)的状态机示例见 [../TASK_GUARD_WORKFLOW_DEMO.md](../TASK_GUARD_WORKFLOW_DEMO.md)。
60
+
55
61
  ## 门禁说明
56
62
 
57
63
  SCALE 2.0 共 23 个门禁,分三层:核心门禁(G0-G8)、元治理门禁(G9-G15)、增强门禁(G16-G22)。
@@ -0,0 +1,162 @@
1
+ # 模板选择指南(Template Guide)
2
+
3
+ 本指南回答两个一直没有文档化的问题:
4
+
5
+ 1. **一个任务到底该用哪些模板?**(按等级 + 按改动类型)
6
+ 2. **每个模板和哪个门禁挂钩?**(写不对会被哪个 Gate 拦下)
7
+
8
+ 模板本体在 [`./templates/`](./templates/),门禁目录见 [GATES_AND_SCORE.md](GATES_AND_SCORE.md),
9
+ 日常闭环见 [../guides/DEVELOPMENT_WORKFLOW.md](../guides/DEVELOPMENT_WORKFLOW.md)。
10
+
11
+ > 数据来源:模板选择矩阵从 `src/skills/routing/SkillPolicy.ts` 的 `domains` 提取;
12
+ > 等级脚手架从 `scripts/workflow/new-task.sh` 与 `scripts/workflow/plan.sh` 提取;
13
+ > 模板↔门禁映射从 `scripts/gates/*-verify.sh` 提取。改了这些源文件请同步本表。
14
+
15
+ ---
16
+
17
+ ## 1. 模板全景(24 个)
18
+
19
+ | 模板 | 一句话场景 | 谁生成/何时用 |
20
+ | --- | --- | --- |
21
+ | [explore.md](./templates/explore.md) | 记录读了哪些文件、主矛盾是什么 | `new-task` 自动生成,G1 检查 |
22
+ | [mini-prd.md](./templates/mini-prd.md) | 一页纸目标/范围/验收,需求侧澄清 | `new-task` 自动生成 |
23
+ | [spec.md](./templates/spec.md) | What / Why / 约束的规格说明 | `make plan` 深规划时生成 |
24
+ | [plan.md](./templates/plan.md) | 边界、异常、回滚、验收的实现计划 | `new-task` 自动生成,**G2 核心** |
25
+ | [tasks.md](./templates/tasks.md) | 计划拆成可勾选的任务清单 | `make plan` 深规划时生成 |
26
+ | [runtime.md](./templates/runtime.md) | 配置来源、运行环境、运行时契约 | `new-task` 自动生成,G2/G18 |
27
+ | [reality-check.md](./templates/reality-check.md) | 已确认/未验证/造假/受限分区自检 | `new-task` 自动生成,**G2 必填** |
28
+ | [resource-cleanup.md](./templates/resource-cleanup.md) | 新增资源保留/移动/删除的处置表 | `new-task` 自动生成,G2 必须存在 |
29
+ | [verification.md](./templates/verification.md) | 实际跑了哪些验证命令、结果如何 | `new-task` 自动生成,G8 |
30
+ | [review.md](./templates/review.md) | 代码审查发现与结论 | `new-task` 自动生成,**G19(L/CRITICAL)** |
31
+ | [summary.md](./templates/summary.md) | 改了什么、验证了什么、未验证什么 | `new-task` 自动生成,沉淀阶段 |
32
+ | [api-contract.md](./templates/api-contract.md) | 接口端点、请求/响应、错误码契约 | 改 API/路由时(domain: api) |
33
+ | [db-change-plan.md](./templates/db-change-plan.md) | 表结构/数据变更与向后兼容 | 改 DB/迁移时(domain: db) |
34
+ | [security-review.md](./templates/security-review.md) | 资产、信任边界、鉴权规则审查 | 改鉴权/权限/迁移时(domain: security/db) |
35
+ | [architecture-review.md](./templates/architecture-review.md) | 触及的模块、公共契约、数据流评估 | 跨模块/标准类改动(domain: engineeringStandards) |
36
+ | [standards-impact.md](./templates/standards-impact.md) | 日志脱敏、架构边界、ORM 等规范核对 | 改 `src/` 工程规范面(domain: engineeringStandards) |
37
+ | [docs-impact.md](./templates/docs-impact.md) | 代码改动需要同步哪些文档 | 改文档或带文档影响时(domain: docs) |
38
+ | [resource-impact.md](./templates/resource-impact.md) | 产物的 Git 策略与保留期 | 涉及资产/媒体/报告时(domain: resourceGovernance) |
39
+ | [ui-spec.md](./templates/ui-spec.md) | 用户目标与主流程的 UI 规格 | 改前端/界面时(domain: ui) |
40
+ | [visual-review.md](./templates/visual-review.md) | 截图证据、布局与响应式核对 | 改 UI 后的视觉验收(domain: ui) |
41
+ | [e2e-plan.md](./templates/e2e-plan.md) | 用户路径与浏览器覆盖计划 | E2E/浏览器自动化(domain: e2e/browserAutomation) |
42
+ | [product-smoke.md](./templates/product-smoke.md) | 经真实产品边界的最小端到端路径 | 需要产品冒烟证据时(G8 profile) |
43
+ | [skill-plan.md](./templates/skill-plan.md) | 识别到的领域意图与技能选择 | skill 路由启用时(多数 domain 必备) |
44
+ | [skill-evidence.md](./templates/skill-evidence.md) | 技能/工具选择理由与证据 | skill 路由启用时(多数 domain 必备) |
45
+
46
+ ---
47
+
48
+ ## 2. 按任务等级选模板
49
+
50
+ 任务等级定义见 [AGENTS.md](../../AGENTS.md) 的「任务等级」表。脚手架由
51
+ `make new-task` / `make plan` 生成,下表标注**最低**要求。
52
+
53
+ | 模板 | S | M | L | CRITICAL |
54
+ | --- | :-: | :-: | :-: | :-: |
55
+ | explore.md | ✅ | ✅ | ✅ | ✅ |
56
+ | plan.md | 选填 | ✅ | ✅ | ✅ |
57
+ | reality-check.md | 选填 | ✅ | ✅ | ✅ |
58
+ | runtime.md | 选填 | ✅ | ✅ | ✅ |
59
+ | resource-cleanup.md | 选填 | ✅ | ✅ | ✅ |
60
+ | verification.md | ✅ | ✅ | ✅ | ✅ |
61
+ | summary.md | 选填 | ✅ | ✅ | ✅ |
62
+ | mini-prd.md | — | 选填 | ✅ | ✅ |
63
+ | spec.md / tasks.md | — | 选填 | ✅ | ✅ |
64
+ | review.md | — | 选填 | ✅(G19 阻断) | ✅(G19 阻断) |
65
+ | security-review.md | — | 视改动 | 视改动 | ✅(安全/权限/发布) |
66
+
67
+ 要点:
68
+
69
+ - `make new-task NAME=x LEVEL=M` 一次性生成 9 个核心制品(explore、mini-prd、plan、
70
+ runtime、reality-check、resource-cleanup、verification、review、summary)。
71
+ - `make plan NAME=x LEVEL=L` 额外生成 spec.md、tasks.md(深规划)。
72
+ - **L / CRITICAL 的 plan.md 必须写「human confirmation / review before execution」**,
73
+ 否则 G2 直接报错(见 §4)。
74
+ - CRITICAL(安全、权限、发布、破坏性操作)需补 security-review.md 并完成人工确认。
75
+
76
+ ---
77
+
78
+ ## 3. 按改动类型选模板(领域矩阵)
79
+
80
+ 下表直接对应 `SkillPolicy.ts` 的 `domains`。命中任一「触发」条件(改动的文件路径或
81
+ 任务描述关键词),就应补齐对应**必备模板**。`skill-plan.md` 与 `skill-evidence.md`
82
+ 在 skill 路由启用时(默认 M/L/CRITICAL)几乎都需要,表中不再重复列出。
83
+
84
+ | 改动类型 | 触发(文件/关键词,节选) | 必备模板(除 skill-plan/skill-evidence) |
85
+ | --- | --- | --- |
86
+ | 前端 / UI | `*.tsx` `*.css`,"ui/界面/组件/响应式" | mini-prd · ui-spec · visual-review |
87
+ | API / 接口 | `**/api/**` `**/routes/**`,"endpoint/接口/路由" | mini-prd · api-contract |
88
+ | 数据库 / 迁移 | `**/migrations/**` `*.sql` `schema.*`,"migration/迁移/schema" | db-change-plan · security-review |
89
+ | 安全 / 鉴权 | `**/auth/**` `**/permission/**`,"token/权限/密钥/rbac" | security-review |
90
+ | 文档 | `docs/**` `*.md`,"docs/文档/readme" | docs-impact |
91
+ | 资源治理 | 媒体/报告/`docs/modules/**`,"asset/资产/截图/视频" | docs-impact · resource-impact |
92
+ | 工程规范 | `src/**` `packages/**`,"日志/脱敏/架构规范/ORM" | standards-impact · architecture-review · security-review |
93
+ | E2E / 浏览器 | `tests/e2e/**` `playwright.config.*`,"e2e/浏览器/端到端" | e2e-plan · verification |
94
+ | 外部 CLI | `scripts/**` `.github/workflows/**`,"codex/claude code/gemini cli" | verification |
95
+ | 代码审查 | PR 模板,"review/评审/pull request" | review |
96
+ | 发版 / 发布 | `CHANGELOG.md` `package.json`,"release/发版/部署" | review · summary |
97
+ | 全栈原型 | "fullstack/mvp/prototype/next.js" | mini-prd · api-contract |
98
+
99
+ > 一个任务可同时命中多个领域(如「改 API + 写迁移」=api+db),取并集补齐。
100
+ > skill 路由的强弱由 `.scale/skills.json` 的 `mode`(off/warn/block)与 `enforceLevels` 决定。
101
+
102
+ ---
103
+
104
+ ## 4. 模板 → 门禁映射
105
+
106
+ 下表说明「模板写不对/缺失会被哪个 Gate 拦下」,关键词约束直接来自门禁脚本,
107
+ **不要改这些关键词**,否则正则匹配失败、门禁立刻报错。
108
+
109
+ | 模板 | 门禁 | 门禁检查什么(关键词/条件) |
110
+ | --- | --- | --- |
111
+ | explore.md | G1 | 探索至少记录 3 个文件并写主矛盾 |
112
+ | plan.md | **G2** | 见下方 G2 关键词清单 |
113
+ | reality-check.md | **G2** | 必须含 6 个分区标题(见下) |
114
+ | runtime.md | G2 / G18 | G2 要求文件存在;G18 校验运行时证据新鲜度与退出码 |
115
+ | resource-cleanup.md | G2 | 必须存在于任务目录 |
116
+ | verification.md | G8 | 文档/工作流制品标准(避免 localhost 链接等) |
117
+ | review.md | **G19** | L/CRITICAL 任务需有审查记录(`.agent/state/review-*.json`) |
118
+ | 任意变更的 `*.md` | G17 | 变更的 markdown 内部相对链接必须有效 |
119
+
120
+ ### G2 计划门——必须保留的关键词(来自 `scripts/gates/G2-verify.sh`)
121
+
122
+ | 检查项 | 必须匹配的关键词(任一,大小写不敏感) |
123
+ | --- | --- |
124
+ | 范围 | `scope` / `boundary` / `boundaries` / `limit` / `non-goal` |
125
+ | 异常覆盖 | `exception` / `error` / `fail` / `failure` / `rollback`(合计 **≥ 3 次**) |
126
+ | 回滚策略 | `rollback` / `recovery` / `disable` / `fallback` |
127
+ | 验收标准 | `acceptance` / `success criteria` / `definition of done` |
128
+ | L/CRITICAL | `human confirmation` / `review before execution` |
129
+
130
+ > ⚠️ `plan.md` 现有 `## Acceptance Criteria` 段名命中 `acceptance` 关键词。
131
+ > 若想改名,必须保留 `acceptance` / `success criteria` / `definition of done` 之一,
132
+ > 例如改成 `## Acceptance & Completion Criteria`,否则 G2 报「missing acceptance criteria」。
133
+
134
+ ### G2 reality-check.md 必填分区
135
+
136
+ `## Confirmed`、`## Not Verified`、`## Stub / Fake / Partial`、`## Credential-Gated`、
137
+ `## Environment-Gated`、`## User-Visible Risk` 六个标题缺一不可。
138
+
139
+ ---
140
+
141
+ ## 5. 两套模板源(改之前先确认)
142
+
143
+ 模板有两套独立来源,消费路径不同,**不要假设它们已经同步**:
144
+
145
+ | 源 | 路径 | 消费者 | 用途 |
146
+ | --- | --- | --- | --- |
147
+ | 文件版 | `docs/workflow/templates/*.md` | `new-task.sh` / `plan.sh` | 本仓库自用任务制品 |
148
+ | 内嵌版 | `src/workflow/GovernanceTemplates.ts` | `scale init` 脚手架 | 生成到**用户项目** |
149
+
150
+ - 改本仓库工作流:改**文件版**即可。
151
+ - 改 `scale` CLI 给用户生成的脚手架:改**内嵌版**(并注意 `tests/` 下的
152
+ `governanceTemplates` 相关测试可能断言其内容)。
153
+ - 两套同步是独立任务,混在一起改容易让测试挂掉。
154
+
155
+ ---
156
+
157
+ ## 6. 端到端怎么走
158
+
159
+ 从 `make new-task` 到提交的完整一遍真实命令演练,见
160
+ [E2E_EXAMPLE.md](./E2E_EXAMPLE.md)。
161
+ FSM Guard(阻止未验证就 COMPLETE)的状态机示例见
162
+ [../TASK_GUARD_WORKFLOW_DEMO.md](../TASK_GUARD_WORKFLOW_DEMO.md)。
@@ -3,6 +3,17 @@
3
3
  Date: {{DATE}}
4
4
  Level: {{LEVEL}}
5
5
 
6
+ ## Goal
7
+
8
+ - Problem / why now:
9
+ - Desired outcome (goal-driven, not just a task list):
10
+ - Success looks like:
11
+
12
+ ## Preconditions
13
+
14
+ - Required state before starting:
15
+ - Dependencies / blockers:
16
+
6
17
  ## Scope / Boundary
7
18
 
8
19
  - In scope:
@@ -14,6 +25,15 @@ Level: {{LEVEL}}
14
25
  2. TBD
15
26
  3. TBD
16
27
 
28
+ ## Steps with Gates
29
+
30
+ | # | Step | Gate it satisfies |
31
+ | --- | --- | --- |
32
+ | 1 | Explore ≥3 files, record main contradiction | G1 |
33
+ | 2 | This plan: scope / exception / rollback / acceptance | G2 |
34
+ | 3 | Implement; change `src/` ⇒ change `tests/` | G3 |
35
+ | 4 | Run lint / tests / verify | G4 / G5 / G6 |
36
+
17
37
  ## Exception / Failure Paths
18
38
 
19
39
  - Expected failure:
@@ -30,6 +50,12 @@ Level: {{LEVEL}}
30
50
 
31
51
  - TBD
32
52
 
53
+ ## Human Confirmation (L / CRITICAL)
54
+
55
+ - L/CRITICAL requires human confirmation / review before execution.
56
+ - Who confirms / when:
57
+ - For S/M: write `N/A`.
58
+
33
59
  ## Verification
34
60
 
35
61
  - `make gate-quality`
@@ -3,14 +3,42 @@
3
3
  Date: {{DATE}}
4
4
  Level: {{LEVEL}}
5
5
 
6
+ > P0 六要素契约(借鉴 Codex Goals 完成契约模型)。`Outcome` 复用 `What`,其余为可选补强字段;
7
+ > 留空即视为未声明,不会破坏旧流程。CLI 对应参数见 `docs/workflow/TEMPLATE_GUIDE.md`。
8
+
6
9
  ## What
7
10
 
11
+ <!-- Outcome: 期望的最终现实状态,而非任务步骤描述。 -->
8
12
 
9
13
  ## Why
10
14
 
11
15
 
16
+ ## Verification Surface
17
+
18
+ <!-- 具体证据来源:测试名 / 基准命令 / 产物路径。verify/review/ship 的 evidence 应能映射回这里。 -->
19
+ <!-- CLI: scale define ... --verification-surface "tests/foo.test.ts,npm run e2e" -->
20
+ -
21
+
22
+ ## Constraints
23
+
24
+ <!-- 运行期间不能退化的指标(性能 / 安全 / 兼容性)。 -->
25
+ <!-- CLI: --constraints "p95 < 200ms,no new prod dependency" -->
26
+ -
27
+
12
28
  ## Boundaries
13
29
 
30
+ <!-- CLI: --boundary-files / --boundary-tools / --boundary-forbidden -->
31
+ - Files:
32
+ - Tools:
33
+ - Forbidden:
34
+
35
+ ## Iteration Strategy
36
+
37
+ <!-- build 阶段每轮迭代后如何决定下一步。CLI: --iteration-strategy "..." -->
38
+
39
+ ## Blocked Stop Condition
40
+
41
+ <!-- 无可行路径时报告什么、需要什么才能解锁。CLI: --blocked-stop "..." -->
14
42
 
15
43
  ## Acceptance Criteria
16
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hongmaple0820/scale-engine",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "description": "Executable AI agent governance with workflow gates, evidence, skill/tool orchestration, and traceable HTML artifacts",
5
5
  "repository": {
6
6
  "type": "git",
@@ -57,6 +57,7 @@
57
57
  "dependencies": {
58
58
  "@hono/node-server": "^2.0.4",
59
59
  "@modelcontextprotocol/sdk": "1.29.0",
60
+ "@typescript-eslint/typescript-estree": "^8.59.3",
60
61
  "better-sqlite3": "^11.10.0",
61
62
  "chokidar": "^3.6.0",
62
63
  "citty": "^0.1.6",
@@ -82,6 +83,7 @@
82
83
  "@types/better-sqlite3": "^7.6.0",
83
84
  "@types/js-yaml": "^4.0.9",
84
85
  "@types/node": "^20.14.0",
86
+ "@typescript-eslint/eslint-plugin": "^8.60.1",
85
87
  "@typescript-eslint/parser": "^8.59.3",
86
88
  "eslint": "^9.0.0",
87
89
  "tsx": "^4.21.0",