@sun-asterisk/sungen 3.2.34 → 3.3.0-alpha.2

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 (889) 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/commands/audit.d.ts.map +1 -1
  41. package/dist/cli/commands/audit.js +10 -5
  42. package/dist/cli/commands/audit.js.map +1 -1
  43. package/dist/cli/commands/capability.d.ts.map +1 -1
  44. package/dist/cli/commands/capability.js +6 -2
  45. package/dist/cli/commands/capability.js.map +1 -1
  46. package/dist/cli/commands/contract-derive-command.d.ts +11 -0
  47. package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
  48. package/dist/cli/commands/contract-derive-command.js +99 -0
  49. package/dist/cli/commands/contract-derive-command.js.map +1 -0
  50. package/dist/cli/commands/contract.d.ts +17 -0
  51. package/dist/cli/commands/contract.d.ts.map +1 -0
  52. package/dist/cli/commands/contract.js +162 -0
  53. package/dist/cli/commands/contract.js.map +1 -0
  54. package/dist/cli/commands/defect.d.ts +7 -0
  55. package/dist/cli/commands/defect.d.ts.map +1 -0
  56. package/dist/cli/commands/defect.js +68 -0
  57. package/dist/cli/commands/defect.js.map +1 -0
  58. package/dist/cli/commands/delivery.d.ts.map +1 -1
  59. package/dist/cli/commands/delivery.js +96 -12
  60. package/dist/cli/commands/delivery.js.map +1 -1
  61. package/dist/cli/commands/generate.d.ts.map +1 -1
  62. package/dist/cli/commands/generate.js +3 -1
  63. package/dist/cli/commands/generate.js.map +1 -1
  64. package/dist/cli/commands/journey.d.ts.map +1 -1
  65. package/dist/cli/commands/journey.js +43 -15
  66. package/dist/cli/commands/journey.js.map +1 -1
  67. package/dist/cli/commands/next.d.ts +8 -0
  68. package/dist/cli/commands/next.d.ts.map +1 -1
  69. package/dist/cli/commands/next.js +68 -8
  70. package/dist/cli/commands/next.js.map +1 -1
  71. package/dist/cli/commands/triage.d.ts +7 -0
  72. package/dist/cli/commands/triage.d.ts.map +1 -0
  73. package/dist/cli/commands/triage.js +98 -0
  74. package/dist/cli/commands/triage.js.map +1 -0
  75. package/dist/cli/commands/update.d.ts +11 -0
  76. package/dist/cli/commands/update.d.ts.map +1 -1
  77. package/dist/cli/commands/update.js +31 -6
  78. package/dist/cli/commands/update.js.map +1 -1
  79. package/dist/cli/index.js +24 -33
  80. package/dist/cli/index.js.map +1 -1
  81. package/dist/cli/project-sungen-invocation.d.ts +7 -0
  82. package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
  83. package/dist/cli/project-sungen-invocation.js +76 -0
  84. package/dist/cli/project-sungen-invocation.js.map +1 -0
  85. package/dist/contract/approve-contract.d.ts +31 -0
  86. package/dist/contract/approve-contract.d.ts.map +1 -0
  87. package/dist/contract/approve-contract.js +87 -0
  88. package/dist/contract/approve-contract.js.map +1 -0
  89. package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
  90. package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
  91. package/dist/contract/assertion-matcher-vocabulary.js +100 -0
  92. package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
  93. package/dist/contract/build-contract-verdict.d.ts +32 -0
  94. package/dist/contract/build-contract-verdict.d.ts.map +1 -0
  95. package/dist/contract/build-contract-verdict.js +123 -0
  96. package/dist/contract/build-contract-verdict.js.map +1 -0
  97. package/dist/contract/build-trace-conformance.d.ts +18 -0
  98. package/dist/contract/build-trace-conformance.d.ts.map +1 -0
  99. package/dist/contract/build-trace-conformance.js +153 -0
  100. package/dist/contract/build-trace-conformance.js.map +1 -0
  101. package/dist/contract/classify-contract-change.d.ts +23 -0
  102. package/dist/contract/classify-contract-change.d.ts.map +1 -0
  103. package/dist/contract/classify-contract-change.js +98 -0
  104. package/dist/contract/classify-contract-change.js.map +1 -0
  105. package/dist/contract/classify-contract-unit.d.ts +18 -0
  106. package/dist/contract/classify-contract-unit.d.ts.map +1 -0
  107. package/dist/contract/classify-contract-unit.js +49 -0
  108. package/dist/contract/classify-contract-unit.js.map +1 -0
  109. package/dist/contract/classify-trace-conformance.d.ts +32 -0
  110. package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
  111. package/dist/contract/classify-trace-conformance.js +117 -0
  112. package/dist/contract/classify-trace-conformance.js.map +1 -0
  113. package/dist/contract/contract-git.d.ts +24 -0
  114. package/dist/contract/contract-git.d.ts.map +1 -0
  115. package/dist/contract/contract-git.js +144 -0
  116. package/dist/contract/contract-git.js.map +1 -0
  117. package/dist/contract/contract-hash.d.ts +7 -0
  118. package/dist/contract/contract-hash.d.ts.map +1 -0
  119. package/dist/contract/contract-hash.js +38 -0
  120. package/dist/contract/contract-hash.js.map +1 -0
  121. package/dist/contract/contract-report-file.d.ts +4 -0
  122. package/dist/contract/contract-report-file.d.ts.map +1 -0
  123. package/dist/contract/contract-report-file.js +60 -0
  124. package/dist/contract/contract-report-file.js.map +1 -0
  125. package/dist/contract/contract-schema.d.ts +71 -0
  126. package/dist/contract/contract-schema.d.ts.map +1 -0
  127. package/dist/contract/contract-schema.js +102 -0
  128. package/dist/contract/contract-schema.js.map +1 -0
  129. package/dist/contract/contract-units.d.ts +12 -0
  130. package/dist/contract/contract-units.d.ts.map +1 -0
  131. package/dist/contract/contract-units.js +96 -0
  132. package/dist/contract/contract-units.js.map +1 -0
  133. package/dist/contract/contracts-lock-file.d.ts +24 -0
  134. package/dist/contract/contracts-lock-file.d.ts.map +1 -0
  135. package/dist/contract/contracts-lock-file.js +140 -0
  136. package/dist/contract/contracts-lock-file.js.map +1 -0
  137. package/dist/contract/data-normalize.d.ts +10 -0
  138. package/dist/contract/data-normalize.d.ts.map +1 -0
  139. package/dist/contract/data-normalize.js +110 -0
  140. package/dist/contract/data-normalize.js.map +1 -0
  141. package/dist/contract/derive-free-feature.d.ts +38 -0
  142. package/dist/contract/derive-free-feature.d.ts.map +1 -0
  143. package/dist/contract/derive-free-feature.js +154 -0
  144. package/dist/contract/derive-free-feature.js.map +1 -0
  145. package/dist/contract/field-semantic-redaction.d.ts +21 -0
  146. package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
  147. package/dist/contract/field-semantic-redaction.js +118 -0
  148. package/dist/contract/field-semantic-redaction.js.map +1 -0
  149. package/dist/contract/free-feature-blocks.d.ts +10 -0
  150. package/dist/contract/free-feature-blocks.d.ts.map +1 -0
  151. package/dist/contract/free-feature-blocks.js +94 -0
  152. package/dist/contract/free-feature-blocks.js.map +1 -0
  153. package/dist/contract/lock-secret-guard.d.ts +22 -0
  154. package/dist/contract/lock-secret-guard.d.ts.map +1 -0
  155. package/dist/contract/lock-secret-guard.js +134 -0
  156. package/dist/contract/lock-secret-guard.js.map +1 -0
  157. package/dist/contract/lock-vs-git-head.d.ts +26 -0
  158. package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
  159. package/dist/contract/lock-vs-git-head.js +28 -0
  160. package/dist/contract/lock-vs-git-head.js.map +1 -0
  161. package/dist/contract/normalize-contract-step.d.ts +21 -0
  162. package/dist/contract/normalize-contract-step.d.ts.map +1 -0
  163. package/dist/contract/normalize-contract-step.js +70 -0
  164. package/dist/contract/normalize-contract-step.js.map +1 -0
  165. package/dist/contract/normalize-feature-steps.d.ts +7 -0
  166. package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
  167. package/dist/contract/normalize-feature-steps.js +127 -0
  168. package/dist/contract/normalize-feature-steps.js.map +1 -0
  169. package/dist/contract/oracle-strength.d.ts +12 -0
  170. package/dist/contract/oracle-strength.d.ts.map +1 -0
  171. package/dist/contract/oracle-strength.js +88 -0
  172. package/dist/contract/oracle-strength.js.map +1 -0
  173. package/dist/contract/project-contract-blockers.d.ts +10 -0
  174. package/dist/contract/project-contract-blockers.d.ts.map +1 -0
  175. package/dist/contract/project-contract-blockers.js +73 -0
  176. package/dist/contract/project-contract-blockers.js.map +1 -0
  177. package/dist/contract/record-contract-approval.d.ts +21 -0
  178. package/dist/contract/record-contract-approval.d.ts.map +1 -0
  179. package/dist/contract/record-contract-approval.js +98 -0
  180. package/dist/contract/record-contract-approval.js.map +1 -0
  181. package/dist/contract/render-free-gherkin.d.ts +40 -0
  182. package/dist/contract/render-free-gherkin.d.ts.map +1 -0
  183. package/dist/contract/render-free-gherkin.js +141 -0
  184. package/dist/contract/render-free-gherkin.js.map +1 -0
  185. package/dist/contract/render-trace-sentence.d.ts +20 -0
  186. package/dist/contract/render-trace-sentence.d.ts.map +1 -0
  187. package/dist/contract/render-trace-sentence.js +109 -0
  188. package/dist/contract/render-trace-sentence.js.map +1 -0
  189. package/dist/contract/render-trace-target.d.ts +14 -0
  190. package/dist/contract/render-trace-target.d.ts.map +1 -0
  191. package/dist/contract/render-trace-target.js +70 -0
  192. package/dist/contract/render-trace-target.js.map +1 -0
  193. package/dist/contract/resolve-unit-trace-identities.d.ts +8 -0
  194. package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
  195. package/dist/contract/resolve-unit-trace-identities.js +78 -0
  196. package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
  197. package/dist/contract/trace/collect-trace-evidence.d.ts +33 -0
  198. package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
  199. package/dist/contract/trace/collect-trace-evidence.js +161 -0
  200. package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
  201. package/dist/contract/trace/identity-cache.d.ts +19 -0
  202. package/dist/contract/trace/identity-cache.d.ts.map +1 -0
  203. package/dist/contract/trace/identity-cache.js +104 -0
  204. package/dist/contract/trace/identity-cache.js.map +1 -0
  205. package/dist/contract/trace/select-final-attempt.d.ts +27 -0
  206. package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
  207. package/dist/contract/trace/select-final-attempt.js +116 -0
  208. package/dist/contract/trace/select-final-attempt.js.map +1 -0
  209. package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
  210. package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
  211. package/dist/contract/trace/snapshot-html-renderer.js +172 -0
  212. package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
  213. package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
  214. package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
  215. package/dist/contract/trace/snapshot-resolver.js +65 -0
  216. package/dist/contract/trace/snapshot-resolver.js.map +1 -0
  217. package/dist/contract/trace/snapshot-store.d.ts +66 -0
  218. package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
  219. package/dist/contract/trace/snapshot-store.js +173 -0
  220. package/dist/contract/trace/snapshot-store.js.map +1 -0
  221. package/dist/contract/trace/target-identity.d.ts +74 -0
  222. package/dist/contract/trace/target-identity.d.ts.map +1 -0
  223. package/dist/contract/trace/target-identity.js +68 -0
  224. package/dist/contract/trace/target-identity.js.map +1 -0
  225. package/dist/contract/trace/test-step-join.d.ts +65 -0
  226. package/dist/contract/trace/test-step-join.d.ts.map +1 -0
  227. package/dist/contract/trace/test-step-join.js +80 -0
  228. package/dist/contract/trace/test-step-join.js.map +1 -0
  229. package/dist/contract/trace/trace-binding.d.ts +21 -0
  230. package/dist/contract/trace/trace-binding.d.ts.map +1 -0
  231. package/dist/contract/trace/trace-binding.js +88 -0
  232. package/dist/contract/trace/trace-binding.js.map +1 -0
  233. package/dist/contract/trace/trace-file-reader.d.ts +41 -0
  234. package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
  235. package/dist/contract/trace/trace-file-reader.js +161 -0
  236. package/dist/contract/trace/trace-file-reader.js.map +1 -0
  237. package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
  238. package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
  239. package/dist/contract/trace/trace-fingerprint.js +96 -0
  240. package/dist/contract/trace/trace-fingerprint.js.map +1 -0
  241. package/dist/contract/trace/trace-identity-resolution.d.ts +26 -0
  242. package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
  243. package/dist/contract/trace/trace-identity-resolution.js +84 -0
  244. package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
  245. package/dist/contract/trace/trace-run-record.d.ts +30 -0
  246. package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
  247. package/dist/contract/trace/trace-run-record.js +121 -0
  248. package/dist/contract/trace/trace-run-record.js.map +1 -0
  249. package/dist/contract/trace/trace-steps.d.ts +19 -0
  250. package/dist/contract/trace/trace-steps.d.ts.map +1 -0
  251. package/dist/contract/trace/trace-steps.js +79 -0
  252. package/dist/contract/trace/trace-steps.js.map +1 -0
  253. package/dist/contract/trace/trace-zip-limits.d.ts +45 -0
  254. package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
  255. package/dist/contract/trace/trace-zip-limits.js +52 -0
  256. package/dist/contract/trace/trace-zip-limits.js.map +1 -0
  257. package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
  258. package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
  259. package/dist/contract/trace/trace-zip-reader.js +186 -0
  260. package/dist/contract/trace/trace-zip-reader.js.map +1 -0
  261. package/dist/contract/verify-approval-decisions.d.ts +5 -0
  262. package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
  263. package/dist/contract/verify-approval-decisions.js +104 -0
  264. package/dist/contract/verify-approval-decisions.js.map +1 -0
  265. package/dist/decisions/append-decision.d.ts +12 -0
  266. package/dist/decisions/append-decision.d.ts.map +1 -0
  267. package/dist/decisions/append-decision.js +73 -0
  268. package/dist/decisions/append-decision.js.map +1 -0
  269. package/dist/decisions/confirmed-decision-commands.d.ts +41 -0
  270. package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
  271. package/dist/decisions/confirmed-decision-commands.js +190 -0
  272. package/dist/decisions/confirmed-decision-commands.js.map +1 -0
  273. package/dist/decisions/decision-file.d.ts +31 -0
  274. package/dist/decisions/decision-file.d.ts.map +1 -0
  275. package/dist/decisions/decision-file.js +139 -0
  276. package/dist/decisions/decision-file.js.map +1 -0
  277. package/dist/decisions/decision-identity.d.ts +12 -0
  278. package/dist/decisions/decision-identity.d.ts.map +1 -0
  279. package/dist/decisions/decision-identity.js +78 -0
  280. package/dist/decisions/decision-identity.js.map +1 -0
  281. package/dist/decisions/decision-integrity-check.d.ts +12 -0
  282. package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
  283. package/dist/decisions/decision-integrity-check.js +102 -0
  284. package/dist/decisions/decision-integrity-check.js.map +1 -0
  285. package/dist/decisions/decision-schema.d.ts +42 -0
  286. package/dist/decisions/decision-schema.d.ts.map +1 -0
  287. package/dist/decisions/decision-schema.js +75 -0
  288. package/dist/decisions/decision-schema.js.map +1 -0
  289. package/dist/decisions/decision-source.d.ts +2 -0
  290. package/dist/decisions/decision-source.d.ts.map +1 -0
  291. package/dist/decisions/decision-source.js +18 -0
  292. package/dist/decisions/decision-source.js.map +1 -0
  293. package/dist/decisions/exclusive-file-create.d.ts +3 -0
  294. package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
  295. package/dist/decisions/exclusive-file-create.js +84 -0
  296. package/dist/decisions/exclusive-file-create.js.map +1 -0
  297. package/dist/decisions/git-head-trust.d.ts +7 -0
  298. package/dist/decisions/git-head-trust.d.ts.map +1 -0
  299. package/dist/decisions/git-head-trust.js +76 -0
  300. package/dist/decisions/git-head-trust.js.map +1 -0
  301. package/dist/decisions/human-confirmation.d.ts +35 -0
  302. package/dist/decisions/human-confirmation.d.ts.map +1 -0
  303. package/dist/decisions/human-confirmation.js +161 -0
  304. package/dist/decisions/human-confirmation.js.map +1 -0
  305. package/dist/decisions/legacy-waiver-migration.d.ts +31 -0
  306. package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
  307. package/dist/decisions/legacy-waiver-migration.js +170 -0
  308. package/dist/decisions/legacy-waiver-migration.js.map +1 -0
  309. package/dist/decisions/read-decisions.d.ts +19 -0
  310. package/dist/decisions/read-decisions.d.ts.map +1 -0
  311. package/dist/decisions/read-decisions.js +90 -0
  312. package/dist/decisions/read-decisions.js.map +1 -0
  313. package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
  314. package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
  315. package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
  316. package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
  317. package/dist/decisions/waiver-decisions.d.ts +24 -0
  318. package/dist/decisions/waiver-decisions.d.ts.map +1 -0
  319. package/dist/decisions/waiver-decisions.js +46 -0
  320. package/dist/decisions/waiver-decisions.js.map +1 -0
  321. package/dist/exporters/csv-exporter.d.ts +4 -0
  322. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  323. package/dist/exporters/csv-exporter.js +1 -1
  324. package/dist/exporters/csv-exporter.js.map +1 -1
  325. package/dist/exporters/feature-parser.d.ts +8 -0
  326. package/dist/exporters/feature-parser.d.ts.map +1 -1
  327. package/dist/exporters/feature-parser.js +12 -0
  328. package/dist/exporters/feature-parser.js.map +1 -1
  329. package/dist/exporters/matrix/build.d.ts +3 -0
  330. package/dist/exporters/matrix/build.d.ts.map +1 -1
  331. package/dist/exporters/matrix/build.js +59 -19
  332. package/dist/exporters/matrix/build.js.map +1 -1
  333. package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
  334. package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
  335. package/dist/exporters/matrix/carry-manual-results.js +76 -6
  336. package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
  337. package/dist/exporters/matrix/export.d.ts +8 -2
  338. package/dist/exporters/matrix/export.d.ts.map +1 -1
  339. package/dist/exporters/matrix/export.js +16 -3
  340. package/dist/exporters/matrix/export.js.map +1 -1
  341. package/dist/exporters/matrix/gates.d.ts +6 -1
  342. package/dist/exporters/matrix/gates.d.ts.map +1 -1
  343. package/dist/exporters/matrix/gates.js +57 -128
  344. package/dist/exporters/matrix/gates.js.map +1 -1
  345. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  346. package/dist/exporters/matrix/render-csv.js +4 -1
  347. package/dist/exporters/matrix/render-csv.js.map +1 -1
  348. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
  349. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
  350. package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
  351. package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
  352. package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
  353. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  354. package/dist/exporters/matrix/render-xlsx.js +6 -0
  355. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  356. package/dist/exporters/matrix/types.d.ts +9 -1
  357. package/dist/exporters/matrix/types.d.ts.map +1 -1
  358. package/dist/exporters/matrix/types.js.map +1 -1
  359. package/dist/exporters/matrix/xlsx-cells.js +1 -1
  360. package/dist/exporters/matrix/xlsx-cells.js.map +1 -1
  361. package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
  362. package/dist/exporters/playwright-report-parser.js +1 -0
  363. package/dist/exporters/playwright-report-parser.js.map +1 -1
  364. package/dist/exporters/scenario-merger.d.ts.map +1 -1
  365. package/dist/exporters/scenario-merger.js +2 -0
  366. package/dist/exporters/scenario-merger.js.map +1 -1
  367. package/dist/exporters/types.d.ts +5 -0
  368. package/dist/exporters/types.d.ts.map +1 -1
  369. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  370. package/dist/generators/test-generator/code-generator.js +13 -0
  371. package/dist/generators/test-generator/code-generator.js.map +1 -1
  372. package/dist/graph/evaluate-graph.d.ts +23 -0
  373. package/dist/graph/evaluate-graph.d.ts.map +1 -0
  374. package/dist/graph/evaluate-graph.js +52 -0
  375. package/dist/graph/evaluate-graph.js.map +1 -0
  376. package/dist/graph/locate-finding.d.ts +20 -0
  377. package/dist/graph/locate-finding.d.ts.map +1 -0
  378. package/dist/graph/locate-finding.js +137 -0
  379. package/dist/graph/locate-finding.js.map +1 -0
  380. package/dist/graph/node-decl.d.ts +66 -0
  381. package/dist/graph/node-decl.d.ts.map +1 -0
  382. package/dist/graph/node-decl.js +8 -0
  383. package/dist/graph/node-decl.js.map +1 -0
  384. package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
  385. package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
  386. package/dist/graph/nodes/core-node-catalog.js +13 -0
  387. package/dist/graph/nodes/core-node-catalog.js.map +1 -0
  388. package/dist/graph/nodes/test-case-contract-nodes.d.ts +21 -0
  389. package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
  390. package/dist/graph/nodes/test-case-contract-nodes.js +59 -0
  391. package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
  392. package/dist/graph/nodes/test-case-nodes.d.ts +26 -0
  393. package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
  394. package/dist/graph/nodes/test-case-nodes.js +66 -0
  395. package/dist/graph/nodes/test-case-nodes.js.map +1 -0
  396. package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
  397. package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
  398. package/dist/graph/nodes/unit-audit-nodes.js +95 -0
  399. package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
  400. package/dist/graph/nodes/unit-contract-node.d.ts +21 -0
  401. package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
  402. package/dist/graph/nodes/unit-contract-node.js +88 -0
  403. package/dist/graph/nodes/unit-contract-node.js.map +1 -0
  404. package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
  405. package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
  406. package/dist/graph/nodes/unit-design-nodes.js +91 -0
  407. package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
  408. package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
  409. package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
  410. package/dist/graph/nodes/unit-execution-nodes.js +79 -0
  411. package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
  412. package/dist/graph/test-case-identity.d.ts +13 -0
  413. package/dist/graph/test-case-identity.d.ts.map +1 -0
  414. package/dist/graph/test-case-identity.js +106 -0
  415. package/dist/graph/test-case-identity.js.map +1 -0
  416. package/dist/graph/test-case-results.d.ts +11 -0
  417. package/dist/graph/test-case-results.d.ts.map +1 -0
  418. package/dist/graph/test-case-results.js +137 -0
  419. package/dist/graph/test-case-results.js.map +1 -0
  420. package/dist/graph/test-case-satisfied.d.ts +25 -0
  421. package/dist/graph/test-case-satisfied.d.ts.map +1 -0
  422. package/dist/graph/test-case-satisfied.js +51 -0
  423. package/dist/graph/test-case-satisfied.js.map +1 -0
  424. package/dist/graph/test-case-state-shape.d.ts +67 -0
  425. package/dist/graph/test-case-state-shape.d.ts.map +1 -0
  426. package/dist/graph/test-case-state-shape.js +3 -0
  427. package/dist/graph/test-case-state-shape.js.map +1 -0
  428. package/dist/graph/test-case-states.d.ts +9 -0
  429. package/dist/graph/test-case-states.d.ts.map +1 -0
  430. package/dist/graph/test-case-states.js +116 -0
  431. package/dist/graph/test-case-states.js.map +1 -0
  432. package/dist/graph/unit-artifact-probes.d.ts +19 -0
  433. package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
  434. package/dist/graph/unit-artifact-probes.js +133 -0
  435. package/dist/graph/unit-artifact-probes.js.map +1 -0
  436. package/dist/graph/unit-state-facts.d.ts +43 -0
  437. package/dist/graph/unit-state-facts.d.ts.map +1 -0
  438. package/dist/graph/unit-state-facts.js +87 -0
  439. package/dist/graph/unit-state-facts.js.map +1 -0
  440. package/dist/harness/audit.d.ts +11 -0
  441. package/dist/harness/audit.d.ts.map +1 -1
  442. package/dist/harness/audit.js +34 -9
  443. package/dist/harness/audit.js.map +1 -1
  444. package/dist/harness/catalog/gate-rules.yaml +647 -0
  445. package/dist/harness/counted-assertions.d.ts +2 -0
  446. package/dist/harness/counted-assertions.d.ts.map +1 -0
  447. package/dist/harness/counted-assertions.js +38 -0
  448. package/dist/harness/counted-assertions.js.map +1 -0
  449. package/dist/harness/defect-draft.d.ts +14 -0
  450. package/dist/harness/defect-draft.d.ts.map +1 -0
  451. package/dist/harness/defect-draft.js +143 -0
  452. package/dist/harness/defect-draft.js.map +1 -0
  453. package/dist/harness/defects.d.ts +24 -0
  454. package/dist/harness/defects.d.ts.map +1 -0
  455. package/dist/harness/defects.js +118 -0
  456. package/dist/harness/defects.js.map +1 -0
  457. package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
  458. package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
  459. package/dist/harness/gates/audit-gate-terms.js +72 -0
  460. package/dist/harness/gates/audit-gate-terms.js.map +1 -0
  461. package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
  462. package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
  463. package/dist/harness/gates/audit-gate-verdict.js +101 -0
  464. package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
  465. package/dist/harness/gates/audit-input-hash.d.ts +4 -0
  466. package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
  467. package/dist/harness/gates/audit-input-hash.js +96 -0
  468. package/dist/harness/gates/audit-input-hash.js.map +1 -0
  469. package/dist/harness/gates/audit-report-verification.d.ts +41 -0
  470. package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
  471. package/dist/harness/gates/audit-report-verification.js +236 -0
  472. package/dist/harness/gates/audit-report-verification.js.map +1 -0
  473. package/dist/harness/gates/decisions-hash.d.ts +13 -0
  474. package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
  475. package/dist/harness/gates/decisions-hash.js +72 -0
  476. package/dist/harness/gates/decisions-hash.js.map +1 -0
  477. package/dist/harness/gates/delivery-checklist.d.ts +21 -0
  478. package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
  479. package/dist/harness/gates/delivery-checklist.js +128 -0
  480. package/dist/harness/gates/delivery-checklist.js.map +1 -0
  481. package/dist/harness/gates/delivery-decision-gate.d.ts +33 -0
  482. package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
  483. package/dist/harness/gates/delivery-decision-gate.js +116 -0
  484. package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
  485. package/dist/harness/gates/delivery-decision-step.d.ts +19 -0
  486. package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
  487. package/dist/harness/gates/delivery-decision-step.js +86 -0
  488. package/dist/harness/gates/delivery-decision-step.js.map +1 -0
  489. package/dist/harness/gates/gate-override-report.d.ts +59 -0
  490. package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
  491. package/dist/harness/gates/gate-override-report.js +86 -0
  492. package/dist/harness/gates/gate-override-report.js.map +1 -0
  493. package/dist/harness/gates/gate-override-scope.d.ts +18 -0
  494. package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
  495. package/dist/harness/gates/gate-override-scope.js +98 -0
  496. package/dist/harness/gates/gate-override-scope.js.map +1 -0
  497. package/dist/harness/gates/gate-override-validation.d.ts +25 -0
  498. package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
  499. package/dist/harness/gates/gate-override-validation.js +81 -0
  500. package/dist/harness/gates/gate-override-validation.js.map +1 -0
  501. package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
  502. package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
  503. package/dist/harness/gates/gate-rule-catalog.js +112 -0
  504. package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
  505. package/dist/harness/gates/gate-terms.d.ts +33 -0
  506. package/dist/harness/gates/gate-terms.d.ts.map +1 -0
  507. package/dist/harness/gates/gate-terms.js +41 -0
  508. package/dist/harness/gates/gate-terms.js.map +1 -0
  509. package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
  510. package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
  511. package/dist/harness/gates/in-run-decision-check.js +138 -0
  512. package/dist/harness/gates/in-run-decision-check.js.map +1 -0
  513. package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
  514. package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
  515. package/dist/harness/gates/journey-gate-inputs.js +81 -0
  516. package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
  517. package/dist/harness/gates/migrated-waiver-review.d.ts +6 -0
  518. package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
  519. package/dist/harness/gates/migrated-waiver-review.js +116 -0
  520. package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
  521. package/dist/harness/gates/resolve-rule.d.ts +59 -0
  522. package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
  523. package/dist/harness/gates/resolve-rule.js +41 -0
  524. package/dist/harness/gates/resolve-rule.js.map +1 -0
  525. package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
  526. package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
  527. package/dist/harness/gates/unit-gate-overrides.js +122 -0
  528. package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
  529. package/dist/harness/journey.d.ts +43 -1
  530. package/dist/harness/journey.d.ts.map +1 -1
  531. package/dist/harness/journey.js +207 -33
  532. package/dist/harness/journey.js.map +1 -1
  533. package/dist/harness/manifest.d.ts +12 -0
  534. package/dist/harness/manifest.d.ts.map +1 -1
  535. package/dist/harness/manifest.js +73 -45
  536. package/dist/harness/manifest.js.map +1 -1
  537. package/dist/harness/next-step.d.ts +37 -6
  538. package/dist/harness/next-step.d.ts.map +1 -1
  539. package/dist/harness/next-step.js +34 -174
  540. package/dist/harness/next-step.js.map +1 -1
  541. package/dist/harness/parse.d.ts +25 -0
  542. package/dist/harness/parse.d.ts.map +1 -1
  543. package/dist/harness/parse.js +38 -13
  544. package/dist/harness/parse.js.map +1 -1
  545. package/dist/harness/provenance.d.ts +29 -0
  546. package/dist/harness/provenance.d.ts.map +1 -1
  547. package/dist/harness/provenance.js +109 -9
  548. package/dist/harness/provenance.js.map +1 -1
  549. package/dist/harness/script-check.d.ts.map +1 -1
  550. package/dist/harness/script-check.js +29 -6
  551. package/dist/harness/script-check.js.map +1 -1
  552. package/dist/harness/sensors.d.ts +14 -3
  553. package/dist/harness/sensors.d.ts.map +1 -1
  554. package/dist/harness/sensors.js +64 -44
  555. package/dist/harness/sensors.js.map +1 -1
  556. package/dist/harness/triage-signals.d.ts +20 -0
  557. package/dist/harness/triage-signals.d.ts.map +1 -0
  558. package/dist/harness/triage-signals.js +30 -0
  559. package/dist/harness/triage-signals.js.map +1 -0
  560. package/dist/harness/triage-unit.d.ts +23 -0
  561. package/dist/harness/triage-unit.d.ts.map +1 -0
  562. package/dist/harness/triage-unit.js +142 -0
  563. package/dist/harness/triage-unit.js.map +1 -0
  564. package/dist/harness/triage.d.ts +28 -0
  565. package/dist/harness/triage.d.ts.map +1 -0
  566. package/dist/harness/triage.js +99 -0
  567. package/dist/harness/triage.js.map +1 -0
  568. package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
  569. package/dist/harness/viewpoint-ledger.js +2 -1
  570. package/dist/harness/viewpoint-ledger.js.map +1 -1
  571. package/dist/hooks/bash-write-targets.d.ts +15 -0
  572. package/dist/hooks/bash-write-targets.d.ts.map +1 -0
  573. package/dist/hooks/bash-write-targets.js +173 -0
  574. package/dist/hooks/bash-write-targets.js.map +1 -0
  575. package/dist/hooks/claude-hook-entry.d.ts +11 -0
  576. package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
  577. package/dist/hooks/claude-hook-entry.js +137 -0
  578. package/dist/hooks/claude-hook-entry.js.map +1 -0
  579. package/dist/hooks/claude-transcript-turn.d.ts +11 -0
  580. package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
  581. package/dist/hooks/claude-transcript-turn.js +143 -0
  582. package/dist/hooks/claude-transcript-turn.js.map +1 -0
  583. package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
  584. package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
  585. package/dist/hooks/guard-delivery-contract-rule.js +152 -0
  586. package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
  587. package/dist/hooks/guard-protected-paths.d.ts +9 -0
  588. package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
  589. package/dist/hooks/guard-protected-paths.js +107 -0
  590. package/dist/hooks/guard-protected-paths.js.map +1 -0
  591. package/dist/hooks/guard-rules.d.ts +37 -0
  592. package/dist/hooks/guard-rules.d.ts.map +1 -0
  593. package/dist/hooks/guard-rules.js +61 -0
  594. package/dist/hooks/guard-rules.js.map +1 -0
  595. package/dist/hooks/guard-tty-spoof-rule.d.ts +15 -0
  596. package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
  597. package/dist/hooks/guard-tty-spoof-rule.js +21 -0
  598. package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
  599. package/dist/hooks/hand-back-core.d.ts +39 -0
  600. package/dist/hooks/hand-back-core.d.ts.map +1 -0
  601. package/dist/hooks/hand-back-core.js +122 -0
  602. package/dist/hooks/hand-back-core.js.map +1 -0
  603. package/dist/hooks/hook-cli-command.d.ts +9 -0
  604. package/dist/hooks/hook-cli-command.d.ts.map +1 -0
  605. package/dist/hooks/hook-cli-command.js +46 -0
  606. package/dist/hooks/hook-cli-command.js.map +1 -0
  607. package/dist/hooks/hook-registry.d.ts +10 -0
  608. package/dist/hooks/hook-registry.d.ts.map +1 -0
  609. package/dist/hooks/hook-registry.js +24 -0
  610. package/dist/hooks/hook-registry.js.map +1 -0
  611. package/dist/hooks/hook-result-contract.d.ts +50 -0
  612. package/dist/hooks/hook-result-contract.d.ts.map +1 -0
  613. package/dist/hooks/hook-result-contract.js +80 -0
  614. package/dist/hooks/hook-result-contract.js.map +1 -0
  615. package/dist/hooks/hook-toggles.d.ts +10 -0
  616. package/dist/hooks/hook-toggles.d.ts.map +1 -0
  617. package/dist/hooks/hook-toggles.js +107 -0
  618. package/dist/hooks/hook-toggles.js.map +1 -0
  619. package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
  620. package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
  621. package/dist/hooks/pre-tool-guard-hook.js +105 -0
  622. package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
  623. package/dist/hooks/session-start-unit-state-hook.d.ts +13 -0
  624. package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
  625. package/dist/hooks/session-start-unit-state-hook.js +57 -0
  626. package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
  627. package/dist/hooks/stop-next-step-hook.d.ts +16 -0
  628. package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
  629. package/dist/hooks/stop-next-step-hook.js +42 -0
  630. package/dist/hooks/stop-next-step-hook.js.map +1 -0
  631. package/dist/hooks/sungen-project-root.d.ts +19 -0
  632. package/dist/hooks/sungen-project-root.d.ts.map +1 -0
  633. package/dist/hooks/sungen-project-root.js +130 -0
  634. package/dist/hooks/sungen-project-root.js.map +1 -0
  635. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
  636. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
  637. package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
  638. package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
  639. package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
  640. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
  641. package/dist/orchestrator/ai-skills/commands.js +16 -6
  642. package/dist/orchestrator/ai-skills/commands.js.map +1 -1
  643. package/dist/orchestrator/ai-skills/golden-skills.test.js +29 -0
  644. package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -1
  645. package/dist/orchestrator/assets-drift.d.ts +5 -0
  646. package/dist/orchestrator/assets-drift.d.ts.map +1 -1
  647. package/dist/orchestrator/assets-drift.js +12 -3
  648. package/dist/orchestrator/assets-drift.js.map +1 -1
  649. package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
  650. package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
  651. package/dist/orchestrator/claude-hooks-install.js +203 -0
  652. package/dist/orchestrator/claude-hooks-install.js.map +1 -0
  653. package/dist/orchestrator/lockstep-version.d.ts +15 -5
  654. package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
  655. package/dist/orchestrator/lockstep-version.js +30 -17
  656. package/dist/orchestrator/lockstep-version.js.map +1 -1
  657. package/dist/orchestrator/project-initializer.d.ts +6 -0
  658. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  659. package/dist/orchestrator/project-initializer.js +24 -0
  660. package/dist/orchestrator/project-initializer.js.map +1 -1
  661. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  662. package/dist/orchestrator/screen-manager.js +4 -2
  663. package/dist/orchestrator/screen-manager.js.map +1 -1
  664. package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  665. package/dist/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
  666. package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  667. package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  668. package/dist/orchestrator/templates/ai-src/commands/create-test.md +14 -16
  669. package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  670. package/dist/orchestrator/templates/ai-src/commands/delivery.md +2 -0
  671. package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
  672. package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  673. package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
  674. package/dist/orchestrator/templates/ai-src/commands/review.md +2 -0
  675. package/dist/orchestrator/templates/ai-src/commands/run-test.md +14 -10
  676. package/dist/orchestrator/templates/ai-src/config/claude.md +20 -7
  677. package/dist/orchestrator/templates/ai-src/config/copilot.md +20 -7
  678. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  679. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  680. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  681. package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
  682. package/dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
  683. package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
  684. package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
  685. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
  686. package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
  687. package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  688. package/dist/utils/safe-yaml-parse.d.ts +8 -0
  689. package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
  690. package/dist/utils/safe-yaml-parse.js +51 -0
  691. package/dist/utils/safe-yaml-parse.js.map +1 -0
  692. package/package.json +3 -3
  693. package/src/basis/anchor-grammar.ts +83 -0
  694. package/src/basis/anchor-hash.ts +27 -0
  695. package/src/basis/bm51-tables.ts +65 -0
  696. package/src/basis/extract-spec-anchors.ts +95 -0
  697. package/src/basis/migration-sentinel.ts +175 -0
  698. package/src/basis/spec-frontmatter.ts +68 -0
  699. package/src/basis/spec-sections.ts +35 -0
  700. package/src/basis/test-basis-schema.ts +81 -0
  701. package/src/capabilities/discover.ts +15 -2
  702. package/src/capabilities/registry.ts +16 -0
  703. package/src/cli/commands/audit.ts +10 -5
  704. package/src/cli/commands/capability.ts +4 -2
  705. package/src/cli/commands/contract-derive-command.ts +61 -0
  706. package/src/cli/commands/contract.ts +130 -0
  707. package/src/cli/commands/defect.ts +49 -0
  708. package/src/cli/commands/delivery.ts +92 -15
  709. package/src/cli/commands/generate.ts +3 -1
  710. package/src/cli/commands/journey.ts +41 -16
  711. package/src/cli/commands/next.ts +64 -10
  712. package/src/cli/commands/triage.ts +57 -0
  713. package/src/cli/commands/update.ts +35 -8
  714. package/src/cli/index.ts +24 -30
  715. package/src/cli/project-sungen-invocation.ts +39 -0
  716. package/src/contract/approve-contract.ts +94 -0
  717. package/src/contract/assertion-matcher-vocabulary.ts +93 -0
  718. package/src/contract/build-contract-verdict.ts +108 -0
  719. package/src/contract/build-trace-conformance.ts +100 -0
  720. package/src/contract/classify-contract-change.ts +92 -0
  721. package/src/contract/classify-contract-unit.ts +47 -0
  722. package/src/contract/classify-trace-conformance.ts +116 -0
  723. package/src/contract/contract-git.ts +106 -0
  724. package/src/contract/contract-hash.ts +34 -0
  725. package/src/contract/contract-report-file.ts +25 -0
  726. package/src/contract/contract-schema.ts +137 -0
  727. package/src/contract/contract-units.ts +52 -0
  728. package/src/contract/contracts-lock-file.ts +97 -0
  729. package/src/contract/data-normalize.ts +66 -0
  730. package/src/contract/derive-free-feature.ts +120 -0
  731. package/src/contract/field-semantic-redaction.ts +80 -0
  732. package/src/contract/free-feature-blocks.ts +56 -0
  733. package/src/contract/lock-secret-guard.ts +95 -0
  734. package/src/contract/lock-vs-git-head.ts +38 -0
  735. package/src/contract/normalize-contract-step.ts +74 -0
  736. package/src/contract/normalize-feature-steps.ts +93 -0
  737. package/src/contract/oracle-strength.ts +80 -0
  738. package/src/contract/project-contract-blockers.ts +36 -0
  739. package/src/contract/record-contract-approval.ts +70 -0
  740. package/src/contract/render-free-gherkin.ts +113 -0
  741. package/src/contract/render-trace-sentence.ts +98 -0
  742. package/src/contract/render-trace-target.ts +68 -0
  743. package/src/contract/resolve-unit-trace-identities.ts +35 -0
  744. package/src/contract/trace/collect-trace-evidence.ts +109 -0
  745. package/src/contract/trace/identity-cache.ts +61 -0
  746. package/src/contract/trace/select-final-attempt.ts +70 -0
  747. package/src/contract/trace/snapshot-html-renderer.ts +136 -0
  748. package/src/contract/trace/snapshot-resolver.ts +66 -0
  749. package/src/contract/trace/snapshot-store.ts +151 -0
  750. package/src/contract/trace/target-identity.ts +104 -0
  751. package/src/contract/trace/test-step-join.ts +104 -0
  752. package/src/contract/trace/trace-binding.ts +56 -0
  753. package/src/contract/trace/trace-file-reader.ts +133 -0
  754. package/src/contract/trace/trace-fingerprint.ts +68 -0
  755. package/src/contract/trace/trace-identity-resolution.ts +74 -0
  756. package/src/contract/trace/trace-run-record.ts +80 -0
  757. package/src/contract/trace/trace-steps.ts +88 -0
  758. package/src/contract/trace/trace-zip-limits.ts +77 -0
  759. package/src/contract/trace/trace-zip-reader.ts +127 -0
  760. package/src/contract/verify-approval-decisions.ts +60 -0
  761. package/src/decisions/append-decision.ts +35 -0
  762. package/src/decisions/confirmed-decision-commands.ts +149 -0
  763. package/src/decisions/decision-file.ts +93 -0
  764. package/src/decisions/decision-identity.ts +73 -0
  765. package/src/decisions/decision-integrity-check.ts +61 -0
  766. package/src/decisions/decision-schema.ts +76 -0
  767. package/src/decisions/decision-source.ts +14 -0
  768. package/src/decisions/exclusive-file-create.ts +42 -0
  769. package/src/decisions/git-head-trust.ts +32 -0
  770. package/src/decisions/human-confirmation.ts +119 -0
  771. package/src/decisions/legacy-waiver-migration.ts +135 -0
  772. package/src/decisions/read-decisions.ts +61 -0
  773. package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
  774. package/src/decisions/waiver-decisions.ts +56 -0
  775. package/src/exporters/csv-exporter.ts +5 -1
  776. package/src/exporters/feature-parser.ts +12 -0
  777. package/src/exporters/matrix/build.ts +62 -18
  778. package/src/exporters/matrix/carry-manual-results.ts +70 -7
  779. package/src/exporters/matrix/export.ts +17 -2
  780. package/src/exporters/matrix/gates.ts +62 -129
  781. package/src/exporters/matrix/render-csv.ts +4 -1
  782. package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
  783. package/src/exporters/matrix/render-xlsx.ts +6 -0
  784. package/src/exporters/matrix/types.ts +9 -1
  785. package/src/exporters/matrix/xlsx-cells.ts +1 -1
  786. package/src/exporters/playwright-report-parser.ts +1 -0
  787. package/src/exporters/scenario-merger.ts +2 -1
  788. package/src/exporters/types.ts +5 -0
  789. package/src/generators/test-generator/code-generator.ts +13 -0
  790. package/src/graph/evaluate-graph.ts +66 -0
  791. package/src/graph/locate-finding.ts +93 -0
  792. package/src/graph/node-decl.ts +72 -0
  793. package/src/graph/nodes/core-node-catalog.ts +15 -0
  794. package/src/graph/nodes/test-case-contract-nodes.ts +74 -0
  795. package/src/graph/nodes/test-case-nodes.ts +68 -0
  796. package/src/graph/nodes/unit-audit-nodes.ts +95 -0
  797. package/src/graph/nodes/unit-contract-node.ts +89 -0
  798. package/src/graph/nodes/unit-design-nodes.ts +89 -0
  799. package/src/graph/nodes/unit-execution-nodes.ts +77 -0
  800. package/src/graph/test-case-identity.ts +75 -0
  801. package/src/graph/test-case-results.ts +90 -0
  802. package/src/graph/test-case-satisfied.ts +55 -0
  803. package/src/graph/test-case-state-shape.ts +62 -0
  804. package/src/graph/test-case-states.ts +84 -0
  805. package/src/graph/unit-artifact-probes.ts +77 -0
  806. package/src/graph/unit-state-facts.ts +112 -0
  807. package/src/harness/audit.ts +46 -11
  808. package/src/harness/catalog/gate-rules.yaml +647 -0
  809. package/src/harness/counted-assertions.ts +33 -0
  810. package/src/harness/defect-draft.ts +115 -0
  811. package/src/harness/defects.ts +94 -0
  812. package/src/harness/gates/audit-gate-terms.ts +80 -0
  813. package/src/harness/gates/audit-gate-verdict.ts +78 -0
  814. package/src/harness/gates/audit-input-hash.ts +55 -0
  815. package/src/harness/gates/audit-report-verification.ts +201 -0
  816. package/src/harness/gates/decisions-hash.ts +42 -0
  817. package/src/harness/gates/delivery-checklist.ts +120 -0
  818. package/src/harness/gates/delivery-decision-gate.ts +139 -0
  819. package/src/harness/gates/delivery-decision-step.ts +89 -0
  820. package/src/harness/gates/gate-override-report.ts +114 -0
  821. package/src/harness/gates/gate-override-scope.ts +66 -0
  822. package/src/harness/gates/gate-override-validation.ts +75 -0
  823. package/src/harness/gates/gate-rule-catalog.ts +82 -0
  824. package/src/harness/gates/gate-terms.ts +59 -0
  825. package/src/harness/gates/in-run-decision-check.ts +99 -0
  826. package/src/harness/gates/journey-gate-inputs.ts +89 -0
  827. package/src/harness/gates/migrated-waiver-review.ts +68 -0
  828. package/src/harness/gates/resolve-rule.ts +94 -0
  829. package/src/harness/gates/unit-gate-overrides.ts +99 -0
  830. package/src/harness/journey.ts +215 -38
  831. package/src/harness/manifest.ts +69 -45
  832. package/src/harness/next-step.ts +60 -170
  833. package/src/harness/parse.ts +40 -13
  834. package/src/harness/provenance.ts +99 -11
  835. package/src/harness/script-check.ts +27 -6
  836. package/src/harness/sensors.ts +73 -47
  837. package/src/harness/triage-signals.ts +46 -0
  838. package/src/harness/triage-unit.ts +113 -0
  839. package/src/harness/triage.ts +127 -0
  840. package/src/harness/viewpoint-ledger.ts +2 -2
  841. package/src/hooks/bash-write-targets.ts +109 -0
  842. package/src/hooks/claude-hook-entry.ts +85 -0
  843. package/src/hooks/claude-transcript-turn.ts +96 -0
  844. package/src/hooks/guard-delivery-contract-rule.ts +110 -0
  845. package/src/hooks/guard-protected-paths.ts +71 -0
  846. package/src/hooks/guard-rules.ts +98 -0
  847. package/src/hooks/guard-tty-spoof-rule.ts +31 -0
  848. package/src/hooks/hand-back-core.ts +112 -0
  849. package/src/hooks/hook-cli-command.ts +17 -0
  850. package/src/hooks/hook-registry.ts +24 -0
  851. package/src/hooks/hook-result-contract.ts +114 -0
  852. package/src/hooks/hook-toggles.ts +66 -0
  853. package/src/hooks/pre-tool-guard-hook.ts +67 -0
  854. package/src/hooks/session-start-unit-state-hook.ts +56 -0
  855. package/src/hooks/stop-next-step-hook.ts +37 -0
  856. package/src/hooks/sungen-project-root.ts +80 -0
  857. package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
  858. package/src/orchestrator/ai-skills/commands.ts +22 -8
  859. package/src/orchestrator/ai-skills/golden-skills.test.ts +23 -0
  860. package/src/orchestrator/assets-drift.ts +12 -5
  861. package/src/orchestrator/claude-hooks-install.ts +168 -0
  862. package/src/orchestrator/lockstep-version.ts +28 -15
  863. package/src/orchestrator/project-initializer.ts +22 -0
  864. package/src/orchestrator/screen-manager.ts +3 -1
  865. package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  866. package/src/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
  867. package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  868. package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  869. package/src/orchestrator/templates/ai-src/commands/create-test.md +14 -16
  870. package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  871. package/src/orchestrator/templates/ai-src/commands/delivery.md +2 -0
  872. package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
  873. package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  874. package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
  875. package/src/orchestrator/templates/ai-src/commands/review.md +2 -0
  876. package/src/orchestrator/templates/ai-src/commands/run-test.md +14 -10
  877. package/src/orchestrator/templates/ai-src/config/claude.md +20 -7
  878. package/src/orchestrator/templates/ai-src/config/copilot.md +20 -7
  879. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  880. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  881. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  882. package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
  883. package/src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
  884. package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
  885. package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
  886. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
  887. package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
  888. package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  889. package/src/utils/safe-yaml-parse.ts +44 -0
