@sun-asterisk/sungen 3.2.35 → 3.3.0-alpha.10

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 (969) hide show
  1. package/dist/basis/anchor-grammar.d.ts +32 -0
  2. package/dist/basis/anchor-grammar.d.ts.map +1 -0
  3. package/dist/basis/anchor-grammar.js +82 -0
  4. package/dist/basis/anchor-grammar.js.map +1 -0
  5. package/dist/basis/anchor-hash.d.ts +6 -0
  6. package/dist/basis/anchor-hash.d.ts.map +1 -0
  7. package/dist/basis/anchor-hash.js +28 -0
  8. package/dist/basis/anchor-hash.js.map +1 -0
  9. package/dist/basis/bm51-tables.d.ts +20 -0
  10. package/dist/basis/bm51-tables.d.ts.map +1 -0
  11. package/dist/basis/bm51-tables.js +71 -0
  12. package/dist/basis/bm51-tables.js.map +1 -0
  13. package/dist/basis/extract-spec-anchors.d.ts +39 -0
  14. package/dist/basis/extract-spec-anchors.d.ts.map +1 -0
  15. package/dist/basis/extract-spec-anchors.js +81 -0
  16. package/dist/basis/extract-spec-anchors.js.map +1 -0
  17. package/dist/basis/migration-sentinel.d.ts +47 -0
  18. package/dist/basis/migration-sentinel.d.ts.map +1 -0
  19. package/dist/basis/migration-sentinel.js +219 -0
  20. package/dist/basis/migration-sentinel.js.map +1 -0
  21. package/dist/basis/spec-frontmatter.d.ts +18 -0
  22. package/dist/basis/spec-frontmatter.d.ts.map +1 -0
  23. package/dist/basis/spec-frontmatter.js +55 -0
  24. package/dist/basis/spec-frontmatter.js.map +1 -0
  25. package/dist/basis/spec-sections.d.ts +18 -0
  26. package/dist/basis/spec-sections.d.ts.map +1 -0
  27. package/dist/basis/spec-sections.js +27 -0
  28. package/dist/basis/spec-sections.js.map +1 -0
  29. package/dist/basis/test-basis-schema.d.ts +28 -0
  30. package/dist/basis/test-basis-schema.d.ts.map +1 -0
  31. package/dist/basis/test-basis-schema.js +141 -0
  32. package/dist/basis/test-basis-schema.js.map +1 -0
  33. package/dist/capabilities/discover.d.ts +4 -0
  34. package/dist/capabilities/discover.d.ts.map +1 -1
  35. package/dist/capabilities/discover.js +16 -2
  36. package/dist/capabilities/discover.js.map +1 -1
  37. package/dist/capabilities/registry.d.ts +15 -0
  38. package/dist/capabilities/registry.d.ts.map +1 -1
  39. package/dist/capabilities/registry.js.map +1 -1
  40. package/dist/cli/case-triage-hint.d.ts +14 -0
  41. package/dist/cli/case-triage-hint.d.ts.map +1 -0
  42. package/dist/cli/case-triage-hint.js +23 -0
  43. package/dist/cli/case-triage-hint.js.map +1 -0
  44. package/dist/cli/commands/audit.js +1 -1
  45. package/dist/cli/commands/audit.js.map +1 -1
  46. package/dist/cli/commands/capability.js +1 -1
  47. package/dist/cli/commands/capability.js.map +1 -1
  48. package/dist/cli/commands/contract-derive-command.d.ts +12 -0
  49. package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
  50. package/dist/cli/commands/contract-derive-command.js +113 -0
  51. package/dist/cli/commands/contract-derive-command.js.map +1 -0
  52. package/dist/cli/commands/contract.d.ts +20 -0
  53. package/dist/cli/commands/contract.d.ts.map +1 -0
  54. package/dist/cli/commands/contract.js +195 -0
  55. package/dist/cli/commands/contract.js.map +1 -0
  56. package/dist/cli/commands/delivery.d.ts.map +1 -1
  57. package/dist/cli/commands/delivery.js +109 -19
  58. package/dist/cli/commands/delivery.js.map +1 -1
  59. package/dist/cli/commands/gate.d.ts.map +1 -1
  60. package/dist/cli/commands/gate.js +2 -1
  61. package/dist/cli/commands/gate.js.map +1 -1
  62. package/dist/cli/commands/generate.d.ts.map +1 -1
  63. package/dist/cli/commands/generate.js +17 -3
  64. package/dist/cli/commands/generate.js.map +1 -1
  65. package/dist/cli/commands/journey.d.ts.map +1 -1
  66. package/dist/cli/commands/journey.js +47 -17
  67. package/dist/cli/commands/journey.js.map +1 -1
  68. package/dist/cli/commands/next.d.ts +13 -0
  69. package/dist/cli/commands/next.d.ts.map +1 -1
  70. package/dist/cli/commands/next.js +98 -9
  71. package/dist/cli/commands/next.js.map +1 -1
  72. package/dist/cli/commands/triage.d.ts +2 -1
  73. package/dist/cli/commands/triage.d.ts.map +1 -1
  74. package/dist/cli/commands/triage.js +45 -3
  75. package/dist/cli/commands/triage.js.map +1 -1
  76. package/dist/cli/commands/update.d.ts +11 -0
  77. package/dist/cli/commands/update.d.ts.map +1 -1
  78. package/dist/cli/commands/update.js +37 -8
  79. package/dist/cli/commands/update.js.map +1 -1
  80. package/dist/cli/index.js +24 -33
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/json-error-on-exit.d.ts +34 -0
  83. package/dist/cli/json-error-on-exit.d.ts.map +1 -0
  84. package/dist/cli/json-error-on-exit.js +63 -0
  85. package/dist/cli/json-error-on-exit.js.map +1 -0
  86. package/dist/cli/project-sungen-invocation.d.ts +13 -0
  87. package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
  88. package/dist/cli/project-sungen-invocation.js +95 -0
  89. package/dist/cli/project-sungen-invocation.js.map +1 -0
  90. package/dist/cli/run-command-hints.d.ts +9 -0
  91. package/dist/cli/run-command-hints.d.ts.map +1 -0
  92. package/dist/cli/run-command-hints.js +84 -0
  93. package/dist/cli/run-command-hints.js.map +1 -0
  94. package/dist/cli/waiting-for-you-block.d.ts +18 -0
  95. package/dist/cli/waiting-for-you-block.d.ts.map +1 -0
  96. package/dist/cli/waiting-for-you-block.js +22 -0
  97. package/dist/cli/waiting-for-you-block.js.map +1 -0
  98. package/dist/contract/accept-opaque-steps.d.ts +3 -0
  99. package/dist/contract/accept-opaque-steps.d.ts.map +1 -0
  100. package/dist/contract/accept-opaque-steps.js +114 -0
  101. package/dist/contract/accept-opaque-steps.js.map +1 -0
  102. package/dist/contract/approve-contract.d.ts +38 -0
  103. package/dist/contract/approve-contract.d.ts.map +1 -0
  104. package/dist/contract/approve-contract.js +93 -0
  105. package/dist/contract/approve-contract.js.map +1 -0
  106. package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
  107. package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
  108. package/dist/contract/assertion-matcher-vocabulary.js +100 -0
  109. package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
  110. package/dist/contract/build-contract-verdict.d.ts +32 -0
  111. package/dist/contract/build-contract-verdict.d.ts.map +1 -0
  112. package/dist/contract/build-contract-verdict.js +123 -0
  113. package/dist/contract/build-contract-verdict.js.map +1 -0
  114. package/dist/contract/build-trace-conformance.d.ts +22 -0
  115. package/dist/contract/build-trace-conformance.d.ts.map +1 -0
  116. package/dist/contract/build-trace-conformance.js +151 -0
  117. package/dist/contract/build-trace-conformance.js.map +1 -0
  118. package/dist/contract/classify-contract-change.d.ts +24 -0
  119. package/dist/contract/classify-contract-change.d.ts.map +1 -0
  120. package/dist/contract/classify-contract-change.js +98 -0
  121. package/dist/contract/classify-contract-change.js.map +1 -0
  122. package/dist/contract/classify-contract-unit.d.ts +18 -0
  123. package/dist/contract/classify-contract-unit.d.ts.map +1 -0
  124. package/dist/contract/classify-contract-unit.js +49 -0
  125. package/dist/contract/classify-contract-unit.js.map +1 -0
  126. package/dist/contract/classify-trace-conformance.d.ts +47 -0
  127. package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
  128. package/dist/contract/classify-trace-conformance.js +164 -0
  129. package/dist/contract/classify-trace-conformance.js.map +1 -0
  130. package/dist/contract/contract-git.d.ts +24 -0
  131. package/dist/contract/contract-git.d.ts.map +1 -0
  132. package/dist/contract/contract-git.js +144 -0
  133. package/dist/contract/contract-git.js.map +1 -0
  134. package/dist/contract/contract-hash.d.ts +7 -0
  135. package/dist/contract/contract-hash.d.ts.map +1 -0
  136. package/dist/contract/contract-hash.js +38 -0
  137. package/dist/contract/contract-hash.js.map +1 -0
  138. package/dist/contract/contract-report-file.d.ts +4 -0
  139. package/dist/contract/contract-report-file.d.ts.map +1 -0
  140. package/dist/contract/contract-report-file.js +60 -0
  141. package/dist/contract/contract-report-file.js.map +1 -0
  142. package/dist/contract/contract-schema.d.ts +92 -0
  143. package/dist/contract/contract-schema.d.ts.map +1 -0
  144. package/dist/contract/contract-schema.js +124 -0
  145. package/dist/contract/contract-schema.js.map +1 -0
  146. package/dist/contract/contract-units.d.ts +12 -0
  147. package/dist/contract/contract-units.d.ts.map +1 -0
  148. package/dist/contract/contract-units.js +96 -0
  149. package/dist/contract/contract-units.js.map +1 -0
  150. package/dist/contract/contracts-lock-file.d.ts +24 -0
  151. package/dist/contract/contracts-lock-file.d.ts.map +1 -0
  152. package/dist/contract/contracts-lock-file.js +141 -0
  153. package/dist/contract/contracts-lock-file.js.map +1 -0
  154. package/dist/contract/data-normalize.d.ts +10 -0
  155. package/dist/contract/data-normalize.d.ts.map +1 -0
  156. package/dist/contract/data-normalize.js +110 -0
  157. package/dist/contract/data-normalize.js.map +1 -0
  158. package/dist/contract/derive-free-feature.d.ts +49 -0
  159. package/dist/contract/derive-free-feature.d.ts.map +1 -0
  160. package/dist/contract/derive-free-feature.js +183 -0
  161. package/dist/contract/derive-free-feature.js.map +1 -0
  162. package/dist/contract/field-semantic-redaction.d.ts +21 -0
  163. package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
  164. package/dist/contract/field-semantic-redaction.js +118 -0
  165. package/dist/contract/field-semantic-redaction.js.map +1 -0
  166. package/dist/contract/free-feature-blocks.d.ts +10 -0
  167. package/dist/contract/free-feature-blocks.d.ts.map +1 -0
  168. package/dist/contract/free-feature-blocks.js +94 -0
  169. package/dist/contract/free-feature-blocks.js.map +1 -0
  170. package/dist/contract/lock-secret-guard.d.ts +22 -0
  171. package/dist/contract/lock-secret-guard.d.ts.map +1 -0
  172. package/dist/contract/lock-secret-guard.js +134 -0
  173. package/dist/contract/lock-secret-guard.js.map +1 -0
  174. package/dist/contract/lock-vs-git-head.d.ts +26 -0
  175. package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
  176. package/dist/contract/lock-vs-git-head.js +28 -0
  177. package/dist/contract/lock-vs-git-head.js.map +1 -0
  178. package/dist/contract/normalize-contract-step.d.ts +21 -0
  179. package/dist/contract/normalize-contract-step.d.ts.map +1 -0
  180. package/dist/contract/normalize-contract-step.js +70 -0
  181. package/dist/contract/normalize-contract-step.js.map +1 -0
  182. package/dist/contract/normalize-feature-steps.d.ts +7 -0
  183. package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
  184. package/dist/contract/normalize-feature-steps.js +127 -0
  185. package/dist/contract/normalize-feature-steps.js.map +1 -0
  186. package/dist/contract/oracle-strength.d.ts +12 -0
  187. package/dist/contract/oracle-strength.d.ts.map +1 -0
  188. package/dist/contract/oracle-strength.js +88 -0
  189. package/dist/contract/oracle-strength.js.map +1 -0
  190. package/dist/contract/project-contract-blockers.d.ts +10 -0
  191. package/dist/contract/project-contract-blockers.d.ts.map +1 -0
  192. package/dist/contract/project-contract-blockers.js +75 -0
  193. package/dist/contract/project-contract-blockers.js.map +1 -0
  194. package/dist/contract/record-contract-approval.d.ts +36 -0
  195. package/dist/contract/record-contract-approval.d.ts.map +1 -0
  196. package/dist/contract/record-contract-approval.js +126 -0
  197. package/dist/contract/record-contract-approval.js.map +1 -0
  198. package/dist/contract/render-free-gherkin.d.ts +42 -0
  199. package/dist/contract/render-free-gherkin.d.ts.map +1 -0
  200. package/dist/contract/render-free-gherkin.js +147 -0
  201. package/dist/contract/render-free-gherkin.js.map +1 -0
  202. package/dist/contract/render-trace-sentence.d.ts +20 -0
  203. package/dist/contract/render-trace-sentence.d.ts.map +1 -0
  204. package/dist/contract/render-trace-sentence.js +109 -0
  205. package/dist/contract/render-trace-sentence.js.map +1 -0
  206. package/dist/contract/render-trace-target.d.ts +14 -0
  207. package/dist/contract/render-trace-target.d.ts.map +1 -0
  208. package/dist/contract/render-trace-target.js +70 -0
  209. package/dist/contract/render-trace-target.js.map +1 -0
  210. package/dist/contract/resolve-unit-trace-identities.d.ts +20 -0
  211. package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
  212. package/dist/contract/resolve-unit-trace-identities.js +62 -0
  213. package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
  214. package/dist/contract/trace/collect-trace-evidence.d.ts +44 -0
  215. package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
  216. package/dist/contract/trace/collect-trace-evidence.js +219 -0
  217. package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
  218. package/dist/contract/trace/identity-cache.d.ts +19 -0
  219. package/dist/contract/trace/identity-cache.d.ts.map +1 -0
  220. package/dist/contract/trace/identity-cache.js +104 -0
  221. package/dist/contract/trace/identity-cache.js.map +1 -0
  222. package/dist/contract/trace/read-file-once.d.ts +20 -0
  223. package/dist/contract/trace/read-file-once.d.ts.map +1 -0
  224. package/dist/contract/trace/read-file-once.js +135 -0
  225. package/dist/contract/trace/read-file-once.js.map +1 -0
  226. package/dist/contract/trace/scenario-id-claims.d.ts +11 -0
  227. package/dist/contract/trace/scenario-id-claims.d.ts.map +1 -0
  228. package/dist/contract/trace/scenario-id-claims.js +89 -0
  229. package/dist/contract/trace/scenario-id-claims.js.map +1 -0
  230. package/dist/contract/trace/select-final-attempt.d.ts +29 -0
  231. package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
  232. package/dist/contract/trace/select-final-attempt.js +119 -0
  233. package/dist/contract/trace/select-final-attempt.js.map +1 -0
  234. package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
  235. package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
  236. package/dist/contract/trace/snapshot-html-renderer.js +172 -0
  237. package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
  238. package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
  239. package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
  240. package/dist/contract/trace/snapshot-resolver.js +65 -0
  241. package/dist/contract/trace/snapshot-resolver.js.map +1 -0
  242. package/dist/contract/trace/snapshot-store.d.ts +66 -0
  243. package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
  244. package/dist/contract/trace/snapshot-store.js +173 -0
  245. package/dist/contract/trace/snapshot-store.js.map +1 -0
  246. package/dist/contract/trace/target-identity.d.ts +74 -0
  247. package/dist/contract/trace/target-identity.d.ts.map +1 -0
  248. package/dist/contract/trace/target-identity.js +68 -0
  249. package/dist/contract/trace/target-identity.js.map +1 -0
  250. package/dist/contract/trace/test-step-join.d.ts +65 -0
  251. package/dist/contract/trace/test-step-join.d.ts.map +1 -0
  252. package/dist/contract/trace/test-step-join.js +80 -0
  253. package/dist/contract/trace/test-step-join.js.map +1 -0
  254. package/dist/contract/trace/trace-binding.d.ts +22 -0
  255. package/dist/contract/trace/trace-binding.d.ts.map +1 -0
  256. package/dist/contract/trace/trace-binding.js +91 -0
  257. package/dist/contract/trace/trace-binding.js.map +1 -0
  258. package/dist/contract/trace/trace-file-reader.d.ts +47 -0
  259. package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
  260. package/dist/contract/trace/trace-file-reader.js +137 -0
  261. package/dist/contract/trace/trace-file-reader.js.map +1 -0
  262. package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
  263. package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
  264. package/dist/contract/trace/trace-fingerprint.js +96 -0
  265. package/dist/contract/trace/trace-fingerprint.js.map +1 -0
  266. package/dist/contract/trace/trace-freshness.d.ts +27 -0
  267. package/dist/contract/trace/trace-freshness.d.ts.map +1 -0
  268. package/dist/contract/trace/trace-freshness.js +146 -0
  269. package/dist/contract/trace/trace-freshness.js.map +1 -0
  270. package/dist/contract/trace/trace-identity-resolution.d.ts +28 -0
  271. package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
  272. package/dist/contract/trace/trace-identity-resolution.js +87 -0
  273. package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
  274. package/dist/contract/trace/trace-run-record.d.ts +32 -0
  275. package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
  276. package/dist/contract/trace/trace-run-record.js +135 -0
  277. package/dist/contract/trace/trace-run-record.js.map +1 -0
  278. package/dist/contract/trace/trace-steps.d.ts +19 -0
  279. package/dist/contract/trace/trace-steps.d.ts.map +1 -0
  280. package/dist/contract/trace/trace-steps.js +79 -0
  281. package/dist/contract/trace/trace-steps.js.map +1 -0
  282. package/dist/contract/trace/trace-zip-limits.d.ts +45 -0
  283. package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
  284. package/dist/contract/trace/trace-zip-limits.js +52 -0
  285. package/dist/contract/trace/trace-zip-limits.js.map +1 -0
  286. package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
  287. package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
  288. package/dist/contract/trace/trace-zip-reader.js +186 -0
  289. package/dist/contract/trace/trace-zip-reader.js.map +1 -0
  290. package/dist/contract/verify-approval-decisions.d.ts +5 -0
  291. package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
  292. package/dist/contract/verify-approval-decisions.js +109 -0
  293. package/dist/contract/verify-approval-decisions.js.map +1 -0
  294. package/dist/decisions/append-decision.d.ts +12 -0
  295. package/dist/decisions/append-decision.d.ts.map +1 -0
  296. package/dist/decisions/append-decision.js +73 -0
  297. package/dist/decisions/append-decision.js.map +1 -0
  298. package/dist/decisions/confirmed-decision-commands.d.ts +41 -0
  299. package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
  300. package/dist/decisions/confirmed-decision-commands.js +190 -0
  301. package/dist/decisions/confirmed-decision-commands.js.map +1 -0
  302. package/dist/decisions/decision-file.d.ts +31 -0
  303. package/dist/decisions/decision-file.d.ts.map +1 -0
  304. package/dist/decisions/decision-file.js +139 -0
  305. package/dist/decisions/decision-file.js.map +1 -0
  306. package/dist/decisions/decision-identity.d.ts +12 -0
  307. package/dist/decisions/decision-identity.d.ts.map +1 -0
  308. package/dist/decisions/decision-identity.js +78 -0
  309. package/dist/decisions/decision-identity.js.map +1 -0
  310. package/dist/decisions/decision-integrity-check.d.ts +12 -0
  311. package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
  312. package/dist/decisions/decision-integrity-check.js +102 -0
  313. package/dist/decisions/decision-integrity-check.js.map +1 -0
  314. package/dist/decisions/decision-schema.d.ts +43 -0
  315. package/dist/decisions/decision-schema.d.ts.map +1 -0
  316. package/dist/decisions/decision-schema.js +76 -0
  317. package/dist/decisions/decision-schema.js.map +1 -0
  318. package/dist/decisions/decision-source.d.ts +2 -0
  319. package/dist/decisions/decision-source.d.ts.map +1 -0
  320. package/dist/decisions/decision-source.js +18 -0
  321. package/dist/decisions/decision-source.js.map +1 -0
  322. package/dist/decisions/exclusive-file-create.d.ts +3 -0
  323. package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
  324. package/dist/decisions/exclusive-file-create.js +84 -0
  325. package/dist/decisions/exclusive-file-create.js.map +1 -0
  326. package/dist/decisions/git-head-trust.d.ts +19 -0
  327. package/dist/decisions/git-head-trust.d.ts.map +1 -0
  328. package/dist/decisions/git-head-trust.js +128 -0
  329. package/dist/decisions/git-head-trust.js.map +1 -0
  330. package/dist/decisions/human-confirmation.d.ts +35 -0
  331. package/dist/decisions/human-confirmation.d.ts.map +1 -0
  332. package/dist/decisions/human-confirmation.js +161 -0
  333. package/dist/decisions/human-confirmation.js.map +1 -0
  334. package/dist/decisions/legacy-waiver-migration.d.ts +38 -0
  335. package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
  336. package/dist/decisions/legacy-waiver-migration.js +179 -0
  337. package/dist/decisions/legacy-waiver-migration.js.map +1 -0
  338. package/dist/decisions/read-decisions.d.ts +19 -0
  339. package/dist/decisions/read-decisions.d.ts.map +1 -0
  340. package/dist/decisions/read-decisions.js +90 -0
  341. package/dist/decisions/read-decisions.js.map +1 -0
  342. package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
  343. package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
  344. package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
  345. package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
  346. package/dist/decisions/waiver-decisions.d.ts +24 -0
  347. package/dist/decisions/waiver-decisions.d.ts.map +1 -0
  348. package/dist/decisions/waiver-decisions.js +46 -0
  349. package/dist/decisions/waiver-decisions.js.map +1 -0
  350. package/dist/exporters/csv-exporter.d.ts +11 -2
  351. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  352. package/dist/exporters/csv-exporter.js +8 -4
  353. package/dist/exporters/csv-exporter.js.map +1 -1
  354. package/dist/exporters/matrix/build.d.ts +3 -0
  355. package/dist/exporters/matrix/build.d.ts.map +1 -1
  356. package/dist/exporters/matrix/build.js +10 -9
  357. package/dist/exporters/matrix/build.js.map +1 -1
  358. package/dist/exporters/matrix/export.d.ts +9 -1
  359. package/dist/exporters/matrix/export.d.ts.map +1 -1
  360. package/dist/exporters/matrix/export.js +13 -4
  361. package/dist/exporters/matrix/export.js.map +1 -1
  362. package/dist/exporters/matrix/gates.d.ts +6 -1
  363. package/dist/exporters/matrix/gates.d.ts.map +1 -1
  364. package/dist/exporters/matrix/gates.js +57 -128
  365. package/dist/exporters/matrix/gates.js.map +1 -1
  366. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  367. package/dist/exporters/matrix/render-csv.js +3 -0
  368. package/dist/exporters/matrix/render-csv.js.map +1 -1
  369. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
  370. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
  371. package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
  372. package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
  373. package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
  374. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  375. package/dist/exporters/matrix/render-xlsx.js +3 -0
  376. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  377. package/dist/exporters/matrix/types.d.ts +4 -1
  378. package/dist/exporters/matrix/types.d.ts.map +1 -1
  379. package/dist/exporters/matrix/types.js.map +1 -1
  380. package/dist/exporters/matrix/xlsx-cells.js +1 -1
  381. package/dist/exporters/matrix/xlsx-cells.js.map +1 -1
  382. package/dist/exporters/test-data-resolver.d.ts.map +1 -1
  383. package/dist/exporters/test-data-resolver.js +2 -12
  384. package/dist/exporters/test-data-resolver.js.map +1 -1
  385. package/dist/exporters/xlsx-exporter.d.ts +3 -2
  386. package/dist/exporters/xlsx-exporter.d.ts.map +1 -1
  387. package/dist/exporters/xlsx-exporter.js +4 -4
  388. package/dist/exporters/xlsx-exporter.js.map +1 -1
  389. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  390. package/dist/generators/gherkin-parser/index.js +0 -1
  391. package/dist/generators/gherkin-parser/index.js.map +1 -1
  392. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
  393. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
  394. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
  395. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  396. package/dist/generators/test-generator/code-generator.js +18 -4
  397. package/dist/generators/test-generator/code-generator.js.map +1 -1
  398. package/dist/generators/test-generator/diagnostics.d.ts +3 -9
  399. package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
  400. package/dist/generators/test-generator/diagnostics.js +3 -9
  401. package/dist/generators/test-generator/diagnostics.js.map +1 -1
  402. package/dist/generators/test-generator/patterns/types.d.ts +1 -1
  403. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  404. package/dist/generators/test-generator/step-mapper.d.ts +0 -8
  405. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  406. package/dist/generators/test-generator/step-mapper.js +8 -52
  407. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  408. package/dist/generators/test-generator/utils/data-resolver.d.ts +0 -16
  409. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  410. package/dist/generators/test-generator/utils/data-resolver.js +0 -59
  411. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  412. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  413. package/dist/generators/test-generator/utils/selector-resolver.js +2 -10
  414. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  415. package/dist/graph/board-human-actions.d.ts +5 -0
  416. package/dist/graph/board-human-actions.d.ts.map +1 -0
  417. package/dist/graph/board-human-actions.js +83 -0
  418. package/dist/graph/board-human-actions.js.map +1 -0
  419. package/dist/graph/evaluate-graph.d.ts +41 -0
  420. package/dist/graph/evaluate-graph.d.ts.map +1 -0
  421. package/dist/graph/evaluate-graph.js +77 -0
  422. package/dist/graph/evaluate-graph.js.map +1 -0
  423. package/dist/graph/human-action.d.ts +21 -0
  424. package/dist/graph/human-action.d.ts.map +1 -0
  425. package/dist/graph/human-action.js +3 -0
  426. package/dist/graph/human-action.js.map +1 -0
  427. package/dist/graph/locate-finding.d.ts +20 -0
  428. package/dist/graph/locate-finding.d.ts.map +1 -0
  429. package/dist/graph/locate-finding.js +137 -0
  430. package/dist/graph/locate-finding.js.map +1 -0
  431. package/dist/graph/manual-triage-decisions.d.ts +19 -0
  432. package/dist/graph/manual-triage-decisions.d.ts.map +1 -0
  433. package/dist/graph/manual-triage-decisions.js +53 -0
  434. package/dist/graph/manual-triage-decisions.js.map +1 -0
  435. package/dist/graph/node-decl.d.ts +75 -0
  436. package/dist/graph/node-decl.d.ts.map +1 -0
  437. package/dist/graph/node-decl.js +11 -0
  438. package/dist/graph/node-decl.js.map +1 -0
  439. package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
  440. package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
  441. package/dist/graph/nodes/core-node-catalog.js +13 -0
  442. package/dist/graph/nodes/core-node-catalog.js.map +1 -0
  443. package/dist/graph/nodes/test-case-contract-nodes.d.ts +21 -0
  444. package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
  445. package/dist/graph/nodes/test-case-contract-nodes.js +72 -0
  446. package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
  447. package/dist/graph/nodes/test-case-nodes.d.ts +29 -0
  448. package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
  449. package/dist/graph/nodes/test-case-nodes.js +95 -0
  450. package/dist/graph/nodes/test-case-nodes.js.map +1 -0
  451. package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
  452. package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
  453. package/dist/graph/nodes/unit-audit-nodes.js +96 -0
  454. package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
  455. package/dist/graph/nodes/unit-contract-node.d.ts +21 -0
  456. package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
  457. package/dist/graph/nodes/unit-contract-node.js +96 -0
  458. package/dist/graph/nodes/unit-contract-node.js.map +1 -0
  459. package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
  460. package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
  461. package/dist/graph/nodes/unit-design-nodes.js +91 -0
  462. package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
  463. package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
  464. package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
  465. package/dist/graph/nodes/unit-execution-nodes.js +79 -0
  466. package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
  467. package/dist/graph/test-case-identity.d.ts +13 -0
  468. package/dist/graph/test-case-identity.d.ts.map +1 -0
  469. package/dist/graph/test-case-identity.js +106 -0
  470. package/dist/graph/test-case-identity.js.map +1 -0
  471. package/dist/graph/test-case-results.d.ts +12 -0
  472. package/dist/graph/test-case-results.d.ts.map +1 -0
  473. package/dist/graph/test-case-results.js +161 -0
  474. package/dist/graph/test-case-results.js.map +1 -0
  475. package/dist/graph/test-case-satisfied.d.ts +26 -0
  476. package/dist/graph/test-case-satisfied.d.ts.map +1 -0
  477. package/dist/graph/test-case-satisfied.js +55 -0
  478. package/dist/graph/test-case-satisfied.js.map +1 -0
  479. package/dist/graph/test-case-state-shape.d.ts +73 -0
  480. package/dist/graph/test-case-state-shape.d.ts.map +1 -0
  481. package/dist/graph/test-case-state-shape.js +3 -0
  482. package/dist/graph/test-case-state-shape.js.map +1 -0
  483. package/dist/graph/test-case-states.d.ts +9 -0
  484. package/dist/graph/test-case-states.d.ts.map +1 -0
  485. package/dist/graph/test-case-states.js +116 -0
  486. package/dist/graph/test-case-states.js.map +1 -0
  487. package/dist/graph/unit-artifact-probes.d.ts +19 -0
  488. package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
  489. package/dist/graph/unit-artifact-probes.js +135 -0
  490. package/dist/graph/unit-artifact-probes.js.map +1 -0
  491. package/dist/graph/unit-results-freshness.d.ts +29 -0
  492. package/dist/graph/unit-results-freshness.d.ts.map +1 -0
  493. package/dist/graph/unit-results-freshness.js +213 -0
  494. package/dist/graph/unit-results-freshness.js.map +1 -0
  495. package/dist/graph/unit-state-facts.d.ts +43 -0
  496. package/dist/graph/unit-state-facts.d.ts.map +1 -0
  497. package/dist/graph/unit-state-facts.js +87 -0
  498. package/dist/graph/unit-state-facts.js.map +1 -0
  499. package/dist/harness/audit.d.ts +14 -2
  500. package/dist/harness/audit.d.ts.map +1 -1
  501. package/dist/harness/audit.js +20 -21
  502. package/dist/harness/audit.js.map +1 -1
  503. package/dist/harness/catalog/gate-rules.yaml +647 -0
  504. package/dist/harness/defect-draft.d.ts.map +1 -1
  505. package/dist/harness/defect-draft.js +12 -2
  506. package/dist/harness/defect-draft.js.map +1 -1
  507. package/dist/harness/defects.d.ts +14 -0
  508. package/dist/harness/defects.d.ts.map +1 -1
  509. package/dist/harness/defects.js +14 -10
  510. package/dist/harness/defects.js.map +1 -1
  511. package/dist/harness/flow-check.d.ts +9 -0
  512. package/dist/harness/flow-check.d.ts.map +1 -1
  513. package/dist/harness/flow-check.js +11 -0
  514. package/dist/harness/flow-check.js.map +1 -1
  515. package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
  516. package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
  517. package/dist/harness/gates/audit-gate-terms.js +72 -0
  518. package/dist/harness/gates/audit-gate-terms.js.map +1 -0
  519. package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
  520. package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
  521. package/dist/harness/gates/audit-gate-verdict.js +102 -0
  522. package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
  523. package/dist/harness/gates/audit-input-hash.d.ts +6 -0
  524. package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
  525. package/dist/harness/gates/audit-input-hash.js +124 -0
  526. package/dist/harness/gates/audit-input-hash.js.map +1 -0
  527. package/dist/harness/gates/audit-report-verification.d.ts +43 -0
  528. package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
  529. package/dist/harness/gates/audit-report-verification.js +241 -0
  530. package/dist/harness/gates/audit-report-verification.js.map +1 -0
  531. package/dist/harness/gates/decisions-hash.d.ts +13 -0
  532. package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
  533. package/dist/harness/gates/decisions-hash.js +72 -0
  534. package/dist/harness/gates/decisions-hash.js.map +1 -0
  535. package/dist/harness/gates/delivery-checklist.d.ts +24 -0
  536. package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
  537. package/dist/harness/gates/delivery-checklist.js +161 -0
  538. package/dist/harness/gates/delivery-checklist.js.map +1 -0
  539. package/dist/harness/gates/delivery-decision-gate.d.ts +33 -0
  540. package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
  541. package/dist/harness/gates/delivery-decision-gate.js +116 -0
  542. package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
  543. package/dist/harness/gates/delivery-decision-step.d.ts +19 -0
  544. package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
  545. package/dist/harness/gates/delivery-decision-step.js +86 -0
  546. package/dist/harness/gates/delivery-decision-step.js.map +1 -0
  547. package/dist/harness/gates/gate-override-report.d.ts +59 -0
  548. package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
  549. package/dist/harness/gates/gate-override-report.js +86 -0
  550. package/dist/harness/gates/gate-override-report.js.map +1 -0
  551. package/dist/harness/gates/gate-override-scope.d.ts +18 -0
  552. package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
  553. package/dist/harness/gates/gate-override-scope.js +98 -0
  554. package/dist/harness/gates/gate-override-scope.js.map +1 -0
  555. package/dist/harness/gates/gate-override-validation.d.ts +25 -0
  556. package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
  557. package/dist/harness/gates/gate-override-validation.js +81 -0
  558. package/dist/harness/gates/gate-override-validation.js.map +1 -0
  559. package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
  560. package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
  561. package/dist/harness/gates/gate-rule-catalog.js +112 -0
  562. package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
  563. package/dist/harness/gates/gate-terms.d.ts +33 -0
  564. package/dist/harness/gates/gate-terms.d.ts.map +1 -0
  565. package/dist/harness/gates/gate-terms.js +41 -0
  566. package/dist/harness/gates/gate-terms.js.map +1 -0
  567. package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
  568. package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
  569. package/dist/harness/gates/in-run-decision-check.js +166 -0
  570. package/dist/harness/gates/in-run-decision-check.js.map +1 -0
  571. package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
  572. package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
  573. package/dist/harness/gates/journey-gate-inputs.js +81 -0
  574. package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
  575. package/dist/harness/gates/migrated-waiver-import-bounds.d.ts +13 -0
  576. package/dist/harness/gates/migrated-waiver-import-bounds.d.ts.map +1 -0
  577. package/dist/harness/gates/migrated-waiver-import-bounds.js +141 -0
  578. package/dist/harness/gates/migrated-waiver-import-bounds.js.map +1 -0
  579. package/dist/harness/gates/migrated-waiver-review.d.ts +16 -0
  580. package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
  581. package/dist/harness/gates/migrated-waiver-review.js +114 -0
  582. package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
  583. package/dist/harness/gates/resolve-rule.d.ts +59 -0
  584. package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
  585. package/dist/harness/gates/resolve-rule.js +41 -0
  586. package/dist/harness/gates/resolve-rule.js.map +1 -0
  587. package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
  588. package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
  589. package/dist/harness/gates/unit-gate-overrides.js +122 -0
  590. package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
  591. package/dist/harness/journey.d.ts +64 -1
  592. package/dist/harness/journey.d.ts.map +1 -1
  593. package/dist/harness/journey.js +258 -34
  594. package/dist/harness/journey.js.map +1 -1
  595. package/dist/harness/manifest.d.ts +12 -0
  596. package/dist/harness/manifest.d.ts.map +1 -1
  597. package/dist/harness/manifest.js +71 -43
  598. package/dist/harness/manifest.js.map +1 -1
  599. package/dist/harness/next-step.d.ts +58 -4
  600. package/dist/harness/next-step.d.ts.map +1 -1
  601. package/dist/harness/next-step.js +55 -204
  602. package/dist/harness/next-step.js.map +1 -1
  603. package/dist/harness/parse.d.ts +7 -0
  604. package/dist/harness/parse.d.ts.map +1 -1
  605. package/dist/harness/parse.js +18 -2
  606. package/dist/harness/parse.js.map +1 -1
  607. package/dist/harness/provenance.d.ts +29 -0
  608. package/dist/harness/provenance.d.ts.map +1 -1
  609. package/dist/harness/provenance.js +109 -9
  610. package/dist/harness/provenance.js.map +1 -1
  611. package/dist/harness/script-check.d.ts.map +1 -1
  612. package/dist/harness/script-check.js +22 -5
  613. package/dist/harness/script-check.js.map +1 -1
  614. package/dist/harness/sensors.d.ts +14 -3
  615. package/dist/harness/sensors.d.ts.map +1 -1
  616. package/dist/harness/sensors.js +41 -38
  617. package/dist/harness/sensors.js.map +1 -1
  618. package/dist/harness/triage-manual-classification.d.ts +32 -0
  619. package/dist/harness/triage-manual-classification.d.ts.map +1 -0
  620. package/dist/harness/triage-manual-classification.js +56 -0
  621. package/dist/harness/triage-manual-classification.js.map +1 -0
  622. package/dist/harness/unit-paths.d.ts +8 -0
  623. package/dist/harness/unit-paths.d.ts.map +1 -1
  624. package/dist/harness/unit-paths.js +23 -1
  625. package/dist/harness/unit-paths.js.map +1 -1
  626. package/dist/hooks/bash-read-only-segment.d.ts +9 -0
  627. package/dist/hooks/bash-read-only-segment.d.ts.map +1 -0
  628. package/dist/hooks/bash-read-only-segment.js +168 -0
  629. package/dist/hooks/bash-read-only-segment.js.map +1 -0
  630. package/dist/hooks/bash-write-targets.d.ts +25 -0
  631. package/dist/hooks/bash-write-targets.d.ts.map +1 -0
  632. package/dist/hooks/bash-write-targets.js +266 -0
  633. package/dist/hooks/bash-write-targets.js.map +1 -0
  634. package/dist/hooks/claude-hook-entry.d.ts +11 -0
  635. package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
  636. package/dist/hooks/claude-hook-entry.js +137 -0
  637. package/dist/hooks/claude-hook-entry.js.map +1 -0
  638. package/dist/hooks/claude-transcript-turn.d.ts +11 -0
  639. package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
  640. package/dist/hooks/claude-transcript-turn.js +143 -0
  641. package/dist/hooks/claude-transcript-turn.js.map +1 -0
  642. package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
  643. package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
  644. package/dist/hooks/guard-delivery-contract-rule.js +152 -0
  645. package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
  646. package/dist/hooks/guard-protected-paths.d.ts +13 -0
  647. package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
  648. package/dist/hooks/guard-protected-paths.js +116 -0
  649. package/dist/hooks/guard-protected-paths.js.map +1 -0
  650. package/dist/hooks/guard-rules.d.ts +20 -0
  651. package/dist/hooks/guard-rules.d.ts.map +1 -0
  652. package/dist/hooks/guard-rules.js +130 -0
  653. package/dist/hooks/guard-rules.js.map +1 -0
  654. package/dist/hooks/guard-tty-spoof-rule.d.ts +17 -0
  655. package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
  656. package/dist/hooks/guard-tty-spoof-rule.js +22 -0
  657. package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
  658. package/dist/hooks/hand-back-core.d.ts +42 -0
  659. package/dist/hooks/hand-back-core.d.ts.map +1 -0
  660. package/dist/hooks/hand-back-core.js +128 -0
  661. package/dist/hooks/hand-back-core.js.map +1 -0
  662. package/dist/hooks/hook-cli-command.d.ts +9 -0
  663. package/dist/hooks/hook-cli-command.d.ts.map +1 -0
  664. package/dist/hooks/hook-cli-command.js +46 -0
  665. package/dist/hooks/hook-cli-command.js.map +1 -0
  666. package/dist/hooks/hook-registry.d.ts +10 -0
  667. package/dist/hooks/hook-registry.d.ts.map +1 -0
  668. package/dist/hooks/hook-registry.js +24 -0
  669. package/dist/hooks/hook-registry.js.map +1 -0
  670. package/dist/hooks/hook-result-contract.d.ts +50 -0
  671. package/dist/hooks/hook-result-contract.d.ts.map +1 -0
  672. package/dist/hooks/hook-result-contract.js +80 -0
  673. package/dist/hooks/hook-result-contract.js.map +1 -0
  674. package/dist/hooks/hook-toggles.d.ts +10 -0
  675. package/dist/hooks/hook-toggles.d.ts.map +1 -0
  676. package/dist/hooks/hook-toggles.js +107 -0
  677. package/dist/hooks/hook-toggles.js.map +1 -0
  678. package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
  679. package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
  680. package/dist/hooks/pre-tool-guard-hook.js +105 -0
  681. package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
  682. package/dist/hooks/session-start-unit-state-hook.d.ts +14 -0
  683. package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
  684. package/dist/hooks/session-start-unit-state-hook.js +60 -0
  685. package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
  686. package/dist/hooks/stop-next-step-hook.d.ts +16 -0
  687. package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
  688. package/dist/hooks/stop-next-step-hook.js +43 -0
  689. package/dist/hooks/stop-next-step-hook.js.map +1 -0
  690. package/dist/hooks/sungen-project-root.d.ts +19 -0
  691. package/dist/hooks/sungen-project-root.d.ts.map +1 -0
  692. package/dist/hooks/sungen-project-root.js +130 -0
  693. package/dist/hooks/sungen-project-root.js.map +1 -0
  694. package/dist/index.d.ts.map +1 -1
  695. package/dist/index.js +1 -2
  696. package/dist/index.js.map +1 -1
  697. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
  698. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
  699. package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
  700. package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
  701. package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
  702. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
  703. package/dist/orchestrator/ai-skills/commands.js +11 -3
  704. package/dist/orchestrator/ai-skills/commands.js.map +1 -1
  705. package/dist/orchestrator/assets-drift.d.ts +5 -0
  706. package/dist/orchestrator/assets-drift.d.ts.map +1 -1
  707. package/dist/orchestrator/assets-drift.js +12 -3
  708. package/dist/orchestrator/assets-drift.js.map +1 -1
  709. package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
  710. package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
  711. package/dist/orchestrator/claude-hooks-install.js +203 -0
  712. package/dist/orchestrator/claude-hooks-install.js.map +1 -0
  713. package/dist/orchestrator/lockstep-version.d.ts +15 -5
  714. package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
  715. package/dist/orchestrator/lockstep-version.js +30 -17
  716. package/dist/orchestrator/lockstep-version.js.map +1 -1
  717. package/dist/orchestrator/project-initializer.d.ts +6 -0
  718. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  719. package/dist/orchestrator/project-initializer.js +24 -0
  720. package/dist/orchestrator/project-initializer.js.map +1 -1
  721. package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  722. package/dist/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
  723. package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  724. package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  725. package/dist/orchestrator/templates/ai-src/commands/create-test.md +17 -16
  726. package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  727. package/dist/orchestrator/templates/ai-src/commands/delivery.md +4 -0
  728. package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
  729. package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  730. package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
  731. package/dist/orchestrator/templates/ai-src/commands/review.md +4 -0
  732. package/dist/orchestrator/templates/ai-src/commands/run-test.md +6 -8
  733. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  734. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  735. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  736. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.claude.md +11 -0
  737. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
  738. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
  739. package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
  740. package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
  741. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
  742. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
  743. package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  744. package/dist/orchestrator/templates/specs-test-data.ts +4 -22
  745. package/dist/utils/safe-yaml-parse.d.ts +8 -0
  746. package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
  747. package/dist/utils/safe-yaml-parse.js +51 -0
  748. package/dist/utils/safe-yaml-parse.js.map +1 -0
  749. package/package.json +3 -3
  750. package/src/basis/anchor-grammar.ts +83 -0
  751. package/src/basis/anchor-hash.ts +27 -0
  752. package/src/basis/bm51-tables.ts +65 -0
  753. package/src/basis/extract-spec-anchors.ts +95 -0
  754. package/src/basis/migration-sentinel.ts +175 -0
  755. package/src/basis/spec-frontmatter.ts +68 -0
  756. package/src/basis/spec-sections.ts +35 -0
  757. package/src/basis/test-basis-schema.ts +81 -0
  758. package/src/capabilities/discover.ts +15 -2
  759. package/src/capabilities/registry.ts +16 -0
  760. package/src/cli/case-triage-hint.ts +31 -0
  761. package/src/cli/commands/audit.ts +1 -1
  762. package/src/cli/commands/capability.ts +1 -1
  763. package/src/cli/commands/contract-derive-command.ts +72 -0
  764. package/src/cli/commands/contract.ts +164 -0
  765. package/src/cli/commands/delivery.ts +106 -19
  766. package/src/cli/commands/gate.ts +2 -1
  767. package/src/cli/commands/generate.ts +16 -3
  768. package/src/cli/commands/journey.ts +45 -18
  769. package/src/cli/commands/next.ts +92 -11
  770. package/src/cli/commands/triage.ts +41 -3
  771. package/src/cli/commands/update.ts +41 -10
  772. package/src/cli/index.ts +24 -30
  773. package/src/cli/json-error-on-exit.ts +72 -0
  774. package/src/cli/project-sungen-invocation.ts +59 -0
  775. package/src/cli/run-command-hints.ts +47 -0
  776. package/src/cli/waiting-for-you-block.ts +27 -0
  777. package/src/contract/accept-opaque-steps.ts +114 -0
  778. package/src/contract/approve-contract.ts +101 -0
  779. package/src/contract/assertion-matcher-vocabulary.ts +93 -0
  780. package/src/contract/build-contract-verdict.ts +108 -0
  781. package/src/contract/build-trace-conformance.ts +103 -0
  782. package/src/contract/classify-contract-change.ts +92 -0
  783. package/src/contract/classify-contract-unit.ts +47 -0
  784. package/src/contract/classify-trace-conformance.ts +170 -0
  785. package/src/contract/contract-git.ts +106 -0
  786. package/src/contract/contract-hash.ts +34 -0
  787. package/src/contract/contract-report-file.ts +25 -0
  788. package/src/contract/contract-schema.ts +166 -0
  789. package/src/contract/contract-units.ts +52 -0
  790. package/src/contract/contracts-lock-file.ts +98 -0
  791. package/src/contract/data-normalize.ts +66 -0
  792. package/src/contract/derive-free-feature.ts +153 -0
  793. package/src/contract/field-semantic-redaction.ts +80 -0
  794. package/src/contract/free-feature-blocks.ts +56 -0
  795. package/src/contract/lock-secret-guard.ts +95 -0
  796. package/src/contract/lock-vs-git-head.ts +38 -0
  797. package/src/contract/normalize-contract-step.ts +74 -0
  798. package/src/contract/normalize-feature-steps.ts +93 -0
  799. package/src/contract/oracle-strength.ts +80 -0
  800. package/src/contract/project-contract-blockers.ts +38 -0
  801. package/src/contract/record-contract-approval.ts +110 -0
  802. package/src/contract/render-free-gherkin.ts +118 -0
  803. package/src/contract/render-trace-sentence.ts +98 -0
  804. package/src/contract/render-trace-target.ts +68 -0
  805. package/src/contract/resolve-unit-trace-identities.ts +58 -0
  806. package/src/contract/trace/collect-trace-evidence.ts +178 -0
  807. package/src/contract/trace/identity-cache.ts +61 -0
  808. package/src/contract/trace/read-file-once.ts +95 -0
  809. package/src/contract/trace/scenario-id-claims.ts +60 -0
  810. package/src/contract/trace/select-final-attempt.ts +77 -0
  811. package/src/contract/trace/snapshot-html-renderer.ts +136 -0
  812. package/src/contract/trace/snapshot-resolver.ts +66 -0
  813. package/src/contract/trace/snapshot-store.ts +151 -0
  814. package/src/contract/trace/target-identity.ts +104 -0
  815. package/src/contract/trace/test-step-join.ts +104 -0
  816. package/src/contract/trace/trace-binding.ts +59 -0
  817. package/src/contract/trace/trace-file-reader.ts +144 -0
  818. package/src/contract/trace/trace-fingerprint.ts +68 -0
  819. package/src/contract/trace/trace-freshness.ts +110 -0
  820. package/src/contract/trace/trace-identity-resolution.ts +77 -0
  821. package/src/contract/trace/trace-run-record.ts +96 -0
  822. package/src/contract/trace/trace-steps.ts +88 -0
  823. package/src/contract/trace/trace-zip-limits.ts +77 -0
  824. package/src/contract/trace/trace-zip-reader.ts +127 -0
  825. package/src/contract/verify-approval-decisions.ts +64 -0
  826. package/src/decisions/append-decision.ts +35 -0
  827. package/src/decisions/confirmed-decision-commands.ts +149 -0
  828. package/src/decisions/decision-file.ts +93 -0
  829. package/src/decisions/decision-identity.ts +73 -0
  830. package/src/decisions/decision-integrity-check.ts +61 -0
  831. package/src/decisions/decision-schema.ts +77 -0
  832. package/src/decisions/decision-source.ts +14 -0
  833. package/src/decisions/exclusive-file-create.ts +42 -0
  834. package/src/decisions/git-head-trust.ts +76 -0
  835. package/src/decisions/human-confirmation.ts +119 -0
  836. package/src/decisions/legacy-waiver-migration.ts +146 -0
  837. package/src/decisions/read-decisions.ts +61 -0
  838. package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
  839. package/src/decisions/waiver-decisions.ts +56 -0
  840. package/src/exporters/csv-exporter.ts +12 -4
  841. package/src/exporters/matrix/build.ts +11 -9
  842. package/src/exporters/matrix/export.ts +16 -4
  843. package/src/exporters/matrix/gates.ts +62 -129
  844. package/src/exporters/matrix/render-csv.ts +3 -0
  845. package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
  846. package/src/exporters/matrix/render-xlsx.ts +3 -0
  847. package/src/exporters/matrix/types.ts +4 -1
  848. package/src/exporters/matrix/xlsx-cells.ts +1 -1
  849. package/src/exporters/test-data-resolver.ts +2 -10
  850. package/src/exporters/xlsx-exporter.ts +5 -4
  851. package/src/generators/gherkin-parser/index.ts +0 -1
  852. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
  853. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
  854. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
  855. package/src/generators/test-generator/code-generator.ts +17 -4
  856. package/src/generators/test-generator/diagnostics.ts +3 -9
  857. package/src/generators/test-generator/patterns/types.ts +0 -2
  858. package/src/generators/test-generator/step-mapper.ts +9 -56
  859. package/src/generators/test-generator/utils/data-resolver.ts +0 -53
  860. package/src/generators/test-generator/utils/selector-resolver.ts +2 -10
  861. package/src/graph/board-human-actions.ts +80 -0
  862. package/src/graph/evaluate-graph.ts +97 -0
  863. package/src/graph/human-action.ts +33 -0
  864. package/src/graph/locate-finding.ts +93 -0
  865. package/src/graph/manual-triage-decisions.ts +55 -0
  866. package/src/graph/node-decl.ts +83 -0
  867. package/src/graph/nodes/core-node-catalog.ts +15 -0
  868. package/src/graph/nodes/test-case-contract-nodes.ts +90 -0
  869. package/src/graph/nodes/test-case-nodes.ts +100 -0
  870. package/src/graph/nodes/unit-audit-nodes.ts +96 -0
  871. package/src/graph/nodes/unit-contract-node.ts +100 -0
  872. package/src/graph/nodes/unit-design-nodes.ts +89 -0
  873. package/src/graph/nodes/unit-execution-nodes.ts +77 -0
  874. package/src/graph/test-case-identity.ts +75 -0
  875. package/src/graph/test-case-results.ts +111 -0
  876. package/src/graph/test-case-satisfied.ts +58 -0
  877. package/src/graph/test-case-state-shape.ts +67 -0
  878. package/src/graph/test-case-states.ts +84 -0
  879. package/src/graph/unit-artifact-probes.ts +79 -0
  880. package/src/graph/unit-results-freshness.ts +165 -0
  881. package/src/graph/unit-state-facts.ts +112 -0
  882. package/src/harness/audit.ts +31 -18
  883. package/src/harness/catalog/gate-rules.yaml +647 -0
  884. package/src/harness/defect-draft.ts +13 -2
  885. package/src/harness/defects.ts +22 -9
  886. package/src/harness/flow-check.ts +11 -0
  887. package/src/harness/gates/audit-gate-terms.ts +80 -0
  888. package/src/harness/gates/audit-gate-verdict.ts +79 -0
  889. package/src/harness/gates/audit-input-hash.ts +79 -0
  890. package/src/harness/gates/audit-report-verification.ts +206 -0
  891. package/src/harness/gates/decisions-hash.ts +42 -0
  892. package/src/harness/gates/delivery-checklist.ts +152 -0
  893. package/src/harness/gates/delivery-decision-gate.ts +139 -0
  894. package/src/harness/gates/delivery-decision-step.ts +89 -0
  895. package/src/harness/gates/gate-override-report.ts +114 -0
  896. package/src/harness/gates/gate-override-scope.ts +66 -0
  897. package/src/harness/gates/gate-override-validation.ts +75 -0
  898. package/src/harness/gates/gate-rule-catalog.ts +82 -0
  899. package/src/harness/gates/gate-terms.ts +59 -0
  900. package/src/harness/gates/in-run-decision-check.ts +124 -0
  901. package/src/harness/gates/journey-gate-inputs.ts +89 -0
  902. package/src/harness/gates/migrated-waiver-import-bounds.ts +103 -0
  903. package/src/harness/gates/migrated-waiver-review.ts +121 -0
  904. package/src/harness/gates/resolve-rule.ts +94 -0
  905. package/src/harness/gates/unit-gate-overrides.ts +99 -0
  906. package/src/harness/journey.ts +287 -39
  907. package/src/harness/manifest.ts +67 -43
  908. package/src/harness/next-step.ts +91 -193
  909. package/src/harness/parse.ts +20 -2
  910. package/src/harness/provenance.ts +99 -11
  911. package/src/harness/script-check.ts +20 -5
  912. package/src/harness/sensors.ts +47 -40
  913. package/src/harness/triage-manual-classification.ts +76 -0
  914. package/src/harness/unit-paths.ts +19 -0
  915. package/src/hooks/bash-read-only-segment.ts +130 -0
  916. package/src/hooks/bash-write-targets.ts +195 -0
  917. package/src/hooks/claude-hook-entry.ts +85 -0
  918. package/src/hooks/claude-transcript-turn.ts +96 -0
  919. package/src/hooks/guard-delivery-contract-rule.ts +110 -0
  920. package/src/hooks/guard-protected-paths.ts +80 -0
  921. package/src/hooks/guard-rules.ts +117 -0
  922. package/src/hooks/guard-tty-spoof-rule.ts +34 -0
  923. package/src/hooks/hand-back-core.ts +118 -0
  924. package/src/hooks/hook-cli-command.ts +17 -0
  925. package/src/hooks/hook-registry.ts +24 -0
  926. package/src/hooks/hook-result-contract.ts +114 -0
  927. package/src/hooks/hook-toggles.ts +66 -0
  928. package/src/hooks/pre-tool-guard-hook.ts +67 -0
  929. package/src/hooks/session-start-unit-state-hook.ts +59 -0
  930. package/src/hooks/stop-next-step-hook.ts +38 -0
  931. package/src/hooks/sungen-project-root.ts +80 -0
  932. package/src/index.ts +1 -2
  933. package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
  934. package/src/orchestrator/ai-skills/commands.ts +17 -5
  935. package/src/orchestrator/assets-drift.ts +12 -5
  936. package/src/orchestrator/claude-hooks-install.ts +168 -0
  937. package/src/orchestrator/lockstep-version.ts +28 -15
  938. package/src/orchestrator/project-initializer.ts +22 -0
  939. package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  940. package/src/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
  941. package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  942. package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  943. package/src/orchestrator/templates/ai-src/commands/create-test.md +17 -16
  944. package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  945. package/src/orchestrator/templates/ai-src/commands/delivery.md +4 -0
  946. package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
  947. package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  948. package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
  949. package/src/orchestrator/templates/ai-src/commands/review.md +4 -0
  950. package/src/orchestrator/templates/ai-src/commands/run-test.md +6 -8
  951. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  952. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  953. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  954. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.claude.md +11 -0
  955. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
  956. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
  957. package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
  958. package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
  959. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
  960. package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
  961. package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  962. package/src/orchestrator/templates/specs-test-data.ts +4 -22
  963. package/src/utils/safe-yaml-parse.ts +44 -0
  964. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
  965. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
  966. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
  967. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
  968. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
  969. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
