@dommaker/harness 1.4.0 → 1.6.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 (258) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +0 -2
  3. package/dist/cli/commands/check.d.ts.map +1 -1
  4. package/dist/cli/commands/check.js +28 -0
  5. package/dist/cli/commands/check.js.map +1 -1
  6. package/dist/cli/commands/definitions.d.ts.map +1 -1
  7. package/dist/cli/commands/definitions.js +1 -39
  8. package/dist/cli/commands/definitions.js.map +1 -1
  9. package/dist/cli/commands/knowledge.d.ts +0 -19
  10. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  11. package/dist/cli/commands/knowledge.js +0 -105
  12. package/dist/cli/commands/knowledge.js.map +1 -1
  13. package/dist/cli/commands/passes-gate.d.ts +0 -2
  14. package/dist/cli/commands/passes-gate.d.ts.map +1 -1
  15. package/dist/cli/commands/passes-gate.js +0 -1
  16. package/dist/cli/commands/passes-gate.js.map +1 -1
  17. package/dist/cli/commands/performance.d.ts +0 -4
  18. package/dist/cli/commands/performance.d.ts.map +1 -1
  19. package/dist/cli/commands/performance.js +10 -20
  20. package/dist/cli/commands/performance.js.map +1 -1
  21. package/dist/cli/commands/report.d.ts +1 -1
  22. package/dist/cli/commands/report.d.ts.map +1 -1
  23. package/dist/cli/commands/report.js +2 -55
  24. package/dist/cli/commands/report.js.map +1 -1
  25. package/dist/cli/commands/status.d.ts.map +1 -1
  26. package/dist/cli/commands/status.js +4 -8
  27. package/dist/cli/commands/status.js.map +1 -1
  28. package/dist/context/index.d.ts +2 -5
  29. package/dist/context/index.d.ts.map +1 -1
  30. package/dist/context/index.js +2 -8
  31. package/dist/context/index.js.map +1 -1
  32. package/dist/context/token-budget.d.ts +0 -29
  33. package/dist/context/token-budget.d.ts.map +1 -1
  34. package/dist/context/token-budget.js +1 -65
  35. package/dist/context/token-budget.js.map +1 -1
  36. package/dist/context/types.d.ts +0 -1
  37. package/dist/context/types.d.ts.map +1 -1
  38. package/dist/context/types.js +0 -9
  39. package/dist/context/types.js.map +1 -1
  40. package/dist/core/constraints/checker.d.ts +14 -0
  41. package/dist/core/constraints/checker.d.ts.map +1 -1
  42. package/dist/core/constraints/checker.js +27 -5
  43. package/dist/core/constraints/checker.js.map +1 -1
  44. package/dist/core/constraints/checkers/capability-sync.d.ts +17 -6
  45. package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
  46. package/dist/core/constraints/checkers/capability-sync.js +48 -19
  47. package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
  48. package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -1
  49. package/dist/core/constraints/checkers/docs-freshness.js +15 -6
  50. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  51. package/dist/core/constraints/checkers/index.d.ts +2 -2
  52. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  53. package/dist/core/constraints/checkers/index.js +2 -1
  54. package/dist/core/constraints/checkers/index.js.map +1 -1
  55. package/dist/core/constraints/checkers/types.d.ts +41 -2
  56. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  57. package/dist/core/constraints/checkers/types.js +33 -0
  58. package/dist/core/constraints/checkers/types.js.map +1 -1
  59. package/dist/core/constraints/git-evidence.d.ts +6 -3
  60. package/dist/core/constraints/git-evidence.d.ts.map +1 -1
  61. package/dist/core/constraints/git-evidence.js +6 -3
  62. package/dist/core/constraints/git-evidence.js.map +1 -1
  63. package/dist/core/index.d.ts +1 -2
  64. package/dist/core/index.d.ts.map +1 -1
  65. package/dist/core/index.js +1 -9
  66. package/dist/core/index.js.map +1 -1
  67. package/dist/core/spec/validator.d.ts +2 -0
  68. package/dist/core/spec/validator.d.ts.map +1 -1
  69. package/dist/core/spec/validator.js +9 -11
  70. package/dist/core/spec/validator.js.map +1 -1
  71. package/dist/core/validators/index.d.ts +1 -1
  72. package/dist/core/validators/index.d.ts.map +1 -1
  73. package/dist/core/validators/passes-gate.d.ts +1 -15
  74. package/dist/core/validators/passes-gate.d.ts.map +1 -1
  75. package/dist/core/validators/passes-gate.js +0 -125
  76. package/dist/core/validators/passes-gate.js.map +1 -1
  77. package/dist/failure/index.d.ts +0 -1
  78. package/dist/failure/index.d.ts.map +1 -1
  79. package/dist/failure/index.js +1 -7
  80. package/dist/failure/index.js.map +1 -1
  81. package/dist/gates/checker-gate.d.ts +2 -1
  82. package/dist/gates/checker-gate.d.ts.map +1 -1
  83. package/dist/gates/checker-gate.js +10 -7
  84. package/dist/gates/checker-gate.js.map +1 -1
  85. package/dist/gates/definitions.d.ts.map +1 -1
  86. package/dist/gates/definitions.js +0 -4
  87. package/dist/gates/definitions.js.map +1 -1
  88. package/dist/gates/performance.d.ts +7 -22
  89. package/dist/gates/performance.d.ts.map +1 -1
  90. package/dist/gates/performance.js +7 -89
  91. package/dist/gates/performance.js.map +1 -1
  92. package/dist/gates/types.d.ts +2 -8
  93. package/dist/gates/types.d.ts.map +1 -1
  94. package/dist/index.d.ts +6 -8
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +4 -22
  97. package/dist/index.js.map +1 -1
  98. package/dist/knowledge/index.d.ts +0 -1
  99. package/dist/knowledge/index.d.ts.map +1 -1
  100. package/dist/knowledge/index.js +1 -3
  101. package/dist/knowledge/index.js.map +1 -1
  102. package/dist/monitoring/trace-analyzer.d.ts +25 -10
  103. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  104. package/dist/monitoring/trace-analyzer.js +147 -116
  105. package/dist/monitoring/trace-analyzer.js.map +1 -1
  106. package/dist/types/constraint.d.ts +8 -0
  107. package/dist/types/constraint.d.ts.map +1 -1
  108. package/dist/types/constraint.js +6 -1
  109. package/dist/types/constraint.js.map +1 -1
  110. package/dist/types/passes-gate.d.ts +0 -19
  111. package/dist/types/passes-gate.d.ts.map +1 -1
  112. package/dist/types/trace.d.ts +9 -0
  113. package/dist/types/trace.d.ts.map +1 -1
  114. package/package.json +1 -1
  115. package/src/CONTEXT.md +1 -0
  116. package/src/__tests__/passes-gate-check.test.ts +20 -4
  117. package/src/__tests__/passes-gate.test.ts +18 -119
  118. package/src/__tests__/performance-gate.test.ts +3 -11
  119. package/src/__tests__/public-exports.test.ts +46 -16
  120. package/src/__tests__/trace-analyzer.test.ts +52 -2
  121. package/src/cli/commands/CONTEXT.md +5 -4
  122. package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +6 -0
  123. package/src/cli/commands/__tests__/check.test.ts +74 -0
  124. package/src/cli/commands/__tests__/passes-gate-dead-options.test.ts +70 -0
  125. package/src/cli/commands/__tests__/passes-gate.test.ts +7 -3
  126. package/src/cli/commands/__tests__/performance.test.ts +5 -16
  127. package/src/cli/commands/__tests__/project-path-convention.test.ts +85 -23
  128. package/src/cli/commands/__tests__/registry.test.ts +52 -3
  129. package/src/cli/commands/__tests__/report-extra.test.ts +0 -19
  130. package/src/cli/commands/__tests__/report-false-green.test.ts +46 -0
  131. package/src/cli/commands/__tests__/report.test.ts +0 -20
  132. package/src/cli/commands/__tests__/status-analysis-wiring.test.ts +68 -0
  133. package/src/cli/commands/__tests__/status-extra.test.ts +63 -116
  134. package/src/cli/commands/__tests__/status.test.ts +66 -148
  135. package/src/cli/commands/check.ts +39 -1
  136. package/src/cli/commands/definitions.ts +1 -39
  137. package/src/cli/commands/knowledge.ts +0 -119
  138. package/src/cli/commands/passes-gate.ts +0 -3
  139. package/src/cli/commands/performance.ts +13 -27
  140. package/src/cli/commands/report.ts +3 -61
  141. package/src/cli/commands/status.ts +5 -10
  142. package/src/context/CONTEXT.md +2 -3
  143. package/src/context/__tests__/token-budget.test.ts +1 -81
  144. package/src/context/index.ts +2 -7
  145. package/src/context/token-budget.ts +0 -73
  146. package/src/context/types.ts +0 -9
  147. package/src/core/CONTEXT.md +6 -6
  148. package/src/core/constraints/__tests__/collect-constraints.test.ts +66 -0
  149. package/src/core/constraints/checker.ts +41 -6
  150. package/src/core/constraints/checkers/__tests__/capability-sync.test.ts +90 -31
  151. package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +176 -0
  152. package/src/core/constraints/checkers/__tests__/docs-freshness.test.ts +18 -9
  153. package/src/core/constraints/checkers/__tests__/three-state-consistency.test.ts +12 -4
  154. package/src/core/constraints/checkers/capability-sync.ts +56 -18
  155. package/src/core/constraints/checkers/docs-freshness.ts +18 -5
  156. package/src/core/constraints/checkers/index.ts +9 -2
  157. package/src/core/constraints/checkers/types.ts +58 -2
  158. package/src/core/constraints/git-evidence.ts +6 -3
  159. package/src/core/index.ts +0 -11
  160. package/src/core/spec/__tests__/validator.test.ts +24 -0
  161. package/src/core/spec/validator.ts +9 -10
  162. package/src/core/validators/__tests__/passes-gate.test.ts +2 -9
  163. package/src/core/validators/index.ts +0 -1
  164. package/src/core/validators/passes-gate.ts +1 -149
  165. package/src/failure/CONTEXT.md +8 -6
  166. package/src/failure/index.ts +0 -10
  167. package/src/gates/CONTEXT.md +4 -3
  168. package/src/gates/__tests__/checker-gate.test.ts +24 -0
  169. package/src/gates/__tests__/performance.test.ts +6 -74
  170. package/src/gates/checker-gate.ts +11 -15
  171. package/src/gates/definitions.ts +0 -4
  172. package/src/gates/performance.ts +9 -111
  173. package/src/gates/types.ts +2 -8
  174. package/src/index.ts +1 -36
  175. package/src/knowledge/CONTEXT.md +1 -2
  176. package/src/knowledge/index.ts +0 -1
  177. package/src/monitoring/CONTEXT.md +2 -2
  178. package/src/monitoring/trace-analyzer.ts +160 -126
  179. package/src/types/constraint.ts +16 -2
  180. package/src/types/passes-gate.ts +0 -26
  181. package/src/types/trace.ts +10 -0
  182. package/src/utils/__tests__/jsonl-skip-disposition.test.ts +0 -1
  183. package/dist/cli/commands/analyze-sessions.d.ts +0 -20
  184. package/dist/cli/commands/analyze-sessions.d.ts.map +0 -1
  185. package/dist/cli/commands/analyze-sessions.js +0 -290
  186. package/dist/cli/commands/analyze-sessions.js.map +0 -1
  187. package/dist/cli/commands/update-user-model.d.ts +0 -25
  188. package/dist/cli/commands/update-user-model.d.ts.map +0 -1
  189. package/dist/cli/commands/update-user-model.js +0 -397
  190. package/dist/cli/commands/update-user-model.js.map +0 -1
  191. package/dist/cli/session-mining/corrections.d.ts +0 -17
  192. package/dist/cli/session-mining/corrections.d.ts.map +0 -1
  193. package/dist/cli/session-mining/corrections.js +0 -58
  194. package/dist/cli/session-mining/corrections.js.map +0 -1
  195. package/dist/cli/session-mining/index.d.ts +0 -13
  196. package/dist/cli/session-mining/index.d.ts.map +0 -1
  197. package/dist/cli/session-mining/index.js +0 -29
  198. package/dist/cli/session-mining/index.js.map +0 -1
  199. package/dist/cli/session-mining/text.d.ts +0 -31
  200. package/dist/cli/session-mining/text.d.ts.map +0 -1
  201. package/dist/cli/session-mining/text.js +0 -126
  202. package/dist/cli/session-mining/text.js.map +0 -1
  203. package/dist/cli/session-mining/transcript.d.ts +0 -34
  204. package/dist/cli/session-mining/transcript.d.ts.map +0 -1
  205. package/dist/cli/session-mining/transcript.js +0 -130
  206. package/dist/cli/session-mining/transcript.js.map +0 -1
  207. package/dist/context/compaction.d.ts +0 -57
  208. package/dist/context/compaction.d.ts.map +0 -1
  209. package/dist/context/compaction.js +0 -165
  210. package/dist/context/compaction.js.map +0 -1
  211. package/dist/core/session/clean-state.d.ts +0 -17
  212. package/dist/core/session/clean-state.d.ts.map +0 -1
  213. package/dist/core/session/clean-state.js +0 -192
  214. package/dist/core/session/clean-state.js.map +0 -1
  215. package/dist/core/session/index.d.ts +0 -6
  216. package/dist/core/session/index.d.ts.map +0 -1
  217. package/dist/core/session/index.js +0 -15
  218. package/dist/core/session/index.js.map +0 -1
  219. package/dist/core/session/startup.d.ts +0 -47
  220. package/dist/core/session/startup.d.ts.map +0 -1
  221. package/dist/core/session/startup.js +0 -263
  222. package/dist/core/session/startup.js.map +0 -1
  223. package/dist/failure/constraint-handler.d.ts +0 -83
  224. package/dist/failure/constraint-handler.d.ts.map +0 -1
  225. package/dist/failure/constraint-handler.js +0 -138
  226. package/dist/failure/constraint-handler.js.map +0 -1
  227. package/dist/knowledge/lifecycle-hooks.d.ts +0 -62
  228. package/dist/knowledge/lifecycle-hooks.d.ts.map +0 -1
  229. package/dist/knowledge/lifecycle-hooks.js +0 -143
  230. package/dist/knowledge/lifecycle-hooks.js.map +0 -1
  231. package/dist/types/session.d.ts +0 -113
  232. package/dist/types/session.d.ts.map +0 -1
  233. package/dist/types/session.js +0 -6
  234. package/dist/types/session.js.map +0 -1
  235. package/src/__tests__/clean-state-extra.test.ts +0 -301
  236. package/src/__tests__/clean-state.test.ts +0 -169
  237. package/src/__tests__/constraint-handler.test.ts +0 -132
  238. package/src/__tests__/passes-gate-extra.test.ts +0 -93
  239. package/src/__tests__/session-startup.test.ts +0 -334
  240. package/src/cli/commands/__tests__/analyze-sessions.test.ts +0 -184
  241. package/src/cli/commands/__tests__/update-user-model.test.ts +0 -234
  242. package/src/cli/commands/analyze-sessions.ts +0 -335
  243. package/src/cli/commands/update-user-model.ts +0 -461
  244. package/src/cli/session-mining/__tests__/transcript.test.ts +0 -118
  245. package/src/cli/session-mining/corrections.ts +0 -56
  246. package/src/cli/session-mining/index.ts +0 -13
  247. package/src/cli/session-mining/text.ts +0 -117
  248. package/src/cli/session-mining/transcript.ts +0 -125
  249. package/src/context/__tests__/compaction.test.ts +0 -169
  250. package/src/context/compaction.ts +0 -201
  251. package/src/core/session/__tests__/startup.test.ts +0 -281
  252. package/src/core/session/clean-state.ts +0 -178
  253. package/src/core/session/index.ts +0 -15
  254. package/src/core/session/startup.ts +0 -253
  255. package/src/failure/constraint-handler.ts +0 -171
  256. package/src/knowledge/__tests__/lifecycle-hooks.test.ts +0 -140
  257. package/src/knowledge/lifecycle-hooks.ts +0 -202
  258. package/src/types/session.ts +0 -132