@@ -2,10 +2,12 @@
2
2
  * Deterministic quality gates for the Test Case & Coverage Matrix
3
3
  * (docs/spec/delivery-coverage-matrix-spec.md §6).
4
4
  *
5
- * Severity behavior:
5
+ * Severity behavior (the level of each finding comes from the gate-rule catalog through
6
+ * `resolveRule`, never from this file — OES-11.2):
6
7
  * error → blocks any render
7
8
  * review → blocks the official render; `--preview` renders with a DRAFT watermark
8
9
  * warning → prints + renders
10
+ * info → prints (only when a gate-override lowered a soft rule); `off` drops the finding
9
11
  *
10
12
  * The gates recompute every signature part from the .feature — the map is never
11
13
  * trusted for derivable facts, only for the semantic fields (target/intent/oracle).
@@ -14,25 +16,37 @@
14
16
  import { splitVpAndName, extractTestcaseType } from '../feature-parser';
15
17
  import { mapContentFingerprint } from './fingerprint';
16
18
  import { bucketTexts } from './step-buckets';
17
- import { CoverageVariant, MatrixFinding, MAX_VARIANTS_PER_ITEM } from './types';
19
+ import { CoverageVariant, GateId, MatrixFinding, MAX_VARIANTS_PER_ITEM } from './types';
18
20
  import { expandMapRef, BuildInputs } from './build';
