@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
@@ -0,0 +1,61 @@
1
+ /**
2
+ * `sungen contract derive --screen <u> [--grep <re>] [--json]` (DOS-14.8, phase 08): free tests'
3
+ * traces → `features/<u>.free.feature`, every scenario `@free @proposed`, deterministic, no LLM.
4
+ *
5
+ * exit 0 written, unchanged, every scenario already approved, or a mobile project (not supported yet)
6
+ * exit 1 nothing to derive (no admissible trace — each skipped test says why, #932), refused (a
7
+ * secret or a machine path would have been written — nothing was), or an error
8
+ */
9
+ import type { Command } from 'commander';
10
+ import * as path from 'path';
11
+ import { deriveFreeFeature, DeriveResult, nothingDerived } from '../../contract/derive-free-feature';
12
+ import { registeredTraceResolver } from '../../contract/resolve-unit-trace-identities';
13
+ import { resolveContractUnit } from '../../contract/contract-units';
14
+
15
+ function print(r: DeriveResult, unit: string): void {
16
+ const L = console.log;
17
+ const rel = path.relative(process.cwd(), r.file);
18
+ L('');
19
+ L(`━━━ Contract derive: ${unit} — free tests' traces → ${rel} ━━━`);
20
+ L('');
21
+ if (r.note) L(` ⚠ ${r.note}`);
22
+ for (const s of r.scenarios) L(` + ${s.title} (${s.steps} steps${s.low ? `, ${s.low} low identity` : ''}${s.opaque ? `, ${s.opaque} opaque` : ''})`);
23
+ for (const s of r.skipped) L(` - ${s.id} skipped: ${s.reason}`);
24
+ if (r.refused?.length) {
25
+ L(` ✗ Refused — nothing was written. ${r.refused.length} likely secret(s) / machine path(s):`);
26
+ for (const h of r.refused) L(` ${h.where} — ${h.reason}`);
27
+ L(' Move the value into test-data (or an env overlay) and use it from there, then derive again.');
28
+ } else if (r.written) {
29
+ L(` ✓ Wrote ${rel}. Review the steps (they ARE the contract), then QA approves on a terminal:`);
30
+ L(` sungen contract approve --screen ${unit}`);
31
+ L(' After approval, re-run the free tests (trace: "on") — a trace older than the contract proves nothing.');
32
+ } else if (r.scenarios.length) {
33
+ L(` = ${rel} is already up to date.`);
34
+ } else if (nothingDerived(r)) {
35
+ L(` ✗ Nothing to derive: no admissible trace of a test for ${unit}${r.skipped.length ? ' (each skipped test above says why)' : ' (try --grep)'}.`);
36
+ }
37
+ L('');
38
+ }
39
+
40
+ export function registerDeriveCommand(contract: Command): void {
41
+ contract
42
+ .command('derive')
43
+ .description("Write features/<unit>.free.feature (@free @proposed) from the free tests' traces — deterministic, no LLM")
44
+ .option('-s, --screen <name>', 'Screen / flow / api unit name')
45
+ .option('--grep <regex>', 'Which tests, matched against "<id> <title> <file>" (default: tests whose file is named after the unit)')
46
+ .option('--json', 'Output the result as JSON')
47
+ .action(async (options) => {
48
+ try {
49
+ if (!options.screen) throw new Error('Provide --screen <name>');
50
+ const unit = resolveContractUnit(process.cwd(), String(options.screen));
51
+ const r = await deriveFreeFeature({
52
+ projectRoot: process.cwd(), unit, grep: options.grep ? String(options.grep) : undefined, resolver: registeredTraceResolver() ?? null,
53
+ });
54
+ if (options.json) console.log(JSON.stringify(r, null, 2)); else print(r, unit.name);
55
+ process.exit(r.refused?.length || nothingDerived(r) ? 1 : 0);
56
+ } catch (error) {
57
+ console.error('Error:', error instanceof Error ? error.message : error);
58
+ process.exit(1);
59
+ }
60
+ });
61
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * `sungen contract approve | check` — the Test Contract (DOS-14, phase 06a).
3
+ *
4
+ * approve --screen <u> [--scenario <id>] [--reason <text>]
5
+ * a human types a confirmation on a TTY; writes contracts.lock.yaml + a contract-approval
6
+ * decision. No TTY → refused with the exact command (exit 1).
7
+ * check --screen <u> [--trace] [--json]
8
+ * rebuilds the verdict from .feature + lock + git HEAD + recorded traces (never from a report),
9
+ * writes .sungen/reports/<slug>-contract.json as output (secret-scanned first). Exit 2 on a hard
10
+ * finding, 0 on pass or review, 1 on an error (unknown unit, untrusted lock, unparseable feature).
11
+ * `--trace` first asks driver-ui (a real browser) for the target identities of free / impl:code
12
+ * traces; without it the cached answers are used (DOS-14.5, 14.6).
13
+ * derive --screen <u> [--grep <re>] → contract-derive-command.ts (DOS-14.8)
14
+ */
15
+ import { Command } from 'commander';
16
+ import * as fs from 'fs';
17
+ import * as path from 'path';
18
+ import { approveContract } from '../../contract/approve-contract';
19
+ import { buildContractVerdict, ContractVerdict } from '../../contract/build-contract-verdict';
20
+ import { contractReportPath, writeContractReport } from '../../contract/contract-report-file';
21
+ import { HARD_CLASSES, REVIEW_CLASSES } from '../../contract/contract-schema';
22
+ import { processIO } from '../../decisions/human-confirmation';
23
+ import { resolveContractUnit } from '../../contract/contract-units';
24
+ import { secretScanHits } from '../../contract/field-semantic-redaction';
25
+ import { resolveUnitTraceIdentities } from '../../contract/resolve-unit-trace-identities';
26
+ import { registerDeriveCommand } from './contract-derive-command';
27
+
28
+ const MARK: Record<string, string> = {
29
+ match: '✓', strengthened: '↑', proposed: '+', 'hash-changed': '⚖', 'oracle-weakened': '✗', 'target-changed': '✗', 'assertion-lost': '✗',
30
+ opaque: '◐', nondeterministic: '≈', inconclusive: '?', unproven: '✗',
31
+ };
32
+ /** `contract check` judges traces with a generous deadline (the guard path keeps ~3 s). */
33
+ const CHECK_TRACE_BUDGET_MS = 120_000;
34
+ const UNPROVEN_HINT = " → free / impl:code tests need their own config (outputDir 'test-results-free', trace: 'on', the sungen run-record reporter), then a fresh run (see `sungen contract derive`).";
35
+
36
+ function printVerdict(v: ContractVerdict, reportFile: string): void {
37
+ const L = console.log;
38
+ const head = v.verdict === 'pass' ? '✓ PASS' : v.verdict === 'review'
39
+ ? '⚖ REVIEW — changed, not weaker. Exit 0 here, but review blocks `sungen delivery` until QA re-approves' : '✗ FAIL';
40
+ L('');
41
+ L(`━━━ Contract check: ${v.unit} — Gherkin vs the approved lock ━━━`);
42
+ L('');
43
+ L(` verdict: ${head}`);
44
+ const matched = v.scenarios.filter((s) => s.class === 'match').length;
45
+ for (const s of v.scenarios.filter((x) => x.class !== 'match')) {
46
+ L(` ${MARK[s.class] ?? '?'} ${s.id} ${s.class}${s.class === 'proposed' ? ' (no approved entry — does not block)' : ''}`);
47
+ for (const f of s.findings) L(` ${f.rule ? `[${f.rule}] ` : ''}${f.step ? `step ${f.step}: ` : ''}${f.detail}`);
48
+ if (s.trace?.hashes.length) L(` trace: ${[...new Set(s.trace.hashes)].join(', ')} (${s.trace.runs.length} run(s))`);
49
+ if (s.class === 'unproven') L(UNPROVEN_HINT);
50
+ }
51
+ if (matched) L(` ✓ ${matched} scenario(s) match the approved contract`);
52
+ const issue = (u: ContractVerdict['uncommitted'][number]): string =>
53
+ u.change === 'tampered' || u.change === 'unverified' ? `lock entry ${u.change}: ${u.detail}` : `lock entry ${u.change} and not committed`;
54
+ for (const u of v.uncommitted.slice(0, 10)) L(` ✗ ${u.id} ${issue(u)} [contract.lock-uncommitted]`);
55
+ if (v.uncommitted.length > 10) L(` ✗ … and ${v.uncommitted.length - 10} more lock entries that are not what QA approved and committed`);
56
+ for (const w of v.warnings) L(` ⚠ ${w}`);
57
+ L('');
58
+ // Only missing / refused traces: re-approving cannot help, a fresh traced run can.
59
+ const blocking = v.scenarios.filter((s) => HARD_CLASSES.has(s.class) || REVIEW_CLASSES.has(s.class));
60
+ const onlyUnproven = blocking.length > 0 && blocking.every((s) => s.class === 'unproven');
61
+ if (v.verdict === 'fail') {
62
+ L(v.uncommitted.length
63
+ ? ' → Commit the approval (lock + decision) through review, or restore the lock from git (`git checkout -- <lock>`).'
64
+ : onlyUnproven ? " → Re-run the free / impl:code tests with trace: 'on', then check again."
65
+ : ' → Restore the approved checks in the .feature — or, if the change is intended, QA approves it on a terminal:');
66
+ }
67
+ if (v.verdict !== 'pass' && !v.uncommitted.length && !onlyUnproven) L(` sungen contract approve --screen ${v.unit}`);
68
+ L(` Report: ${path.relative(process.cwd(), reportFile)}`);
69
+ L('');
70
+ }
71
+
72
+ function unitOrThrow(name: string | undefined): { name: string; dir: string } {
73
+ if (!name) throw new Error('Provide --screen <name>');
74
+ return resolveContractUnit(process.cwd(), name);
75
+ }
76
+
77
+ export function registerContractCommand(program: Command): void {
78
+ const contract = program
79
+ .command('contract')
80
+ .description('Test Contract (DOS-14): the Gherkin QA approved is the contract — lock it (TTY) and check the .feature was not weakened');
81
+
82
+ contract
83
+ .command('approve')
84
+ .description('Lock the current Gherkin as the approved contract — a human types a confirmation on a TTY')
85
+ .option('-s, --screen <name>', 'Screen / flow / api unit name')
86
+ .option('--scenario <id>', 'Approve one scenario only (its ID, e.g. VP-LOGIN-001)')
87
+ .option('--reason <text>', 'Why (recorded in the contract-approval decision)')
88
+ .action(async (options) => {
89
+ try {
90
+ const unit = unitOrThrow(options.screen);
91
+ const r = await approveContract({ projectRoot: process.cwd(), unit: unit.name, scenario: options.scenario, reason: options.reason, io: processIO() });
92
+ if (r.status === 'nothing-to-approve') { console.log(`\n= Nothing to approve: every chosen scenario of ${unit.name} already matches its approved lock entry.\n`); return; }
93
+ console.log(`\n✓ Approved ${r.approved.length} scenario(s)${r.removed.length ? `, removed ${r.removed.length}` : ''} → ${path.relative(process.cwd(), r.lockPath)} (decision ${r.decisionId})`);
94
+ console.log(' Commit the lock and the decision through review: until they are in git HEAD, `sungen contract check` reports contract.lock-uncommitted.\n');
95
+ } catch (error) {
96
+ console.error('Error:', error instanceof Error ? error.message : error);
97
+ process.exit(1);
98
+ }
99
+ });
100
+
101
+ contract
102
+ .command('check')
103
+ .description('Compare the .feature with the approved lock on the strength ladder, and the lock with git HEAD')
104
+ .option('-s, --screen <name>', 'Screen / flow / api unit name')
105
+ .option('--trace', 'Resolve free / impl:code trace target identities with @sungen/driver-ui (a real browser) first')
106
+ .option('--json', 'Output the verdict as JSON')
107
+ .action(async (options) => {
108
+ let unit: { name: string; dir: string } | undefined;
109
+ try {
110
+ unit = unitOrThrow(options.screen);
111
+ const notes = options.trace ? await resolveUnitTraceIdentities(process.cwd(), unit) : [];
112
+ // The CLI may take its time; the guard (contractBlockers) keeps the ~3 s default.
113
+ const verdict = buildContractVerdict(process.cwd(), unit, { traceBudgetMs: CHECK_TRACE_BUDGET_MS });
114
+ verdict.warnings.push(...notes);
115
+ const hits = secretScanHits(JSON.stringify(verdict, null, 2), `${unit.name}-contract.json`);
116
+ if (hits.length) throw new Error(`Refused to write the contract report — likely secret(s): ${hits.map((h) => `${h.where} ${h.reason}`).join('; ')}`);
117
+ const file = writeContractReport(process.cwd(), verdict);
118
+ if (options.json) console.log(JSON.stringify(verdict, null, 2));
119
+ else printVerdict(verdict, file);
120
+ process.exit(verdict.exitCode);
121
+ } catch (error) {
122
+ // Unreadable = not run (DOS-14.0): an earlier report must not outlive the inputs it judged.
123
+ if (unit) fs.rmSync(contractReportPath(process.cwd(), unit.name), { force: true });
124
+ console.error('Error:', error instanceof Error ? error.message : error);
125
+ process.exit(1);
126
+ }
127
+ });
128
+
129
+ registerDeriveCommand(contract);
130
+ }
@@ -0,0 +1,49 @@
1
+ import { Command } from 'commander';
2
+ import { resolveUnit } from '../resolve-unit';
3
+ import { draftDefects } from '../../harness/defect-draft';
4
+ import { readDefects } from '../../harness/defects';
5
+
6
+ /**
7
+ * `sungen defect draft|list` — defect records under qa/defects/ (see harness/defects.ts).
8
+ * `draft` writes one record per product-candidate row of the unit's last `sungen triage`.
9
+ */
10
+ export function registerDefectCommand(program: Command): void {
11
+ const defect = program.command('defect').description('Draft and list defect records (qa/defects/DEF-NNN-*.md) from red scenarios');
12
+
13
+ defect
14
+ .command('draft')
15
+ .description('Draft a defect record for each product-candidate row of the last `sungen triage`')
16
+ .option('-s, --screen <name>', 'Screen or flow name')
17
+ .option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
18
+ .option('--scenario <title|id>', 'Only the scenario whose title contains this text, or that carries this VP id')
19
+ .option('--json', 'Output raw JSON')
20
+ .action((o: { screen?: string; api?: string; scenario?: string; json?: boolean }) => {
21
+ try {
22
+ const name = o.screen || o.api;
23
+ if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
24
+ const unit = resolveUnit(name, process.cwd());
25
+ if (!unit) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
26
+ const r = draftDefects(process.cwd(), unit, { scenario: o.scenario });
27
+ if (o.json) { console.log(JSON.stringify(r, null, 2)); return; }
28
+ if (r.missingTriage) { console.log(`\n ${name}: no triage yet — run \`sungen triage --screen ${name}\` after the tests.\n`); return; }
29
+ for (const f of r.written) console.log(` ✎ ${f}`);
30
+ for (const s of r.skipped) console.log(` ○ already recorded as ${s.id}: ${s.scenario}`);
31
+ if (!r.written.length && !r.skipped.length) console.log(` ✓ ${name}: no product-candidate rows to draft.`);
32
+ } catch (error) {
33
+ console.error('Error:', error instanceof Error ? error.message : error);
34
+ process.exitCode = 1;
35
+ }
36
+ });
37
+
38
+ defect
39
+ .command('list')
40
+ .description('List defect records (id, severity, status, units, scenario count)')
41
+ .option('--status <status>', 'Only records with this status (open, fixed, verified, closed, wont-fix)')
42
+ .option('--json', 'Output raw JSON')
43
+ .action((o: { status?: string; json?: boolean }) => {
44
+ const rows = readDefects(process.cwd()).filter((r) => !o.status || r.status === o.status);
45
+ if (o.json) { console.log(JSON.stringify(rows, null, 2)); return; }
46
+ if (!rows.length) { console.log(' (no defect records)'); return; }
47
+ for (const r of rows) console.log(` ${r.id} ${r.severity.padEnd(8)} ${r.status.padEnd(9)} ${r.units.join(',')} ${r.scenarios.length} scenario(s) ${r.title}`);
48
+ });
49
+ }
@@ -7,7 +7,7 @@ import { Command } from 'commander';
7
7
  import * as path from 'path';
8
8
  import * as fs from 'fs';
9
9
  import { parse as parseYaml } from 'yaml';
10
- import { parseFeatureMetadata } from '../../exporters/feature-parser';
10
+ import { isHookScenario, parseFeatureMetadata } from '../../exporters/feature-parser';
11
11
  import { parseSpecFile } from '../../exporters/spec-parser';
12
12
  import { loadTestData } from '../../exporters/test-data-resolver';
13
13
  import { loadSelectorKeyMap } from '../../exporters/selector-key-resolver';
@@ -20,7 +20,7 @@ import {
20
20
  renderCsv,
21
21
  writeCsv,
22
22
  } from '../../exporters/csv-exporter';
23
- import { renderXlsxMultiSheet, writeXlsx, buildApiDetailRows, addApiDetailSheet } from '../../exporters/xlsx-exporter';
23
+ import { renderXlsxMultiSheet, writeXlsx, buildApiDetailRows, addApiDetailSheet, deliverableXlsxPath } from '../../exporters/xlsx-exporter';
24
24
  import { loadApiCatalog } from '../../exporters/api-catalog-loader';
25
25
  import { resolveApiEnvironment } from '../../exporters/api-environment';
26
26
  import { getEnvironment, platformOfResultFile, RunEnvironment } from '../../exporters/run-environment';
@@ -38,9 +38,14 @@ import {
38
38
  hasReview,
39
39
  } from '../../exporters/matrix/export';
40
40
  import { MatrixFinding } from '../../exporters/matrix/types';
41
- import { ManualCarryReport } from '../../exporters/matrix/carry-manual-results';
41
+ import { applyManualCarry, ManualCarryReport, PriorManualResults, readPriorManualResults } from '../../exporters/matrix/carry-manual-results';
42
42
  import { formatTestOutcome, resultTotals } from '../../exporters/matrix/result-totals';
43
43
  import { readCapabilities } from '../../harness/capability';
44
+ import { processIO } from '../../decisions/human-confirmation';
45
+ import { DeliveryDecisionGate } from '../../harness/gates/delivery-decision-gate';
46
+ import { runDeliveryDecisionStep } from '../../harness/gates/delivery-decision-step';
47
+ import { deliverableGateOverrides, InRunAcceptance } from '../../harness/gates/gate-override-report';
48
+ import { ChecklistUnit, renderChecklist, unitChecklist } from '../../harness/gates/delivery-checklist';
44
49
 
45
50
  const COLOR = {
46
51
  reset: '\x1b[0m',
@@ -85,6 +90,12 @@ export interface DeliveryTarget {
85
90
  isFlow: boolean;
86
91
  }
87
92
 
93
+ /** The command that regenerates a target's unit — flag by kind, the unit (not feature) name. */
94
+ function generateCommandFor(target: DeliveryTarget): string {
95
+ const flag = target.kind === 'flow' ? '--flow' : target.kind === 'api' ? '--api' : '--screen';
96
+ return `sungen generate ${flag} ${target.screen}`;
97
+ }
98
+
88
99
  function makeTarget(screen: string, featureBaseName: string, kind: UnitKind): DeliveryTarget {
89
100
  return { screen, featureBaseName, name: featureBaseName, kind, isFlow: kind === 'flow' };
90
101
  }
@@ -464,6 +475,7 @@ async function exportTarget(
464
475
  if (isMobileProject(cwd)) removeBaseDeliverables(cwd, target.featureBaseName);
465
476
  const rows = buildTestCaseRows({
466
477
  screen: label,
478
+ generateCommand: generateCommandFor(target),
467
479
  featureName: feature.featureName,
468
480
  // OS-precise env column: a mobile dual-id Path resolves to just the
469
481
  // android package / ios bundle id for SUNGEN_ENV=android|ios.
@@ -522,6 +534,7 @@ async function exportTarget(
522
534
  for (const variant of osVariants) {
523
535
  const variantRows = buildTestCaseRows({
524
536
  screen: label,
537
+ generateCommand: generateCommandFor(target),
525
538
  featureName: feature.featureName,
526
539
  featurePath: resolvePlatformAppId(featurePath, variant.locale), // OS-precise app id
527
540
  merged,
@@ -574,6 +587,7 @@ async function exportTarget(
574
587
  const variantResults = variant.resultsPath ? loadPlaywrightReport(variant.resultsPath) : null;
575
588
  const variantRows = buildTestCaseRows({
576
589
  screen: label,
590
+ generateCommand: generateCommandFor(target),
577
591
  featureName: feature.featureName,
578
592
  // No-op for web (URL Path); for a mobile fall-through (a no-suffix result
579
593
  // json) this collapses the dual-id to the android package so the combined
@@ -651,7 +665,7 @@ export function matrixPathsFor(cwd: string, target: DeliveryTarget): MatrixTarge
651
665
  }
652
666
 
653
667
  function printFindings(findings: MatrixFinding[]): void {
654
- const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}·` } as const;
668
+ const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}·`, info: `${COLOR.gray}i` } as const;
655
669
  for (const f of findings) {
656
670
  log(` ${icon[f.severity]} [Gate ${f.gate}]${COLOR.reset} ${f.ref ? `${f.ref}: ` : ''}${f.message}`);
657
671
  }
@@ -676,23 +690,29 @@ async function exportMatrixTarget(
676
690
  target: DeliveryTarget,
677
691
  opts: { check?: boolean; preview?: boolean; format?: MatrixFormat },
678
692
  env: EnvironmentInfo,
693
+ decisions?: DeliveryDecisionGate,
679
694
  ): Promise<MatrixRunSummary | 'skipped' | null> {
680
695
  const paths = matrixPathsFor(cwd, target);
681
696
  paths.runEnv = matrixRunEnv(cwd, target, env, paths);
697
+ paths.gateRules = decisions?.rulesFor(qaDir(cwd, target)); // the unit's gate-overrides apply to its matrix gates
682
698
 
683
699
  // A feature whose scenarios are ALL @exploration probes has nothing to deliver —
684
700
  // skip it quietly (no map required) instead of demanding a reviewed grouping for
685
701
  // probes that are, by contract, outside the official suite.
686
702
  {
687
703
  const featureMeta = parseFeatureMetadata(paths.featureFile);
688
- const deliverable = featureMeta.scenarios.filter((s) => !s.tags.some((t) => /^@exploration\b/i.test(t)));
689
- if (featureMeta.scenarios.length > 0 && deliverable.length === 0) {
690
- log(`${COLOR.gray}${paths.label}: nothing to deliver — all ${featureMeta.scenarios.length} scenario(s) are @exploration probes (outside the official suite).${COLOR.reset}`);
704
+ // Hooks are setup/teardown, never test cases — they neither need nor make a deliverable (#880).
705
+ const scenarios = featureMeta.scenarios.filter((s) => !isHookScenario(s));
706
+ const deliverable = scenarios.filter((s) => !s.tags.some((t) => /^@exploration\b/i.test(t)));
707
+ if (scenarios.length > 0 && deliverable.length === 0) {
708
+ log(`${COLOR.gray}${paths.label}: nothing to deliver — all ${scenarios.length} scenario(s) are @exploration probes (outside the official suite).${COLOR.reset}`);
691
709
  return 'skipped';
692
710
  }
693
711
  }
694
712
 
695
713
  const { model, mapMissing, mapErrors } = loadMatrixModel(paths);
714
+ // An audit that is untrusted or FAILs never yields an official deliverable: --preview renders a DRAFT (#935).
715
+ if (model && decisions?.auditDraft(qaDir(cwd, target))) model.manifest.approvalState = 'draft';
696
716
 
697
717
  if (mapMissing) {
698
718
  log(`${COLOR.yellow}${paths.label}: no delivery map${COLOR.reset} (${path.relative(cwd, paths.mapFile)})`);
@@ -707,6 +727,18 @@ async function exportMatrixTarget(
707
727
  return null;
708
728
  }
709
729
 
730
+ // The tester's recorded Manual results are part of the outcome: read them BEFORE anything is
731
+ // counted, so this line, the workbook's totals and the summary table all agree (#891). A file
732
+ // that cannot be read is reported where it matters — when it would be overwritten.
733
+ const format = opts.format ?? 'xlsx';
734
+ let prior: PriorManualResults | null = null;
735
+ let priorError: Error | null = null;
736
+ try { prior = await readPriorManualResults(deliverableXlsxPath(cwd, paths.unit)); }
737
+ // A CSV-only export overwrites no workbook, so an unreadable one only means "nothing to carry".
738
+ catch (e) { if (format !== 'csv') priorError = e as Error; }
739
+ applyManualCarry(model, prior);
740
+ model.gateOverrides = deliverableGateOverrides(decisions?.overridesFor(qaDir(cwd, target)) ?? [], hasReview(model.findings), decisions?.acceptedInRun);
741
+
710
742
  log(`${COLOR.bold}${paths.label}${COLOR.reset} — ${model.manifest.itemCount} delivery item(s), ${model.manifest.variantCount} coverage variant(s), review: ${model.manifest.approvalState} (design), test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
711
743
  {
712
744
  const mocked = model.items.flatMap((it) => it.variants.filter((v) => v.mocked));
@@ -741,7 +773,8 @@ async function exportMatrixTarget(
741
773
 
742
774
  let deliverables: Awaited<ReturnType<typeof writeMatrixDeliverables>>;
743
775
  try {
744
- deliverables = await writeMatrixDeliverables(paths, model, opts.format ?? 'xlsx');
776
+ if (priorError) throw priorError;
777
+ deliverables = await writeMatrixDeliverables(paths, model, format, prior);
745
778
  } catch (e) {
746
779
  // The existing workbook could not be read, so writing would destroy its Manual results.
747
780
  log(` ${COLOR.red}not written:${COLOR.reset} ${(e as Error).message}`);
@@ -869,6 +902,19 @@ function printSummaryTable(summaries: ScreenSummary[]): void {
869
902
  }
870
903
  }
871
904
 
905
+ /** T6: one checklist block per delivered unit, each box from what its command says now (delivery-checklist.ts). */
906
+ async function printDeliveryChecklist(cwd: string, targets: DeliveryTarget[], accepted?: InRunAcceptance): Promise<void> {
907
+ const units = new Map<string, ChecklistUnit>();
908
+ for (const t of targets) {
909
+ const dir = qaDir(cwd, t);
910
+ if (!units.has(dir)) units.set(dir, { label: t.isFlow ? `flow/${t.screen}` : t.screen, unitName: t.screen, unitDir: dir, kind: t.kind, resultsPath: resolveResultsPath(cwd, t) });
911
+ }
912
+ const rows: Array<{ label: string; boxes: Awaited<ReturnType<typeof unitChecklist>> }> = [];
913
+ for (const u of units.values()) rows.push({ label: u.label, boxes: await unitChecklist(cwd, u, accepted) });
914
+ log('');
915
+ for (const line of renderChecklist(rows)) log(line);
916
+ }
917
+
872
918
  // ----------------------------------------------------------------------------
873
919
  // Command registration
874
920
  // ----------------------------------------------------------------------------
@@ -887,10 +933,11 @@ export function registerDeliveryCommand(program: Command): void {
887
933
  .option('--approve [ids]', 'Approve proposed groups (all, or a comma-separated id list) + stamp fingerprints')
888
934
  .option('--preview', 'Render the matrix despite review-required findings (DRAFT watermark)')
889
935
  .option('--format <format>', 'Matrix output format: xlsx (default) | csv | both', 'xlsx')
936
+ .option('--accept-in-run', 'Deliver despite gate-overrides/waivers/approvals recorded during the run (decision.in-run) — a human confirms on a terminal')
890
937
  .action(async (names: string[], options: {
891
938
  skipPreflight?: boolean; continueOnMissing?: boolean; env?: string;
892
939
  legacy?: boolean; full?: boolean; check?: boolean; approve?: boolean | string; preview?: boolean;
893
- format?: string;
940
+ format?: string; acceptInRun?: boolean;
894
941
  }) => {
895
942
  try {
896
943
  // Same effect as running with SUNGEN_ENV=<env> — result-file resolution,
@@ -967,6 +1014,30 @@ export function registerDeliveryCommand(program: Command): void {
967
1014
  .reduce<SecretScanResult>((a, r) => ({ hits: [...a.hits, ...r.hits], unscanned: [...a.unscanned, ...r.unscanned] }), { hits: [], unscanned: [] });
968
1015
  for (const line of formatSecretScan(secretScan)) log(line);
969
1016
 
1017
+ // OES-11.3–11.5: decisions that do not verify, rejected overrides, a stale audit and in-run
1018
+ // decisions stop the delivery before anything is written (approval only stamps the map).
1019
+ let decisions: DeliveryDecisionGate | undefined;
1020
+ // --approve only stamps a matrix map. With --legacy / --full it would skip this gate and
1021
+ // fall through to the export, so the combination is refused before anything is written.
1022
+ if (options.approve !== undefined && (options.legacy || options.full)) {
1023
+ console.error(`${COLOR.red}--approve applies to the matrix deliverable only${COLOR.reset} — it cannot be combined with --legacy / --full`);
1024
+ process.exit(1);
1025
+ }
1026
+ if (options.approve === undefined) {
1027
+ const gate = await runDeliveryDecisionStep({
1028
+ projectRoot: cwd, acceptInRun: !!options.acceptInRun, io: processIO(), log,
1029
+ // --preview / --check soften only the matrix export; --legacy has no draft mode, so it always needs one.
1030
+ requireTrustedAudit: !!(options.legacy || options.full) || (!options.preview && !options.check),
1031
+ refs: toExport.map((t) => ({ label: t.isFlow ? `flow/${t.featureBaseName}` : t.featureBaseName, unitName: t.screen, unitDir: qaDir(cwd, t), resultsPath: resolveResultsPath(cwd, t) })),
1032
+ argv: ['sungen', 'delivery', ...(names ?? []), ...(options.env ? ['--env', options.env] : []), ...(options.legacy || options.full ? ['--legacy'] : [])],
1033
+ });
1034
+ if (!gate) {
1035
+ await printDeliveryChecklist(cwd, toExport);
1036
+ process.exit(1);
1037
+ }
1038
+ decisions = gate;
1039
+ }
1040
+
970
1041
  // 3. Export
971
1042
  const legacy = options.legacy || options.full;
972
1043
  if (!legacy) {
@@ -981,9 +1052,9 @@ export function registerDeliveryCommand(program: Command): void {
981
1052
  // Same contract as the export path: an all-@exploration feature has no
982
1053
  // deliverable variants, so there is no map to approve — skip, not an error.
983
1054
  {
984
- const featureMeta = parseFeatureMetadata(paths.featureFile);
985
- if (featureMeta.scenarios.length > 0
986
- && featureMeta.scenarios.every((s) => s.tags.some((t) => /^@exploration\b/i.test(t)))) {
1055
+ const scenarios = parseFeatureMetadata(paths.featureFile).scenarios.filter((s) => !isHookScenario(s));
1056
+ if (scenarios.length > 0
1057
+ && scenarios.every((s) => s.tags.some((t) => /^@exploration\b/i.test(t)))) {
987
1058
  log(`${COLOR.gray}${paths.label}: nothing to approve — all scenario(s) are @exploration probes.${COLOR.reset}`);
988
1059
  continue;
989
1060
  }
@@ -1012,21 +1083,26 @@ export function registerDeliveryCommand(program: Command): void {
1012
1083
  for (const target of toExport) {
1013
1084
  const s = await exportMatrixTarget(cwd, target, {
1014
1085
  check: options.check, preview: options.preview, format: format as MatrixFormat,
1015
- }, env);
1086
+ }, env, decisions);
1016
1087
  if (s === 'skipped') continue; // all-@exploration feature — neither exported nor a failure
1017
1088
  if (s) matrixSummaries.push(s);
1018
1089
  else notExported.push(target.isFlow ? `flow/${target.featureBaseName}` : target.featureBaseName);
1019
1090
  }
1020
1091
  if (matrixSummaries.length > 0 && !options.check) printMatrixSummaryTable(matrixSummaries);
1092
+ for (const line of decisions?.summaryLines() ?? []) log(line);
1021
1093
  printSkipSummary(skipped, notExported);
1094
+ await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
1022
1095
  // A named target that produced nothing is a failure. A sweep is a failure
1023
1096
  // only when it produced nothing at all — units still waiting for a map or
1024
1097
  // an approval are the normal state of a live project. Preflight skips are
1025
1098
  // not counted here: reaching this point in an explicit scope means
1026
1099
  // --continue-on-missing was passed, which IS the opt-in to tolerate them.
1027
- const failed = explicitScope
1100
+ // --check reports like its checklist: an audit box that does not hold is a non-zero exit (#935).
1101
+ const auditFails = (decisions?.untrustedAudits.length ?? 0) + (decisions?.failingAudits.length ?? 0);
1102
+ if (options.check && auditFails) log(`${COLOR.red}✗ --check: ${auditFails} unit(s) whose audit does not pass — see the audit box above.${COLOR.reset}`);
1103
+ const failed = (explicitScope
1028
1104
  ? notExported.length > 0
1029
- : matrixSummaries.length === 0;
1105
+ : matrixSummaries.length === 0) || (!!options.check && auditFails > 0);
1030
1106
  if (failed) process.exit(1);
1031
1107
  return;
1032
1108
  }
@@ -1041,6 +1117,7 @@ export function registerDeliveryCommand(program: Command): void {
1041
1117
  // 4. Summary
1042
1118
  printSummaryTable(summaries);
1043
1119
  printSkipSummary(skipped, []);
1120
+ await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
1044
1121
  // Same rule as the matrix path: every attempted target in an explicit scope
1045
1122
  // must have produced a file; a sweep only fails when nothing was written.
1046
1123
  if (explicitScope ? summaries.length < toExport.length : summaries.length === 0) process.exit(1);
@@ -7,6 +7,7 @@ import { scanTestDataSecrets, formatSecretScan, type SecretScanResult } from '..
7
7
  import { capabilityRegistry } from '../../capabilities/registry';
8
8
  import { discoverAndRegisterCapabilities } from '../../capabilities/discover';
9
9
  import { readCapabilities, writeCapabilities, driverMeta, loadDriverCatalog } from '../../harness/capability';
10
+ import { isHandWritten } from '../../harness/parse';
10
11
 
11
12
  /**
12
13
  * Find .feature files recursively in a directory
@@ -20,7 +21,8 @@ function findFeatureFiles(dir: string): string[] {
20
21
  const fullPath = path.join(dir, entry.name);
21
22
  if (entry.isDirectory()) {
22
23
  files.push(...findFeatureFiles(fullPath));
23
- } else if (entry.isFile() && entry.name.endsWith('.feature')) {
24
+ } else if (entry.isFile() && entry.name.endsWith('.feature') && !isHandWritten([], fullPath)) {
25
+ // A derived `*.free.feature` is a contract for hand-written tests — never compiled (DOS-14.8).
24
26
  files.push(fullPath);
25
27
  }
26
28
  }
@@ -1,10 +1,12 @@
1
1
  import { Command } from 'commander';
2
2
  import * as path from 'path';
3
- import * as fs from 'fs';
4
- import { runJourney, waive, signoff, renderJourneyBoard, rollupJourney, renderRollupBoard } from '../../harness/journey';
3
+ import { runJourney, renderJourneyBoard, rollupJourney, renderRollupBoard, writeJourneyFileBestEffort } from '../../harness/journey';
5
4
  import { reportSlug } from '../../harness/unit-paths';
6
5
  import { findUnitDir } from '../resolve-unit';
6
+ import { answerPendingMigration, decideWithConfirmation, DECIDE_KINDS, signoffWithConfirmation, waiveWithConfirmation } from '../../decisions/confirmed-decision-commands';
7
+ import { processIO } from '../../decisions/human-confirmation';
7
8
 
9
+ const collect = (value: string, previous: string[]): string[] => [...previous, value];
8
10
 
9
11
  export function registerJourneyCommand(program: Command): void {
10
12
  program
@@ -12,22 +14,41 @@ export function registerJourneyCommand(program: Command): void {
12
14
  .description('Durable "you are here" board (#381): obligations + what-to-review + next, synthesised read-only from the audit report + ledger already on disk.')
13
15
  .option('-s, --screen <name>', 'Screen / flow / api unit name')
14
16
  .option('--all', 'Roll up every unit (screens + flows + api) into one board — the serial review surface for multi-unit fan-out')
15
- .option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason')
16
- .option('--reason <text>', 'The reason a waived obligation is acceptable (mandatory with --waive)')
17
- .option('--signoff', 'Sign off the review queue — the single human gate (allowed only when every other obligation is satisfied/waived)')
17
+ .option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason; a human types a confirmation on a TTY')
18
+ .option('--reason <text>', 'Why: mandatory with --waive and --decide')
19
+ .option('--decide <kind>', `Record a decision (${DECIDE_KINDS.join(' | ')}) in qa/decisions/, or the unit's with --screen — a human types a confirmation on a TTY`)
20
+ .option('--text <text>', 'What was decided (with --decide)')
21
+ .option('--anchor <id>', 'Spec anchor the decision is about, e.g. SPEC-AUTH-001#A-2 (repeatable, with --decide)', collect, [])
22
+ .option('--payload <json>', 'Kind-specific fields as a JSON object, e.g. a gate-override\'s {"rule","severity","scope"} (with --decide)')
23
+ .option('--visibility <v>', 'internal (default, never exported) | client (with --decide)')
24
+ .option('--supersedes <id>', 'The decision this one replaces — the old entry is never edited (with --decide)')
25
+ .option('--signoff', 'Sign off the review queue — the single human gate (allowed only when every other obligation is satisfied/waived); a human types a confirmation on a TTY')
18
26
  .option('--by <name>', 'Who is signing off (recorded with --signoff)')
19
27
  .option('--json', 'Output the raw JSON report')
20
- .action((options) => {
28
+ .action(async (options) => {
29
+ const io = processIO();
21
30
  try {
31
+ if (options.decide) {
32
+ if (options.screen && !findUnitDir(options.screen)) throw new Error(`Not found: qa/screens/${options.screen}, qa/flows/${options.screen}, or qa/api/${options.screen}`);
33
+ const r = await decideWithConfirmation({
34
+ projectRoot: process.cwd(), unit: options.screen, kind: options.decide, text: options.text, reason: options.reason,
35
+ anchors: options.anchor, payload: options.payload, visibility: options.visibility, supersedes: options.supersedes, io,
36
+ });
37
+ if (options.json) { console.log(JSON.stringify({ status: r.status, path: path.relative(process.cwd(), r.path), entry: r.entry }, null, 2)); return; }
38
+ console.log(`\n${r.status === 'created' ? '✓ Recorded' : '= Already recorded'} ${r.entry.id} → ${path.relative(process.cwd(), r.path)}`);
39
+ console.log(' Commit it through review: a decision not yet in git HEAD is flagged at delivery (decision.in-run).\n');
40
+ return;
41
+ }
42
+
22
43
  if (options.all) {
23
44
  const rows = rollupJourney(process.cwd());
24
45
  const board = renderRollupBoard(rows);
25
46
  const outDir = path.join(process.cwd(), '.sungen', 'journey');
26
- fs.mkdirSync(outDir, { recursive: true });
27
- fs.writeFileSync(path.join(outDir, '_rollup.json'), JSON.stringify(rows, null, 2), 'utf-8');
28
- fs.writeFileSync(path.join(outDir, '_rollup.board.md'), board, 'utf-8');
47
+ // Derived files: a read-only checkout still gets the board (DOS-13.3).
48
+ writeJourneyFileBestEffort(path.join(outDir, '_rollup.json'), JSON.stringify(rows, null, 2));
49
+ const written = writeJourneyFileBestEffort(path.join(outDir, '_rollup.board.md'), board);
29
50
  if (options.json) console.log(JSON.stringify(rows, null, 2));
30
- else { console.log(''); console.log(board); console.log(` Board: ${path.relative(process.cwd(), path.join(outDir, '_rollup.board.md'))}`); console.log(''); }
51
+ else { console.log(''); console.log(board); console.log(` Board: ${written ? path.relative(process.cwd(), written) : '(not written — read-only checkout)'}`); console.log(''); }
31
52
  return;
32
53
  }
33
54
 
@@ -35,25 +56,29 @@ export function registerJourneyCommand(program: Command): void {
35
56
  if (!name) throw new Error('Provide --screen <name> (or --all for the roll-up)');
36
57
  if (!findUnitDir(name)) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
37
58
 
59
+ // A migration killed half-way (T6): a human answers REVERT or KEEP before anything else runs.
60
+ const restored = await answerPendingMigration(process.cwd(), name, io);
61
+ if (restored) io.output.write(` Interrupted migration resolved${restored.length ? ` — restored ${restored.length} file(s)` : ' — kept the new files'}.\n`);
62
+
38
63
  const report = options.waive
39
- ? waive(process.cwd(), name, options.waive, options.reason || '')
64
+ ? await waiveWithConfirmation({ projectRoot: process.cwd(), unit: name, obligation: options.waive, reason: options.reason || '', io })
40
65
  : options.signoff
41
- ? signoff(process.cwd(), name, options.by)
66
+ ? await signoffWithConfirmation({ projectRoot: process.cwd(), unit: name, by: options.by, io })
42
67
  : runJourney(process.cwd(), name);
43
68
 
44
69
  const outDir = path.join(process.cwd(), '.sungen', 'journey');
45
- fs.mkdirSync(outDir, { recursive: true });
46
70
  const slug = reportSlug(name);
47
- fs.writeFileSync(path.join(outDir, `${slug}.json`), JSON.stringify(report, null, 2), 'utf-8');
71
+ // Derived files: a read-only checkout still gets the board (DOS-13.3).
72
+ writeJourneyFileBestEffort(path.join(outDir, `${slug}.json`), JSON.stringify(report, null, 2));
48
73
  const board = renderJourneyBoard(report);
49
- fs.writeFileSync(path.join(outDir, `${slug}.board.md`), board, 'utf-8');
74
+ const written = writeJourneyFileBestEffort(path.join(outDir, `${slug}.board.md`), board);
50
75
 
51
76
  if (options.json) {
52
77
  console.log(JSON.stringify(report, null, 2));
53
78
  } else {
54
79
  console.log('');
55
80
  console.log(board);
56
- console.log(` Board: ${path.relative(process.cwd(), path.join(outDir, `${slug}.board.md`))}`);
81
+ console.log(` Board: ${written ? path.relative(process.cwd(), written) : '(not written — read-only checkout)'}`);
57
82
  console.log('');
58
83
  }
59
84
  } catch (error) {