@@ -7,13 +7,12 @@
7
7
  * 「过了没」的判定依据不在本文件:唯一入口是 test-output.ts 的 judgeTestRun(ADR-0014)
8
8
  */
9
9
 
10
- import { execAsync, delay } from '../../utils/exec';
10
+ import { execAsync } from '../../utils/exec';
11
11
  import { judgeTestRun } from './test-output';
12
12
  import * as fs from 'fs/promises';
13
13
  import * as path from 'path';
14
14
  import type {
15
15
  PassesGateConfig,
16
- PassesGateResult,
17
16
  TaskTestResult,
18
17
  DynamicTask,
19
18
  TestResult,
@@ -30,24 +29,8 @@ const DEFAULT_CONFIG: Required<PassesGateConfig> = {
30
29
  testCommand: '',
31
30
  requireEvidence: true,
32
31
  allowPartialPass: false,
33
- maxRetries: 2,
34
- retryDelay: 1000,
35
32
  };
36
33
 
37
- /**
38
- * 测试文件保护模式
39
- */
40
- const PROTECTED_TEST_PATTERNS = [
41
- '**/*.test.ts',
42
- '**/*.test.tsx',
43
- '**/*.test.js',
44
- '**/*.spec.ts',
45
- '**/*.spec.tsx',
46
- '**/*.spec.js',
47
- '**/tests/**',
48
- '**/__tests__/**',
49
- ];
50
-
51
34
  /**
52
35
  * 检测项目的测试命令(唯一正本,CLI 与库调用共消费,架构评审 A2)
53
36
  *
@@ -98,7 +81,6 @@ export async function detectTestCommand(projectPath: string): Promise<string | u
98
81
  */
99
82
  export class PassesGate {
100
83
  private config: Required<PassesGateConfig>;
101
- private testResults: Map<string, TaskTestResult> = new Map();
102
84
 
103
85
  constructor(config: Partial<PassesGateConfig> = {}) {
104
86
  this.config = { ...DEFAULT_CONFIG, ...config };
@@ -170,99 +152,6 @@ export class PassesGate {
170
152
  };
171
153
  }
172
154
 
173
- /**
174
- * 设置任务通过状态
175
- * 核心方法:强制测试验证
176
- */
177
- async setPasses(
178
- taskId: string,
179
- value: boolean,
180
- workDir: string,
181
- task?: DynamicTask
182
- ): Promise<PassesGateResult> {
183
- if (!this.config.enabled) {
184
- return {
185
- taskId,
186
- allowed: true,
187
- attempts: 0,
188
- };
189
- }
190
-
191
- // 如果设置为 false,直接允许
192
- if (value === false) {
193
- return {
194
- taskId,
195
- allowed: true,
196
- testResult: {
197
- passed: false,
198
- command: 'manual',
199
- timestamp: new Date(),
200
- },
201
- attempts: 0,
202
- };
203
- }
204
-
205
- // 如果设置为 true,必须运行测试
206
- let attempts = 0;
207
- let lastError: string | undefined;
208
- let testResult: TaskTestResult | undefined;
209
-
210
- while (attempts <= this.config.maxRetries) {
211
- attempts++;
212
-
213
- try {
214
- testResult = await this.runTest(workDir, task);
215
-
216
- if (testResult.passed) {
217
- // 记录测试结果
218
- this.testResults.set(taskId, testResult);
219
-
220
- // 如果要求证据,验证证据存在
221
- if (this.config.requireEvidence && testResult.evidence) {
222
- const evidenceExists = await this.verifyEvidence(testResult.evidence, workDir);
223
- if (!evidenceExists) {
224
- return {
225
- taskId,
226
- allowed: false,
227
- error: 'Test evidence not found',
228
- testResult,
229
- attempts,
230
- };
231
- }
232
- }
233
-
234
- return {
235
- taskId,
236
- allowed: true,
237
- testResult,
238
- attempts,
239
- };
240
- }
241
-
242
- lastError = `Tests failed: ${testResult.failures?.join(', ') || 'Unknown error'}`;
243
-
244
- // 等待后重试
245
- if (attempts <= this.config.maxRetries) {
246
- await delay(this.config.retryDelay);
247
- }
248
- } catch (error: any) {
249
- lastError = error.message;
250
-
251
- if (attempts <= this.config.maxRetries) {
252
- await delay(this.config.retryDelay);
253
- }
254
- }
255
- }
256
-
257
- return {
258
- taskId,
259
- allowed: false,
260
- error: lastError,
261
- testResult,
262
- attempts,
263
- };
264
- }
265
-
266
155
  /**
267
156
  * 运行测试(CLI 使用)
268
157
  *
@@ -404,43 +293,6 @@ export class PassesGate {
404
293
  }
405
294
  }
406
295
 
407
- /**
408
- * 检测是否修改了测试文件
409
- */
410
- async checkTestFileChanges(workDir: string): Promise<string[]> {
411
- const changedTestFiles: string[] = [];
412
-
413
- try {
414
- const { stdout } = await execAsync('git diff --name-only', { cwd: workDir });
415
- const changedFiles = stdout.split('\n').filter(Boolean);
416
-
417
- // 简单的模式匹配
418
- for (const file of changedFiles) {
419
- const isTestFile = PROTECTED_TEST_PATTERNS.some(() => {
420
- return file.includes('.test.') ||
421
- file.includes('.spec.') ||
422
- file.includes('/tests/') ||
423
- file.includes('/__tests__/');
424
- });
425
-
426
- if (isTestFile) {
427
- changedTestFiles.push(file);
428
- }
429
- }
430
- } catch {
431
- // Git 不可用,跳过检查
432
- }
433
-
434
- return changedTestFiles;
435
- }
436
-
437
- /**
438
- * 获取任务的测试结果
439
- */
440
- getTestResult(taskId: string): TaskTestResult | undefined {
441
- return this.testResults.get(taskId);
442
- }
443
-
444
296
  }
445
297
 
446
298
  /**
@@ -1,18 +1,16 @@
1
1
  # failure/
2
2
 
3
3
  ## 职责
4
- 失败处理:错误分类(可扩展规则)、失败记录(文件存储)、约束违规统一处理策略。
4
+ 失败处理:错误分类(可扩展规则)、失败记录(文件存储)
5
5
 
6
6
  ## 核心导出
7
7
  - `ErrorClassifier` — 错误分类器(可配置规则)
8
8
  - `FailureRecorder` — 失败记录器(文件存储)
9
- - `ConstraintViolationHandler` — 约束违规处理: block / collect / safeBoolean 三种策略
10
9
  - `types.ts` — 错误分类/记录类型定义
11
10
 
12
11
  ## 依赖关系
13
- - 依赖 `src/types/constraint` ConstraintViolationError
14
- - 依赖 `src/core/constraints/` 约束检查结果
15
- - 被 `src/cli/commands/report.ts` 消费(executeWithCollect),并经包根导出
12
+ - 依赖 `src/types/` 错误分类/记录类型
13
+ - 经包根导出(ADR-0003 显式清单)
16
14
 
17
15
  ## 约定
18
16
  - 分类规则可扩展(自定义 ErrorClassifierConfig)
@@ -20,5 +18,9 @@
20
18
  - 不包含业务逻辑,只提供通用能力
21
19
 
22
20
  ## 注意事项
23
- - S4 统一处理策略:executeWithBlock / executeWithCollect / executeWithSafeBoolean
24
21
  - 分类器基于规则匹配,不调用 LLM
22
+ - S4 约束违规处理策略模块(ConstraintViolationHandler / executeWithBlock /
23
+ executeWithCollect / executeWithSafeBoolean)已删除(架构评审候选1):
24
+ COLLECT 对真实 checker 结构上不可交付(checker 首个铁律违规即 throw,
25
+ handler 的 catch 只能吞证据造假绿)。语义归宿——阻断 = `checkConstraints` 本体,
26
+ 收集 = `checker.collectConstraints`(report 直调);BLOCK/SAFE_BOOLEAN 零生产消费者随迁
@@ -23,13 +23,3 @@ export {
23
23
  createFailureRecorder,
24
24
  type FailureRecorderConfig,
25
25
  } from './recorder';
26
-
27
- // 约束违规处理(S4:统一处理策略)
28
- export {
29
- ConstraintViolationHandler,
30
- executeWithBlock,
31
- executeWithCollect,
32
- executeWithSafeBoolean,
33
- type ViolationStrategy,
34
- type ViolationHandlingResult,
35
- } from './constraint-handler';
@@ -9,7 +9,7 @@
9
9
  - 定义表:`GATE_DEFINITIONS`(`definitions.ts`)——id/description/默认 order/CLI 元数据;CLI 元数据形状即 `CommandDefinition`(ADR-0007:门禁与非门禁共用同一命令定义形状,bin 单引擎单循环;门禁特有语义 = `subcommandStrict:false` 未知子命令落回默认 action + `bareRunsAction:true` 裸跑执行 action);bin/harness.js 注册表驱动生成 6 门禁命令(纯数据模块,禁 import 实现,保 --help 懒加载;CLI 实现引用为 module+export,per-command 懒加载,H5)
10
10
  - 执行器:`runGates`(`runner.ts`)——按 order 升序;deny 单调(下游 abstain 不得改回 allow)+ ask 枚举预留 fail-closed = deny;决策浅冻结
11
11
  - 生效集:`getEffectiveGates(projectRoot)`(`effective-gates.ts`)——对齐 getEffectiveConstraints 裁剪模式:config.yml `gates.order` 重排 + `gates.<id>.enabled:false` 移除;enabled 段未注册校验与裁剪走 core/effective-set 共享筛选器(throw 模式),order 重排与重复 id 检测留本侧
12
- - checker-as-guard 接线点:`createCheckerGate(check)`(`checker-gate.ts`)——ConstraintCheck → Gate(studio #129 随动);false→denytrue/'skip'→abstain;env 经 `buildCheckEnv(..., 'none')` 构造(显式不接证据,语义见 core/constraints/checkers/types.ts 工厂 doc)
12
+ - checker-as-guard 接线点:`createCheckerGate(check)`(`checker-gate.ts`)——ConstraintCheck → Gate(studio #129 随动);判定经唯一归一点 `normalizeCheckOutcome`(harness#119/ADR-0016):`false` 或 `CheckDetail.pass=false` deny(证据行随理由带出),`true`(含 pass+提示)/'skip' abstain;env 经 `buildCheckEnv(..., 'none')` 构造(显式不接证据,语义见 core/constraints/checkers/types.ts 工厂 doc)
13
13
  - 门禁类:`ReviewGate` / `SecurityGate` / `PerformanceGate` / `ContractGate` / `SpecAcceptanceGate` / `CommandGate`(各自执行细节私有,保留 `check()`/`scan()` 报告方法);SpecAcceptanceGate 的 runner 输出解读与 e2e 判负都从 `core/validators/test-output.ts` 的 `judgeTestRun` 取(解析收口 ADR-0012、判定依据 ADR-0014,本层既不自带正则也不自写判定 `if`)
14
14
  - `types.ts` — GateResult(报告结构,保留)/ GateContext / GateDecision 等公共类型 + 报告构造器 `pass` / `fail` / `fromError`(动态 passed 走 `gateResult`):timestamp 与 duration 口径唯一落点,门禁实现禁止手写 GateResult 字面量(duration 是可选字段,漏写无编译期报错)
15
15
  - 便捷工厂函数:createReviewGate / createSecurityGate / createPerformanceGate / createContractGate / createSpecAcceptanceGate / createCommandGate
@@ -23,11 +23,12 @@
23
23
  - deny 单调是接口契约:决策浅冻结,下游不得改写上游决策
24
24
  - `runGates` 是 Gate 链语义的**参考实现**(deny 单调 / ask fail-closed / 全决策浅冻结):仓内暂无生产调用方(harness CLI 文件驱动逐命令执行,studio `runCompletionGuards` 经 checker-gate 复用语义但不 import),消费方只有测试。「deny 后短路跳过剩余门禁」类优化在出现真实消费者前不做——它与「按执行顺序的全部决策」报告契约直接冲突,短路等于改 GateResult 语义(harness#115 裁决,防后续评审重复提议)
25
25
  - ask 枚举预留:暂无实现,runGates fail-closed 按 deny 计
26
- - **收到的根要传到自己每个 IO/执行点(harness#95)**:门禁只认 `context.projectPath`,内部相对子路径一律锚到它(`SpecAcceptanceGate` 的 tasksPath、`ContractGate` 的 contractPath、e2e/scan/benchmark 的 `cwd`),禁止「根已传入却又取 cwd」、禁止 `xxxPath: './…'` 相对默认值——否则 `-p` 半失效且表现为假绿(acceptance 的「无 tasks.yml 即跳过」= passed:true)。本层唯一保留的 cwd 站点是 `checker-gate` 对 `ctx.projectPath` 的缺省兜底(豁免理由见守护表)。约定正本与两道机器可检的闸见 `src/cli/commands/CONTEXT.md`
26
+ - **收到的根要传到自己每个 IO/执行点(harness#95)**:门禁只认 `context.projectPath`,内部相对子路径一律锚到它(`SpecAcceptanceGate` 的 tasksPath、`ContractGate` 的 contractPath、e2e/scan 的 `cwd`),禁止「根已传入却又取 cwd」、禁止 `xxxPath: './…'` 相对默认值——否则 `-p` 半失效且表现为假绿(acceptance 的「无 tasks.yml 即跳过」= passed:true)。本层唯一保留的 cwd 站点是 `checker-gate` 对 `ctx.projectPath` 的缺省兜底(豁免理由见守护表)。约定正本与两道机器可检的闸见 `src/cli/commands/CONTEXT.md`
27
27
 
28
28
  ## 注意事项
29
29
  - 门禁系统不包含业务逻辑,只提供检查能力
30
30
  - `acceptance.ts` 的 13 处 return 是 `AcceptanceGateResult`(无 gate/duration 字段,`evaluate()` 归一化为 GateResult 报告——设计如此,见该方法注释),不是 GateResult 字面量,故不套 `pass`/`fail` 构造器;改成 GateResult 会动公共类型形状
31
- - 统一的是决策协议(id/order/三态),执行细节(gh pr view/正则黑名单/OpenAPI diff/benchmark)私有——不要把执行细节塞进 Gate 接口
31
+ - 统一的是决策协议(id/order/三态),执行细节(gh pr view/正则黑名单/OpenAPI diff/json-summary 覆盖率)私有——不要把执行细节塞进 Gate 接口
32
+ - `PerformanceGate` 只执法有真实现的维度(coverage 走 json-summary、bundleSize 走 dist 测量);responseTime/memoryUsage/throughput 三维无真实现(原 Math.random 伪造 + 未接线的 runBenchmark)已随 benchmark 机制整体删除(ADR-0018,架构评审候选2)
32
33
  - config.yml gates 段为新增面:引用未注册 id 直接抛错(无历史残留配置需兼容)
33
34
  - CommandGate 为命令黑名单检查(SEC-006)
@@ -37,6 +37,30 @@ describe('createCheckerGate', () => {
37
37
  expect(decision.result.message).toContain('跳过');
38
38
  });
39
39
 
40
+ // harness#119:CheckDetail 形状接入后,映射必须经 normalizeCheckOutcome——
41
+ // 写 `outcome !== false` 会把 { pass: false } 读成「不是 false」= 通过,deny 静默丢失
42
+ it('CheckDetail{pass:false} → deny,理由带出证据行', async () => {
43
+ const gate = createCheckerGate({
44
+ id: 'detail-fail',
45
+ evaluate: () => ({ pass: false, evidence: ['src/gone.ts'] }),
46
+ });
47
+ const decision = await gate.evaluate(ctx);
48
+ expect(decision.status).toBe('deny');
49
+ expect(decision.result.passed).toBe(false);
50
+ expect(decision.result.message).toContain('判定违规');
51
+ expect(decision.result.message).toContain('src/gone.ts');
52
+ });
53
+
54
+ it('CheckDetail{pass:true} + 提示证据 → abstain(提示不得变拦截)', async () => {
55
+ const gate = createCheckerGate({
56
+ id: 'detail-hint',
57
+ evaluate: () => ({ pass: true, evidence: ['仓库级漂移 1 项', 'src/drifted.ts'] }),
58
+ });
59
+ const decision = await gate.evaluate(ctx);
60
+ expect(decision.status).toBe('abstain');
61
+ expect(decision.result.message).toContain('通过');
62
+ });
63
+
40
64
  it('决策浅冻结(单调语义契约)', async () => {
41
65
  const gate = createCheckerGate(contextFlag('flag-freeze', () => true));
42
66
  const decision = await gate.evaluate(ctx);
@@ -37,21 +37,16 @@ describe('PerformanceGate', () => {
37
37
  const defaultGate = new PerformanceGate();
38
38
  const config = defaultGate.getConfig();
39
39
  expect(config.enabled).toBe(true);
40
- expect(config.warmupRuns).toBe(2);
41
- expect(config.measureRuns).toBe(5);
40
+ expect(config.thresholds).toEqual({});
42
41
  });
43
42
 
44
43
  it('should accept custom config', () => {
45
44
  const customGate = new PerformanceGate({
46
45
  enabled: false,
47
- warmupRuns: 3,
48
- measureRuns: 10,
49
46
  coverageTimeout: 60000,
50
47
  });
51
48
  const config = customGate.getConfig();
52
49
  expect(config.enabled).toBe(false);
53
- expect(config.warmupRuns).toBe(3);
54
- expect(config.measureRuns).toBe(10);
55
50
  expect(config.coverageTimeout).toBe(60000);
56
51
  });
57
52
  });
@@ -164,17 +159,16 @@ describe('PerformanceGate', () => {
164
159
 
165
160
  it('should include metrics in result', async () => {
166
161
  const strictGate = new PerformanceGate({
167
- thresholds: {
168
- maxResponseTime: 1000,
169
- maxMemoryUsage: 500,
170
- },
162
+ thresholds: { maxBundleSize: 1000 },
171
163
  });
172
164
 
165
+ mockFs.readdir.mockResolvedValueOnce(['bundle.js'] as any);
166
+ mockFs.stat.mockResolvedValueOnce({ isFile: () => true, size: 500 * 1024 } as any);
167
+
173
168
  const result = await strictGate.check(baseContext);
174
169
 
175
170
  expect(result.details?.metrics).toBeDefined();
176
- expect(result.details?.metrics.responseTime).toBeDefined();
177
- expect(result.details?.metrics.memoryUsage).toBeDefined();
171
+ expect(result.details?.metrics.bundleSize).toBeDefined();
178
172
  });
179
173
  });
180
174
 
@@ -257,66 +251,6 @@ describe('PerformanceGate', () => {
257
251
  });
258
252
  });
259
253
 
260
- describe('runBenchmark()', () => {
261
- it('should return benchmark results', async () => {
262
- mockExec.mockImplementation((cmd, opts, callback) => {
263
- callback(null, { stdout: '', stderr: '' });
264
- });
265
-
266
- const result = await gate.runBenchmark(baseContext);
267
-
268
- expect(result.avgResponseTime).toBeGreaterThanOrEqual(0);
269
- expect(result.avgMemoryUsage).toBeGreaterThanOrEqual(0);
270
- });
271
-
272
- it('should run warmup and measure runs', async () => {
273
- const customGate = new PerformanceGate({
274
- warmupRuns: 1,
275
- measureRuns: 2,
276
- benchmarkCommand: 'npm run bench',
277
- });
278
-
279
- // Each exec call should succeed
280
- mockExec.mockImplementation((cmd, opts, callback) => {
281
- callback(null, { stdout: '', stderr: '' });
282
- });
283
-
284
- await customGate.runBenchmark(baseContext);
285
-
286
- // warmupRuns + measureRuns = 3 calls
287
- expect(mockExec).toHaveBeenCalledTimes(3);
288
- });
289
-
290
- it('should use custom benchmark command', async () => {
291
- const customGate = new PerformanceGate({
292
- benchmarkCommand: 'npm run benchmark',
293
- });
294
-
295
- mockExec.mockImplementation((cmd, opts, callback) => {
296
- expect(cmd).toContain('npm run benchmark');
297
- callback(null, { stdout: '', stderr: '' });
298
- });
299
-
300
- await customGate.runBenchmark(baseContext);
301
- });
302
-
303
- it('should handle benchmark error', async () => {
304
- const errorGate = new PerformanceGate({
305
- warmupRuns: 1,
306
- benchmarkCommand: 'npm run bench',
307
- });
308
-
309
- // Mock exec to fail
310
- mockExec.mockImplementationOnce((cmd, opts, callback) => {
311
- callback(new Error('Benchmark failed'), null);
312
- });
313
-
314
- const result = await errorGate.runBenchmark(baseContext);
315
-
316
- expect(result.error).toContain('failed');
317
- });
318
- });
319
-
320
254
  describe('setThresholds()', () => {
321
255
  it('should update thresholds', () => {
322
256
  gate.setThresholds({
@@ -346,12 +280,10 @@ describe('PerformanceGate', () => {
346
280
  it('should update timeouts', () => {
347
281
  gate.setTimeouts({
348
282
  coverage: 30000,
349
- benchmark: 20000,
350
283
  });
351
284
 
352
285
  const config = gate.getConfig();
353
286
  expect(config.coverageTimeout).toBe(30000);
354
- expect(config.benchmarkTimeout).toBe(20000);
355
287
  });
356
288
  });
357
289
 
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import type { ConstraintCheck } from '../core/constraints/checkers';
11
- import { buildCheckEnv } from '../core/constraints/checkers';
11
+ import { buildCheckEnv, normalizeCheckOutcome } from '../core/constraints/checkers';
12
12
  import type { Gate, GateContext, GateDecision } from './types';
13
13
  import { gateResult } from './types';
14
14
  import { decisionFromResult } from './decision';
@@ -16,7 +16,8 @@ import { decisionFromResult } from './decision';
16
16
  /**
17
17
  * 将已注册 checker 适配为统一 Gate(checker-as-guard 接线点)
18
18
  *
19
- * 判定映射:false(违反)→ deny;true(满足)/ 'skip'(未评估)→ abstain。
19
+ * 判定映射:violated(false 或 CheckDetail.pass=false)→ deny;
20
+ * 满足 / 'skip'(未评估)→ abstain。违规证据随理由带出。
20
21
  *
21
22
  * @param check 已注册的 ConstraintCheck(经 checkers 注册表取回)
22
23
  * @param order 门禁顺序(供 guard 链排序)
@@ -29,19 +30,14 @@ export function createCheckerGate(check: ConstraintCheck, order = 0): Gate {
29
30
  const startTime = Date.now();
30
31
  const projectPath = ctx.projectPath || process.cwd();
31
32
  const env = buildCheckEnv({ operation: 'manual', projectPath }, 'none');
32
- const outcome = await check.evaluate(env);
33
- return decisionFromResult(
34
- gateResult(
35
- check.id,
36
- outcome !== false,
37
- outcome === false
38
- ? `checker "${check.id}" 判定违规`
39
- : outcome === 'skip'
40
- ? `checker "${check.id}" 跳过(证据未接线)`
41
- : `checker "${check.id}" 通过`,
42
- startTime
43
- )
44
- );
33
+ const outcome = normalizeCheckOutcome(await check.evaluate(env));
34
+ const evidence = outcome.evidence.map((e) => `\n - ${e}`).join('');
35
+ const reason = outcome.skipped
36
+ ? `checker "${check.id}" 跳过(证据未接线)`
37
+ : outcome.satisfied
38
+ ? `checker "${check.id}" 通过`
39
+ : `checker "${check.id}" 判定违规${evidence}`;
40
+ return decisionFromResult(gateResult(check.id, outcome.satisfied, reason, startTime));
45
41
  },
46
42
  };
47
43
  }
@@ -111,8 +111,6 @@ export const GATE_DEFINITIONS: GateDefinition[] = [
111
111
  { flags: '--coverage-threshold <n>', description: '覆盖率阈值', defaultValue: '80' },
112
112
  { flags: '--bundle', description: '检查打包大小', defaultValue: false },
113
113
  { flags: '--bundle-threshold <n>', description: '打包大小阈值 (KB)', defaultValue: '500' },
114
- { flags: '--benchmark', description: '运行基准测试', defaultValue: false },
115
- { flags: '--benchmark-timeout <n>', description: '基准测试超时(秒)', defaultValue: '60' },
116
114
  ],
117
115
  action: { module: 'performance', export: 'performance' },
118
116
  mapActionArgs: (_positionals, options) => [
@@ -122,8 +120,6 @@ export const GATE_DEFINITIONS: GateDefinition[] = [
122
120
  coverageThreshold: parseInt(String(options.coverageThreshold), 10),
123
121
  bundle: options.bundle,
124
122
  bundleThreshold: parseInt(String(options.bundleThreshold), 10),
125
- benchmark: options.benchmark,
126
- benchmarkTimeout: parseInt(String(options.benchmarkTimeout), 10),
127
123
  },
128
124
  ],
129
125
  },
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * 性能门禁
3
- *
4
- * 检查性能指标:
5
- * - 响应时间
6
- * - 内存使用
7
- * - 测试覆盖率
8
- * - 打包大小
9
- *
3
+ *
4
+ * 检查性能指标(架构评审候选2:只留有真实现的维度):
5
+ * - 测试覆盖率(json-summary)
6
+ * - 打包大小(dist 目录测量)
7
+ *
8
+ * 响应时间/内存使用/吞吐量维度已删除:原实现用 Math.random() 伪造指标并据此判负,
9
+ * runBenchmark 的真实现从未被 check() 调用且语义可疑(量的是 harness 进程自己的
10
+ * heap)——零真实消费者的维度按 ADR-0015 同构判例删薄(ADR-0018)。
11
+ *
10
12
  * 改进:
11
13
  * - 添加超时机制
12
14
  * - 改进错误处理
@@ -23,8 +25,6 @@ import { decisionFromResult } from './decision';
23
25
  // 默认超时时间(毫秒)
24
26
  const DEFAULT_TIMEOUTS = {
25
27
  coverage: 120000, // 覆盖率测试:2分钟
26
- benchmark: 60000, // 基准测试:1分钟
27
- bundle: 10000, // 打包大小:10秒
28
28
  };
29
29
 
30
30
  /**
@@ -33,8 +33,6 @@ const DEFAULT_TIMEOUTS = {
33
33
  export interface ExtendedPerformanceGateConfig extends PerformanceGateConfig {
34
34
  /** 覆盖率测试超时(毫秒) */
35
35
  coverageTimeout?: number;
36
- /** 基准测试超时(毫秒) */
37
- benchmarkTimeout?: number;
38
36
  }