21
+ import { CATALOG_GATE_RULES, GateRules } from '../../harness/gates/resolve-rule';
19
22
 
20
23
  export interface GateContext {
21
24
  inputs: BuildInputs;
22
25
  variants: CoverageVariant[];
23
26
  variantsByVp: Map<string, CoverageVariant[]>;
27
+ /** The unit's gate rules (catalog + its gate-overrides); the catalog alone when absent. */
28
+ rules?: GateRules;
24
29
  }
25
30
 
31
+ /** A gate site found its condition: the rule decides the finding's severity, or drops it. */
32
+ type ReportFinding = (rule: string, gate: GateId, message: string, ref?: string) => void;
33
+
26
34
  export function runGates(ctx: GateContext): MatrixFinding[] {
27
35
  const findings: MatrixFinding[] = [];
28
- gateASource(ctx, findings);
29
- gateBMapping(ctx, findings);
30
- gateCAggregation(ctx, findings);
31
- gateDExecutability(ctx, findings);
32
- gateEDrift(ctx, findings);
33
- gateGReviewState(ctx, findings);
34
- gateWWording(ctx, findings);
35
- gateKCategory(ctx, findings);
36
+ const rules = ctx.rules ?? CATALOG_GATE_RULES;
37
+ const report: ReportFinding = (rule, gate, message, ref) => {
38
+ const { severity } = rules.resolve(rule);
39
+ if (severity === 'off') return;
40
+ findings.push({ gate, severity, ...(ref !== undefined ? { ref } : {}), message });
41
+ };
42
+ gateASource(ctx, report);
43
+ gateBMapping(ctx, report);
44
+ gateCAggregation(ctx, report);
45
+ gateDExecutability(ctx, report);
46
+ gateEDrift(ctx, report);
47
+ gateGReviewState(ctx, report);
48
+ gateWWording(ctx, report);
49
+ gateKCategory(ctx, report);
36
50
  return findings;
37
51
  }