@@ -1,22 +1,110 @@
1
1
  /**
2
- * Provenance stamp for deterministic reports (score-determinism D1).
2
+ * Provenance stamp for deterministic reports (score-determinism D1), and the RULES the audit's
3
+ * verdict was judged by (#933, owner decision W4).
3
4
  *
4
- * The audit score is a pure function of the project files + the bundled catalog.
5
- * Stamping the sungen version + a catalog hash into the report lets two users who
6
- * get different scores see IMMEDIATELY whether the cause is a version/catalog
7
- * mismatch (the main residual source of cross-user variance) rather than a real
8
- * difference in their test design.
5
+ * The audit score is a pure function of the project files + the bundled catalogs + the scoring
6
+ * code. Stamping them into the report lets two users who get different scores see IMMEDIATELY
7
+ * whether the cause is a rules mismatch rather than a real difference in their test design — and
8
+ * lets `verifyAuditReport` tell a report judged by today's rules from one judged by other rules:
9
+ *
10
+ * sungenVersion which package wrote it — informational: a newer sungen with the same rules
11
+ * gives the same verdict, so the version alone never makes a report stale
12
+ * catalogHash sha256(universal-viewpoints.yaml), first 12 hex — the viewpoint catalog
13
+ * rulesHash sha256(AUDIT_RULES_VERSION + every catalog file under harness/catalog/ + each
14
+ * bundled driver's sources/catalogs), first 12 hex — everything the verdict
15
+ * depends on that is not the project's own files. No package VERSION is hashed:
16
+ * packages are lockstep-versioned, so a release would stale every report
9
17
  */