39
37
 
40
38
  /**
@@ -48,12 +46,8 @@ export class PerformanceGate implements Gate {
48
46
  constructor(config: Partial<ExtendedPerformanceGateConfig> = {}) {
49
47
  this.config = {
50
48
  enabled: config.enabled ?? true,
51
- benchmarkCommand: config.benchmarkCommand ?? '',
52
49
  thresholds: config.thresholds ?? {},
53
- warmupRuns: config.warmupRuns ?? 2,
54
- measureRuns: config.measureRuns ?? 5,
55
50
  coverageTimeout: config.coverageTimeout ?? DEFAULT_TIMEOUTS.coverage,
56
- benchmarkTimeout: config.benchmarkTimeout ?? DEFAULT_TIMEOUTS.benchmark,
57
51
  };
58
52
  }
59
53
 
@@ -80,20 +74,6 @@ export class PerformanceGate implements Gate {
80
74
  const failures: string[] = [];
81
75
  const warnings: string[] = [];
82
76
 
83
- // 检查响应时间
84
- if (thresholds.maxResponseTime && metrics.responseTime !== undefined) {
85
- if (metrics.responseTime > thresholds.maxResponseTime) {
86
- failures.push(`响应时间 ${metrics.responseTime}ms > ${thresholds.maxResponseTime}ms`);
87
- }
88
- }
89
-
90
- // 检查内存使用
91
- if (thresholds.maxMemoryUsage && metrics.memoryUsage !== undefined) {
92
- if (metrics.memoryUsage > thresholds.maxMemoryUsage) {
93
- failures.push(`内存使用 ${metrics.memoryUsage}MB > ${thresholds.maxMemoryUsage}MB`);
94
- }
95
- }
96
-
97
77
  // 检查覆盖率
98
78
  if (thresholds.minCoverage) {
99
79
  if (metrics.coverageError) {
@@ -124,8 +104,6 @@ export class PerformanceGate implements Gate {
124
104
  startTime,
125
105
  {
126
106
  metrics: {
127
- responseTime: metrics.responseTime,
128
- memoryUsage: metrics.memoryUsage,
129
107
  coverage: metrics.coverage,
130
108
  bundleSize: metrics.bundleSize,
131
109
  },
@@ -146,8 +124,6 @@ export class PerformanceGate implements Gate {
146
124
  projectPath: string,
147
125
  thresholds: PerformanceThresholds
148
126
  ): Promise<{
149
- responseTime?: number;
150
- memoryUsage?: number;
151
127
  coverage?: number;
152
128
  coverageError?: string;
153
129
  bundleSize?: number;
@@ -175,15 +151,6 @@ export class PerformanceGate implements Gate {
175
151
  }
176
152
  }
177
153
 
178
- // 模拟响应时间和内存(需要实际基准测试)
179
- if (thresholds.maxResponseTime) {
180
- metrics.responseTime = Math.floor(Math.random() * 500) + 100;
181
- }
182
-
183
- if (thresholds.maxMemoryUsage) {
184
- metrics.memoryUsage = Math.floor(Math.random() * 200) + 50;
185
- }
186
-
187
154
  return metrics;
188
155
  }
189
156
 
@@ -258,78 +225,11 @@ export class PerformanceGate implements Gate {
258
225
  */