38
52
 
@@ -54,16 +68,13 @@ const VP_CATEGORY_RULE: Array<[RegExp, string, string]> = [
54
68
  * have while hiding the security work it does have. Same for `VP-NFR-*`.
55
69
  * (normal vs abnormal stays a judgement call and is never checked.)
56
70
  */
57
- function gateKCategory(ctx: GateContext, findings: MatrixFinding[]): void {
71
+ function gateKCategory(ctx: GateContext, report: ReportFinding): void {
58
72
  for (const g of ctx.inputs.map.groups) {
59
73
  const vs = g.variants.flatMap((ref) => expandMapRef(ref, ctx.variantsByVp));
60
74
  for (const [re, expected, label] of VP_CATEGORY_RULE) {
61
75
  const hits = vs.filter((v) => re.test(v.vpCategory));
62
76
  if (hits.length > 0 && g.category !== expected) {
63
- findings.push({
64
- gate: 'K', severity: 'warning', ref: g.id,
65
- message: `group ${g.id} is \`category: ${g.category}\` but ${hits.length}/${vs.length} of its variants are ${label} scenarios (${hits.slice(0, 3).map((v) => v.vpId).join(', ')}) — use \`category: ${expected}\` or the Coverage grid's ${expected} column stays empty`,
66
- });
77
+ report('matrix.gate-k.category-mismatch', 'K', `group ${g.id} is \`category: ${g.category}\` but ${hits.length}/${vs.length} of its variants are ${label} scenarios (${hits.slice(0, 3).map((v) => v.vpId).join(', ')}) — use \`category: ${expected}\` or the Coverage grid's ${expected} column stays empty`, g.id);
67
78
  }
68
79
  }
69
80
  }
@@ -71,52 +82,40 @@ function gateKCategory(ctx: GateContext, findings: MatrixFinding[]): void {
71
82
 
72
83
  // --- Gate A — source quality ------------------------------------------------
73
84
 
74
- function gateASource(ctx: GateContext, findings: MatrixFinding[]): void {
85
+ function gateASource(ctx: GateContext, report: ReportFinding): void {
75
86
  const { feature, merged } = ctx.inputs;
76
87
 
77
88
  if (bucketTexts(feature.backgroundOrderedSteps, 'when').length > 0 || bucketTexts(feature.backgroundOrderedSteps, 'then').length > 0) {
78
- findings.push({
79
- gate: 'A', severity: 'error',
80
- message: 'Background contains When/Then steps — setup only; move the action/oracle into scenarios',
81
- });
89
+ report('matrix.gate-a.background-when-then', 'A', 'Background contains When/Then steps — setup only; move the action/oracle into scenarios');
82
90
  }
83
91
 
84
92
  const seen = new Map<string, number>();
85
93
  for (const m of merged) {
86
94
  const { vpId } = splitVpAndName(m.feature.name);
87
95
  if (!vpId) {
88
- findings.push({
89
- gate: 'A', severity: 'error', ref: m.feature.name,
90
- message: `scenario "${m.feature.name}" has no VP-id prefix — matrix variants must be addressable`,
91
- });
96
+ report('matrix.gate-a.no-vp-id', 'A', `scenario "${m.feature.name}" has no VP-id prefix — matrix variants must be addressable`, m.feature.name);
92
97
  continue;
93
98
  }
94
99
  seen.set(vpId, (seen.get(vpId) ?? 0) + 1);
95
100
 
96
101
  const isManual = extractTestcaseType(m.feature.tags) === 'Manual';
97
102
  if (m.resolvedExpected.length === 0) {
98
- findings.push({
99
- gate: 'A', severity: 'error', ref: vpId,
100
- message: isManual
101
- ? `manual scenario ${vpId} has no observable oracle (no Then steps and no Observable/Oracle comment lines)`
102
- : `scenario ${vpId} has no Then step — a variant without an observable oracle cannot be delivered`,
103
- });
103
+ report('matrix.gate-a.no-oracle', 'A', isManual
104
+ ? `manual scenario ${vpId} has no observable oracle (no Then steps and no Observable/Oracle comment lines)`
105
+ : `scenario ${vpId} has no Then step — a variant without an observable oracle cannot be delivered`, vpId);
104
106
  }
105
107
  if (m.unlabeledManualOracle) {
106
- findings.push({
107
- gate: 'A', severity: 'warning', ref: vpId,
108
- message: `manual oracle found only in an unlabeled comment — exported verbatim into Expected; write the \`# Tester verifies:\` block as numbered "N. Observable: …" lines`,
109
- });
108
+ report('matrix.gate-a.unlabeled-manual-oracle', 'A', `manual oracle found only in an unlabeled comment — exported verbatim into Expected; write the \`# Tester verifies:\` block as numbered "N. Observable: …" lines`, vpId);
110
109
  }
111
110
  }
112
111
  for (const [vpId, n] of seen) {
113
- if (n > 1) findings.push({ gate: 'A', severity: 'error', ref: vpId, message: `duplicate VP-id ${vpId} (${n} scenarios)` });
112
+ if (n > 1) report('matrix.gate-a.duplicate-vp-id', 'A', `duplicate VP-id ${vpId} (${n} scenarios)`, vpId);
114
113
  }
115
114
  }
116
115
 
117
116
  // --- Gate B — mapping completeness -------------------------------------------
118
117
 
119
- function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
118
+ function gateBMapping(ctx: GateContext, report: ReportFinding): void {
120
119
  const { map } = ctx.inputs;
121
120
  const { variants, variantsByVp } = ctx;
122
121
 
@@ -126,10 +125,7 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
126
125
  for (const ref of g.variants) {
127
126
  const expanded = expandMapRef(ref, variantsByVp);
128
127
  if (expanded.length === 0) {
129
- findings.push({
130
- gate: 'B', severity: 'error', ref: g.id,
131
- message: `group ${g.id} references ${ref} which matches no scenario/@cases row in the .feature`,
132
- });
128
+ report('matrix.gate-b.ref-matches-nothing', 'B', `group ${g.id} references ${ref} which matches no scenario/@cases row in the .feature`, g.id);
133
129
  continue;
134
130
  }
135
131
  for (const v of expanded) {
@@ -142,10 +138,7 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
142
138
 
143
139
  for (const [ref, groups] of owners) {
144
140
  if (groups.length > 1) {
145
- findings.push({
146
- gate: 'B', severity: 'error', ref,
147
- message: `variant ${ref} belongs to ${groups.length} groups (${groups.join(', ')}) — exactly one required`,
148
- });
141
+ report('matrix.gate-b.double-mapped', 'B', `variant ${ref} belongs to ${groups.length} groups (${groups.join(', ')}) — exactly one required`, ref);
149
142
  }
150
143
  }
151
144
 
@@ -153,32 +146,23 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
153
146
  const grouped = owners.has(v.ref);
154
147
  const disposed = v.vpId in map.dispositions;
155
148
  if (!grouped && !disposed) {
156
- findings.push({
157
- gate: 'B', severity: 'error', ref: v.ref,
158
- message: `variant ${v.ref} is in no group and has no disposition — 100% source disposition is required`,
159
- });
149
+ report('matrix.gate-b.unmapped', 'B', `variant ${v.ref} is in no group and has no disposition — 100% source disposition is required`, v.ref);
160
150
  }
161
151
  if (grouped && disposed) {
162
- findings.push({
163
- gate: 'B', severity: 'error', ref: v.ref,
164
- message: `variant ${v.ref} is grouped AND disposed (${map.dispositions[v.vpId].as}) — pick one`,
165
- });
152
+ report('matrix.gate-b.grouped-and-disposed', 'B', `variant ${v.ref} is grouped AND disposed (${map.dispositions[v.vpId].as}) — pick one`, v.ref);
166
153
  }
167
154
  }
168
155
 
169
156
  for (const vpId of Object.keys(map.dispositions)) {
170
157
  if (!variantsByVp.has(vpId)) {
171
- findings.push({
172
- gate: 'B', severity: 'warning', ref: vpId,
173
- message: `disposition for ${vpId} matches no scenario (stale entry?)`,
174
- });
158
+ report('matrix.gate-b.stale-disposition', 'B', `disposition for ${vpId} matches no scenario (stale entry?)`, vpId);
175
159
  }
176
160
  }
177
161
  }
178
162
 
179
163
  // --- Gate C — aggregation safety ---------------------------------------------
180
164
 
181
- function gateCAggregation(ctx: GateContext, findings: MatrixFinding[]): void {
165
+ function gateCAggregation(ctx: GateContext, report: ReportFinding): void {
182
166
  const { map } = ctx.inputs;
183
167
  const { variantsByVp } = ctx;
184
168
 
@@ -207,47 +191,32 @@ function gateCAggregation(ctx: GateContext, findings: MatrixFinding[]): void {
207
191
  for (const [label, keyOf] of hard) {
208
192
  const distinct = new Set(vs.map(keyOf));
209
193
  if (distinct.size > 1) {
210
- findings.push({
211
- gate: 'C', severity: 'error', ref: g.id,
212
- message: `group ${g.id} mixes ${label}s (${[...distinct].join(' vs ')}) — mandatory split`,
213
- });
194
+ report('matrix.gate-c.mixed-layers', 'C', `group ${g.id} mixes ${label}s (${[...distinct].join(' vs ')}) — mandatory split`, g.id);
214
195
  }
215
196
  }
216
197
 
217
198
  // Heuristic signature parts — REVIEW_REQUIRED (equivalence was inferred, not declared).
218
199
  const preProfiles = new Set(vs.map((v) => v.preconditionProfile));
219
200
  if (!heuristicsConfirmed && preProfiles.size > 1) {
220
- findings.push({
221
- gate: 'C', severity: 'review', ref: g.id,
222
- message: `group ${g.id} variants have different precondition profiles — confirm the grouping is safe or split`,
223
- });
201
+ report('matrix.gate-c.precondition-profiles', 'C', `group ${g.id} variants have different precondition profiles — confirm the grouping is safe or split`, g.id);
224
202
  }
225
203
  const oracleShapes = new Set(vs.map((v) => v.oracleShape.join(' ; ')));
226
204
  if (!heuristicsConfirmed && oracleShapes.size > 1) {
227
- findings.push({
228
- gate: 'C', severity: 'review', ref: g.id,
229
- message: `group ${g.id} variants assert different oracle shapes (${oracleShapes.size} shapes) — confirm they are one oracle family`,
230
- });
205
+ report('matrix.gate-c.oracle-shapes', 'C', `group ${g.id} variants assert different oracle shapes (${oracleShapes.size} shapes) — confirm they are one oracle family`, g.id);
231
206
  }
232
207
  if (!heuristicsConfirmed && vs.some((v) => v.procedureProfile === 'sequence')) {
233
- findings.push({
234
- gate: 'C', severity: 'review', ref: g.id,
235
- message: `group ${g.id} contains a sequence-sensitive scenario — ordered flows stay solo items unless QA confirms`,
236
- });
208
+ report('matrix.gate-c.sequence-sensitive', 'C', `group ${g.id} contains a sequence-sensitive scenario — ordered flows stay solo items unless QA confirms`, g.id);
237
209
  }
238
210
 
239
211
  if (vs.length > MAX_VARIANTS_PER_ITEM) {
240
- findings.push({
241
- gate: 'C', severity: 'warning', ref: g.id,
242
- message: `group ${g.id} has ${vs.length} variants (> ${MAX_VARIANTS_PER_ITEM}) — consider splitting for reviewability`,
243
- });
212
+ report('matrix.gate-c.too-many-variants', 'C', `group ${g.id} has ${vs.length} variants (> ${MAX_VARIANTS_PER_ITEM}) — consider splitting for reviewability`, g.id);
244
213
  }
245
214
  }
246
215
  }
247
216
 
248
217
  // --- Gate D — manual executability -------------------------------------------
249
218
 
250
- function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
219
+ function gateDExecutability(ctx: GateContext, report: ReportFinding): void {
251
220
  const { map, testData, feature } = ctx.inputs;
252
221
  const { variantsByVp } = ctx;
253
222
 
@@ -262,16 +231,10 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
262
231
  || bucketTexts(feature.backgroundOrderedSteps, 'given').length > 0
263
232
  || v.apiCalls > 0;
264
233
  if (!hasPrecondition) {
265
- findings.push({
266
- gate: 'D', severity: 'error', ref: v.ref,
267
- message: `${v.ref}: no precondition (no Background, auth tag, or Given) — a tester cannot establish the start state`,
268
- });
234
+ report('matrix.gate-d.no-precondition', 'D', `${v.ref}: no precondition (no Background, auth tag, or Given) — a tester cannot establish the start state`, v.ref);
269
235
  }
270
236
  if (v.trigger.length === 0) {
271
- findings.push({
272
- gate: 'D', severity: 'error', ref: v.ref,
273
- message: `${v.ref}: no action/trigger (no When steps${v.mode === 'manual' ? ' and no Setup/Action comment lines' : ''})`,
274
- });
237
+ report('matrix.gate-d.no-trigger', 'D', `${v.ref}: no action/trigger (no When steps${v.mode === 'manual' ? ' and no Setup/Action comment lines' : ''})`, v.ref);
275
238
  }
276
239
  // Oracle emptiness is Gate A (source) — not repeated here.
277
240
  }
@@ -289,10 +252,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
289
252
  const inRows = vs.some((v) => v.caseLabel !== undefined); // dataset rows carry their own columns
290
253
  const atRuntime = runtime.has(varName) || runtime.has(varName.split(/[.[]/)[0]);
291
254
  if (!inRows && !atRuntime && (!testData || !(varName in testData))) {
292
- findings.push({
293
- gate: 'D', severity: 'error', ref: vpId,
294
- message: `${vpId}: {{${varName}}} does not resolve in test-data — the variant is not reproducible`,
295
- });
255
+ report('matrix.gate-d.unresolved-var', 'D', `${vpId}: {{${varName}}} does not resolve in test-data — the variant is not reproducible`, vpId);
296
256
  }
297
257
  }
298
258
  }
@@ -304,10 +264,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
304
264
  const rendered = [...v.precondition, ...v.trigger, ...v.oracle, ...v.verification, ...v.data];
305
265
  const token = rendered.map((t) => t.match(/\{\{[^}]*\}\}/)).find(Boolean);
306
266
  if (token) {
307
- findings.push({
308
- gate: 'D', severity: 'error', ref: v.ref,
309
- message: `${v.ref}: unresolved template token ${token[0]} remains in the rendered output — the export is not deterministic for a tester`,
310
- });
267
+ report('matrix.gate-d.template-token-remains', 'D', `${v.ref}: unresolved template token ${token[0]} remains in the rendered output — the export is not deterministic for a tester`, v.ref);
311
268
  }
312
269
  }
313
270
  }
@@ -315,7 +272,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
315
272
 
316
273
  // --- Gate E — drift (stale approval) ------------------------------------------
317
274
 
318
- function gateEDrift(ctx: GateContext, findings: MatrixFinding[]): void {
275
+ function gateEDrift(ctx: GateContext, report: ReportFinding): void {
319
276
  const { map } = ctx.inputs;
320
277
  const { variantsByVp } = ctx;
321
278
 
@@ -326,15 +283,9 @@ function gateEDrift(ctx: GateContext, findings: MatrixFinding[]): void {
326
283
  const liveMap = mapContentFingerprint(map.groups, map.dispositions);
327
284
  if (map.groups.some((g) => g.review === 'approved')) {
328
285
  if (!stampedMap) {
329
- findings.push({
330
- gate: 'E', severity: 'review',
331
- message: 'the delivery map has no stamped content fingerprint — run `sungen delivery --approve` to record the reviewed wording',
332
- });
286
+ report('matrix.gate-e.map-unstamped', 'E', 'the delivery map has no stamped content fingerprint — run `sungen delivery --approve` to record the reviewed wording');
333
287
  } else if (stampedMap !== liveMap) {
334
- findings.push({
335
- gate: 'E', severity: 'review',
336
- message: 'the delivery map wording/grouping changed since approval — re-review, then `sungen delivery --approve`',
337
- });
288
+ report('matrix.gate-e.map-drift', 'E', 'the delivery map wording/grouping changed since approval — re-review, then `sungen delivery --approve`');
338
289
  }
339
290
  }
340
291
 
@@ -345,15 +296,9 @@ function gateEDrift(ctx: GateContext, findings: MatrixFinding[]): void {
345
296
  for (const v of vs) {
346
297
  const stamped = map.fingerprints[v.ref] ?? map.fingerprints[v.vpId];
347
298
  if (!stamped) {
348
- findings.push({
349
- gate: 'E', severity: 'review', ref: g.id,
350
- message: `group ${g.id}: ${v.ref} has no stamped fingerprint — run \`sungen delivery --approve\` after review`,
351
- });
299
+ report('matrix.gate-e.variant-unstamped', 'E', `group ${g.id}: ${v.ref} has no stamped fingerprint — run \`sungen delivery --approve\` after review`, g.id);
352
300
  } else if (stamped !== v.fingerprint) {
353
- findings.push({
354
- gate: 'E', severity: 'review', ref: g.id,
355
- message: `group ${g.id}: ${v.ref} changed since approval (fingerprint drift) — re-review the grouping`,
356
- });
301
+ report('matrix.gate-e.variant-drift', 'E', `group ${g.id}: ${v.ref} changed since approval (fingerprint drift) — re-review the grouping`, g.id);
357
302
  }
358
303
  }
359
304
  }
@@ -370,30 +315,21 @@ const WORDING_SMELLS: Array<[RegExp, string]> = [
370
315
  [/\[[^\]]+\]/, 'a [selector-style] reference — use the visible UI label'],
371
316
  ];
372
317
 
373
- function gateWWording(ctx: GateContext, findings: MatrixFinding[]): void {
318
+ function gateWWording(ctx: GateContext, report: ReportFinding): void {
374
319
  for (const g of ctx.inputs.map.groups) {
375
320
  const variantCount = g.variants.flatMap((ref) => expandMapRef(ref, ctx.variantsByVp)).length;
376
321
  // Without a digest the parent row can only list variant refs — a reviewer
377
322
  // then has to expand the item to learn which dimensions it covers.
378
323
  if (variantCount > 3 && !g.dimensions) {
379
- findings.push({
380
- gate: 'W', severity: 'warning', ref: g.id,
381
- message: `group ${g.id} has ${variantCount} variants and no \`dimensions:\` digest — add a short one (e.g. "required ×3 · format ×9") so the collapsed view stays informative`,
382
- });
324
+ report('matrix.gate-w.dimensions-missing', 'W', `group ${g.id} has ${variantCount} variants and no \`dimensions:\` digest — add a short one (e.g. "required ×3 · format ×9") so the collapsed view stays informative`, g.id);
383
325
  }
384
326
  if (g.dimensions && g.dimensions.length > 120) {
385
- findings.push({
386
- gate: 'W', severity: 'warning', ref: g.id,
387
- message: `group ${g.id} \`dimensions:\` is ${g.dimensions.length} chars — keep the digest short (≤120)`,
388
- });
327
+ report('matrix.gate-w.dimensions-long', 'W', `group ${g.id} \`dimensions:\` is ${g.dimensions.length} chars — keep the digest short (≤120)`, g.id);
389
328
  }
390
329
  for (const [field, text] of ([['intent', g.intent], ['oracle', g.oracle], ...(g.dimensions ? [['dimensions', g.dimensions] as const] : [])] as const)) {
391
330
  for (const [re, what] of WORDING_SMELLS) {
392
331
  if (re.test(text)) {
393
- findings.push({
394
- gate: 'W', severity: 'warning', ref: g.id,
395
- message: `group ${g.id} ${field} contains ${what}`,
396
- });
332
+ report('matrix.gate-w.wording-smell', 'W', `group ${g.id} ${field} contains ${what}`, g.id);
397
333
  }
398
334
  }
399
335
  }
@@ -402,12 +338,9 @@ function gateWWording(ctx: GateContext, findings: MatrixFinding[]): void {
402
338
 
403
339
  // --- Gate G — review state -----------------------------------------------------
404
340
 
405
- function gateGReviewState(ctx: GateContext, findings: MatrixFinding[]): void {
341
+ function gateGReviewState(ctx: GateContext, report: ReportFinding): void {
406
342
  const proposed = ctx.inputs.map.groups.filter((g) => g.review !== 'approved');
407
343
  if (proposed.length > 0) {
408
- findings.push({
409
- gate: 'G', severity: 'review',
410
- message: `${proposed.length} group(s) still \`proposed\` (${proposed.slice(0, 5).map((g) => g.id).join(', ')}${proposed.length > 5 ? ', …' : ''}) — approve them or render with --preview`,
411
- });
344
+ report('matrix.gate-g.groups-proposed', 'G', `${proposed.length} group(s) still \`proposed\` (${proposed.slice(0, 5).map((g) => g.id).join(', ')}${proposed.length > 5 ? ', …' : ''}) — approve them or render with --preview`);
412
345
  }
413
346
  }
@@ -11,6 +11,7 @@ import { variantState } from './build';
11
11
  import { coverageSummary, itemModeLabel, itemResultLabel } from './render-xlsx';
12
12
  import { MatrixModel } from './types';
13
13
  import { formatTestOutcome, resultTotals } from './result-totals';
14
+ import { overrideManifestLines } from '../../harness/gates/gate-override-report';
14
15
 
15
16
  const HEADERS = [
16
17
  'Level', 'ID', 'Target', 'Test Intent / Condition', 'Category', 'Priority',
@@ -36,6 +37,8 @@ export function renderMatrixCsv(model: MatrixModel): string {
36
37
  lines.push(`# Test Case & Coverage Matrix — ${model.unit}`);
37
38
  // Two different facts, two different words: the map's design REVIEW state, and the runs' OUTCOME.
38
39
  lines.push(`# delivery items: ${model.manifest.itemCount} · coverage variants: ${model.manifest.variantCount} · review: ${model.manifest.approvalState} (design) · test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
40
+ // OES-11.6: a CSV-only reader still learns which client-visible gate overrides the delivery leaned on.
41
+ lines.push(...overrideManifestLines(model.gateOverrides));
39
42
  lines.push(HEADERS.map(esc).join(','));
40
43
 
41
44
  for (const item of model.items) {
@@ -78,7 +81,7 @@ export function renderMatrixCsv(model: MatrixModel): string {
78
81
  v.mode === 'manual' ? 'Manual' : 'Auto',
79
82
  v.traces.join(' '),
80
83
  variantState(v),
81
- isoDate(v.result?.startTime),
84
+ v.manualDate ?? isoDate(v.result?.startTime),
82
85
  // Redact BEFORE clipping — a clip boundary must never split a secret in
83
86
  // a way that lets its prefix through. Same denylist as the Note column.
84
87
  v.result?.error ? clipNoteField(redactSecrets(String(v.result.error), model.secretValues)) : '',
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Sheet 5 — "Gate overrides" (OES-11.6): which quality gate a human relaxed for this unit, why, and
3
+ * whether the delivery leaned on it (`PASS (overridden)`). Present only when a gate-override touches
4
+ * the unit, so a workbook without overrides is unchanged.
5
+ *
6
+ * `visibility: internal` decisions never reach this sheet — the model carries only client-visible
7
+ * rows plus a count of the withheld ones (red-team #14).
8
+ */
9
+ import * as ExcelJS from 'exceljs';
10
+ import { MatrixModel } from './types';
11
+ import { dataCell, headerCell } from './xlsx-cells';
12
+
13
+ export const GATE_OVERRIDES_SHEET = 'Gate overrides';
14
+
15
+ const COLUMNS: Array<{ label: string; width: number }> = [
16
+ { label: 'Rule', width: 34 }, { label: 'Catalog level', width: 13 }, { label: 'Override level', width: 14 },
17
+ { label: 'Scope', width: 22 }, { label: 'Status', width: 12 }, { label: 'Changed an outcome', width: 12 },
18
+ { label: 'Reason', width: 60 }, { label: 'Decision', width: 20 }, { label: 'Recorded by', width: 18 }, { label: 'Recorded at', width: 24 },
19
+ ];
20
+
21
+ export function addGateOverridesSheet(wb: ExcelJS.Workbook, model: MatrixModel): void {
22
+ const o = model.gateOverrides;
23
+ if (!o) return;
24
+ const ws = wb.addWorksheet(GATE_OVERRIDES_SHEET);
25
+ COLUMNS.forEach((c, i) => { ws.getColumn(i + 1).width = c.width; });
26
+ ws.getCell('A1').value = 'Gate status';
27
+ ws.getCell('A1').font = { bold: true };
28
+ ws.getCell('B1').value = o.status;
29
+ ws.getCell('B1').font = { bold: true };
30
+ ws.getCell('A2').value = 'Internal decisions (counted, not listed)';
31
+ ws.getCell('B2').value = o.internalCount;
32
+ const header = ws.getRow(4);
33
+ COLUMNS.forEach((c, i) => headerCell(header.getCell(i + 1), c.label));
34
+ o.rows.forEach((r, n) => {
35
+ const row = ws.getRow(5 + n);
36
+ [r.rule, r.catalogSeverity ?? '', r.severity, r.scope, r.status, r.triggered ? 'yes' : 'no', r.reason, r.decisionId, r.by, r.validFrom]
37
+ .forEach((v, i) => dataCell(row.getCell(i + 1), v));
38
+ });
39
+ let next = 5 + o.rows.length;
40
+ if (o.rows.length === 0) ws.getCell(`A${next++}`).value = 'No client-visible gate override.';
41
+ const a = o.acceptedInRun;
42
+ if (a) {
43
+ // L5: who accepted decisions recorded during the run, on a terminal, for this delivery.
44
+ ws.getCell(`A${next + 1}`).value = 'In-run decisions accepted';
45
+ ws.getCell(`A${next + 1}`).font = { bold: true };
46
+ ws.getCell(`B${next + 1}`).value = `by ${a.by} at ${a.at}`;
47
+ ws.getCell(`A${next + 2}`).value = 'Decisions';
48
+ ws.getCell(`B${next + 2}`).value = [a.ids.join(', '), a.internalCount ? `${a.internalCount} internal (ids withheld)` : ''].filter(Boolean).join(' · ') || '—';
49
+ }
50
+ }
@@ -8,6 +8,7 @@
8
8
  * 3. Manual — the cases a person runs.
9
9
  * 4. Coverage — requirement coverage, the target × category grid,
10
10
  * dispositions and the generation manifest, over the whole model.
11
+ * 5. Gate overrides — only when a gate-override touches the unit (client rows only).
11
12
  *
12
13
  * Auto and Manual are always both created, even when one side is empty: the
13
14
  * Overview then always reads the same two rows, and QA has a place to add
@@ -20,6 +21,7 @@ import { DeliveryItem, MatrixModel } from './types';
20
21
  import { addTestcaseSheet } from './render-testcase-sheet';
21
22
  import { addCoverageSheet } from './render-coverage-sheet';
22
23
  import { addMatrixOverviewSheet, SheetProjection } from './render-overview-sheet';
24
+ import { addGateOverridesSheet } from './render-gate-overrides-sheet';
23
25
 
24
26
  // The CSV renderer and the tests import these from here — they moved to
25
27
  // `item-labels.ts` when this module was split, and stay reachable at the old path.
@@ -74,6 +76,9 @@ export function projectItems(model: MatrixModel, mode: 'auto' | 'manual'): Deliv
74
76
 
75
77
  export function renderMatrixXlsx(model: MatrixModel, sungenVersion?: string): ExcelJS.Workbook {
76
78
  const wb = new ExcelJS.Workbook();
79
+ // Every total and roll-up is a formula with a cached result. The cache is what a preview
80
+ // (GitHub, Drive, QuickLook) shows; a spreadsheet app recomputes on open as well (#891).
81
+ wb.calcProperties.fullCalcOnLoad = true;
77
82
  const sheets: SheetProjection[] = [
78
83
  { sheetName: 'Auto', items: projectItems(model, 'auto') },
79
84
  { sheetName: 'Manual', items: projectItems(model, 'manual') },
@@ -82,5 +87,6 @@ export function renderMatrixXlsx(model: MatrixModel, sungenVersion?: string): Ex
82
87
  addMatrixOverviewSheet(wb, model, sheets, sungenVersion);
83
88
  for (const s of sheets) addTestcaseSheet(wb, s.sheetName, model, s.items, sungenVersion);
84
89
  addCoverageSheet(wb, model, sungenVersion);
90
+ addGateOverridesSheet(wb, model); // only when a gate-override touches the unit (OES-11.6)
85
91
  return wb;
86
92
  }
@@ -147,6 +147,11 @@ export interface CoverageVariant {
147
147
  fingerprint: string;
148
148
  /** Execution result, when the run report has one for this variant. */
149
149
  result?: PlaywrightResult;
150
+ /** A Manual variant's result as the tester recorded it in the previous workbook, carried
151
+ * BEFORE rendering so every total, roll-up, the CSV and the CLI count it (#891). */
152
+ manualState?: VariantState;
153
+ /** The Executed Date the tester recorded with it (yyyy-mm-dd, or as typed). */
154
+ manualDate?: string;
150
155
  }
151
156
 
152
157
  export type ItemResult = 'passed' | 'failed' | 'blocked' | 'partial' | 'not_run' | 'na';
@@ -214,7 +219,8 @@ export interface RequirementCoverage {
214
219
  // ---------------------------------------------------------------------------
215
220
 
216
221
  export type GateId = 'A' | 'B' | 'C' | 'D' | 'E' | 'G' | 'K' | 'R' | 'W';
217
- export type FindingSeverity = 'error' | 'review' | 'warning';
222
+ /** `info` appears only when a gate-override lowered a soft rule (OES-11.3). */
223
+ export type FindingSeverity = 'error' | 'review' | 'warning' | 'info';
218
224
 
219
225
  export interface MatrixFinding {
220
226
  gate: GateId;
@@ -260,6 +266,8 @@ export interface MatrixModel {
260
266
  /** Who ran the suite and against what — fills Test Executor / Test Environment on rows that
261
267
  * ran (#850). Absent when the caller has no run context (gates-only paths). */
262
268
  runEnv?: import('../run-environment').RunEnvironment;
269
+ /** Gate overrides touching the unit (OES-11.6) — client-visible rows only; internal ones are only counted. */
270
+ gateOverrides?: import('../../harness/gates/gate-override-report').DeliverableGateOverrides;
263
271
  }
264
272
 
265
273
  /** Complexity warning threshold (rules draft Gate I; raised for compact grouping) — echoed in the manifest. */
@@ -49,7 +49,7 @@ export function draftBanner(ws: ExcelJS.Worksheet, model: MatrixModel): void {
49
49
  if (model.manifest.approvalState !== 'draft') return;
50
50
  ws.mergeCells('A5:H5');
51
51
  const c = ws.getCell('A5');
52
- c.value = 'DRAFT — NOT APPROVED FOR OFFICIAL DELIVERY (review-required findings or proposed groups remain)';
52
+ c.value = 'DRAFT — NOT APPROVED FOR OFFICIAL DELIVERY (review-required findings, proposed groups, or an audit that does not pass)';
53
53
  c.font = { bold: true, size: 11, name: ARIAL_FONT, color: { argb: 'FFFFFFFF' } };
54
54
  c.fill = { type: 'pattern', pattern: 'solid', fgColor: DRAFT_RED };
55
55
  c.alignment = { horizontal: 'center', vertical: 'middle' };
@@ -161,6 +161,7 @@ export function loadPlaywrightReport(reportPath: string): Map<string, Playwright
161
161
  errorMessages: distinct.length > 0 ? distinct : undefined,
162
162
  tracePath: trace,
163
163
  projectName: test?.projectName,
164
+ attempts: results.length || undefined,
164
165
  });
165
166
  }
166
167
  return result;
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { FeatureMetadata, OrderedStep, ScenarioMetadata, SpecFileData, SpecTest } from './types';
12
- import { isStepsBaseScenario, isSampleScaffoldScenario, extractTestcaseType } from './feature-parser';
12
+ import { isStepsBaseScenario, isSampleScaffoldScenario, isHookScenario, extractTestcaseType } from './feature-parser';
13
13
  import { SCENARIO_ID } from './feature-parser';
14
14
  import { extractUnlabeledOracle, onlyPresenceAssertions } from './manual-hybrid-oracle';
15
15
 
@@ -139,6 +139,7 @@ export function mergeFeatureAndSpec(
139
139
  for (const scenario of feature.scenarios) {
140
140
  if (isStepsBaseScenario(scenario)) continue; // skip @steps base scenarios
141
141
  if (isSampleScaffoldScenario(scenario)) continue; // skip default sample
142
+ if (isHookScenario(scenario)) continue; // skip @beforeAll/@afterEach/@afterAll hooks
142
143
 
143
144
  const specTest = findMatchingSpecTest(scenario, spec.tests, feature.scenarios);
144
145
  const base = scenario.extendsName ? stepsBaseByName.get(scenario.extendsName) : undefined;
@@ -95,6 +95,9 @@ export interface ScenarioMetadata {
95
95
  * as Gherkin steps — the merger parses these into Steps/Expected for the report.
96
96
  */
97
97
  comments?: string[];
98
+ /** Set for a `@beforeAll` / `@afterEach` / `@afterAll` scenario — a hook the compiler emits as
99
+ * `test.beforeAll()` etc., never a test case (#880). */
100
+ hookType?: 'beforeAll' | 'afterEach' | 'afterAll';
98
101
  }
99
102
 
100
103
  /**
@@ -134,6 +137,8 @@ export interface PlaywrightResult {
134
137
  errorMessages?: string[];
135
138
  tracePath?: string;
136
139
  projectName?: string;
140
+ /** How many attempts the test took (retries + 1). A pass with attempts > 1 is flaky. */
141
+ attempts?: number;
137
142
  }
138
143
 
139
144
  /**
@@ -9,6 +9,7 @@ import { parseResetTier, DEFAULT_RESET_TIER } from './reset-tier';
9
9
  import { capabilityRegistry } from '../../capabilities/registry';
10
10
  import { discoverAndRegisterCapabilities } from '../../capabilities/discover';
11
11
  import { readCapabilities } from '../../harness/capability';
12
+ import { isHandWritten } from '../../harness/parse';
12
13
  import { parseManualComments } from '../../exporters/scenario-merger';
13
14
  import { isPresencePlaceholderHybrid } from '../../exporters/manual-hybrid-oracle';
14
15
  import { findSyntaxError } from './utils/spec-syntax-check';
@@ -780,6 +781,12 @@ export class CodeGenerator {
780
781
 
781
782
  const renderedScenarios: Array<{ code: string; authRole?: string; noAuth?: boolean }> = [];
782
783
  for (const scenario of feature.scenarios) {
784
+ // @free / @impl:code / @proposed: implemented by hand-written code and proven by its trace —
785
+ // never compiled (DOS-14.8). The same predicate script-check uses, so the counts agree.
786
+ if (!scenario.stepsName && !scenario.hookType && isHandWritten([...(feature.tags || []), ...(scenario.tags || [])], feature.sourceFile)) {
787
+ console.log(` ⊘ Skipped hand-written scenario: ${scenario.name}`);
788
+ continue;
789
+ }
783
790
  if (isManual(scenario.tags)) {
784
791
  // SG-W008 — two-direction rule for @manual scenarios:
785
792
  // • HAS Gherkin steps → the Gherkin must be COMPLETE: Given/When/Then. A dangling
@@ -1458,6 +1465,12 @@ export class CodeGenerator {
1458
1465
  console.log(`⊘ Skipped @manual feature: ${feature.name}`);
1459
1466
  continue;
1460
1467
  }
1468
+ // A feature whose scenarios are all hand-written (a derived *.free.feature) emits no spec.
1469
+ const own = feature.scenarios.filter((sc) => !sc.stepsName && !sc.hookType);
1470
+ if (own.length && own.every((sc) => isHandWritten([...(feature.tags || []), ...(sc.tags || [])], feature.sourceFile))) {
1471
+ console.log(`⊘ Skipped hand-written feature: ${feature.name}`);
1472
+ continue;
1473
+ }
1461
1474
 
1462
1475
  try {
1463
1476
  const generatedTest = await this.generateTest(feature, outputDir);