@dommaker/harness 0.16.9 → 0.17.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 (337) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +33 -32
  3. package/bin/harness.js +33 -20
  4. package/dist/cli/commands/check.d.ts +3 -2
  5. package/dist/cli/commands/check.d.ts.map +1 -1
  6. package/dist/cli/commands/check.js +69 -36
  7. package/dist/cli/commands/check.js.map +1 -1
  8. package/dist/cli/commands/constraints-report.d.ts +42 -0
  9. package/dist/cli/commands/constraints-report.d.ts.map +1 -0
  10. package/dist/cli/commands/constraints-report.js +233 -0
  11. package/dist/cli/commands/constraints-report.js.map +1 -0
  12. package/dist/cli/commands/constraints-retire.d.ts +71 -0
  13. package/dist/cli/commands/constraints-retire.d.ts.map +1 -0
  14. package/dist/cli/commands/constraints-retire.js +384 -0
  15. package/dist/cli/commands/constraints-retire.js.map +1 -0
  16. package/dist/cli/commands/constraints.d.ts +1 -1
  17. package/dist/cli/commands/constraints.d.ts.map +1 -1
  18. package/dist/cli/commands/constraints.js +4 -4
  19. package/dist/cli/commands/constraints.js.map +1 -1
  20. package/dist/cli/commands/index.d.ts +2 -1
  21. package/dist/cli/commands/index.d.ts.map +1 -1
  22. package/dist/cli/commands/index.js +10 -4
  23. package/dist/cli/commands/index.js.map +1 -1
  24. package/dist/cli/commands/init.d.ts +20 -0
  25. package/dist/cli/commands/init.d.ts.map +1 -1
  26. package/dist/cli/commands/init.js +81 -59
  27. package/dist/cli/commands/init.js.map +1 -1
  28. package/dist/cli/commands/report.js +4 -4
  29. package/dist/cli/commands/report.js.map +1 -1
  30. package/dist/cli/commands/status.d.ts.map +1 -1
  31. package/dist/cli/commands/status.js +3 -4
  32. package/dist/cli/commands/status.js.map +1 -1
  33. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +5 -1
  34. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
  35. package/dist/cli/commands/sync-docs/capabilities-syncer.js +2 -10
  36. package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
  37. package/dist/cli/commands/validate.d.ts.map +1 -1
  38. package/dist/cli/commands/validate.js +1 -5
  39. package/dist/cli/commands/validate.js.map +1 -1
  40. package/dist/core/constraints/capabilities-parser.d.ts +7 -0
  41. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  42. package/dist/core/constraints/capabilities-parser.js +13 -0
  43. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  44. package/dist/core/constraints/checker.d.ts +13 -5
  45. package/dist/core/constraints/checker.d.ts.map +1 -1
  46. package/dist/core/constraints/checker.js +62 -25
  47. package/dist/core/constraints/checker.js.map +1 -1
  48. package/dist/core/constraints/checkers/capability-sync.d.ts +9 -2
  49. package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
  50. package/dist/core/constraints/checkers/capability-sync.js +55 -22
  51. package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
  52. package/dist/core/constraints/checkers/context-doc-sync.d.ts +3 -0
  53. package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
  54. package/dist/core/constraints/checkers/context-doc-sync.js +8 -2
  55. package/dist/core/constraints/checkers/context-doc-sync.js.map +1 -1
  56. package/dist/core/constraints/checkers/docs-freshness.d.ts +1 -0
  57. package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -1
  58. package/dist/core/constraints/checkers/docs-freshness.js +39 -0
  59. package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
  60. package/dist/core/constraints/checkers/index.d.ts +8 -4
  61. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  62. package/dist/core/constraints/checkers/index.js +29 -46
  63. package/dist/core/constraints/checkers/index.js.map +1 -1
  64. package/dist/core/constraints/checkers/iron-flags.d.ts +6 -7
  65. package/dist/core/constraints/checkers/iron-flags.d.ts.map +1 -1
  66. package/dist/core/constraints/checkers/iron-flags.js +10 -17
  67. package/dist/core/constraints/checkers/iron-flags.js.map +1 -1
  68. package/dist/core/constraints/checkers/no-hardcoded-credentials.d.ts +13 -0
  69. package/dist/core/constraints/checkers/no-hardcoded-credentials.d.ts.map +1 -0
  70. package/dist/core/constraints/checkers/no-hardcoded-credentials.js +91 -0
  71. package/dist/core/constraints/checkers/no-hardcoded-credentials.js.map +1 -0
  72. package/dist/core/constraints/checkers/types.d.ts +15 -4
  73. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  74. package/dist/core/constraints/checkers/types.js +16 -4
  75. package/dist/core/constraints/checkers/types.js.map +1 -1
  76. package/dist/core/constraints/context-builder.d.ts +6 -3
  77. package/dist/core/constraints/context-builder.d.ts.map +1 -1
  78. package/dist/core/constraints/context-builder.js +29 -20
  79. package/dist/core/constraints/context-builder.js.map +1 -1
  80. package/dist/core/constraints/definitions/guidelines.d.ts +6 -2
  81. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  82. package/dist/core/constraints/definitions/guidelines.js +29 -572
  83. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  84. package/dist/core/constraints/definitions/iron-laws.d.ts +6 -2
  85. package/dist/core/constraints/definitions/iron-laws.d.ts.map +1 -1
  86. package/dist/core/constraints/definitions/iron-laws.js +48 -231
  87. package/dist/core/constraints/definitions/iron-laws.js.map +1 -1
  88. package/dist/core/constraints/definitions/prompts.d.ts +12 -0
  89. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -0
  90. package/dist/core/constraints/definitions/prompts.js +405 -0
  91. package/dist/core/constraints/definitions/prompts.js.map +1 -0
  92. package/dist/core/constraints/definitions.d.ts +15 -9
  93. package/dist/core/constraints/definitions.d.ts.map +1 -1
  94. package/dist/core/constraints/definitions.js +18 -12
  95. package/dist/core/constraints/definitions.js.map +1 -1
  96. package/dist/core/constraints/index.d.ts +3 -2
  97. package/dist/core/constraints/index.d.ts.map +1 -1
  98. package/dist/core/constraints/index.js +8 -2
  99. package/dist/core/constraints/index.js.map +1 -1
  100. package/dist/core/constraints/injection-drift.d.ts +48 -0
  101. package/dist/core/constraints/injection-drift.d.ts.map +1 -0
  102. package/dist/core/constraints/injection-drift.js +140 -0
  103. package/dist/core/constraints/injection-drift.js.map +1 -0
  104. package/dist/core/constraints/injection-renderer.d.ts +23 -0
  105. package/dist/core/constraints/injection-renderer.d.ts.map +1 -0
  106. package/dist/core/constraints/injection-renderer.js +44 -0
  107. package/dist/core/constraints/injection-renderer.js.map +1 -0
  108. package/dist/core/constraints/interceptor.d.ts.map +1 -1
  109. package/dist/core/constraints/interceptor.js +3 -2
  110. package/dist/core/constraints/interceptor.js.map +1 -1
  111. package/dist/core/constraints/usage-report.d.ts +95 -0
  112. package/dist/core/constraints/usage-report.d.ts.map +1 -0
  113. package/dist/core/constraints/usage-report.js +206 -0
  114. package/dist/core/constraints/usage-report.js.map +1 -0
  115. package/dist/core/effective-constraints.d.ts +47 -0
  116. package/dist/core/effective-constraints.d.ts.map +1 -0
  117. package/dist/core/effective-constraints.js +60 -0
  118. package/dist/core/effective-constraints.js.map +1 -0
  119. package/dist/core/index.d.ts +1 -0
  120. package/dist/core/index.d.ts.map +1 -1
  121. package/dist/core/index.js +2 -0
  122. package/dist/core/index.js.map +1 -1
  123. package/dist/core/project-config-loader.d.ts +17 -2
  124. package/dist/core/project-config-loader.d.ts.map +1 -1
  125. package/dist/core/project-config-loader.js +54 -8
  126. package/dist/core/project-config-loader.js.map +1 -1
  127. package/dist/dashboard/data.d.ts +1 -9
  128. package/dist/dashboard/data.d.ts.map +1 -1
  129. package/dist/dashboard/data.js +7 -15
  130. package/dist/dashboard/data.js.map +1 -1
  131. package/dist/dashboard/types.d.ts +13 -1
  132. package/dist/dashboard/types.d.ts.map +1 -1
  133. package/dist/index.d.ts +0 -4
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +1 -13
  136. package/dist/index.js.map +1 -1
  137. package/dist/monitoring/index.d.ts +0 -2
  138. package/dist/monitoring/index.d.ts.map +1 -1
  139. package/dist/monitoring/index.js +0 -2
  140. package/dist/monitoring/index.js.map +1 -1
  141. package/dist/monitoring/knowledge-evolver.d.ts +1 -1
  142. package/dist/monitoring/knowledge-evolver.js +1 -1
  143. package/dist/monitoring/trace-analyzer.d.ts +1 -1
  144. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  145. package/dist/monitoring/trace-analyzer.js +16 -10
  146. package/dist/monitoring/trace-analyzer.js.map +1 -1
  147. package/dist/monitoring/traces.d.ts +2 -1
  148. package/dist/monitoring/traces.d.ts.map +1 -1
  149. package/dist/monitoring/traces.js +5 -3
  150. package/dist/monitoring/traces.js.map +1 -1
  151. package/dist/presets/standard.d.ts +3 -1
  152. package/dist/presets/standard.d.ts.map +1 -1
  153. package/dist/presets/standard.js +18 -8
  154. package/dist/presets/standard.js.map +1 -1
  155. package/dist/types/constraint.d.ts +51 -11
  156. package/dist/types/constraint.d.ts.map +1 -1
  157. package/dist/types/constraint.js +8 -4
  158. package/dist/types/constraint.js.map +1 -1
  159. package/dist/types/index.d.ts +1 -1
  160. package/dist/types/index.d.ts.map +1 -1
  161. package/dist/types/index.js.map +1 -1
  162. package/dist/types/monitoring-types.d.ts +2 -63
  163. package/dist/types/monitoring-types.d.ts.map +1 -1
  164. package/dist/types/monitoring-types.js +2 -2
  165. package/dist/types/project-config.d.ts +18 -1
  166. package/dist/types/project-config.d.ts.map +1 -1
  167. package/dist/types/trace.d.ts +16 -7
  168. package/dist/types/trace.d.ts.map +1 -1
  169. package/dist/types/trace.js +8 -0
  170. package/dist/types/trace.js.map +1 -1
  171. package/package.json +1 -1
  172. package/src/CONTEXT.md +2 -2
  173. package/src/__tests__/checker-extra.test.ts +228 -333
  174. package/src/__tests__/checker.test.ts +87 -724
  175. package/src/__tests__/constraint-doctor.test.ts +5 -5
  176. package/src/__tests__/doctor-extra.test.ts +164 -0
  177. package/src/__tests__/effective-constraints.test.ts +147 -0
  178. package/src/__tests__/extend-exceptions.test.ts +3 -3
  179. package/src/__tests__/iron-laws.test.ts +115 -91
  180. package/src/__tests__/no-hardcoded-credentials.test.ts +90 -0
  181. package/src/__tests__/presets.test.ts +7 -7
  182. package/src/__tests__/project-config-loader-extra.test.ts +4 -4
  183. package/src/__tests__/skip-semantics.test.ts +322 -0
  184. package/src/cli/commands/CONTEXT.md +5 -3
  185. package/src/cli/commands/__tests__/check-drift.test.ts +127 -0
  186. package/src/cli/commands/__tests__/check-skip-output.test.ts +128 -0
  187. package/src/cli/commands/__tests__/check.test.ts +14 -25
  188. package/src/cli/commands/__tests__/constraints-report.test.ts +327 -0
  189. package/src/cli/commands/__tests__/constraints-retire.test.ts +283 -0
  190. package/src/cli/commands/__tests__/init-injection.test.ts +234 -0
  191. package/src/cli/commands/__tests__/status-extra.test.ts +11 -11
  192. package/src/cli/commands/__tests__/status.test.ts +1 -1
  193. package/src/cli/commands/check.ts +72 -38
  194. package/src/cli/commands/constraints-report.ts +234 -0
  195. package/src/cli/commands/constraints-retire.ts +443 -0
  196. package/src/cli/commands/constraints.ts +5 -5
  197. package/src/cli/commands/index.ts +2 -1
  198. package/src/cli/commands/init.ts +94 -66
  199. package/src/cli/commands/report.ts +6 -6
  200. package/src/cli/commands/status.ts +3 -4
  201. package/src/cli/commands/sync-docs/capabilities-syncer.ts +5 -7
  202. package/src/cli/commands/validate.ts +1 -5
  203. package/src/core/CONTEXT.md +7 -4
  204. package/src/core/constraints/__tests__/injection-drift.test.ts +164 -0
  205. package/src/core/constraints/__tests__/interceptor.test.ts +4 -0
  206. package/src/core/constraints/capabilities-parser.ts +13 -0
  207. package/src/core/constraints/checker.ts +73 -28
  208. package/src/core/constraints/checkers/capability-sync.ts +72 -29
  209. package/src/core/constraints/checkers/context-doc-sync.ts +9 -2
  210. package/src/core/constraints/checkers/docs-freshness.ts +43 -0
  211. package/src/core/constraints/checkers/index.ts +38 -71
  212. package/src/core/constraints/checkers/iron-flags.ts +13 -49
  213. package/src/core/constraints/checkers/no-hardcoded-credentials.ts +93 -0
  214. package/src/core/constraints/checkers/types.ts +27 -5
  215. package/src/core/constraints/context-builder.ts +28 -19
  216. package/src/core/constraints/definitions/guidelines.ts +29 -597
  217. package/src/core/constraints/definitions/iron-laws.ts +48 -239
  218. package/src/core/constraints/definitions/prompts.ts +419 -0
  219. package/src/core/constraints/definitions.ts +18 -11
  220. package/src/core/constraints/index.ts +10 -1
  221. package/src/core/constraints/injection-drift.ts +139 -0
  222. package/src/core/constraints/injection-renderer.ts +44 -0
  223. package/src/core/constraints/interceptor.ts +3 -2
  224. package/src/core/constraints/usage-report.ts +254 -0
  225. package/src/core/effective-constraints.ts +85 -0
  226. package/src/core/index.ts +4 -1
  227. package/src/core/project-config-loader.ts +58 -9
  228. package/src/dashboard/__tests__/data.test.ts +5 -12
  229. package/src/dashboard/data.ts +9 -19
  230. package/src/dashboard/types.ts +18 -1
  231. package/src/index.ts +0 -12
  232. package/src/knowledge/CONTEXT.md +2 -2
  233. package/src/monitoring/CONTEXT.md +3 -4
  234. package/src/monitoring/index.ts +0 -2
  235. package/src/monitoring/knowledge-evolver.ts +1 -1
  236. package/src/monitoring/trace-analyzer.ts +15 -10
  237. package/src/monitoring/traces.ts +10 -6
  238. package/src/presets/__tests__/standard.test.ts +11 -9
  239. package/src/presets/standard.ts +24 -15
  240. package/src/types/constraint.ts +59 -14
  241. package/src/types/index.ts +1 -3
  242. package/src/types/monitoring-types.ts +2 -84
  243. package/src/types/project-config.ts +21 -1
  244. package/src/types/trace.ts +18 -7
  245. package/src/verification/CONTEXT.md +1 -1
  246. package/dist/cli/commands/flow.d.ts +0 -22
  247. package/dist/cli/commands/flow.d.ts.map +0 -1
  248. package/dist/cli/commands/flow.js +0 -275
  249. package/dist/cli/commands/flow.js.map +0 -1
  250. package/dist/constraints/lifecycle-runner.d.ts +0 -52
  251. package/dist/constraints/lifecycle-runner.d.ts.map +0 -1
  252. package/dist/constraints/lifecycle-runner.js +0 -151
  253. package/dist/constraints/lifecycle-runner.js.map +0 -1
  254. package/dist/constraints/registry.d.ts +0 -27
  255. package/dist/constraints/registry.d.ts.map +0 -1
  256. package/dist/constraints/registry.js +0 -128
  257. package/dist/constraints/registry.js.map +0 -1
  258. package/dist/constraints/types.d.ts +0 -53
  259. package/dist/constraints/types.d.ts.map +0 -1
  260. package/dist/constraints/types.js +0 -8
  261. package/dist/constraints/types.js.map +0 -1
  262. package/dist/core/constraints/checkers/always-pass.d.ts +0 -17
  263. package/dist/core/constraints/checkers/always-pass.d.ts.map +0 -1
  264. package/dist/core/constraints/checkers/always-pass.js +0 -23
  265. package/dist/core/constraints/checkers/always-pass.js.map +0 -1
  266. package/dist/core/constraints/checkers/guideline-flags.d.ts +0 -9
  267. package/dist/core/constraints/checkers/guideline-flags.d.ts.map +0 -1
  268. package/dist/core/constraints/checkers/guideline-flags.js +0 -13
  269. package/dist/core/constraints/checkers/guideline-flags.js.map +0 -1
  270. package/dist/core/constraints/checkers/no-any-type.d.ts +0 -6
  271. package/dist/core/constraints/checkers/no-any-type.d.ts.map +0 -1
  272. package/dist/core/constraints/checkers/no-any-type.js +0 -42
  273. package/dist/core/constraints/checkers/no-any-type.js.map +0 -1
  274. package/dist/core/constraints/checkers/no-excuse-patterns.d.ts +0 -6
  275. package/dist/core/constraints/checkers/no-excuse-patterns.d.ts.map +0 -1
  276. package/dist/core/constraints/checkers/no-excuse-patterns.js +0 -25
  277. package/dist/core/constraints/checkers/no-excuse-patterns.js.map +0 -1
  278. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.d.ts +0 -6
  279. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.d.ts.map +0 -1
  280. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.js +0 -34
  281. package/dist/core/constraints/checkers/no-fuzzy-completion-claim.js.map +0 -1
  282. package/dist/core/constraints/checkers/no-performative-agreement.d.ts +0 -8
  283. package/dist/core/constraints/checkers/no-performative-agreement.d.ts.map +0 -1
  284. package/dist/core/constraints/checkers/no-performative-agreement.js +0 -23
  285. package/dist/core/constraints/checkers/no-performative-agreement.js.map +0 -1
  286. package/dist/core/constraints/checkers/no-simplification-without-approval.d.ts +0 -6
  287. package/dist/core/constraints/checkers/no-simplification-without-approval.d.ts.map +0 -1
  288. package/dist/core/constraints/checkers/no-simplification-without-approval.js +0 -30
  289. package/dist/core/constraints/checkers/no-simplification-without-approval.js.map +0 -1
  290. package/dist/core/constraints/checkers/test-coverage.d.ts +0 -6
  291. package/dist/core/constraints/checkers/test-coverage.d.ts.map +0 -1
  292. package/dist/core/constraints/checkers/test-coverage.js +0 -33
  293. package/dist/core/constraints/checkers/test-coverage.js.map +0 -1
  294. package/dist/core/constraints/checkers/yagni.d.ts +0 -8
  295. package/dist/core/constraints/checkers/yagni.d.ts.map +0 -1
  296. package/dist/core/constraints/checkers/yagni.js +0 -96
  297. package/dist/core/constraints/checkers/yagni.js.map +0 -1
  298. package/dist/core/constraints/definitions/tips.d.ts +0 -7
  299. package/dist/core/constraints/definitions/tips.d.ts.map +0 -1
  300. package/dist/core/constraints/definitions/tips.js +0 -62
  301. package/dist/core/constraints/definitions/tips.js.map +0 -1
  302. package/dist/evolution/auto-evolve.d.ts +0 -35
  303. package/dist/evolution/auto-evolve.d.ts.map +0 -1
  304. package/dist/evolution/auto-evolve.js +0 -64
  305. package/dist/evolution/auto-evolve.js.map +0 -1
  306. package/dist/evolution/index.d.ts +0 -2
  307. package/dist/evolution/index.d.ts.map +0 -1
  308. package/dist/evolution/index.js +0 -18
  309. package/dist/evolution/index.js.map +0 -1
  310. package/dist/monitoring/constraint-evolver.d.ts +0 -120
  311. package/dist/monitoring/constraint-evolver.d.ts.map +0 -1
  312. package/dist/monitoring/constraint-evolver.js +0 -410
  313. package/dist/monitoring/constraint-evolver.js.map +0 -1
  314. package/src/__tests__/constraint-evolver.test.ts +0 -405
  315. package/src/__tests__/doctor-evolver.test.ts +0 -381
  316. package/src/cli/commands/__tests__/flow.test.ts +0 -343
  317. package/src/cli/commands/flow.ts +0 -277
  318. package/src/constraints/__tests__/lifecycle-runner.test.ts +0 -246
  319. package/src/constraints/__tests__/registry.test.ts +0 -196
  320. package/src/constraints/lifecycle-runner.ts +0 -184
  321. package/src/constraints/registry.ts +0 -134
  322. package/src/constraints/types.ts +0 -59
  323. package/src/core/constraints/checkers/always-pass.ts +0 -22
  324. package/src/core/constraints/checkers/guideline-flags.ts +0 -30
  325. package/src/core/constraints/checkers/no-any-type.ts +0 -42
  326. package/src/core/constraints/checkers/no-excuse-patterns.ts +0 -24
  327. package/src/core/constraints/checkers/no-fuzzy-completion-claim.ts +0 -33
  328. package/src/core/constraints/checkers/no-performative-agreement.ts +0 -22
  329. package/src/core/constraints/checkers/no-simplification-without-approval.ts +0 -29
  330. package/src/core/constraints/checkers/test-coverage.ts +0 -35
  331. package/src/core/constraints/checkers/yagni.ts +0 -65
  332. package/src/core/constraints/definitions/tips.ts +0 -63
  333. package/src/evolution/CONTEXT.md +0 -22
  334. package/src/evolution/__tests__/auto-evolve.test.ts +0 -319
  335. package/src/evolution/auto-evolve.ts +0 -98
  336. package/src/evolution/index.ts +0 -1
  337. package/src/monitoring/constraint-evolver.ts +0 -501
