@dommaker/harness 1.9.0 → 1.11.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 (285) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +9 -12
  3. package/dist/cli/commands/check.d.ts +3 -3
  4. package/dist/cli/commands/check.d.ts.map +1 -1
  5. package/dist/cli/commands/check.js +41 -78
  6. package/dist/cli/commands/check.js.map +1 -1
  7. package/dist/cli/commands/constraints-report.d.ts +2 -10
  8. package/dist/cli/commands/constraints-report.d.ts.map +1 -1
  9. package/dist/cli/commands/constraints-report.js +4 -57
  10. package/dist/cli/commands/constraints-report.js.map +1 -1
  11. package/dist/cli/commands/constraints-retire.d.ts +9 -23
  12. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  13. package/dist/cli/commands/constraints-retire.js +39 -121
  14. package/dist/cli/commands/constraints-retire.js.map +1 -1
  15. package/dist/cli/commands/constraints.d.ts +3 -8
  16. package/dist/cli/commands/constraints.d.ts.map +1 -1
  17. package/dist/cli/commands/constraints.js +8 -23
  18. package/dist/cli/commands/constraints.js.map +1 -1
  19. package/dist/cli/commands/definitions.d.ts.map +1 -1
  20. package/dist/cli/commands/definitions.js +7 -12
  21. package/dist/cli/commands/definitions.js.map +1 -1
  22. package/dist/cli/commands/init.d.ts +0 -32
  23. package/dist/cli/commands/init.d.ts.map +1 -1
  24. package/dist/cli/commands/init.js +7 -149
  25. package/dist/cli/commands/init.js.map +1 -1
  26. package/dist/cli/commands/report.d.ts.map +1 -1
  27. package/dist/cli/commands/report.js +14 -17
  28. package/dist/cli/commands/report.js.map +1 -1
  29. package/dist/cli/commands/scaffold-templates.d.ts +1 -3
  30. package/dist/cli/commands/scaffold-templates.d.ts.map +1 -1
  31. package/dist/cli/commands/scaffold-templates.js +2 -53
  32. package/dist/cli/commands/scaffold-templates.js.map +1 -1
  33. package/dist/cli/commands/scaffold.d.ts +0 -2
  34. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  35. package/dist/cli/commands/scaffold.js +0 -10
  36. package/dist/cli/commands/scaffold.js.map +1 -1
  37. package/dist/cli/commands/status.js +10 -10
  38. package/dist/cli/commands/status.js.map +1 -1
  39. package/dist/cli/commands/sync-docs/agents-syncer.d.ts +0 -2
  40. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
  41. package/dist/cli/commands/sync-docs/agents-syncer.js +4 -23
  42. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
  43. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  44. package/dist/core/constraints/capabilities-parser.js +16 -4
  45. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  46. package/dist/core/constraints/checker.d.ts +15 -24
  47. package/dist/core/constraints/checker.d.ts.map +1 -1
  48. package/dist/core/constraints/checker.js +33 -72
  49. package/dist/core/constraints/checker.js.map +1 -1
  50. package/dist/core/constraints/checkers/docs-freshness.js +1 -1
  51. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  52. package/dist/core/constraints/checkers/governance-presence.d.ts +2 -1
  53. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
  54. package/dist/core/constraints/checkers/governance-presence.js +4 -3
  55. package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
  56. package/dist/core/constraints/checkers/index.d.ts +1 -1
  57. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  58. package/dist/core/constraints/checkers/index.js +4 -8
  59. package/dist/core/constraints/checkers/index.js.map +1 -1
  60. package/dist/core/constraints/checkers/iron-flags.d.ts +3 -4
  61. package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -1
  62. package/dist/core/constraints/checkers/iron-flags.js +4 -5
  63. package/dist/core/constraints/checkers/iron-flags.js.map +1 -1
  64. package/dist/core/constraints/checkers/no-test-simplification.js +1 -1
  65. package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
  66. package/dist/core/constraints/checkers/types.d.ts +1 -1
  67. package/dist/core/constraints/checkers/types.js +1 -1
  68. package/dist/core/constraints/definitions/guidelines.d.ts +4 -4
  69. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  70. package/dist/core/constraints/definitions/guidelines.js +9 -25
  71. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  72. package/dist/core/constraints/definitions/iron-laws.d.ts +4 -4
  73. package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -1
  74. package/dist/core/constraints/definitions/iron-laws.js +10 -81
  75. package/dist/core/constraints/definitions/iron-laws.js.map +1 -1
  76. package/dist/core/constraints/definitions.d.ts +7 -9
  77. package/dist/core/constraints/definitions.d.ts.map +1 -1
  78. package/dist/core/constraints/definitions.js +13 -16
  79. package/dist/core/constraints/definitions.js.map +1 -1
  80. package/dist/core/constraints/index.d.ts +2 -5
  81. package/dist/core/constraints/index.d.ts.map +1 -1
  82. package/dist/core/constraints/index.js +3 -13
  83. package/dist/core/constraints/index.js.map +1 -1
  84. package/dist/core/constraints/injection-writer.d.ts +10 -38
  85. package/dist/core/constraints/injection-writer.d.ts.map +1 -1
  86. package/dist/core/constraints/injection-writer.js +17 -54
  87. package/dist/core/constraints/injection-writer.js.map +1 -1
  88. package/dist/core/constraints/run-env.d.ts +1 -10
  89. package/dist/core/constraints/run-env.d.ts.map +1 -1
  90. package/dist/core/constraints/run-env.js +1 -22
  91. package/dist/core/constraints/run-env.js.map +1 -1
  92. package/dist/core/constraints/usage-report.d.ts +6 -8
  93. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  94. package/dist/core/constraints/usage-report.js +6 -11
  95. package/dist/core/constraints/usage-report.js.map +1 -1
  96. package/dist/core/effective-constraints.d.ts +12 -22
  97. package/dist/core/effective-constraints.d.ts.map +1 -1
  98. package/dist/core/effective-constraints.js +13 -30
  99. package/dist/core/effective-constraints.js.map +1 -1
  100. package/dist/core/index.d.ts +2 -2
  101. package/dist/core/index.d.ts.map +1 -1
  102. package/dist/core/index.js +3 -9
  103. package/dist/core/index.js.map +1 -1
  104. package/dist/core/project-config-loader.d.ts +4 -42
  105. package/dist/core/project-config-loader.d.ts.map +1 -1
  106. package/dist/core/project-config-loader.js +16 -125
  107. package/dist/core/project-config-loader.js.map +1 -1
  108. package/dist/core/validators/passes-gate.d.ts +2 -2
  109. package/dist/core/validators/passes-gate.js +6 -6
  110. package/dist/core/validators/passes-gate.js.map +1 -1
  111. package/dist/index.d.ts +9 -10
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +21 -18
  114. package/dist/index.js.map +1 -1
  115. package/dist/knowledge/lint.d.ts +17 -0
  116. package/dist/knowledge/lint.d.ts.map +1 -1
  117. package/dist/knowledge/lint.js +52 -0
  118. package/dist/knowledge/lint.js.map +1 -1
  119. package/dist/knowledge/store.d.ts +7 -0
  120. package/dist/knowledge/store.d.ts.map +1 -1
  121. package/dist/knowledge/store.js +48 -13
  122. package/dist/knowledge/store.js.map +1 -1
  123. package/dist/knowledge/types.d.ts +5 -1
  124. package/dist/knowledge/types.d.ts.map +1 -1
  125. package/dist/knowledge/types.js +5 -1
  126. package/dist/knowledge/types.js.map +1 -1
  127. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  128. package/dist/monitoring/trace-analyzer.js +11 -12
  129. package/dist/monitoring/trace-analyzer.js.map +1 -1
  130. package/dist/monitoring/traces.d.ts +4 -4
  131. package/dist/monitoring/traces.d.ts.map +1 -1
  132. package/dist/monitoring/traces.js +8 -8
  133. package/dist/monitoring/traces.js.map +1 -1
  134. package/dist/presets/standard.d.ts +8 -10
  135. package/dist/presets/standard.d.ts.map +1 -1
  136. package/dist/presets/standard.js +10 -16
  137. package/dist/presets/standard.js.map +1 -1
  138. package/dist/types/constraint.d.ts +24 -35
  139. package/dist/types/constraint.d.ts.map +1 -1
  140. package/dist/types/constraint.js +8 -7
  141. package/dist/types/constraint.js.map +1 -1
  142. package/dist/types/passes-gate.d.ts +5 -5
  143. package/dist/types/passes-gate.d.ts.map +1 -1
  144. package/dist/types/project-config.d.ts +8 -66
  145. package/dist/types/project-config.d.ts.map +1 -1
  146. package/dist/types/project-config.js +3 -2
  147. package/dist/types/project-config.js.map +1 -1
  148. package/dist/types/trace.d.ts +8 -10
  149. package/dist/types/trace.d.ts.map +1 -1
  150. package/package.json +2 -2
  151. package/src/CONTEXT.md +2 -2
  152. package/src/__tests__/checker-extra.test.ts +37 -61
  153. package/src/__tests__/checker.test.ts +10 -115
  154. package/src/__tests__/effective-constraints.test.ts +18 -83
  155. package/src/__tests__/iron-laws.test.ts +71 -90
  156. package/src/__tests__/passes-gate-check.test.ts +2 -2
  157. package/src/__tests__/project-config-loader-extra.test.ts +22 -123
  158. package/src/__tests__/project-config-loader.test.ts +5 -33
  159. package/src/__tests__/public-exports.test.ts +8 -7
  160. package/src/__tests__/public-type-surface.test.ts +7 -5
  161. package/src/__tests__/public-value-surface.test.ts +1 -7
  162. package/src/__tests__/skip-semantics.test.ts +21 -37
  163. package/src/__tests__/trace-analyzer-extra.test.ts +14 -14
  164. package/src/__tests__/trace-analyzer.test.ts +21 -21
  165. package/src/__tests__/trace-collector.test.ts +22 -22
  166. package/src/__tests__/traces.test.ts +27 -28
  167. package/src/__tests__/usage-report-public-export.test.ts +21 -0
  168. package/src/cli/commands/CONTEXT.md +12 -12
  169. package/src/cli/commands/__tests__/check-read-count.test.ts +4 -15
  170. package/src/cli/commands/__tests__/check-skip-output.test.ts +14 -14
  171. package/src/cli/commands/__tests__/check.test.ts +14 -31
  172. package/src/cli/commands/__tests__/constraints-report-json-flag.test.ts +101 -0
  173. package/src/cli/commands/__tests__/constraints-report.test.ts +12 -80
  174. package/src/cli/commands/__tests__/constraints-retire.test.ts +42 -231
  175. package/src/cli/commands/__tests__/init-governance-io.test.ts +12 -58
  176. package/src/cli/commands/__tests__/init-ondisk.test.ts +13 -21
  177. package/src/cli/commands/__tests__/init.test.ts +1 -16
  178. package/src/cli/commands/__tests__/numeric-flag-assembly.test.ts +1 -1
  179. package/src/cli/commands/__tests__/passes-gate-dead-options.test.ts +1 -1
  180. package/src/cli/commands/__tests__/project-path-anchoring.test.ts +2 -2
  181. package/src/cli/commands/__tests__/registry.test.ts +1 -1
  182. package/src/cli/commands/__tests__/report-extra.test.ts +4 -4
  183. package/src/cli/commands/__tests__/report.test.ts +1 -1
  184. package/src/cli/commands/__tests__/scaffold.test.ts +4 -14
  185. package/src/cli/commands/__tests__/status-analysis-wiring.test.ts +3 -3
  186. package/src/cli/commands/__tests__/status-extra.test.ts +14 -14
  187. package/src/cli/commands/__tests__/status.test.ts +12 -12
  188. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +1 -1
  189. package/src/cli/commands/check.ts +43 -82
  190. package/src/cli/commands/constraints-report.ts +4 -59
  191. package/src/cli/commands/constraints-retire.ts +49 -154
  192. package/src/cli/commands/constraints.ts +11 -26
  193. package/src/cli/commands/definitions.ts +7 -12
  194. package/src/cli/commands/init.ts +8 -179
  195. package/src/cli/commands/report.ts +19 -23
  196. package/src/cli/commands/scaffold-templates.ts +1 -53
  197. package/src/cli/commands/scaffold.ts +0 -11
  198. package/src/cli/commands/status.ts +10 -10
  199. package/src/cli/commands/sync-docs/agents-syncer.ts +4 -25
  200. package/src/core/CONTEXT.md +9 -9
  201. package/src/core/constraints/__tests__/capability-counts.test.ts +5 -5
  202. package/src/core/constraints/__tests__/collect-constraints.test.ts +13 -8
  203. package/src/core/constraints/__tests__/git-evidence.test.ts +4 -7
  204. package/src/core/constraints/__tests__/injection-writer.test.ts +8 -61
  205. package/src/core/constraints/__tests__/run-env.test.ts +5 -34
  206. package/src/core/constraints/__tests__/trace-injection.test.ts +1 -1
  207. package/src/core/constraints/capabilities-parser.ts +17 -5
  208. package/src/core/constraints/checker.ts +39 -88
  209. package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +5 -8
  210. package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +1 -53
  211. package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +5 -25
  212. package/src/core/constraints/checkers/docs-freshness.ts +1 -1
  213. package/src/core/constraints/checkers/governance-presence.ts +4 -3
  214. package/src/core/constraints/checkers/index.ts +4 -10
  215. package/src/core/constraints/checkers/iron-flags.ts +3 -12
  216. package/src/core/constraints/checkers/no-test-simplification.ts +1 -1
  217. package/src/core/constraints/checkers/types.ts +1 -1
  218. package/src/core/constraints/definitions/guidelines.ts +8 -25
  219. package/src/core/constraints/definitions/iron-laws.ts +9 -82
  220. package/src/core/constraints/definitions.ts +14 -15
  221. package/src/core/constraints/index.ts +4 -19
  222. package/src/core/constraints/injection-writer.ts +16 -61
  223. package/src/core/constraints/run-env.ts +1 -33
  224. package/src/core/constraints/usage-report.ts +9 -16
  225. package/src/core/effective-constraints.ts +14 -45
  226. package/src/core/index.ts +3 -10
  227. package/src/core/project-config-loader.ts +20 -145
  228. package/src/core/validators/passes-gate.ts +6 -6
  229. package/src/failure/CONTEXT.md +1 -1
  230. package/src/hooks/__tests__/bootstrap.test.ts +3 -5
  231. package/src/index.ts +28 -18
  232. package/src/knowledge/CONTEXT.md +4 -3
  233. package/src/knowledge/__tests__/lint.test.ts +84 -0
  234. package/src/knowledge/__tests__/store.test.ts +70 -0
  235. package/src/knowledge/lint.ts +60 -1
  236. package/src/knowledge/store.ts +48 -11
  237. package/src/knowledge/types.ts +7 -1
  238. package/src/monitoring/CONTEXT.md +1 -1
  239. package/src/monitoring/__tests__/trace-file-anchoring.test.ts +1 -1
  240. package/src/monitoring/__tests__/traces.test.ts +22 -22
  241. package/src/monitoring/trace-analyzer.ts +12 -13
  242. package/src/monitoring/traces.ts +8 -8
  243. package/src/presets/__tests__/standard.test.ts +12 -16
  244. package/src/presets/standard.ts +14 -23
  245. package/src/types/__tests__/types.test.ts +3 -3
  246. package/src/types/constraint.ts +26 -40
  247. package/src/types/passes-gate.ts +5 -5
  248. package/src/types/project-config.ts +8 -77
  249. package/src/types/trace.ts +8 -11
  250. package/dist/cli/commands/posteval-plan.d.ts +0 -15
  251. package/dist/cli/commands/posteval-plan.d.ts.map +0 -1
  252. package/dist/cli/commands/posteval-plan.js +0 -86
  253. package/dist/cli/commands/posteval-plan.js.map +0 -1
  254. package/dist/core/constraints/agent-prompt-renderer.d.ts +0 -32
  255. package/dist/core/constraints/agent-prompt-renderer.d.ts.map +0 -1
  256. package/dist/core/constraints/agent-prompt-renderer.js +0 -55
  257. package/dist/core/constraints/agent-prompt-renderer.js.map +0 -1
  258. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts +0 -6
  259. package/dist/core/constraints/checkers/no-bypass-checkpoint.d.ts.map +0 -1
  260. package/dist/core/constraints/checkers/no-bypass-checkpoint.js +0 -40
  261. package/dist/core/constraints/checkers/no-bypass-checkpoint.js.map +0 -1
  262. package/dist/core/constraints/definitions/prompts.d.ts +0 -12
  263. package/dist/core/constraints/definitions/prompts.d.ts.map +0 -1
  264. package/dist/core/constraints/definitions/prompts.js +0 -400
  265. package/dist/core/constraints/definitions/prompts.js.map +0 -1
  266. package/dist/core/constraints/injection-drift.d.ts +0 -61
  267. package/dist/core/constraints/injection-drift.d.ts.map +0 -1
  268. package/dist/core/constraints/injection-drift.js +0 -131
  269. package/dist/core/constraints/injection-drift.js.map +0 -1
  270. package/dist/core/constraints/injection-renderer.d.ts +0 -23
  271. package/dist/core/constraints/injection-renderer.d.ts.map +0 -1
  272. package/dist/core/constraints/injection-renderer.js +0 -44
  273. package/dist/core/constraints/injection-renderer.js.map +0 -1
  274. package/src/cli/commands/__tests__/check-drift.test.ts +0 -158
  275. package/src/cli/commands/__tests__/init-injection.test.ts +0 -466
  276. package/src/cli/commands/__tests__/posteval-plan.test.ts +0 -204
  277. package/src/cli/commands/posteval-plan.ts +0 -98
  278. package/src/core/constraints/__tests__/agent-prompt-renderer.test.ts +0 -129
  279. package/src/core/constraints/__tests__/injection-drift.test.ts +0 -247
  280. package/src/core/constraints/agent-prompt-renderer.ts +0 -67
  281. package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +0 -76
  282. package/src/core/constraints/checkers/no-bypass-checkpoint.ts +0 -40
  283. package/src/core/constraints/definitions/prompts.ts +0 -414
  284. package/src/core/constraints/injection-drift.ts +0 -142
  285. package/src/core/constraints/injection-renderer.ts +0 -44