10
18
  import * as fs from 'fs';
11
19
  import * as path from 'path';
12
20
  import * as crypto from 'crypto';
13
21
 
22
+ /**
23
+ * The version of the audit's SCORING CODE. Bump it (by one) in the same change whenever what
24
+ * `runAudit` computes for the same project can change: a sensor, a threshold, a gate term
25
+ * (audit-gate-terms.ts), the score model or weights, a finding that feeds the verdict, or the
26
+ * audit sensor of a bundled driver. Every report scored before the bump then reads stale and asks
27
+ * for one `sungen audit`. Catalog edits (harness/catalog/*.yaml) and bundled-driver changes (their
28
+ * sources and catalogs are hashed) need no bump.
29
+ * A release that changes none of these keeps every report trusted across the upgrade.
30
+ * Enforced by tests/audit/run.ts: its rules lock (tests/audit/audit-rules.lock.json) fails when the
31
+ * fixtures' audit output changes under an unchanged rules hash. After the bump, re-record it:
32
+ * npx tsx tests/audit/run.ts --record-rules-lock
33
+ */
34
+ export const AUDIT_RULES_VERSION = 1;
35
+
14
36
  export interface Provenance {
15
37
  sungenVersion: string;
16
38
  catalogHash: string; // sha256(universal-viewpoints.yaml), first 12 hex — the catalog that drives the score
39
+ rulesHash: string; // sha256(AUDIT_RULES_VERSION + harness/catalog/*.yaml + bundled drivers), first 12 hex — the verdict's rules
40
+ }
41
+
42
+ /** A bundled driver as an input of the rules: its package dir, or null when it is not installed. */
43
+ export interface DriverRulesInput { name: string; version?: string; dir: string | null }
44
+
45
+ /** What is not a driver's rule: dependencies, build output, tests, docs, editor and lock files. */
46
+ const SKIP_DIR = new Set(['node_modules', 'dist', 'tests', 'test', 'coverage']);
47
+ const SKIP_FILE = /^(?:\.|package(?:-lock)?\.json$|tsconfig.*\.json$|.*\.(?:md|tsbuildinfo)$)/;
48
+
49
+ function driverFiles(root: string, rel = ''): string[] {
50
+ const out: string[] = [];
51
+ for (const e of fs.readdirSync(path.join(root, rel), { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name, 'en'))) {
52
+ if (e.name.startsWith('.')) continue;
53
+ const r = rel ? `${rel}/${e.name}` : e.name;
54
+ if (e.isDirectory()) { if (!SKIP_DIR.has(e.name)) out.push(...driverFiles(root, r)); }
55
+ else if (e.isFile() && !SKIP_FILE.test(e.name)) out.push(r);
56
+ }
57
+ return out;
58
+ }
59
+
60
+ /** The package root above a driver's resolved entry file (the dir whose package.json names it). */
61
+ function packageRootOf(entry: string, name: string): string | null {
62
+ let dir = path.dirname(entry);
63
+ for (let i = 0; i < 8; i++) {
64
+ try { if (JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'))?.name === name) return dir; } catch { /* keep walking */ }
65
+ const parent = path.dirname(dir);
66
+ if (parent === dir) break;
67
+ dir = parent;
68
+ }
69
+ return null;
17
70
  }
18
71
 
72
+ /** Each bundled driver as discovery would load it (project anchor, then core's), or `absent`. */
73
+ export function bundledDriverRulesInputs(): DriverRulesInput[] {
74
+ // Lazy: discovery pulls the capability registry, which nothing else here needs.
75
+ const { bundledDriverNames, resolveDriverCopy } = require('../capabilities/discover') as typeof import('../capabilities/discover');
76
+ return bundledDriverNames().map((name) => {
77
+ const copy = resolveDriverCopy(name);
78
+ const dir = copy ? packageRootOf(copy.resolved, name) : null;
79
+ return { name, version: copy?.version, dir };
80
+ });
81
+ }
82
+
83
+ const CATALOG_DIR = path.join(__dirname, 'catalog');
84
+ const sha12 = (s: string | Buffer): string => crypto.createHash('sha256').update(s).digest('hex').slice(0, 12);
85
+
86
+ /**
87
+ * The rules hash: the scoring version, every *.yaml of the catalog dir (by name), and each bundled
88
+ * driver — every source / catalog file of its package (by relative path; build output, tests and
89
+ * dependencies excluded), or a stable `absent` marker when it is not installed. A driver's version is
90
+ * deliberately left out: releases bump every package in lockstep, and only content changes the rules.
91
+ */
92
+ export function rulesHashOf(rulesVersion: number, catalogDir: string = CATALOG_DIR, drivers: DriverRulesInput[] = bundledDriverRulesInputs()): string {
93
+ const files = fs.readdirSync(catalogDir).filter((f) => f.endsWith('.yaml')).sort();
94
+ const h = crypto.createHash('sha256').update(`audit-rules:${rulesVersion}\n`);
95
+ for (const f of files) h.update(`${f}\n`).update(fs.readFileSync(path.join(catalogDir, f))).update('\n');
96
+ for (const d of [...drivers].sort((a, b) => a.name.localeCompare(b.name, 'en'))) {
97
+ h.update(`driver:${d.name}\n`);
98
+ if (!d.dir) { h.update('absent\n'); continue; }
99
+ for (const f of driverFiles(d.dir)) h.update(`${f}\n`).update(fs.readFileSync(path.join(d.dir, f))).update('\n');
100
+ }
101
+ return h.digest('hex').slice(0, 12);
102
+ }
103
+
104
+ let cached: Provenance | null = null;
105
+
19
106
  export function getProvenance(): Provenance {
107
+ if (cached) return cached;
20
108
  let sungenVersion = 'unknown';
21
109
  try {
22
110
  const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8'));
@@ -24,10 +112,10 @@ export function getProvenance(): Provenance {
24
112
  } catch { /* version stays 'unknown' */ }
25
113
 
26
114
  let catalogHash = 'unknown';
27
- try {
28
- const cat = fs.readFileSync(path.join(__dirname, 'catalog', 'universal-viewpoints.yaml'), 'utf-8');
29
- catalogHash = crypto.createHash('sha256').update(cat).digest('hex').slice(0, 12);
30
- } catch { /* hash stays 'unknown' */ }
115
+ try { catalogHash = sha12(fs.readFileSync(path.join(CATALOG_DIR, 'universal-viewpoints.yaml'), 'utf-8')); } catch { /* hash stays 'unknown' */ }
116
+ let rulesHash = 'unknown';
117
+ try { rulesHash = rulesHashOf(AUDIT_RULES_VERSION); } catch { /* hash stays 'unknown' */ }
31
118
 
32
- return { sungenVersion, catalogHash };
119
+ cached = { sungenVersion, catalogHash, rulesHash };
120
+ return cached;
33
121
  }
@@ -18,6 +18,8 @@ import * as os from 'os';
18
18
  import { loadUnitScenarios, ScenarioInfo } from './parse';
19
19
  import { featureFilesFor } from './unit-paths';
20
20
  import { readTextFile } from './read-text';
21
+ import { CATALOG_GATE_RULES } from './gates/resolve-rule';
22
+ import { evaluateGateTerms } from './gates/gate-terms';
21
23
 
22
24
  export interface ScriptCheckResult {
23
25
  screen: string;
@@ -340,7 +342,8 @@ function findSpecs(dir: string, name: string, kind: UnitKind): string[] {
340
342
  export async function runScriptCheck(screenDir: string, screenName: string, kind: UnitKind): Promise<ScriptCheckResult> {
341
343
  const featureFiles = featureFilesFor(screenDir, screenName);
342
344
  const scenarios = loadUnitScenarios(screenDir, screenName);
343
- const automated = scenarios.filter((s) => !s.manual);
345
+ // Hand-written (@free / @impl:code) scenarios are proven by their traces, not compiled — no twin expected.
346
+ const automated = scenarios.filter((s) => !s.manual && !s.handWritten);
344
347
  const manual = scenarios.filter((s) => s.manual);
345
348
 
346
349
  const committedSpecs = findSpecs(path.join(process.cwd(), 'specs', 'generated'), screenName, kind);
@@ -388,9 +391,10 @@ export async function runScriptCheck(screenDir: string, screenName: string, kind
388
391
  // failed regenerate degrades check C to its heuristic instead of crashing it.
389
392
  let stepTrace: Map<string, string[]> | undefined;
390
393
  if (committedSpec) {
394
+ let tmp: string | undefined;
391
395
  try {
392
396
  const { CodeGenerator } = require('../generators/test-generator/code-generator');
393
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sungen-scriptcheck-'));
397
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sungen-scriptcheck-'));
394
398
  const qaSourceDir = path.join(process.cwd(), 'qa', kind === 'flow' ? 'flows' : kind === 'api' ? 'api' : 'screens');
395
399
  // api units derive their unit id (api/<area>) from the feature path — like `generate --api`;
396
400
  // screen/flow pass screenName + flowMode explicitly (unchanged → byte-identical regenerate).
@@ -428,9 +432,11 @@ export async function runScriptCheck(screenDir: string, screenName: string, kind
428
432
  if (drift === 'drift') {
429
433
  findings.push('DRIFT: committed spec differs from a fresh regenerate → spec was hand-edited or the .feature changed without `sungen generate`. The test code no longer reflects the Gherkin.');
430
434
  }
431
- fs.rmSync(tmp, { recursive: true, force: true });
432
435
  } catch (e) {
433
436
  findings.push(`Drift check skipped (regenerate failed): ${e instanceof Error ? e.message : e}`);
437
+ } finally {
438
+ // Removed on every path: a throwing regenerate used to leave one sungen-scriptcheck-* dir per call.
439
+ if (tmp) fs.rmSync(tmp, { recursive: true, force: true });
434
440
  }
435
441
  }
436
442
 
@@ -446,7 +452,16 @@ export async function runScriptCheck(screenDir: string, screenName: string, kind
446
452
  }
447
453
  const bypass = assertionlessTests.length > 0 || hollowSteps.length > 0;
448
454
 
449
- const ok = !!committedSpec && countMatch && missingInSpec.length === 0 && extraInSpec.length === 0 && drift === 'in-sync' && !bypass;
455
+ // Every term is a hard rule (the #387 drift family): no gate-override can lower one, so the
456
+ // catalog alone decides (OES-11.3).
457
+ const faithful = evaluateGateTerms([
458
+ { rule: 'script.no-spec', holds: !!committedSpec },
459
+ { rule: 'script.count-mismatch', holds: countMatch },
460
+ { rule: 'script.missing-in-spec', holds: missingInSpec.length === 0 },
461
+ { rule: 'script.extra-in-spec', holds: extraInSpec.length === 0 },
462
+ { rule: 'script.drift', holds: drift === 'in-sync' },
463
+ { rule: 'script.bypass', holds: !bypass },
464
+ ], CATALOG_GATE_RULES);
450
465
 
451
466
  return {
452
467
  screen: screenName,
@@ -462,7 +477,7 @@ export async function runScriptCheck(screenDir: string, screenName: string, kind
462
477
  assertionlessTests,
463
478
  hollowSteps,
464
479
  bypass,
465
- status: ok ? 'OK' : 'FAIL',
480
+ status: faithful.pass ? 'OK' : 'FAIL',
466
481
  findings,
467
482
  };
468
483
  }
@@ -13,6 +13,8 @@ import { ScenarioInfo, ViewpointEntry, idPrefix } from './parse';
13
13
  import { readTextFile } from './read-text';
14
14
  import { keywordHit, hasKeyword } from './keyword-match';
15
15
  import { countedAssertions } from './counted-assertions';
16
+ import { CATALOG_GATE_RULES, GateRules } from './gates/resolve-rule';
17
+ import { ruleVerdict, sensorSeverityOf } from './gates/gate-terms';
16
18
 
17
19
  // Business-critical category keywords (matched by CONTAINMENT against the VP category, so a
18
20
  // compound category like LIST-DISPLAY / ADD-TO-CART / PRODUCT-DISCOVERY classifies correctly).
@@ -276,6 +278,8 @@ export function assertionDepth(
276
278
  scenarios: ScenarioInfo[],
277
279
  dataThemes: CatalogTheme[] = [],
278
280
  focus = 'functional',
281
+ /** The unit's gate rules; the catalog alone (today's levels) by default. */
282
+ rules: GateRules = CATALOG_GATE_RULES,
279
283
  ): DepthResult {
280
284
  const nonManual = scenarios.filter((s) => !s.manual);
281
285
  const shallow = nonManual.filter((s) => s.shallow);
@@ -299,8 +303,7 @@ export function assertionDepth(
299
303
  const ratio = required.length ? 1 - reqShallow.length / required.length : 1;
300
304
 
301
305
  const threshold = DEPTH_THRESHOLDS[focus] ?? DEPTH_THRESHOLDS.functional;
302
- let verdict: DepthVerdict = 'pass';
303
- if (ratio < threshold) verdict = WARN_ONLY_FOCUS.has(focus) ? 'warn' : 'fail';
306
+ const verdict = ruleVerdict(rules, 'audit.assertion-depth', ratio < threshold, WARN_ONLY_FOCUS.has(focus));
304
307
 
305
308
  return {
306
309
  total: nonManual.length,
@@ -711,7 +714,10 @@ export interface ClaimUnproven {
711
714
  claim: string; // the claim keyword matched in the title
712
715
  need: string; // the assertion shape the steps must contain
713
716
  hint: string; // how to fix
714
- severity: 'fail' | 'warn';
717
+ /** Resolved from the row's catalog rule (fail = blocks when under the ratio; info only via an override). */
718
+ severity: 'fail' | 'warn' | 'info';
719
+ /** The gate rule that decided `severity` (`claim.*`, or `claim.partial-proof`). */
720
+ rule: string;
715
721
  }
716
722
 
717
723
  export interface ClaimProofResult {
@@ -726,16 +732,17 @@ export interface ClaimProofResult {
726
732
  }
727
733
 
728
734
  interface ClaimRule {
735
+ /** The catalog rule (`claim.*`) whose resolved severity a missing proof gets (OES-11.2). */
736
+ rule: string;
729
737
  claim: string;
730
738
  title: RegExp; // claim keyword(s) in the title
731
739
  proof: RegExp; // required assertion shape in the steps
732
740
  need: string;
733
741
  hint: string;
734
- severity: 'fail' | 'warn';
735
742
  // Optional: even when `proof` matches, if `underproof` also matches the proof is
736
- // PARTIAL (the right shape exists but on the wrong/another element) → a warn-level
737
- // finding. e.g. an "each card exposes <action>" claim that has a see-all on price
738
- // but asserts the actions with singular presence.
743
+ // PARTIAL (the right shape exists but on the wrong/another element) → a finding at the
744
+ // `claim.partial-proof` rule's level. e.g. an "each card exposes <action>" claim that has
745
+ // a see-all on price but asserts the actions with singular presence.
739
746
  underproof?: RegExp;
740
747
  underNeed?: string;
741
748
  underHint?: string;
@@ -749,29 +756,30 @@ const CLAIM_RULES: ClaimRule[] = [
749
756
  // catch, so proving it with a substring proves the opposite of what the title says. Found on
750
757
  // a real basic flow whose seven confirmation rows all used `contains` while claiming the six
751
758
  // values "survive unchanged" (#599).
759
+ rule: 'claim.unchanged-preserved',
752
760
  claim: 'unchanged/preserved',
753
761
  title: /\b(unchanged|unmodified|un-?edited|identical|preserved|intact|verbatim|as entered|without (?:any )?(?:change|modification))\b/,
754
762
  proof: /^(?![\s\S]*\bcontains \{\{)/,
755
763
  need: 'exact-value assertions (`see [X] text with {{v}}` / `field with {{v}}`) for the values the title says are unchanged',
756
764
  hint: 'swap `contains {{v}}` for `with {{v}}` on the continuity rows. A substring match cannot distinguish "unchanged" from "changed by adding a prefix" — and if the screen genuinely renders extra text around the value, say so in the title instead of claiming exactness.',
757
- severity: 'warn',
758
765
  },
759
766
  {
760
767
  // An ORDER claim ("sorted by date descending", "ties broken by last-updated") is invisible to
761
768
  // a presence check: `see [List] table` passes whatever order the rows are in. It sits ahead of
762
769
  // the generic rules so "all results sorted …" is judged as an ordering claim, not an all-claim.
763
770
  // A tiebreaker is a Tier-1 guard in the tc-generation skill, yet no rule recognised it (#810).
771
+ rule: 'claim.ordering-sort',
764
772
  claim: 'ordering/sort',
765
773
  title: /\b(ascending|descending|sorted|sorts|sort order|ordered by|order by|in (?:chronological|alphabetical|reverse|numeric) order|(?:newest|oldest|latest|earliest|highest|lowest) first|tie-?break(?:s|er|ers)?|ties?)\b|降順|昇順|並び順|giảm dần|tăng dần|sắp xếp/,
766
774
  proof: /match data|is sorted|sorted (?:ascending|descending)|\brow \d+\b|\.first\.|\.last\.|\[\d+\]\.|order by/,
767
775
  need: 'an order-sensitive assertion (`table match data:` rows in the expected order, `is sorted ascending|descending`, or positional `row N` checks)',
768
776
  hint: 'a presence check passes in any order — assert the rows in their expected sequence (`User see [T] table match data:`), or the column sort state; a tiebreak needs two rows sharing the primary key.',
769
- severity: 'fail',
770
777
  },
771
778
  {
772
779
  // A LIMIT claim ("never exceeds 10", "at most 5 files") is a count claim in disguise.
773
780
  // Ahead of 'no-side-effect', whose negation+effect pattern would otherwise swallow
774
781
  // "never exceeds 10 records" and ask for a duplicate-count proof.
782
+ rule: 'claim.limit-cap',
775
783
  claim: 'limit/cap',
776
784
  // The quantity must be ≥2 ("at most ONE order" is a no-duplicate claim — left to the rules
777
785
  // below) and not a duration ("up to 30 seconds" is a timing claim, not a cap).
@@ -779,51 +787,50 @@ const CLAIM_RULES: ClaimRule[] = [
779
787
  proof: /\bcount\b|tohavecount|table with|row with \{\{|match data|is at most|\bexactly\b|field with \{\{|\berror\b|invalid|is disabled/,
780
788
  need: 'a count/boundary assertion (count is N, `is at most`, the N+1th input rejected or truncated)',
781
789
  hint: 'assert the boundary itself — the count at the cap, or the value/error when one more is attempted — not just that the list or field is present.',
782
- severity: 'fail',
783
790
  },
784
791
  {
792
+ rule: 'claim.all-every-each',
785
793
  claim: 'all/every/each',
786
794
  title: /\b(all|every|each)\b/,
787
795
  proof: /\bsee all\b/,
788
796
  need: 'a `User see all …` assertion (every element, not one)',
789
797
  hint: 'assert across all matched elements — for per-card structure use the all-card DSL (roadmap Q2).',
790
- severity: 'fail',
791
798
  // singular action presence under an "each/every" claim = partial proof
792
799
  underproof: /\bsee \[[^\]]+\] (link|button)\b/,
793
800
  underNeed: 'an all-card assertion for the claimed action (not single presence)',
794
801
  underHint: 'the actions are asserted once, not per-card — wrap them with the all-card DSL `User see all [Card] contain [Action]` (roadmap Q2).',
795
802
  },
796
803
  {
804
+ rule: 'claim.only-belong-to',
797
805
  claim: 'only/belong-to',
798
806
  title: /\b(only|belongs? to|exclusively)\b/,
799
807
  proof: /\bsee all\b[^.]*\bcontain/,
800
808
  need: 'all-match (`User see all … contains …`)',
801
809
  hint: 'all displayed items must match the facet; "no items OUTSIDE" is UI-limited → verify via hybrid API/DB or mark @manual with reason.',
802
- severity: 'warn',
803
810
  },
804
811
  {
812
+ rule: 'claim.single-exactly-one',
805
813
  claim: 'single/exactly-one',
806
814
  title: /\b(a single|single|exactly one|just one|only one)\b/,
807
815
  proof: /\bcount\b|\btable with\b|\bexactly\b|tohavecount/,
808
816
  need: 'a count assertion (e.g. count is 1)',
809
817
  hint: 'assert the quantity, not just presence.',
810
- severity: 'fail',
811
818
  },
812
819
  {
820
+ rule: 'claim.correct-matching-identity',
813
821
  claim: 'correct/matching/identity',
814
822
  title: /\b(correct|matching|the same|same (product|name|price|value|item)|consistency|identity|lands? in|is the (product|item))\b/,
815
823
  proof: /\bremember\b/,
816
824
  need: 'capture + compare (`User remember … as {{v}}` then assert {{v}})',
817
825
  hint: 'remember the value on the source, then assert it on the target (cross-screen → defer to a flow as @manual).',
818
- severity: 'fail',
819
826
  },
820
827
  {
828
+ rule: 'claim.changes-toggles',
821
829
  claim: 'changes/toggles',
822
830
  title: /\b(changes?|toggles?|updates?|reflects?|reopens?)\b/,
823
831
  proof: /\bremember\b|\bis hidden\b/,
824
832
  need: 'a state delta (before ≠ after, or a visible→hidden contrast)',
825
833
  hint: 'capture the before-state and assert the after-state differs, or assert the visible/hidden transition.',
826
- severity: 'warn',
827
834
  },
828
835
  {
829
836
  // GENERAL — mutation-absence. A title asserts that a STATE-CHANGING action does NOT
@@ -834,6 +841,7 @@ const CLAIM_RULES: ClaimRule[] = [
834
841
  // count/contrast (record count unchanged) or defer to @manual. This is the general
835
842
  // category behind "browser back does not re-submit", "does not re-charge the card",
836
843
  // "double-click does not create two orders" — not a per-feature keyword.
844
+ rule: 'claim.no-side-effect',
837
845
  claim: 'no-side-effect/no-duplicate',
838
846
  // The negation must attach to an EFFECT — something created, sent, stored, charged, fired
839
847
  // twice — not to the INPUT being refused. "duplicate address is rejected" is an observable
@@ -851,33 +859,33 @@ const CLAIM_RULES: ClaimRule[] = [
851
859
  proof: /\bcount\b|ok_count|status_counts|row with \{\{|table with|tohavecount|is hidden|are hidden|is disabled|are disabled|not complete|no longer/,
852
860
  need: 'a record/request-count proof (count stays at one, e.g. `User see [Table] row with {{count}}`, an API `{{name.ok_count}}` invariant, or a `@query` DB count) or @manual with a request-count oracle',
853
861
  hint: 'a "does-not-happen / does-not-repeat" claim about a state-changing action is NOT proven by a terminal `see [...] page` — that page is identical whether or not the action (re-)fired. Prove the side-effect count is unchanged, or mark @manual with a setup→action→assert-no-duplicate oracle.',
854
- severity: 'fail',
855
862
  },
856
863
  {
864
+ rule: 'claim.hidden-rejected',
857
865
  claim: 'hidden/rejected/not-complete',
858
866
  title: /\b(hidden|closed|dismiss(es|ed)?|not complete|rejected|inert)\b/,
859
867
  proof: /\bis hidden\b|\bare hidden\b|message is hidden|not complete|\bhidden\b/,
860
868
  need: 'a negative / hidden assertion (`… is hidden`)',
861
869
  hint: 'assert the absence/hidden state that the title claims, not just an unrelated visible element.',
862
- severity: 'fail',
863
870
  },
864
871
  {
872
+ rule: 'claim.cleared-emptied',
865
873
  claim: 'cleared/emptied',
866
874
  title: /\b(cleared|clears|emptied|empties|reset to empty|wiped)\b/,
867
875
  proof: /\bis empty\b|with \{\{empty|with ['"]?['"]?\s*$|\bempty\b/,
868
876
  need: 'an empty/cleared assertion after the action (e.g. `field with {{empty_value}}` / `is empty`)',
869
877
  hint: 'prove the value is actually gone — return to the screen and assert the field is empty, not just that the action ran.',
870
- severity: 'fail',
871
878
  },
872
879
  {
880
+ rule: 'claim.restored-preserved',
873
881
  claim: 'restored/preserved',
874
882
  title: /\b(restored|preserved|persists?|retained|remembered|kept)\b/,
875
883
  proof: /\bremember\b|with \{\{|field with/,
876
884
  need: 'the value re-asserted after the transition (capture or `field with {{v}}` after returning)',
877
885
  hint: 'prove the value survives — assert the field still holds the typed value after the reload/return, not just that it was typed.',
878
- severity: 'warn',
879
886
  },
880
887
  {
888
+ rule: 'claim.independent-separate',
881
889
  claim: 'independent/separate',
882
890
  title: /\b(independent|separate|isolat(ed|es)|per[- ]tab|two tabs|each tab)\b/,
883
891
  // A storage `does not exist` check on the OTHER tenant's key proves isolation
@@ -886,23 +894,22 @@ const CLAIM_RULES: ClaimRule[] = [
886
894
  proof: /\bcontext\b|tab a|tab b|second (tab|context)|does not exist/,
887
895
  need: 'a multi-context proof (tab A vs tab B)',
888
896
  hint: 'independence across tabs/contexts is rarely DSL-expressible — mark @manual with a clear setup/action/oracle.',
889
- severity: 'warn',
890
897
  },
891
898
  {
899
+ rule: 'claim.sanitized-inert',
892
900
  claim: 'sanitized/inert',
893
901
  title: /\b(sanitized|sanitised|escaped|inert|not executed|not rendered|stripped)\b/,
894
902
  proof: /field with \{\{|payload|inert|toContainText|is hidden/,
895
903
  need: 'the payload echoed as inert text (`field with {{payload}}`) + no execution',
896
904
  hint: 'prove the payload round-trips as literal text and triggers nothing — assert the field value and the absence of any effect.',
897
- severity: 'warn',
898
905
  },
899
906
  {
907
+ rule: 'claim.announces-aria',
900
908
  claim: 'announces/aria',
901
909
  title: /\b(announce[sd]?|aria|screen[- ]reader|programmatically associated)\b/,
902
910
  proof: /aria|role|@manual|describedby|is focused|tab order/,
903
911
  need: 'an aria/role assertion (or @manual with a screen-reader oracle)',
904
912
  hint: 'ARIA announcement is usually not DSL-expressible — assert aria attributes if possible, else @manual with an NVDA/VoiceOver oracle.',
905
- severity: 'warn',
906
913
  },
907
914
  {
908
915
  // GENERAL CATCH-ALL (last) — any negative/absence title not handled by a specific
@@ -912,6 +919,7 @@ const CLAIM_RULES: ClaimRule[] = [
912
919
  // only a positive presence. WARN, because a positive proxy is sometimes a valid
913
920
  // negative proof (e.g. "stayed on the login page"); the semantic reviewer is the
914
921
  // authoritative recall layer for the residue this can't judge structurally.
922
+ rule: 'claim.negative-absence',
915
923
  claim: 'negative-claim/absence',
916
924
  title: /(\bno\b|\bnot\b|n['’]t\b|\bnever\b|\bwithout\b|\bcannot\b|prevent|block|avoid|reject|disabl|\bdeny\b|denies|\bkhông\b|\bchưa\b)/i,
917
925
  // `does not exist` covers the storage-absence shape — the broad "any storage
@@ -921,7 +929,6 @@ const CLAIM_RULES: ClaimRule[] = [
921
929
  proof: /is hidden|are hidden|is empty|no longer|not complete|disabl|invalid|rejected|\berror\b|\bcount\b|row with \{\{|table with|\bremember\b|\bexactly\b|tohavecount|does not exist|tab order/i,
922
930
  need: 'a proof of the ABSENCE — a contrast/empty/hidden/error/count assertion, or @manual with an oracle',
923
931
  hint: 'a negative claim ("no / not / không …") is not proven by a positive `see [X]` that looks the same whether or not the claim holds. Assert the contrast (state hidden/empty, error shown, count unchanged), or mark @manual.',
924
- severity: 'warn',
925
932
  },
926
933
  ];
927
934
 
@@ -1014,7 +1021,12 @@ export function taxonomyLint(scenarios: ScenarioInfo[]): TaxonomyResult {
1014
1021
  return { total: scenarios.length, checked, mislabeled };
1015
1022
  }
1016
1023
 
1017
- export function claimProof(scenarios: ScenarioInfo[], focus = 'functional'): ClaimProofResult {
1024
+ /**
1025
+ * `rules` resolves each row's catalog rule for the unit being audited (the catalog alone by default —
1026
+ * today's levels). A rule switched `off` by a gate-override is not measured: its unproven claim is
1027
+ * neither counted nor reported (a partial-proof switched off leaves the claim proven).
1028
+ */
1029
+ export function claimProof(scenarios: ScenarioInfo[], focus = 'functional', rules: GateRules = CATALOG_GATE_RULES): ClaimProofResult {
1018
1030
  const measured = scenarios.filter((s) => !s.manual);
1019
1031
  const unproven: ClaimUnproven[] = [];
1020
1032
  let withClaims = 0;
@@ -1023,19 +1035,17 @@ export function claimProof(scenarios: ScenarioInfo[], focus = 'functional'): Cla
1023
1035
  const title = s.name.toLowerCase();
1024
1036
  const rule = CLAIM_RULES.find((r) => r.title.test(title));
1025
1037
  if (!rule) continue; // no claim → not measured
1038
+ const miss = !rule.proof.test(s.stepsText)
1039
+ // proof shape entirely absent → the claim's own rule decides the level
1040
+ ? { rule: rule.rule, need: rule.need, hint: rule.hint }
1041
+ : rule.underproof && rule.underproof.test(s.stepsText)
1042
+ // right shape exists but only as a partial proof
1043
+ ? { rule: 'claim.partial-proof', need: rule.underNeed ?? rule.need, hint: rule.underHint ?? rule.hint }
1044
+ : null;
1045
+ const severity = miss ? sensorSeverityOf(rules.resolve(miss.rule)) : undefined;
1046
+ if (miss && severity === null && miss.rule === rule.rule) continue; // the claim's rule is off for this unit
1026
1047
  withClaims++;
1027
- if (!rule.proof.test(s.stepsText)) {
1028
- // proof shape entirely absent → fail at the rule's severity
1029
- unproven.push({ name: s.name, claim: rule.claim, need: rule.need, hint: rule.hint, severity: rule.severity });
1030
- } else if (rule.underproof && rule.underproof.test(s.stepsText)) {
1031
- // right shape exists but only as a partial proof → warn
1032
- unproven.push({
1033
- name: s.name, claim: rule.claim,
1034
- need: rule.underNeed ?? rule.need,
1035
- hint: rule.underHint ?? rule.hint,
1036
- severity: 'warn',
1037
- });
1038
- }
1048
+ if (miss && severity) unproven.push({ name: s.name, claim: rule.claim, need: miss.need, hint: miss.hint, severity, rule: miss.rule });
1039
1049
  }
1040
1050
 
1041
1051
  const proven = withClaims - unproven.length;
@@ -1043,10 +1053,7 @@ export function claimProof(scenarios: ScenarioInfo[], focus = 'functional'): Cla
1043
1053
  const threshold = DEPTH_THRESHOLDS[focus] ?? DEPTH_THRESHOLDS.functional;
1044
1054
 
1045
1055
  const hasFail = unproven.some((u) => u.severity === 'fail');
1046
- let verdict: DepthVerdict = 'pass';
1047
- if (ratio < threshold) {
1048
- verdict = WARN_ONLY_FOCUS.has(focus) || !hasFail ? 'warn' : 'fail';
1049
- }
1056
+ const verdict = ruleVerdict(rules, 'audit.claim-proof', ratio < threshold, WARN_ONLY_FOCUS.has(focus) || !hasFail);
1050
1057
 
1051
1058
  return { total: measured.length, withClaims, proven, unproven, ratio, focus, threshold, verdict };
1052
1059
  }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * `sungen triage --screen <u> --case <id> --as product|test-defect|environment --reason "…"` (#928):
3
+ * classify one red by hand — the one `sungen triage` left unclassified, or one it got wrong — as a
4
+ * `triage-classification` decision in the unit's `decisions/` (read back by graph/manual-triage-decisions.ts).
5
+ *
6
+ * validated first the class, a reason, a case that exists, is red and is not exempt — before any
7
+ * prompt, so a human never confirms something that is then rejected
8
+ * product stricter than any automatic class (it leads to a QA decision): anyone may record it
9
+ * test-defect, can hide a product defect behind "fix the test" / "re-run": a human types a
10
+ * environment confirmation on a terminal (DOS-13.4); without one it is refused, nothing is
11
+ * written and the exact command is printed. Only after the typed phrase does the
12
+ * entry carry `humanConfirmed: true`, and a reader ignores one without it
13
+ * bound evidence_hash = the case's red as it reads now; a re-run voids the classification
14
+ */
15
+ import type { AppendResult } from '../decisions/append-decision';
16
+ import { appendDecision } from '../decisions/append-decision';
17
+ import type { DecisionDraft } from '../decisions/decision-schema';
18
+ import { gitUserName } from '../decisions/decision-source';
19
+ import { ConfirmationIO, formatCommand, requireTypedConfirmation } from '../decisions/human-confirmation';
20
+ import { resolveUnitCandidates } from '../cli/resolve-unit';
21
+ import { HUMAN_ONLY_TRIAGE, MANUAL_TRIAGE_AS, ManualTriageClass, TRIAGE_DECISION_KIND } from '../graph/manual-triage-decisions';
22
+ import { exemptionOf } from '../graph/test-case-satisfied';
23
+ import { testCaseStates } from '../graph/test-case-states';
24
+ import { unitScopeOfDir } from './gates/unit-gate-overrides';
25
+
26
+ export interface ClassifyRedCaseInput {
27
+ projectRoot: string;
28
+ unit: string;
29
+ caseId: string;
30
+ /** product | test-defect | environment */
31
+ as: string;
32
+ reason?: string;
33
+ io: ConfirmationIO;
34
+ }
35
+
36
+ export interface ClassifyRedCaseResult extends AppendResult { caseId: string; class: ManualTriageClass }
37
+
38
+ export async function classifyRedCase(i: ClassifyRedCaseInput): Promise<ClassifyRedCaseResult> {
39
+ const cls = Object.prototype.hasOwnProperty.call(MANUAL_TRIAGE_AS, i.as) ? MANUAL_TRIAGE_AS[i.as] : undefined;
40
+ if (!cls) throw new Error(`--as must be one of ${Object.keys(MANUAL_TRIAGE_AS).join(', ')} (got "${i.as}")`);
41
+ const reason = (i.reason ?? '').trim();
42
+ if (!reason) throw new Error('--reason is required: a classification records WHY this red is what you say it is');
43
+ const found = resolveUnitCandidates(i.unit, i.projectRoot);
44
+ if (found.length !== 1) throw new Error(`"${i.unit}" does not name exactly one unit under qa/screens, qa/flows or qa/api`);
45
+ const unitDir = found[0].dir;
46
+ const scope = unitScopeOfDir(i.projectRoot, unitDir);
47
+ if (!scope) throw new Error(`"${i.unit}" has no decisions scope`);
48
+ const cases = testCaseStates(i.projectRoot, i.unit, { unitDir, auditFindings: [] });
49
+ const tc = cases.find((c) => c.id === i.caseId);
50
+ if (!tc) {
51
+ const known = cases.slice(0, 8).map((c) => c.id).join(', ');
52
+ throw new Error(`no test case "${i.caseId}" in ${i.unit}${known ? ` — known: ${known}${cases.length > 8 ? ', …' : ''}` : ''}`);
53
+ }
54
+ if (tc.result !== 'failed' || !tc.evidence) throw new Error(`${tc.id} has no red result to classify (result: ${tc.result})`);
55
+ const exempt = exemptionOf(tc);
56
+ if (exempt) throw new Error(`${tc.id} is exempt (${exempt}) — it needs no classification`);
57
+
58
+ const human = HUMAN_ONLY_TRIAGE.has(cls);
59
+ if (human) {
60
+ await requireTypedConfirmation({
61
+ what: `classify the red ${tc.id} of ${i.unit} as ${cls}`,
62
+ phrase: tc.id,
63
+ command: formatCommand(['sungen', 'triage', found[0].kind === 'api' ? '--api' : '--screen', i.unit, '--case', tc.id, '--as', i.as, '--reason', reason]),
64
+ summary: [`case: ${tc.title}`, `automatic triage: ${tc.triage ? `${tc.triage.class} (${tc.triage.ruleId})` : 'none current'}`, `reason: ${reason}`,
65
+ `recorded by: ${gitUserName(i.projectRoot)}`, `as ${cls} it leaves the product-defect path — confirm only after reading its evidence (trace, error)`,
66
+ 'it stops counting as soon as the case runs again'],
67
+ io: i.io,
68
+ });
69
+ }
70
+ const draft: DecisionDraft = {
71
+ kind: TRIAGE_DECISION_KIND, anchors: [], text: `${tc.id} is ${cls}: ${tc.title}`, reason,
72
+ payload: { case: tc.id, class: cls, ...(human ? { humanConfirmed: true } : {}) },
73
+ source: { by: gitUserName(i.projectRoot), where: 'cli' }, valid_from: new Date().toISOString(), visibility: 'internal', evidence_hash: tc.evidence,
74
+ };
75
+ return { ...appendDecision(i.projectRoot, scope, draft), caseId: tc.id, class: cls };
76
+ }
@@ -49,3 +49,22 @@ export function featureFilesFor(unitDir: string, unit: string): string[] {
49
49
  ...names.filter((n) => n !== canonicalName),
50
50
  ].map((n) => path.join(dir, n));
51
51
  }
52
+
53
+ /**
54
+ * The catalog-resolution id for a unit dir (relative to qa/): screen · flows/<flow> · api/<area> ·
55
+ * api/flows/<flow>; a bare screen is its basename. Shared by the audit, which scores and links the
56
+ * unit under this id, and its inputsHash, which reads what the audit reads under the same id.
57
+ */
58
+ export function catalogIdFromScreenDir(screenDir: string): string {
59
+ const parts = screenDir.split(path.sep);
60
+ const qa = parts.lastIndexOf('qa');
61
+ if (qa >= 0) {
62
+ if (parts[qa + 1] === 'api' && parts[qa + 2] === 'flows' && parts[qa + 3]) return `api/flows/${parts[qa + 3]}`;
63
+ if (parts[qa + 1] === 'api' && parts[qa + 2]) return `api/${parts[qa + 2]}`;
64
+ if (parts[qa + 1] === 'flows' && parts[qa + 2]) return `flows/${parts[qa + 2]}`;
65
+ }
66
+ return path.basename(screenDir);
67
+ }
68
+
69
+ /** A screen unit — the only kind a sibling flow credits (TQ-4); flows and api units are not. */
70
+ export const isScreenUnitId = (catalogId: string): boolean => !/^(flows|api)\//.test(catalogId);