@@ -1,62 +1,26 @@
1
1
  /**
2
2
  * 铁律层轻量检查(工单 21):纯上下文证据标志判定,无 I/O
3
+ *
4
+ * ADR-0001 后仅存活的三个 flag:hasVerificationEvidence / hasSingleTask / hasRequirement
5
+ *
6
+ * 三态语义(ADR-0001 防爆措施):
7
+ * - undefined = flag 未接线 → skip(不评估,CLI pre-commit 等路径不误报违规)
8
+ * - 显式 false → fail;true → pass
3
9
  */
4
10
 
5
- import { contextFlag } from './types';
11
+ import { contextEvidenceFlag } from './types';
6
12
 
7
- export const noSelfApproval = contextFlag(
8
- 'no_self_approval',
9
- ctx => ctx.hasTest === true
10
- );
11
-
12
- export const noCompletionWithoutVerification = contextFlag(
13
+ export const noCompletionWithoutVerification = contextEvidenceFlag(
13
14
  'no_completion_without_verification',
14
- ctx => ctx.hasVerificationEvidence === true
15
+ ctx => ctx.hasVerificationEvidence
15
16
  );
16
17
 
17
- export const incrementalProgress = contextFlag(
18
+ export const incrementalProgress = contextEvidenceFlag(
18
19
  'incremental_progress',
19
- // undefined = 未验证 → Iron Law 必须显式确认
20
- ctx => ctx.hasSingleTask === true
21
- );
22
-
23
- export const verifyExternalCapability = contextFlag(
24
- 'verify_external_capability',
25
- ctx => ctx.hasExternalCapabilityVerification === true
20
+ ctx => ctx.hasSingleTask
26
21
  );
27
22
 
28
- export const noImplementationWithoutRequirementReview = contextFlag(
29
- 'no_implementation_without_requirement_review',
30
- ctx => ctx.hasRequirementReview === true
31
- );
32
-
33
- export const noImplementationWithoutRequirement = contextFlag(
23
+ export const noImplementationWithoutRequirement = contextEvidenceFlag(
34
24
  'no_implementation_without_requirement',
35
- ctx => ctx.hasRequirement === true
36
- );
37
-
38
- export const preferWorktree = contextFlag(
39
- 'prefer_worktree',
40
- ctx => ctx.hasWorktree === true
41
- );
42
-
43
- export const noClaimWithoutEvidence = contextFlag(
44
- 'no_claim_without_evidence',
45
- ctx =>
46
- ctx.hasVerificationEvidence === true ||
47
- (ctx.taskDescription || '').includes('test') ||
48
- ctx.hasTest === true
49
- );
50
-
51
- export const noDeleteWithoutContext = contextFlag(
52
- 'no_delete_without_context',
53
- ctx =>
54
- ctx.hasRequirementReview === true ||
55
- ctx.hasRequirement === true ||
56
- ctx.isExistingDesign === true
57
- );
58
-
59
- export const twoStageReviewRequired = contextFlag(
60
- 'two_stage_review_required',
61
- ctx => ctx.hasTwoStageReview === true
25
+ ctx => ctx.hasRequirement
62
26
  );
@@ -0,0 +1,93 @@
1
+ /**
2
+ * no_hardcoded_credentials:硬编码凭证扫描(ADR-0001:shell 扫描逻辑接入真 checker)
3
+ *
4
+ * 扫描 staged diff 的新增行(无 staged diff 时退化为变更文件内容),
5
+ * 命中常见私钥/密码/token 模式即 fail。
6
+ *
7
+ * 模板文件(.example/.sample/.template)与占位符值(your_xxx、process.env 引用等)豁免。
8
+ */
9
+
10
+ import { readFileSync } from 'fs';
11
+ import { join } from 'path';
12
+ import type { ConstraintCheck } from './types';
13
+
14
+ /** 私钥/令牌指纹模式(命中即违规,无例外) */
15
+ const FINGERPRINT_PATTERNS: RegExp[] = [
16
+ // PEM 私钥头
17
+ /-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY(?: BLOCK)?-----/,
18
+ // AWS Access Key ID
19
+ /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/,
20
+ // GitHub token
21
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/,
22
+ /\bgithub_pat_[A-Za-z0-9_]{20,}\b/,
23
+ // Slack token
24
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/,
25
+ // Google API key
26
+ /\bAIza[0-9A-Za-z_-]{35}\b/,
27
+ ];
28
+
29
+ /** 通用赋值模式:password/secret/token/api key = "字面量"(不要求前词边界,覆盖 dbPassword 等 camelCase) */
30
+ const ASSIGNMENT_PATTERN =
31
+ /(?:password|passwd|secret|api[_-]?key|access[_-]?token|auth[_-]?token)\b\s*[:=]\s*['"][^'"\n]{8,}['"]/i;
32
+
33
+ /** 占位符/环境变量引用等明显非真实值 */
34
+ const PLACEHOLDER_PATTERN =
35
+ /process\.env|your[_-]|<[^>]+>|\$\{|xxx+|placeholder|example|changeme|dummy|fake|test/i;
36
+
37
+ /** 允许占位符的模板文件后缀 */
38
+ const TEMPLATE_SUFFIXES = ['.example', '.sample', '.template', '.dist'];
39
+
40
+ function isTemplateFile(file: string): boolean {
41
+ return TEMPLATE_SUFFIXES.some(s => file.endsWith(s));
42
+ }
43
+
44
+ /** 判定一段文本是否包含硬编码凭证 */
45
+ export function containsHardcodedCredential(text: string): boolean {
46
+ for (const line of text.split('\n')) {
47
+ // 占位符/环境变量引用行整体豁免(your_xxx、process.env、示例值等)
48
+ if (PLACEHOLDER_PATTERN.test(line)) continue;
49
+ for (const pattern of FINGERPRINT_PATTERNS) {
50
+ if (pattern.test(line)) return true;
51
+ }
52
+ if (ASSIGNMENT_PATTERN.test(line)) return true;
53
+ }
54
+ return false;
55
+ }
56
+
57
+ export const noHardcodedCredentials: ConstraintCheck = {
58
+ id: 'no_hardcoded_credentials',
59
+ evaluate: async (env) => {
60
+ const files = (env.context.changedFiles || []).filter(f => !isTemplateFile(f));
61
+
62
+ // 1) staged diff 新增行
63
+ let scanned = false;
64
+ try {
65
+ const diff = await env.stagedDiff();
66
+ const added = diff
67
+ .split('\n')
68
+ .filter(l => l.startsWith('+') && !l.startsWith('+++'))
69
+ .map(l => l.slice(1))
70
+ .join('\n');
71
+ if (added.trim().length > 0) {
72
+ scanned = true;
73
+ if (containsHardcodedCredential(added)) return false;
74
+ }
75
+ } catch {
76
+ // diff 不可用 → 退化为文件内容扫描
77
+ }
78
+
79
+ // 2) 变更文件内容(diff 为空或不可用时)
80
+ if (!scanned) {
81
+ for (const file of files) {
82
+ try {
83
+ const content = readFileSync(join(env.projectPath, file), 'utf-8');
84
+ if (containsHardcodedCredential(content)) return false;
85
+ } catch {
86
+ // 文件不可读(已删除/二进制)→ 跳过
87
+ }
88
+ }
89
+ }
90
+
91
+ return true;
92
+ },
93
+ };
@@ -26,14 +26,22 @@ export interface CheckEnv {
26
26
  srcScan(root: string): string[];
27
27
  }
28
28
 
29
+ /**
30
+ * 检查结果三态(ADR-0001 存在性探测 / flag 未接线):
31
+ * - true = 满足(pass)
32
+ * - false = 违反(fail)
33
+ * - 'skip' = 未评估(项目未采用对应约定,或证据 flag 未接线),不计 pass/fail
34
+ */
35
+ export type CheckOutcome = boolean | 'skip';
36
+
29
37
  /**
30
38
  * 单条约束检查实现
31
39
  */
32
40
  export interface ConstraintCheck {
33
41
  /** 约束 ID(与 definitions 一致) */
34
42
  id: string;
35
- /** 检查主体:true = 满足 */
36
- evaluate(env: CheckEnv): Promise<boolean> | boolean;
43
+ /** 检查主体:true = 满足;false = 违反;'skip' = 未评估 */
44
+ evaluate(env: CheckEnv): Promise<CheckOutcome> | CheckOutcome;
37
45
  }
38
46
 
39
47
  /**
@@ -47,8 +55,22 @@ export function contextFlag(
47
55
  }
48
56
 
49
57
  /**
50
- * 构造恒通过检查(promptInjection 驱动 / 仅提示类约束)
58
+ * 构造证据标志检查(ADR-0001:flag 未接线 = skip 而非 fail)
59
+ *
60
+ * - flag === undefined:调用方未接线该证据 → 'skip'(不评估,不误报违规)
61
+ * - flag === false:显式无证据 → fail
62
+ * - flag === true:有证据 → pass
51
63
  */
52
- export function alwaysPass(id: string): ConstraintCheck {
53
- return { id, evaluate: () => true };
64
+ export function contextEvidenceFlag(
65
+ id: string,
66
+ pick: (context: ConstraintContext) => boolean | undefined
67
+ ): ConstraintCheck {
68
+ return {
69
+ id,
70
+ evaluate: (env) => {
71
+ const value = pick(env.context);
72
+ if (value === undefined) return 'skip';
73
+ return value;
74
+ },
75
+ };
54
76
  }
@@ -11,6 +11,7 @@ import * as path from 'path';
11
11
  import { execSync } from 'child_process';
12
12
  import { execAsync } from '../../utils/exec';
13
13
  import { detectSourceRoots } from '../../utils/detect-source-roots';
14
+ import { DEFAULT_TRACE_FILE } from '../../types/trace';
14
15
  import type { ConstraintContext, ConstraintTrigger } from '../../types/constraint';
15
16
 
16
17
  /**
@@ -58,21 +59,31 @@ export function isNewDirectory(headDirs: Set<string> | null, filePath: string):
58
59
  return !headDirs.has(path.dirname(filePath));
59
60
  }
60
61
 
62
+ /**
63
+ * 代码文件扩展名(ADR-0001:code_implementation 推断信号)
64
+ *
65
+ * 纯文档/配置(.md/.json/.yml 等)不算代码变更。
66
+ */
67
+ const CODE_FILE_REGEX = /\.(?:ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|rb|php|cs|cpp|cc|c|h|vue|svelte)$/i;
68
+
61
69
  /**
62
70
  * 检测触发条件
71
+ *
72
+ * ADR-0001:变更包含代码文件时,在主推断之外附加 code_implementation
73
+ * (返回数组 [主推断, 'code_implementation'];主推断逻辑保持不变)。
63
74
  */
64
75
  export function detectTrigger(
65
76
  changedFiles: string[],
66
77
  options: { trigger?: ConstraintTrigger; projectPath?: string }
67
- ): ConstraintTrigger {
78
+ ): ConstraintTrigger | ConstraintTrigger[] {
68
79
  if (options.trigger) return options.trigger;
69
80
 
70
81
  // 根据变更文件推断触发条件
71
- // 注意:不自动推断 code_implementation——那是 caller 的语义判断。
72
- // pre-commit 无法区分"模板编辑"和"逻辑实现",保守使用 file_modification。
73
82
  const hasTestChange = changedFiles.some(f =>
74
83
  f.includes('.test.') || f.includes('.spec.') || f.includes('__tests__')
75
84
  );
85
+ // pre-commit 场景下变更含代码文件 → 附加 code_implementation 推断
86
+ const hasCodeChange = changedFiles.some(f => CODE_FILE_REGEX.test(f));
76
87
  const projectPath = options.projectPath || process.cwd();
77
88
  const sourceRoots = detectSourceRoots(projectPath);
78
89
  const hasModuleChange = changedFiles.some(f =>
@@ -84,23 +95,22 @@ export function detectTrigger(
84
95
  isNewDirectory(headDirs, f)
85
96
  );
86
97
 
87
- if (hasTestChange && !hasModuleChange) return 'test_creation';
88
- if (hasModuleCreation) return 'module_creation';
89
- if (hasModuleChange) return 'module_modification';
98
+ let primary: ConstraintTrigger;
99
+ if (hasTestChange && !hasModuleChange) primary = 'test_creation';
100
+ else if (hasModuleCreation) primary = 'module_creation';
101
+ else if (hasModuleChange) primary = 'module_modification';
102
+ else primary = 'file_modification';
90
103
 
91
- return 'file_modification';
104
+ return hasCodeChange ? [primary, 'code_implementation'] : primary;
92
105
  }
93
106
 
94
107
  /**
95
108
  * 检测是否有失败的测试记录
96
- * 扫描 .harness/traces/ 中最近的 trace 记录
109
+ * 扫描 trace 文件(DEFAULT_TRACE_FILE)中最近的记录
97
110
  */
98
111
  export async function detectFailingTest(projectPath: string): Promise<boolean> {
99
112
  try {
100
- const tracesDir = path.join(projectPath, '.harness', 'traces');
101
- if (!fs.existsSync(tracesDir)) return false;
102
-
103
- const traceFile = path.join(tracesDir, 'execution.log');
113
+ const traceFile = path.join(projectPath, DEFAULT_TRACE_FILE);
104
114
  if (!fs.existsSync(traceFile)) return false;
105
115
 
106
116
  const content = fs.readFileSync(traceFile, 'utf-8');
@@ -146,14 +156,11 @@ export function detectRootCauseInvestigation(projectPath: string): boolean {
146
156
 
147
157
  /**
148
158
  * 检测是否有验证证据
149
- * 检查 .harness/traces/ 中最近的成功验证记录
159
+ * 检查 trace 文件(DEFAULT_TRACE_FILE)中最近的成功验证记录
150
160
  */
151
161
  export async function detectVerificationEvidence(projectPath: string): Promise<boolean> {
152
162
  try {
153
- const tracesDir = path.join(projectPath, '.harness', 'traces');
154
- if (!fs.existsSync(tracesDir)) return false;
155
-
156
- const traceFile = path.join(tracesDir, 'execution.log');
163
+ const traceFile = path.join(projectPath, DEFAULT_TRACE_FILE);
157
164
  if (!fs.existsSync(traceFile)) return false;
158
165
 
159
166
  const content = fs.readFileSync(traceFile, 'utf-8');
@@ -245,10 +252,12 @@ export async function buildConstraintContext(options: {
245
252
  }): Promise<ConstraintContext> {
246
253
  const projectPath = options.projectPath || process.cwd();
247
254
  const changedFiles = await getChangedFiles(options.staged, options.projectPath);
248
- const trigger = detectTrigger(changedFiles, { trigger: options.trigger, projectPath });
255
+ const inferred = detectTrigger(changedFiles, { trigger: options.trigger, projectPath });
256
+ const triggers = Array.isArray(inferred) ? inferred : [inferred];
249
257
 
250
258
  return {
251
- operation: trigger,
259
+ operation: triggers[0],
260
+ extraTriggers: triggers.slice(1),
252
261
  projectPath,
253
262
  changedFiles,
254
263
  hasTest: changedFiles.some(f => f.includes('.test.') || f.includes('.spec.')),