@@ -1,15 +1,13 @@
1
1
  /**
2
2
  * checker.ts 测试
3
3
  *
4
- * ADR-0001:只覆盖存活 check 约束的 checker 行为;
5
- * prompt 类约束的短路语义见 'Prompt constraints' 一节;
6
- * 已退役/被吸收约束的用例随之移除。
4
+ * ADR-0029:只覆盖存活 check 约束的 checker 行为;
5
+ * prompt 面已删除,其短路用例随之移除。
7
6
  */
8
7
 
9
8
  import { ConstraintChecker, checkConstraint } from '../core/constraints/checker';
10
- import { PROMPTS } from '../core/constraints/definitions';
11
9
  import type { ConstraintContext } from '../types/constraint';
12
- import { writeFileSync, rmSync, mkdtempSync } from 'fs';
10
+ import { rmSync, mkdtempSync } from 'fs';
13
11
  import { join } from 'path';
14
12
  import { tmpdir } from 'os';
15
13
 
@@ -31,42 +29,7 @@ describe('ConstraintChecker', () => {
31
29
  }
32
30
  });
33
31
 
34
- describe('Iron Laws', () => {
35
- it('should check no_bypass_checkpoint with skip patterns', async () => {
36
- // 创建包含 skip 的文件
37
- const skipFile = join(tempDir, 'skip-test.ts');
38
- writeFileSync(skipFile, 'test.skip("skipped test", () => {});');
39
-
40
- const context: ConstraintContext = {
41
- operation: 'code_implementation',
42
- changedFiles: [skipFile],
43
- };
44
-
45
- const result = await checker.check(
46
- { id: 'no_bypass_checkpoint', kind: 'check', level: 'guideline', rule: 'NO BYPASS', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
47
- context
48
- );
49
-
50
- expect(result.satisfied).toBe(false);
51
- });
52
-
53
- it('should pass no_bypass_checkpoint without skip patterns', async () => {
54
- const normalFile = join(tempDir, 'normal-test.ts');
55
- writeFileSync(normalFile, 'test("normal test", () => { expect(true).toBe(true); });');
56
-
57
- const context: ConstraintContext = {
58
- operation: 'code_implementation',
59
- changedFiles: [normalFile],
60
- };
61
-
62
- const result = await checker.check(
63
- { id: 'no_bypass_checkpoint', kind: 'check', level: 'guideline', rule: 'NO BYPASS', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
64
- context
65
- );
66
-
67
- expect(result.satisfied).toBe(true);
68
- });
69
-
32
+ describe('error 级约束', () => {
70
33
  it('should check no_completion_without_verification', async () => {
71
34
  const contextWithEvidence: ConstraintContext = {
72
35
  operation: 'code_implementation',
@@ -79,71 +42,21 @@ describe('ConstraintChecker', () => {
79
42
  };
80
43
 
81
44
  const resultWithEvidence = await checker.check(
82
- { id: 'no_completion_without_verification', kind: 'check', level: 'iron_law', rule: 'NO COMPLETION', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
45
+ { id: 'no_completion_without_verification', kind: 'check', severity: 'error', rule: 'NO COMPLETION', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
83
46
  contextWithEvidence
84
47
  );
85
48
 
86
49
  const resultWithoutEvidence = await checker.check(
87
- { id: 'no_completion_without_verification', kind: 'check', level: 'iron_law', rule: 'NO COMPLETION', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
50
+ { id: 'no_completion_without_verification', kind: 'check', severity: 'error', rule: 'NO COMPLETION', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
88
51
  contextWithoutEvidence
89
52
  );
90
53
 
91
54
  expect(resultWithEvidence.satisfied).toBe(true);
92
55
  expect(resultWithoutEvidence.satisfied).toBe(false);
93
56
  });
94
-
95
- it('should check incremental_progress', async () => {
96
- const contextWithSingleTask: ConstraintContext = {
97
- operation: 'code_implementation',
98
- hasSingleTask: true,
99
- };
100
-
101
- const contextWithMultipleTasks: ConstraintContext = {
102
- operation: 'code_implementation',
103
- hasSingleTask: false,
104
- };
105
-
106
- const resultWith = await checker.check(
107
- { id: 'incremental_progress', kind: 'check', level: 'iron_law', rule: 'ONE TASK', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
108
- contextWithSingleTask
109
- );
110
-
111
- const resultWithout = await checker.check(
112
- { id: 'incremental_progress', kind: 'check', level: 'iron_law', rule: 'ONE TASK', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
113
- contextWithMultipleTasks
114
- );
115
-
116
- expect(resultWith.satisfied).toBe(true);
117
- expect(resultWithout.satisfied).toBe(false);
118
- });
119
-
120
- it('should check no_implementation_without_requirement', async () => {
121
- const contextWithRequirement: ConstraintContext = {
122
- operation: 'code_implementation',
123
- hasRequirement: true,
124
- };
125
-
126
- const contextWithoutRequirement: ConstraintContext = {
127
- operation: 'code_implementation',
128
- hasRequirement: false,
129
- };
130
-
131
- const resultWith = await checker.check(
132
- { id: 'no_implementation_without_requirement', kind: 'check', level: 'iron_law', rule: 'REQ EXISTS', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
133
- contextWithRequirement
134
- );
135
-
136
- const resultWithout = await checker.check(
137
- { id: 'no_implementation_without_requirement', kind: 'check', level: 'iron_law', rule: 'REQ EXISTS', message: 'test', trigger: 'code_implementation', enforcement: 'test' },
138
- contextWithoutRequirement
139
- );
140
-
141
- expect(resultWith.satisfied).toBe(true);
142
- expect(resultWithout.satisfied).toBe(false);
143
- });
144
57
  });
145
58
 
146
- describe('Guidelines', () => {
59
+ describe('warning 级约束', () => {
147
60
  it('should check capability_sync without CAPABILITIES.md', async () => {
148
61
  // 注意:tempDir 在 harness 仓库内,如果有缓存的变更,会检查到代码变更
149
62
  // 所以需要创建一个无代码变更的场景或创建 CAPABILITIES.md
@@ -159,7 +72,7 @@ describe('ConstraintChecker', () => {
159
72
  fs.writeFileSync(capabilitiesPath, '# Capabilities\n');
160
73
 
161
74
  const result = await checker.check(
162
- { id: 'capability_sync', kind: 'check', level: 'guideline', rule: 'CAPABILITY SYNC', message: 'test', trigger: 'commit', enforcement: 'test' },
75
+ { id: 'capability_sync', kind: 'check', severity: 'warning', rule: 'CAPABILITY SYNC', message: 'test', trigger: 'commit', enforcement: 'test' },
163
76
  context
164
77
  );
165
78
 
@@ -171,24 +84,6 @@ describe('ConstraintChecker', () => {
171
84
  });
172
85
  });
173
86
 
174
- describe('Prompt constraints(ADR-0001:不执行 checker,check() 短路 satisfied)', () => {
175
- it('所有内置 prompt 约束 check() 均短路通过', async () => {
176
- const context: ConstraintContext = { operation: 'code_implementation' };
177
- for (const prompt of Object.values(PROMPTS)) {
178
- const result = await checker.check(prompt, context);
179
- expect(result.satisfied).toBe(true);
180
- }
181
- });
182
-
183
- it('prompt 短路不产生 requiredAction/message', async () => {
184
- const context: ConstraintContext = { operation: 'code_implementation' };
185
- const result = await checker.check(PROMPTS['no_fix_without_root_cause'], context);
186
- expect(result.satisfied).toBe(true);
187
- expect(result.message).toBeUndefined();
188
- expect(result.requiredAction).toBeUndefined();
189
- });
190
- });
191
-
192
87
  describe('Helper functions', () => {
193
88
  it('should check single constraint via checkConstraint', async () => {
194
89
  const context: ConstraintContext = {
@@ -205,8 +100,8 @@ describe('ConstraintChecker', () => {
205
100
  operation: 'code_implementation',
206
101
  };
207
102
 
208
- const result = await checkConstraint('no_fuzzy_completion_claim', context);
209
- expect(result.id).toBe('no_fuzzy_completion_claim');
103
+ const result = await checkConstraint('no_completion_without_verification', context);
104
+ expect(result.id).toBe('no_completion_without_verification');
210
105
  expect(result.satisfied).toBe(true);
211
106
  });
212
107
 
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * 生效约束集(getEffectiveConstraints / lintEffectiveConfig)测试
3
3
  *
4
- * 合并矩阵:preset 裁剪 / config.yml 禁用 / custom 追加 / scenes 过滤 / 未知 id 诊断
4
+ * 合并矩阵(ADR-0029):preset 裁剪 / config.yml 禁用 / 未知 id 诊断
5
+ * (custom 追加与 scenes 过滤已随文本注入层关停一并退役)
5
6
  */
6
7
 
7
8
  import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
@@ -11,25 +12,19 @@ import {
11
12
  lintEffectiveConfig,
12
13
  } from '../core/effective-constraints';
13
14
  import { createProjectFixture } from '../test-setup/project-fixture';
14
- import { IRON_LAWS, GUIDELINES, PROMPTS } from '../core/constraints/definitions';
15
+ import { CONSTRAINTS } from '../core/constraints/definitions';
15
16
 
16
- const BUILTIN_TOTAL =
17
- Object.keys(IRON_LAWS).length + Object.keys(GUIDELINES).length + Object.keys(PROMPTS).length;
18
- /** 带 appliesTo 标签的内置 prompt(scenes 过滤对象) */
19
- const SCENE_PROMPTS = Object.values(PROMPTS)
20
- .filter(c => c.appliesTo && c.appliesTo.length > 0)
21
- .map(c => c.id);
17
+ const BUILTIN_TOTAL = Object.keys(CONSTRAINTS).length;
22
18
 
23
19
  describe('getEffectiveConstraints / lintEffectiveConfig', () => {
24
20
  let tempDir: string;
25
21
  let counter = 0;
26
22
 
27
- const setupProject = (configYaml?: string, customYaml?: string): string =>
23
+ const setupProject = (configYaml?: string): string =>
28
24
  createProjectFixture({
29
25
  parentDir: tempDir,
30
26
  name: `p${counter++}`,
31
27
  config: configYaml,
32
- files: customYaml === undefined ? undefined : { '.harness/custom-constraints.yml': customYaml },
33
28
  });
34
29
 
35
30
  beforeEach(() => {
@@ -42,65 +37,28 @@ describe('getEffectiveConstraints / lintEffectiveConfig', () => {
42
37
  });
43
38
 
44
39
  describe('合并矩阵', () => {
45
- it('无配置项目:内置全集减去场景专属 prompt(scenes 缺省为空)', () => {
40
+ it('无配置项目:内置全集(全部 kind=check,带 severity)', () => {
46
41
  const dir = setupProject();
47
42
  const constraints = getEffectiveConstraints(dir);
48
- const ids = constraints.map(c => c.id);
49
-
50
- expect(constraints.length).toBe(BUILTIN_TOTAL - SCENE_PROMPTS.length);
51
- for (const id of SCENE_PROMPTS) {
52
- expect(ids).not.toContain(id);
53
- }
54
- // check + prompt 均带 kind
55
- expect(constraints.every(c => c.kind === 'check' || c.kind === 'prompt')).toBe(true);
56
- expect(constraints.filter(c => c.kind === 'check')).toHaveLength(
57
- Object.keys(IRON_LAWS).length + Object.keys(GUIDELINES).length
58
- );
59
- });
60
-
61
- it('scenes 命中:对应场景 prompt 进入生效集,其余场景 prompt 仍排除', () => {
62
- const dir = setupProject(`scenes:\n - agent-skill\n`);
63
- const ids = getEffectiveConstraints(dir).map(c => c.id);
64
43
 
65
- expect(ids).toContain('no_skill_without_test');
66
- expect(ids).not.toContain('no_model_for_deterministic');
44
+ expect(constraints.length).toBe(BUILTIN_TOTAL);
45
+ expect(constraints.every(c => c.kind === 'check')).toBe(true);
67
46
  });
68
47
 
69
- it('config.yml 禁用:check 与 prompt 条目均从生效集移除', () => {
48
+ it('config.yml 禁用:条目从生效集移除', () => {
70
49
  const dir = setupProject(`
71
50
  constraints:
72
- no_bypass_checkpoint:
51
+ capability_sync:
73
52
  enabled: false
74
- no_fuzzy_completion_claim:
53
+ docs_freshness:
75
54
  enabled: false
76
55
  `);
77
56
  const constraints = getEffectiveConstraints(dir);
78
57
  const ids = constraints.map(c => c.id);
79
58
 
80
- expect(ids).not.toContain('no_bypass_checkpoint');
81
- expect(ids).not.toContain('no_fuzzy_completion_claim');
82
- expect(constraints.length).toBe(BUILTIN_TOTAL - SCENE_PROMPTS.length - 2);
83
- });
84
-
85
- it('config.yml 禁用:custom 约束同样从生效集移除(retire 落 config.yml 的退役路径)', () => {
86
- const dir = setupProject(
87
- `
88
- constraints:
89
- my_project_rule:
90
- enabled: false
91
- `,
92
- `
93
- custom_constraints:
94
- my_project_rule:
95
- level: iron_law
96
- rule: MY RULE
97
- message: 项目自定义
98
- `
99
- );
100
- const constraints = getEffectiveConstraints(dir);
101
- const ids = constraints.map(c => c.id);
102
-
103
- expect(ids).not.toContain('my_project_rule');
59
+ expect(ids).not.toContain('capability_sync');
60
+ expect(ids).not.toContain('docs_freshness');
61
+ expect(constraints.length).toBe(BUILTIN_TOTAL - 2);
104
62
  });
105
63
 
106
64
  it('preset: relaxed 裁剪生效集', () => {
@@ -111,33 +69,13 @@ custom_constraints:
111
69
  expect(ids).toEqual(
112
70
  expect.arrayContaining([
113
71
  'no_completion_without_verification',
114
- 'incremental_progress',
115
- 'no_implementation_without_requirement',
116
- 'no_bypass_checkpoint',
117
72
  'no_hardcoded_credentials',
118
73
  ])
119
74
  );
120
- expect(constraints).toHaveLength(5);
75
+ expect(constraints).toHaveLength(2);
121
76
  expect(constraints.every(c => c.kind === 'check')).toBe(true);
122
77
  });
123
78
 
124
- it('custom-constraints.yml 追加自定义约束(kind=prompt)', () => {
125
- const dir = setupProject(undefined, `
126
- custom_constraints:
127
- my_project_rule:
128
- level: guideline
129
- rule: MY RULE
130
- message: 项目自定义
131
- trigger: code_implementation
132
- `);
133
- const constraints = getEffectiveConstraints(dir);
134
- const custom = constraints.find(c => c.id === 'my_project_rule');
135
-
136
- expect(custom).toBeDefined();
137
- expect(custom!.kind).toBe('prompt');
138
- expect(custom!.level).toBe('guideline');
139
- });
140
-
141
79
  it('禁用未知 id(已移除约束的残留配置):不报错,lint 可诊断', () => {
142
80
  const dir = setupProject(`
143
81
  constraints:
@@ -146,19 +84,16 @@ constraints:
146
84
  `);
147
85
  // 生效集不受影响、不抛错
148
86
  const constraints = getEffectiveConstraints(dir);
149
- expect(constraints.length).toBe(BUILTIN_TOTAL - SCENE_PROMPTS.length);
87
+ expect(constraints.length).toBe(BUILTIN_TOTAL);
150
88
 
151
89
  const lint = lintEffectiveConfig(dir);
152
90
  expect(lint.unknownIds).toContain('removed_legacy_constraint');
153
91
  });
154
92
 
155
- it('lintEffectiveConfig 报告 scenes 与被场景过滤的 prompt', () => {
156
- const dir = setupProject(`scenes:\n - llm-app\n`);
93
+ it('lintEffectiveConfig:干净配置 unknownIds 为空', () => {
94
+ const dir = setupProject();
157
95
  const lint = lintEffectiveConfig(dir);
158
96
 
159
- expect(lint.scenes).toEqual(['llm-app']);
160
- expect(lint.sceneExcluded).toContain('no_skill_without_test');
161
- expect(lint.sceneExcluded).not.toContain('no_model_for_deterministic');
162
97
  expect(lint.unknownIds).toEqual([]);
163
98
  });
164
99
  });
@@ -1,12 +1,10 @@
1
1
  /**
2
- * 约束系统测试(ADR-0001kind 二元模型,26 条清单构成 + 注册表闭环)
2
+ * 约束系统测试(ADR-0029severity 显式模型——三层命名废弃、prompt 面删除、注册表闭环保留)
3
3
  */
4
4
 
5
5
  import { describe, it, expect } from '@jest/globals';
6
6
  import {
7
- IRON_LAWS,
8
- GUIDELINES,
9
- PROMPTS,
7
+ CONSTRAINTS,
10
8
  getAllConstraints,
11
9
  findConstraintsByTrigger,
12
10
  getConstraint
@@ -16,32 +14,28 @@ import { getConstraintCheck, registeredCheckCount } from '../core/constraints/ch
16
14
  import type { ConstraintContext } from '../types/constraint';
17
15
 
18
16
  describe('Constraint System', () => {
19
- describe('清单构成(ADR-00014226)', () => {
20
- it('getAllConstraints 返回 26 条:10 check + 16 prompt', () => {
17
+ describe('清单构成(ADR-0029167,全部 kind=check)', () => {
18
+ it('getAllConstraints 返回 7 check 约束', () => {
21
19
  const all = getAllConstraints();
22
- expect(all).toHaveLength(26);
23
- expect(all.filter(c => c.kind === 'check')).toHaveLength(10);
24
- expect(all.filter(c => c.kind === 'prompt')).toHaveLength(16);
20
+ expect(all).toHaveLength(7);
21
+ expect(all.every(c => c.kind === 'check')).toBe(true);
25
22
  });
26
23
 
27
- it('check = 5 iron + 5 guideline', () => {
28
- expect(Object.keys(IRON_LAWS)).toHaveLength(5);
29
- expect(Object.keys(GUIDELINES)).toHaveLength(5);
30
- Object.values(IRON_LAWS).forEach(c => {
24
+ it('severity 分桶 = 3 error + 4 warning', () => {
25
+ const errors = Object.values(CONSTRAINTS).filter(c => c.severity === 'error');
26
+ const warnings = Object.values(CONSTRAINTS).filter(c => c.severity === 'warning');
27
+ expect(errors).toHaveLength(3);
28
+ expect(warnings).toHaveLength(4);
29
+ Object.values(CONSTRAINTS).forEach(c => {
31
30
  expect(c.kind).toBe('check');
32
- expect(c.level).toBe('iron_law');
33
- });
34
- Object.values(GUIDELINES).forEach(c => {
35
- expect(c.kind).toBe('check');
36
- expect(c.level).toBe('guideline');
37
31
  });
38
32
  });
39
33
 
40
- it('prompt 16 条,level 统一为 prompt', () => {
41
- expect(Object.keys(PROMPTS)).toHaveLength(16);
42
- Object.values(PROMPTS).forEach(c => {
43
- expect(c.kind).toBe('prompt');
44
- expect(c.level).toBe('prompt');
34
+ it('prompt 面字段已删除(promptInjection / injectPrompt / appliesTo 不存在)', () => {
35
+ Object.values(CONSTRAINTS).forEach(c => {
36
+ expect('promptInjection' in c).toBe(false);
37
+ expect('injectPrompt' in c).toBe(false);
38
+ expect('appliesTo' in c).toBe(false);
45
39
  });
46
40
  });
47
41
 
@@ -78,20 +72,48 @@ describe('Constraint System', () => {
78
72
  }
79
73
  });
80
74
 
81
- it('场景标签:no_skill_without_test / no_model_for_deterministic', () => {
82
- expect(PROMPTS['no_skill_without_test'].appliesTo).toEqual(['agent-skill']);
83
- expect(PROMPTS['no_model_for_deterministic'].appliesTo).toEqual(['llm-app']);
75
+ it('harness#174 删除的 10 条不再存在', () => {
76
+ const removed = [
77
+ 'incremental_progress',
78
+ 'no_implementation_without_requirement',
79
+ 'no_bypass_checkpoint',
80
+ 'simplest_solution_first',
81
+ 'no_simplification_without_approval',
82
+ 'follow_conventions',
83
+ 'first_principles_first',
84
+ 'no_conflict_blending',
85
+ 'no_performative_agreement',
86
+ 'no_skill_without_test',
87
+ ];
88
+ for (const id of removed) {
89
+ expect(getConstraint(id)).toBeUndefined();
90
+ expect(getConstraintCheck(id)).toBeUndefined();
91
+ }
92
+ });
93
+
94
+ it('ADR-0029:prompt 类 9 条随文本注入层关停删除', () => {
95
+ const removed = [
96
+ 'no_fuzzy_completion_claim',
97
+ 'no_fix_without_root_cause',
98
+ 'no_code_without_test',
99
+ 'fix_the_problem_not_the_gate',
100
+ 'verify_external_capability',
101
+ 'no_delete_without_context',
102
+ 'design_decision_requires_discussion',
103
+ 'surgical_changes_only',
104
+ 'no_model_for_deterministic',
105
+ ];
106
+ for (const id of removed) {
107
+ expect(getConstraint(id)).toBeUndefined();
108
+ expect(getConstraintCheck(id)).toBeUndefined();
109
+ }
84
110
  });
85
111
 
86
112
  it('no_completion_without_verification 不硬编码具体命令示例(#25:口径由项目声明)', () => {
87
- const law = IRON_LAWS['no_completion_without_verification'];
88
- expect(law.promptInjection).not.toMatch(/npm test|npm run build/);
113
+ const law = CONSTRAINTS['no_completion_without_verification'];
89
114
  expect(law.description).not.toMatch(/npm test|npm run build/);
90
- expect(law.promptInjection).not.toContain('完整');
91
115
  expect(law.description).not.toContain('完整');
92
- expect(law.promptInjection).toContain('项目声明的测试');
93
116
  expect(law.description).toContain('项目声明的测试');
94
- expect(law.promptInjection).toContain('不得凭记忆声称完成');
95
117
  });
96
118
  });
97
119
 
@@ -107,12 +129,6 @@ describe('Constraint System', () => {
107
129
  const checkCount = getAllConstraints().filter(c => c.kind === 'check').length;
108
130
  expect(registeredCheckCount()).toBe(checkCount);
109
131
  });
110
-
111
- it('prompt 约束不注册 checker', () => {
112
- for (const c of Object.values(PROMPTS)) {
113
- expect(getConstraintCheck(c.id)).toBeUndefined();
114
- }
115
- });
116
132
  });
117
133
 
118
134
  describe('Helper Functions', () => {
@@ -122,10 +138,10 @@ describe('Constraint System', () => {
122
138
  });
123
139
 
124
140
  it('should get single constraint by id', () => {
125
- const constraint = getConstraint('no_fix_without_root_cause');
141
+ const constraint = getConstraint('no_completion_without_verification');
126
142
  expect(constraint).toBeDefined();
127
- expect(constraint?.kind).toBe('prompt');
128
- expect(constraint?.level).toBe('prompt');
143
+ expect(constraint?.kind).toBe('check');
144
+ expect(constraint?.severity).toBe('error');
129
145
  });
130
146
 
131
147
  it('should return undefined for unknown constraint', () => {
@@ -147,16 +163,7 @@ describe('Constraint Checker', () => {
147
163
  };
148
164
 
149
165
  const result = constraintChecker.findApplicableConstraints(context);
150
- expect(result.ironLaws.length + result.guidelines.length).toBeGreaterThan(0);
151
- });
152
-
153
- it('prompt 约束 check() 短路 satisfied,不查注册表', async () => {
154
- const context: ConstraintContext = {
155
- operation: 'code_implementation',
156
- };
157
-
158
- const result = await constraintChecker.check(PROMPTS['no_fix_without_root_cause'], context);
159
- expect(result.satisfied).toBe(true);
166
+ expect(result.errors.length + result.warnings.length).toBeGreaterThan(0);
160
167
  });
161
168
 
162
169
  it('kind=check 但未注册 checker 的约束应抛错(不许静默 pass)', async () => {
@@ -169,7 +176,7 @@ describe('Constraint Checker', () => {
169
176
  {
170
177
  id: 'ghost_check_constraint',
171
178
  kind: 'check',
172
- level: 'guideline',
179
+ severity: 'warning',
173
180
  rule: 'GHOST',
174
181
  message: 'test',
175
182
  trigger: 'code_implementation',
@@ -189,66 +196,40 @@ describe('Constraint Checker', () => {
189
196
  };
190
197
 
191
198
  const result = await constraintChecker.checkConstraints(context);
192
- expect(result.ironLaws.length + result.guidelines.length).toBeGreaterThan(0);
199
+ expect(result.errors.length + result.warnings.length).toBeGreaterThan(0);
193
200
  });
194
201
 
195
- it('should skip incremental_progress when hasSingleTask is undefined(未接线不评估)', async () => {
202
+ it('should skip no_completion_without_verification when hasVerificationEvidence is undefined(未接线不评估)', async () => {
196
203
  const context: ConstraintContext = {
197
204
  operation: 'code_implementation',
198
205
  };
199
206
 
200
- const result = await constraintChecker.check(IRON_LAWS['incremental_progress'], context);
207
+ const result = await constraintChecker.check(CONSTRAINTS['no_completion_without_verification'], context);
201
208
  expect(result.skipped).toBe(true);
202
209
  expect(result.satisfied).toBe(true);
203
210
  });
204
211
 
205
- it('should pass incremental_progress when hasSingleTask is true', async () => {
212
+ it('should pass no_completion_without_verification when hasVerificationEvidence is true', async () => {
206
213
  const context: ConstraintContext = {
207
214
  operation: 'code_implementation',
208
- hasSingleTask: true,
209
- };
210
-
211
- const result = await constraintChecker.check(IRON_LAWS['incremental_progress'], context);
212
- expect(result.satisfied).toBe(true);
213
- });
214
-
215
- it('should skip no_implementation_without_requirement when hasRequirement is undefined(未接线不评估)', async () => {
216
- const context: ConstraintContext = {
217
- operation: 'code_implementation',
218
- };
219
-
220
- const result = await constraintChecker.check(IRON_LAWS['no_implementation_without_requirement'], context);
221
- expect(result.skipped).toBe(true);
222
- expect(result.satisfied).toBe(true);
223
- });
224
-
225
- it('should pass no_implementation_without_requirement when hasRequirement is true', async () => {
226
- const context: ConstraintContext = {
227
- operation: 'code_implementation',
228
- hasRequirement: true,
215
+ hasVerificationEvidence: true,
229
216
  };
230
217
 
231
- const result = await constraintChecker.check(IRON_LAWS['no_implementation_without_requirement'], context);
218
+ const result = await constraintChecker.check(CONSTRAINTS['no_completion_without_verification'], context);
232
219
  expect(result.satisfied).toBe(true);
233
220
  });
234
221
  });
235
222
 
236
- describe('Constraint Levels', () => {
237
- it('should have correct level for iron laws', () => {
238
- Object.values(IRON_LAWS).forEach(law => {
239
- expect(law.level).toBe('iron_law');
240
- });
241
- });
242
-
243
- it('should have correct level for guidelines', () => {
244
- Object.values(GUIDELINES).forEach(guideline => {
245
- expect(guideline.level).toBe('guideline');
223
+ describe('Constraint Severity', () => {
224
+ it('error 级约束 severity 均为 error', () => {
225
+ ['no_completion_without_verification', 'no_test_simplification', 'docs_freshness'].forEach(id => {
226
+ expect(CONSTRAINTS[id].severity).toBe('error');
246
227
  });
247
228
  });
248
229
 
249
- it('should have correct level for prompts', () => {
250
- Object.values(PROMPTS).forEach(prompt => {
251
- expect(prompt.level).toBe('prompt');
230
+ it('warning 级约束 severity 均为 warning', () => {
231
+ ['no_hardcoded_credentials', 'capability_sync', 'context_doc_sync', 'governance_presence'].forEach(id => {
232
+ expect(CONSTRAINTS[id].severity).toBe('warning');
252
233
  });
253
234
  });
254
235
  });
@@ -30,7 +30,7 @@ describe('PassesGate.check()', () => {
30
30
  expect(result.violations).toBeDefined();
31
31
  expect(result.violations?.length).toBe(1);
32
32
  expect(result.violations?.[0]?.id).toBe('no_self_approval');
33
- expect(result.violations?.[0]?.level).toBe('iron_law');
33
+ expect(result.violations?.[0]?.severity).toBe('error');
34
34
  expect(result.testResult).toEqual(testResult);
35
35
  });
36
36
 
@@ -47,7 +47,7 @@ describe('PassesGate.check()', () => {
47
47
  expect(result.violations).toBeDefined();
48
48
  expect(result.violations?.length).toBe(1);
49
49
  expect(result.violations?.[0]?.id).toBe('no_completion_without_verification');
50
- expect(result.violations?.[0]?.level).toBe('iron_law');
50
+ expect(result.violations?.[0]?.severity).toBe('error');
51
51
  expect(result.testResult).toEqual(testResult);
52
52
  });
53
53