259
226
  private formatMetrics(metrics: any): string {
260
227
  const parts: string[] = [];
261
- if (metrics.responseTime !== undefined) parts.push(`响应时间=${metrics.responseTime}ms`);
262
- if (metrics.memoryUsage !== undefined) parts.push(`内存=${metrics.memoryUsage}MB`);
263
228
  if (metrics.coverage !== undefined) parts.push(`覆盖率=${metrics.coverage}%`);
264
229
  if (metrics.bundleSize !== undefined) parts.push(`打包=${metrics.bundleSize}KB`);
265
230
  return parts.join(', ') || '无指标';
266
231
  }
267
232
 
268
- /**
269
- * 运行基准测试(带超时)
270
- */
271
- async runBenchmark(context: GateContext): Promise<{
272
- avgResponseTime: number;
273
- avgMemoryUsage: number;
274
- minResponseTime: number;
275
- maxResponseTime: number;
276
- error?: string;
277
- }> {
278
- const results: Array<{ responseTime: number; memoryUsage: number }> = [];
279
-
280
- try {
281
- // 预热运行
282
- for (let i = 0; i < this.config.warmupRuns; i++) {
283
- await this.singleBenchmark(context);
284
- }
285
-
286
- // 测量运行
287
- for (let i = 0; i < this.config.measureRuns; i++) {
288
- const result = await this.singleBenchmark(context);
289
- results.push(result);
290
- }
291
-
292
- const responseTimes = results.map(r => r.responseTime);
293
- const memoryUsages = results.map(r => r.memoryUsage);
294
-
295
- return {
296
- avgResponseTime: responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length,
297
- avgMemoryUsage: memoryUsages.reduce((a, b) => a + b, 0) / memoryUsages.length,
298
- minResponseTime: Math.min(...responseTimes),
299
- maxResponseTime: Math.max(...responseTimes),
300
- };
301
- } catch (error: any) {
302
- return {
303
- avgResponseTime: 0,
304
- avgMemoryUsage: 0,
305
- minResponseTime: 0,
306
- maxResponseTime: 0,
307
- error: error.message || '基准测试失败',
308
- };
309
- }
310
- }
311
-
312
- /**
313
- * 单次基准测试(带超时)
314
- */
315
- private async singleBenchmark(context: GateContext): Promise<{ responseTime: number; memoryUsage: number }> {
316
- const start = Date.now();
317
-
318
- // 如果有基准测试命令,运行它
319
- if (this.config.benchmarkCommand || context.benchmarkCommand) {
320
- await execAsync(this.config.benchmarkCommand || context.benchmarkCommand!, {
321
- cwd: context.projectPath,
322
- timeout: this.config.benchmarkTimeout,
323
- killSignal: 'SIGTERM',
324
- });
325
- }
326
-
327
- const responseTime = Date.now() - start;
328
- const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
329
-
330
- return { responseTime, memoryUsage };
331
- }
332
-
333
233
  /**
334
234
  * 设置阈值
335
235
  */
@@ -342,10 +242,8 @@ export class PerformanceGate implements Gate {
342
242
  */
343
243
  setTimeouts(options: {
344
244
  coverage?: number;
345
- benchmark?: number;
346
245
  }): void {
347
246
  if (options.coverage) this.config.coverageTimeout = options.coverage;
348
- if (options.benchmark) this.config.benchmarkTimeout = options.benchmark;
349
247
  }
350
248
 
351
249
  /**