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

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 (866) 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/registry.d.ts +15 -0
  34. package/dist/capabilities/registry.d.ts.map +1 -1
  35. package/dist/capabilities/registry.js.map +1 -1
  36. package/dist/cli/commands/audit.d.ts.map +1 -1
  37. package/dist/cli/commands/audit.js +9 -4
  38. package/dist/cli/commands/audit.js.map +1 -1
  39. package/dist/cli/commands/capability.d.ts.map +1 -1
  40. package/dist/cli/commands/capability.js +6 -2
  41. package/dist/cli/commands/capability.js.map +1 -1
  42. package/dist/cli/commands/contract-derive-command.d.ts +10 -0
  43. package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
  44. package/dist/cli/commands/contract-derive-command.js +99 -0
  45. package/dist/cli/commands/contract-derive-command.js.map +1 -0
  46. package/dist/cli/commands/contract.d.ts +17 -0
  47. package/dist/cli/commands/contract.d.ts.map +1 -0
  48. package/dist/cli/commands/contract.js +162 -0
  49. package/dist/cli/commands/contract.js.map +1 -0
  50. package/dist/cli/commands/defect.d.ts +7 -0
  51. package/dist/cli/commands/defect.d.ts.map +1 -0
  52. package/dist/cli/commands/defect.js +68 -0
  53. package/dist/cli/commands/defect.js.map +1 -0
  54. package/dist/cli/commands/delivery.d.ts.map +1 -1
  55. package/dist/cli/commands/delivery.js +87 -10
  56. package/dist/cli/commands/delivery.js.map +1 -1
  57. package/dist/cli/commands/generate.d.ts.map +1 -1
  58. package/dist/cli/commands/generate.js +3 -1
  59. package/dist/cli/commands/generate.js.map +1 -1
  60. package/dist/cli/commands/journey.d.ts.map +1 -1
  61. package/dist/cli/commands/journey.js +41 -13
  62. package/dist/cli/commands/journey.js.map +1 -1
  63. package/dist/cli/commands/next.d.ts +8 -0
  64. package/dist/cli/commands/next.d.ts.map +1 -1
  65. package/dist/cli/commands/next.js +64 -6
  66. package/dist/cli/commands/next.js.map +1 -1
  67. package/dist/cli/commands/triage.d.ts +7 -0
  68. package/dist/cli/commands/triage.d.ts.map +1 -0
  69. package/dist/cli/commands/triage.js +98 -0
  70. package/dist/cli/commands/triage.js.map +1 -0
  71. package/dist/cli/commands/update.d.ts +11 -0
  72. package/dist/cli/commands/update.d.ts.map +1 -1
  73. package/dist/cli/commands/update.js +31 -6
  74. package/dist/cli/commands/update.js.map +1 -1
  75. package/dist/cli/index.js +24 -33
  76. package/dist/cli/index.js.map +1 -1
  77. package/dist/contract/approve-contract.d.ts +31 -0
  78. package/dist/contract/approve-contract.d.ts.map +1 -0
  79. package/dist/contract/approve-contract.js +87 -0
  80. package/dist/contract/approve-contract.js.map +1 -0
  81. package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
  82. package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
  83. package/dist/contract/assertion-matcher-vocabulary.js +100 -0
  84. package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
  85. package/dist/contract/build-contract-verdict.d.ts +32 -0
  86. package/dist/contract/build-contract-verdict.d.ts.map +1 -0
  87. package/dist/contract/build-contract-verdict.js +123 -0
  88. package/dist/contract/build-contract-verdict.js.map +1 -0
  89. package/dist/contract/build-trace-conformance.d.ts +18 -0
  90. package/dist/contract/build-trace-conformance.d.ts.map +1 -0
  91. package/dist/contract/build-trace-conformance.js +153 -0
  92. package/dist/contract/build-trace-conformance.js.map +1 -0
  93. package/dist/contract/classify-contract-change.d.ts +23 -0
  94. package/dist/contract/classify-contract-change.d.ts.map +1 -0
  95. package/dist/contract/classify-contract-change.js +98 -0
  96. package/dist/contract/classify-contract-change.js.map +1 -0
  97. package/dist/contract/classify-contract-unit.d.ts +18 -0
  98. package/dist/contract/classify-contract-unit.d.ts.map +1 -0
  99. package/dist/contract/classify-contract-unit.js +49 -0
  100. package/dist/contract/classify-contract-unit.js.map +1 -0
  101. package/dist/contract/classify-trace-conformance.d.ts +32 -0
  102. package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
  103. package/dist/contract/classify-trace-conformance.js +117 -0
  104. package/dist/contract/classify-trace-conformance.js.map +1 -0
  105. package/dist/contract/contract-git.d.ts +24 -0
  106. package/dist/contract/contract-git.d.ts.map +1 -0
  107. package/dist/contract/contract-git.js +144 -0
  108. package/dist/contract/contract-git.js.map +1 -0
  109. package/dist/contract/contract-hash.d.ts +7 -0
  110. package/dist/contract/contract-hash.d.ts.map +1 -0
  111. package/dist/contract/contract-hash.js +38 -0
  112. package/dist/contract/contract-hash.js.map +1 -0
  113. package/dist/contract/contract-report-file.d.ts +4 -0
  114. package/dist/contract/contract-report-file.d.ts.map +1 -0
  115. package/dist/contract/contract-report-file.js +60 -0
  116. package/dist/contract/contract-report-file.js.map +1 -0
  117. package/dist/contract/contract-schema.d.ts +71 -0
  118. package/dist/contract/contract-schema.d.ts.map +1 -0
  119. package/dist/contract/contract-schema.js +102 -0
  120. package/dist/contract/contract-schema.js.map +1 -0
  121. package/dist/contract/contract-units.d.ts +12 -0
  122. package/dist/contract/contract-units.d.ts.map +1 -0
  123. package/dist/contract/contract-units.js +96 -0
  124. package/dist/contract/contract-units.js.map +1 -0
  125. package/dist/contract/contracts-lock-file.d.ts +24 -0
  126. package/dist/contract/contracts-lock-file.d.ts.map +1 -0
  127. package/dist/contract/contracts-lock-file.js +140 -0
  128. package/dist/contract/contracts-lock-file.js.map +1 -0
  129. package/dist/contract/data-normalize.d.ts +10 -0
  130. package/dist/contract/data-normalize.d.ts.map +1 -0
  131. package/dist/contract/data-normalize.js +110 -0
  132. package/dist/contract/data-normalize.js.map +1 -0
  133. package/dist/contract/derive-free-feature.d.ts +30 -0
  134. package/dist/contract/derive-free-feature.d.ts.map +1 -0
  135. package/dist/contract/derive-free-feature.js +145 -0
  136. package/dist/contract/derive-free-feature.js.map +1 -0
  137. package/dist/contract/field-semantic-redaction.d.ts +21 -0
  138. package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
  139. package/dist/contract/field-semantic-redaction.js +118 -0
  140. package/dist/contract/field-semantic-redaction.js.map +1 -0
  141. package/dist/contract/free-feature-blocks.d.ts +10 -0
  142. package/dist/contract/free-feature-blocks.d.ts.map +1 -0
  143. package/dist/contract/free-feature-blocks.js +94 -0
  144. package/dist/contract/free-feature-blocks.js.map +1 -0
  145. package/dist/contract/lock-secret-guard.d.ts +22 -0
  146. package/dist/contract/lock-secret-guard.d.ts.map +1 -0
  147. package/dist/contract/lock-secret-guard.js +134 -0
  148. package/dist/contract/lock-secret-guard.js.map +1 -0
  149. package/dist/contract/lock-vs-git-head.d.ts +26 -0
  150. package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
  151. package/dist/contract/lock-vs-git-head.js +28 -0
  152. package/dist/contract/lock-vs-git-head.js.map +1 -0
  153. package/dist/contract/normalize-contract-step.d.ts +21 -0
  154. package/dist/contract/normalize-contract-step.d.ts.map +1 -0
  155. package/dist/contract/normalize-contract-step.js +70 -0
  156. package/dist/contract/normalize-contract-step.js.map +1 -0
  157. package/dist/contract/normalize-feature-steps.d.ts +7 -0
  158. package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
  159. package/dist/contract/normalize-feature-steps.js +127 -0
  160. package/dist/contract/normalize-feature-steps.js.map +1 -0
  161. package/dist/contract/oracle-strength.d.ts +12 -0
  162. package/dist/contract/oracle-strength.d.ts.map +1 -0
  163. package/dist/contract/oracle-strength.js +88 -0
  164. package/dist/contract/oracle-strength.js.map +1 -0
  165. package/dist/contract/project-contract-blockers.d.ts +10 -0
  166. package/dist/contract/project-contract-blockers.d.ts.map +1 -0
  167. package/dist/contract/project-contract-blockers.js +73 -0
  168. package/dist/contract/project-contract-blockers.js.map +1 -0
  169. package/dist/contract/record-contract-approval.d.ts +21 -0
  170. package/dist/contract/record-contract-approval.d.ts.map +1 -0
  171. package/dist/contract/record-contract-approval.js +98 -0
  172. package/dist/contract/record-contract-approval.js.map +1 -0
  173. package/dist/contract/render-free-gherkin.d.ts +40 -0
  174. package/dist/contract/render-free-gherkin.d.ts.map +1 -0
  175. package/dist/contract/render-free-gherkin.js +141 -0
  176. package/dist/contract/render-free-gherkin.js.map +1 -0
  177. package/dist/contract/render-trace-sentence.d.ts +20 -0
  178. package/dist/contract/render-trace-sentence.d.ts.map +1 -0
  179. package/dist/contract/render-trace-sentence.js +109 -0
  180. package/dist/contract/render-trace-sentence.js.map +1 -0
  181. package/dist/contract/render-trace-target.d.ts +14 -0
  182. package/dist/contract/render-trace-target.d.ts.map +1 -0
  183. package/dist/contract/render-trace-target.js +70 -0
  184. package/dist/contract/render-trace-target.js.map +1 -0
  185. package/dist/contract/resolve-unit-trace-identities.d.ts +8 -0
  186. package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
  187. package/dist/contract/resolve-unit-trace-identities.js +78 -0
  188. package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
  189. package/dist/contract/trace/collect-trace-evidence.d.ts +33 -0
  190. package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
  191. package/dist/contract/trace/collect-trace-evidence.js +161 -0
  192. package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
  193. package/dist/contract/trace/identity-cache.d.ts +19 -0
  194. package/dist/contract/trace/identity-cache.d.ts.map +1 -0
  195. package/dist/contract/trace/identity-cache.js +104 -0
  196. package/dist/contract/trace/identity-cache.js.map +1 -0
  197. package/dist/contract/trace/select-final-attempt.d.ts +27 -0
  198. package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
  199. package/dist/contract/trace/select-final-attempt.js +116 -0
  200. package/dist/contract/trace/select-final-attempt.js.map +1 -0
  201. package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
  202. package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
  203. package/dist/contract/trace/snapshot-html-renderer.js +172 -0
  204. package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
  205. package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
  206. package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
  207. package/dist/contract/trace/snapshot-resolver.js +65 -0
  208. package/dist/contract/trace/snapshot-resolver.js.map +1 -0
  209. package/dist/contract/trace/snapshot-store.d.ts +66 -0
  210. package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
  211. package/dist/contract/trace/snapshot-store.js +173 -0
  212. package/dist/contract/trace/snapshot-store.js.map +1 -0
  213. package/dist/contract/trace/target-identity.d.ts +74 -0
  214. package/dist/contract/trace/target-identity.d.ts.map +1 -0
  215. package/dist/contract/trace/target-identity.js +68 -0
  216. package/dist/contract/trace/target-identity.js.map +1 -0
  217. package/dist/contract/trace/test-step-join.d.ts +65 -0
  218. package/dist/contract/trace/test-step-join.d.ts.map +1 -0
  219. package/dist/contract/trace/test-step-join.js +80 -0
  220. package/dist/contract/trace/test-step-join.js.map +1 -0
  221. package/dist/contract/trace/trace-binding.d.ts +21 -0
  222. package/dist/contract/trace/trace-binding.d.ts.map +1 -0
  223. package/dist/contract/trace/trace-binding.js +88 -0
  224. package/dist/contract/trace/trace-binding.js.map +1 -0
  225. package/dist/contract/trace/trace-file-reader.d.ts +35 -0
  226. package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
  227. package/dist/contract/trace/trace-file-reader.js +155 -0
  228. package/dist/contract/trace/trace-file-reader.js.map +1 -0
  229. package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
  230. package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
  231. package/dist/contract/trace/trace-fingerprint.js +96 -0
  232. package/dist/contract/trace/trace-fingerprint.js.map +1 -0
  233. package/dist/contract/trace/trace-identity-resolution.d.ts +26 -0
  234. package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
  235. package/dist/contract/trace/trace-identity-resolution.js +84 -0
  236. package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
  237. package/dist/contract/trace/trace-run-record.d.ts +27 -0
  238. package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
  239. package/dist/contract/trace/trace-run-record.js +115 -0
  240. package/dist/contract/trace/trace-run-record.js.map +1 -0
  241. package/dist/contract/trace/trace-steps.d.ts +19 -0
  242. package/dist/contract/trace/trace-steps.d.ts.map +1 -0
  243. package/dist/contract/trace/trace-steps.js +79 -0
  244. package/dist/contract/trace/trace-steps.js.map +1 -0
  245. package/dist/contract/trace/trace-zip-limits.d.ts +41 -0
  246. package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
  247. package/dist/contract/trace/trace-zip-limits.js +48 -0
  248. package/dist/contract/trace/trace-zip-limits.js.map +1 -0
  249. package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
  250. package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
  251. package/dist/contract/trace/trace-zip-reader.js +186 -0
  252. package/dist/contract/trace/trace-zip-reader.js.map +1 -0
  253. package/dist/contract/verify-approval-decisions.d.ts +5 -0
  254. package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
  255. package/dist/contract/verify-approval-decisions.js +104 -0
  256. package/dist/contract/verify-approval-decisions.js.map +1 -0
  257. package/dist/decisions/append-decision.d.ts +12 -0
  258. package/dist/decisions/append-decision.d.ts.map +1 -0
  259. package/dist/decisions/append-decision.js +73 -0
  260. package/dist/decisions/append-decision.js.map +1 -0
  261. package/dist/decisions/confirmed-decision-commands.d.ts +30 -0
  262. package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
  263. package/dist/decisions/confirmed-decision-commands.js +172 -0
  264. package/dist/decisions/confirmed-decision-commands.js.map +1 -0
  265. package/dist/decisions/decision-file.d.ts +31 -0
  266. package/dist/decisions/decision-file.d.ts.map +1 -0
  267. package/dist/decisions/decision-file.js +139 -0
  268. package/dist/decisions/decision-file.js.map +1 -0
  269. package/dist/decisions/decision-identity.d.ts +12 -0
  270. package/dist/decisions/decision-identity.d.ts.map +1 -0
  271. package/dist/decisions/decision-identity.js +78 -0
  272. package/dist/decisions/decision-identity.js.map +1 -0
  273. package/dist/decisions/decision-integrity-check.d.ts +12 -0
  274. package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
  275. package/dist/decisions/decision-integrity-check.js +102 -0
  276. package/dist/decisions/decision-integrity-check.js.map +1 -0
  277. package/dist/decisions/decision-schema.d.ts +42 -0
  278. package/dist/decisions/decision-schema.d.ts.map +1 -0
  279. package/dist/decisions/decision-schema.js +75 -0
  280. package/dist/decisions/decision-schema.js.map +1 -0
  281. package/dist/decisions/decision-source.d.ts +2 -0
  282. package/dist/decisions/decision-source.d.ts.map +1 -0
  283. package/dist/decisions/decision-source.js +18 -0
  284. package/dist/decisions/decision-source.js.map +1 -0
  285. package/dist/decisions/exclusive-file-create.d.ts +3 -0
  286. package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
  287. package/dist/decisions/exclusive-file-create.js +84 -0
  288. package/dist/decisions/exclusive-file-create.js.map +1 -0
  289. package/dist/decisions/git-head-trust.d.ts +7 -0
  290. package/dist/decisions/git-head-trust.d.ts.map +1 -0
  291. package/dist/decisions/git-head-trust.js +76 -0
  292. package/dist/decisions/git-head-trust.js.map +1 -0
  293. package/dist/decisions/human-confirmation.d.ts +33 -0
  294. package/dist/decisions/human-confirmation.d.ts.map +1 -0
  295. package/dist/decisions/human-confirmation.js +155 -0
  296. package/dist/decisions/human-confirmation.js.map +1 -0
  297. package/dist/decisions/legacy-waiver-migration.d.ts +31 -0
  298. package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
  299. package/dist/decisions/legacy-waiver-migration.js +170 -0
  300. package/dist/decisions/legacy-waiver-migration.js.map +1 -0
  301. package/dist/decisions/read-decisions.d.ts +19 -0
  302. package/dist/decisions/read-decisions.d.ts.map +1 -0
  303. package/dist/decisions/read-decisions.js +90 -0
  304. package/dist/decisions/read-decisions.js.map +1 -0
  305. package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
  306. package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
  307. package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
  308. package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
  309. package/dist/decisions/waiver-decisions.d.ts +24 -0
  310. package/dist/decisions/waiver-decisions.d.ts.map +1 -0
  311. package/dist/decisions/waiver-decisions.js +46 -0
  312. package/dist/decisions/waiver-decisions.js.map +1 -0
  313. package/dist/exporters/csv-exporter.d.ts +4 -0
  314. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  315. package/dist/exporters/csv-exporter.js +1 -1
  316. package/dist/exporters/csv-exporter.js.map +1 -1
  317. package/dist/exporters/feature-parser.d.ts +8 -0
  318. package/dist/exporters/feature-parser.d.ts.map +1 -1
  319. package/dist/exporters/feature-parser.js +12 -0
  320. package/dist/exporters/feature-parser.js.map +1 -1
  321. package/dist/exporters/matrix/build.d.ts +3 -0
  322. package/dist/exporters/matrix/build.d.ts.map +1 -1
  323. package/dist/exporters/matrix/build.js +59 -19
  324. package/dist/exporters/matrix/build.js.map +1 -1
  325. package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
  326. package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
  327. package/dist/exporters/matrix/carry-manual-results.js +76 -6
  328. package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
  329. package/dist/exporters/matrix/export.d.ts +8 -2
  330. package/dist/exporters/matrix/export.d.ts.map +1 -1
  331. package/dist/exporters/matrix/export.js +16 -3
  332. package/dist/exporters/matrix/export.js.map +1 -1
  333. package/dist/exporters/matrix/gates.d.ts +6 -1
  334. package/dist/exporters/matrix/gates.d.ts.map +1 -1
  335. package/dist/exporters/matrix/gates.js +57 -128
  336. package/dist/exporters/matrix/gates.js.map +1 -1
  337. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  338. package/dist/exporters/matrix/render-csv.js +4 -1
  339. package/dist/exporters/matrix/render-csv.js.map +1 -1
  340. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
  341. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
  342. package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
  343. package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
  344. package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
  345. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  346. package/dist/exporters/matrix/render-xlsx.js +6 -0
  347. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  348. package/dist/exporters/matrix/types.d.ts +9 -1
  349. package/dist/exporters/matrix/types.d.ts.map +1 -1
  350. package/dist/exporters/matrix/types.js.map +1 -1
  351. package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
  352. package/dist/exporters/playwright-report-parser.js +1 -0
  353. package/dist/exporters/playwright-report-parser.js.map +1 -1
  354. package/dist/exporters/scenario-merger.d.ts.map +1 -1
  355. package/dist/exporters/scenario-merger.js +2 -0
  356. package/dist/exporters/scenario-merger.js.map +1 -1
  357. package/dist/exporters/types.d.ts +5 -0
  358. package/dist/exporters/types.d.ts.map +1 -1
  359. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  360. package/dist/generators/test-generator/code-generator.js +13 -0
  361. package/dist/generators/test-generator/code-generator.js.map +1 -1
  362. package/dist/graph/evaluate-graph.d.ts +21 -0
  363. package/dist/graph/evaluate-graph.d.ts.map +1 -0
  364. package/dist/graph/evaluate-graph.js +49 -0
  365. package/dist/graph/evaluate-graph.js.map +1 -0
  366. package/dist/graph/locate-finding.d.ts +20 -0
  367. package/dist/graph/locate-finding.d.ts.map +1 -0
  368. package/dist/graph/locate-finding.js +137 -0
  369. package/dist/graph/locate-finding.js.map +1 -0
  370. package/dist/graph/node-decl.d.ts +59 -0
  371. package/dist/graph/node-decl.d.ts.map +1 -0
  372. package/dist/graph/node-decl.js +8 -0
  373. package/dist/graph/node-decl.js.map +1 -0
  374. package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
  375. package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
  376. package/dist/graph/nodes/core-node-catalog.js +13 -0
  377. package/dist/graph/nodes/core-node-catalog.js.map +1 -0
  378. package/dist/graph/nodes/test-case-contract-nodes.d.ts +19 -0
  379. package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
  380. package/dist/graph/nodes/test-case-contract-nodes.js +56 -0
  381. package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
  382. package/dist/graph/nodes/test-case-nodes.d.ts +26 -0
  383. package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
  384. package/dist/graph/nodes/test-case-nodes.js +66 -0
  385. package/dist/graph/nodes/test-case-nodes.js.map +1 -0
  386. package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
  387. package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
  388. package/dist/graph/nodes/unit-audit-nodes.js +95 -0
  389. package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
  390. package/dist/graph/nodes/unit-contract-node.d.ts +20 -0
  391. package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
  392. package/dist/graph/nodes/unit-contract-node.js +81 -0
  393. package/dist/graph/nodes/unit-contract-node.js.map +1 -0
  394. package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
  395. package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
  396. package/dist/graph/nodes/unit-design-nodes.js +90 -0
  397. package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
  398. package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
  399. package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
  400. package/dist/graph/nodes/unit-execution-nodes.js +79 -0
  401. package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
  402. package/dist/graph/test-case-identity.d.ts +13 -0
  403. package/dist/graph/test-case-identity.d.ts.map +1 -0
  404. package/dist/graph/test-case-identity.js +106 -0
  405. package/dist/graph/test-case-identity.js.map +1 -0
  406. package/dist/graph/test-case-results.d.ts +11 -0
  407. package/dist/graph/test-case-results.d.ts.map +1 -0
  408. package/dist/graph/test-case-results.js +137 -0
  409. package/dist/graph/test-case-results.js.map +1 -0
  410. package/dist/graph/test-case-satisfied.d.ts +25 -0
  411. package/dist/graph/test-case-satisfied.d.ts.map +1 -0
  412. package/dist/graph/test-case-satisfied.js +51 -0
  413. package/dist/graph/test-case-satisfied.js.map +1 -0
  414. package/dist/graph/test-case-state-shape.d.ts +67 -0
  415. package/dist/graph/test-case-state-shape.d.ts.map +1 -0
  416. package/dist/graph/test-case-state-shape.js +3 -0
  417. package/dist/graph/test-case-state-shape.js.map +1 -0
  418. package/dist/graph/test-case-states.d.ts +9 -0
  419. package/dist/graph/test-case-states.d.ts.map +1 -0
  420. package/dist/graph/test-case-states.js +116 -0
  421. package/dist/graph/test-case-states.js.map +1 -0
  422. package/dist/graph/unit-artifact-probes.d.ts +19 -0
  423. package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
  424. package/dist/graph/unit-artifact-probes.js +133 -0
  425. package/dist/graph/unit-artifact-probes.js.map +1 -0
  426. package/dist/graph/unit-state-facts.d.ts +43 -0
  427. package/dist/graph/unit-state-facts.d.ts.map +1 -0
  428. package/dist/graph/unit-state-facts.js +87 -0
  429. package/dist/graph/unit-state-facts.js.map +1 -0
  430. package/dist/harness/audit.d.ts +11 -0
  431. package/dist/harness/audit.d.ts.map +1 -1
  432. package/dist/harness/audit.js +34 -9
  433. package/dist/harness/audit.js.map +1 -1
  434. package/dist/harness/catalog/gate-rules.yaml +647 -0
  435. package/dist/harness/counted-assertions.d.ts +2 -0
  436. package/dist/harness/counted-assertions.d.ts.map +1 -0
  437. package/dist/harness/counted-assertions.js +38 -0
  438. package/dist/harness/counted-assertions.js.map +1 -0
  439. package/dist/harness/defect-draft.d.ts +14 -0
  440. package/dist/harness/defect-draft.d.ts.map +1 -0
  441. package/dist/harness/defect-draft.js +143 -0
  442. package/dist/harness/defect-draft.js.map +1 -0
  443. package/dist/harness/defects.d.ts +24 -0
  444. package/dist/harness/defects.d.ts.map +1 -0
  445. package/dist/harness/defects.js +118 -0
  446. package/dist/harness/defects.js.map +1 -0
  447. package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
  448. package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
  449. package/dist/harness/gates/audit-gate-terms.js +72 -0
  450. package/dist/harness/gates/audit-gate-terms.js.map +1 -0
  451. package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
  452. package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
  453. package/dist/harness/gates/audit-gate-verdict.js +101 -0
  454. package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
  455. package/dist/harness/gates/audit-input-hash.d.ts +4 -0
  456. package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
  457. package/dist/harness/gates/audit-input-hash.js +96 -0
  458. package/dist/harness/gates/audit-input-hash.js.map +1 -0
  459. package/dist/harness/gates/audit-report-verification.d.ts +32 -0
  460. package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
  461. package/dist/harness/gates/audit-report-verification.js +207 -0
  462. package/dist/harness/gates/audit-report-verification.js.map +1 -0
  463. package/dist/harness/gates/decisions-hash.d.ts +13 -0
  464. package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
  465. package/dist/harness/gates/decisions-hash.js +72 -0
  466. package/dist/harness/gates/decisions-hash.js.map +1 -0
  467. package/dist/harness/gates/delivery-checklist.d.ts +21 -0
  468. package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
  469. package/dist/harness/gates/delivery-checklist.js +128 -0
  470. package/dist/harness/gates/delivery-checklist.js.map +1 -0
  471. package/dist/harness/gates/delivery-decision-gate.d.ts +29 -0
  472. package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
  473. package/dist/harness/gates/delivery-decision-gate.js +91 -0
  474. package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
  475. package/dist/harness/gates/delivery-decision-step.d.ts +16 -0
  476. package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
  477. package/dist/harness/gates/delivery-decision-step.js +71 -0
  478. package/dist/harness/gates/delivery-decision-step.js.map +1 -0
  479. package/dist/harness/gates/gate-override-report.d.ts +59 -0
  480. package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
  481. package/dist/harness/gates/gate-override-report.js +86 -0
  482. package/dist/harness/gates/gate-override-report.js.map +1 -0
  483. package/dist/harness/gates/gate-override-scope.d.ts +18 -0
  484. package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
  485. package/dist/harness/gates/gate-override-scope.js +98 -0
  486. package/dist/harness/gates/gate-override-scope.js.map +1 -0
  487. package/dist/harness/gates/gate-override-validation.d.ts +25 -0
  488. package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
  489. package/dist/harness/gates/gate-override-validation.js +81 -0
  490. package/dist/harness/gates/gate-override-validation.js.map +1 -0
  491. package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
  492. package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
  493. package/dist/harness/gates/gate-rule-catalog.js +112 -0
  494. package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
  495. package/dist/harness/gates/gate-terms.d.ts +33 -0
  496. package/dist/harness/gates/gate-terms.d.ts.map +1 -0
  497. package/dist/harness/gates/gate-terms.js +41 -0
  498. package/dist/harness/gates/gate-terms.js.map +1 -0
  499. package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
  500. package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
  501. package/dist/harness/gates/in-run-decision-check.js +138 -0
  502. package/dist/harness/gates/in-run-decision-check.js.map +1 -0
  503. package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
  504. package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
  505. package/dist/harness/gates/journey-gate-inputs.js +81 -0
  506. package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
  507. package/dist/harness/gates/migrated-waiver-review.d.ts +6 -0
  508. package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
  509. package/dist/harness/gates/migrated-waiver-review.js +116 -0
  510. package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
  511. package/dist/harness/gates/resolve-rule.d.ts +59 -0
  512. package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
  513. package/dist/harness/gates/resolve-rule.js +41 -0
  514. package/dist/harness/gates/resolve-rule.js.map +1 -0
  515. package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
  516. package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
  517. package/dist/harness/gates/unit-gate-overrides.js +122 -0
  518. package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
  519. package/dist/harness/journey.d.ts +24 -1
  520. package/dist/harness/journey.d.ts.map +1 -1
  521. package/dist/harness/journey.js +114 -23
  522. package/dist/harness/journey.js.map +1 -1
  523. package/dist/harness/manifest.d.ts +12 -0
  524. package/dist/harness/manifest.d.ts.map +1 -1
  525. package/dist/harness/manifest.js +73 -45
  526. package/dist/harness/manifest.js.map +1 -1
  527. package/dist/harness/next-step.d.ts +37 -6
  528. package/dist/harness/next-step.d.ts.map +1 -1
  529. package/dist/harness/next-step.js +34 -174
  530. package/dist/harness/next-step.js.map +1 -1
  531. package/dist/harness/parse.d.ts +25 -0
  532. package/dist/harness/parse.d.ts.map +1 -1
  533. package/dist/harness/parse.js +38 -13
  534. package/dist/harness/parse.js.map +1 -1
  535. package/dist/harness/script-check.d.ts.map +1 -1
  536. package/dist/harness/script-check.js +29 -6
  537. package/dist/harness/script-check.js.map +1 -1
  538. package/dist/harness/sensors.d.ts +14 -3
  539. package/dist/harness/sensors.d.ts.map +1 -1
  540. package/dist/harness/sensors.js +64 -44
  541. package/dist/harness/sensors.js.map +1 -1
  542. package/dist/harness/triage-signals.d.ts +20 -0
  543. package/dist/harness/triage-signals.d.ts.map +1 -0
  544. package/dist/harness/triage-signals.js +30 -0
  545. package/dist/harness/triage-signals.js.map +1 -0
  546. package/dist/harness/triage-unit.d.ts +23 -0
  547. package/dist/harness/triage-unit.d.ts.map +1 -0
  548. package/dist/harness/triage-unit.js +142 -0
  549. package/dist/harness/triage-unit.js.map +1 -0
  550. package/dist/harness/triage.d.ts +28 -0
  551. package/dist/harness/triage.d.ts.map +1 -0
  552. package/dist/harness/triage.js +99 -0
  553. package/dist/harness/triage.js.map +1 -0
  554. package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
  555. package/dist/harness/viewpoint-ledger.js +2 -1
  556. package/dist/harness/viewpoint-ledger.js.map +1 -1
  557. package/dist/hooks/bash-write-targets.d.ts +15 -0
  558. package/dist/hooks/bash-write-targets.d.ts.map +1 -0
  559. package/dist/hooks/bash-write-targets.js +173 -0
  560. package/dist/hooks/bash-write-targets.js.map +1 -0
  561. package/dist/hooks/claude-hook-entry.d.ts +11 -0
  562. package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
  563. package/dist/hooks/claude-hook-entry.js +137 -0
  564. package/dist/hooks/claude-hook-entry.js.map +1 -0
  565. package/dist/hooks/claude-transcript-turn.d.ts +11 -0
  566. package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
  567. package/dist/hooks/claude-transcript-turn.js +143 -0
  568. package/dist/hooks/claude-transcript-turn.js.map +1 -0
  569. package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
  570. package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
  571. package/dist/hooks/guard-delivery-contract-rule.js +152 -0
  572. package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
  573. package/dist/hooks/guard-protected-paths.d.ts +9 -0
  574. package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
  575. package/dist/hooks/guard-protected-paths.js +106 -0
  576. package/dist/hooks/guard-protected-paths.js.map +1 -0
  577. package/dist/hooks/guard-rules.d.ts +37 -0
  578. package/dist/hooks/guard-rules.d.ts.map +1 -0
  579. package/dist/hooks/guard-rules.js +61 -0
  580. package/dist/hooks/guard-rules.js.map +1 -0
  581. package/dist/hooks/guard-tty-spoof-rule.d.ts +15 -0
  582. package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
  583. package/dist/hooks/guard-tty-spoof-rule.js +21 -0
  584. package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
  585. package/dist/hooks/hand-back-core.d.ts +37 -0
  586. package/dist/hooks/hand-back-core.d.ts.map +1 -0
  587. package/dist/hooks/hand-back-core.js +115 -0
  588. package/dist/hooks/hand-back-core.js.map +1 -0
  589. package/dist/hooks/hook-cli-command.d.ts +9 -0
  590. package/dist/hooks/hook-cli-command.d.ts.map +1 -0
  591. package/dist/hooks/hook-cli-command.js +46 -0
  592. package/dist/hooks/hook-cli-command.js.map +1 -0
  593. package/dist/hooks/hook-registry.d.ts +10 -0
  594. package/dist/hooks/hook-registry.d.ts.map +1 -0
  595. package/dist/hooks/hook-registry.js +24 -0
  596. package/dist/hooks/hook-registry.js.map +1 -0
  597. package/dist/hooks/hook-result-contract.d.ts +50 -0
  598. package/dist/hooks/hook-result-contract.d.ts.map +1 -0
  599. package/dist/hooks/hook-result-contract.js +80 -0
  600. package/dist/hooks/hook-result-contract.js.map +1 -0
  601. package/dist/hooks/hook-toggles.d.ts +10 -0
  602. package/dist/hooks/hook-toggles.d.ts.map +1 -0
  603. package/dist/hooks/hook-toggles.js +107 -0
  604. package/dist/hooks/hook-toggles.js.map +1 -0
  605. package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
  606. package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
  607. package/dist/hooks/pre-tool-guard-hook.js +105 -0
  608. package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
  609. package/dist/hooks/session-start-unit-state-hook.d.ts +13 -0
  610. package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
  611. package/dist/hooks/session-start-unit-state-hook.js +55 -0
  612. package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
  613. package/dist/hooks/stop-next-step-hook.d.ts +16 -0
  614. package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
  615. package/dist/hooks/stop-next-step-hook.js +42 -0
  616. package/dist/hooks/stop-next-step-hook.js.map +1 -0
  617. package/dist/hooks/sungen-project-root.d.ts +19 -0
  618. package/dist/hooks/sungen-project-root.d.ts.map +1 -0
  619. package/dist/hooks/sungen-project-root.js +130 -0
  620. package/dist/hooks/sungen-project-root.js.map +1 -0
  621. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
  622. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
  623. package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
  624. package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
  625. package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
  626. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
  627. package/dist/orchestrator/ai-skills/commands.js +16 -6
  628. package/dist/orchestrator/ai-skills/commands.js.map +1 -1
  629. package/dist/orchestrator/ai-skills/golden-skills.test.js +29 -0
  630. package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -1
  631. package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
  632. package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
  633. package/dist/orchestrator/claude-hooks-install.js +203 -0
  634. package/dist/orchestrator/claude-hooks-install.js.map +1 -0
  635. package/dist/orchestrator/lockstep-version.d.ts +15 -5
  636. package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
  637. package/dist/orchestrator/lockstep-version.js +30 -17
  638. package/dist/orchestrator/lockstep-version.js.map +1 -1
  639. package/dist/orchestrator/project-initializer.d.ts +6 -0
  640. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  641. package/dist/orchestrator/project-initializer.js +23 -0
  642. package/dist/orchestrator/project-initializer.js.map +1 -1
  643. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  644. package/dist/orchestrator/screen-manager.js +4 -2
  645. package/dist/orchestrator/screen-manager.js.map +1 -1
  646. package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  647. package/dist/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
  648. package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  649. package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  650. package/dist/orchestrator/templates/ai-src/commands/create-test.md +14 -16
  651. package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  652. package/dist/orchestrator/templates/ai-src/commands/delivery.md +2 -0
  653. package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
  654. package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  655. package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
  656. package/dist/orchestrator/templates/ai-src/commands/review.md +2 -0
  657. package/dist/orchestrator/templates/ai-src/commands/run-test.md +14 -10
  658. package/dist/orchestrator/templates/ai-src/config/claude.md +20 -7
  659. package/dist/orchestrator/templates/ai-src/config/copilot.md +20 -7
  660. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  661. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  662. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  663. package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
  664. package/dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
  665. package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
  666. package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
  667. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
  668. package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
  669. package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  670. package/dist/utils/safe-yaml-parse.d.ts +8 -0
  671. package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
  672. package/dist/utils/safe-yaml-parse.js +51 -0
  673. package/dist/utils/safe-yaml-parse.js.map +1 -0
  674. package/package.json +3 -3
  675. package/src/basis/anchor-grammar.ts +83 -0
  676. package/src/basis/anchor-hash.ts +27 -0
  677. package/src/basis/bm51-tables.ts +65 -0
  678. package/src/basis/extract-spec-anchors.ts +95 -0
  679. package/src/basis/migration-sentinel.ts +175 -0
  680. package/src/basis/spec-frontmatter.ts +68 -0
  681. package/src/basis/spec-sections.ts +35 -0
  682. package/src/basis/test-basis-schema.ts +81 -0
  683. package/src/capabilities/registry.ts +16 -0
  684. package/src/cli/commands/audit.ts +9 -4
  685. package/src/cli/commands/capability.ts +4 -2
  686. package/src/cli/commands/contract-derive-command.ts +60 -0
  687. package/src/cli/commands/contract.ts +130 -0
  688. package/src/cli/commands/defect.ts +49 -0
  689. package/src/cli/commands/delivery.ts +85 -13
  690. package/src/cli/commands/generate.ts +3 -1
  691. package/src/cli/commands/journey.ts +39 -14
  692. package/src/cli/commands/next.ts +60 -8
  693. package/src/cli/commands/triage.ts +57 -0
  694. package/src/cli/commands/update.ts +35 -8
  695. package/src/cli/index.ts +24 -30
  696. package/src/contract/approve-contract.ts +94 -0
  697. package/src/contract/assertion-matcher-vocabulary.ts +93 -0
  698. package/src/contract/build-contract-verdict.ts +108 -0
  699. package/src/contract/build-trace-conformance.ts +100 -0
  700. package/src/contract/classify-contract-change.ts +92 -0
  701. package/src/contract/classify-contract-unit.ts +47 -0
  702. package/src/contract/classify-trace-conformance.ts +116 -0
  703. package/src/contract/contract-git.ts +106 -0
  704. package/src/contract/contract-hash.ts +34 -0
  705. package/src/contract/contract-report-file.ts +25 -0
  706. package/src/contract/contract-schema.ts +137 -0
  707. package/src/contract/contract-units.ts +52 -0
  708. package/src/contract/contracts-lock-file.ts +97 -0
  709. package/src/contract/data-normalize.ts +66 -0
  710. package/src/contract/derive-free-feature.ts +110 -0
  711. package/src/contract/field-semantic-redaction.ts +80 -0
  712. package/src/contract/free-feature-blocks.ts +56 -0
  713. package/src/contract/lock-secret-guard.ts +95 -0
  714. package/src/contract/lock-vs-git-head.ts +38 -0
  715. package/src/contract/normalize-contract-step.ts +74 -0
  716. package/src/contract/normalize-feature-steps.ts +93 -0
  717. package/src/contract/oracle-strength.ts +80 -0
  718. package/src/contract/project-contract-blockers.ts +36 -0
  719. package/src/contract/record-contract-approval.ts +70 -0
  720. package/src/contract/render-free-gherkin.ts +113 -0
  721. package/src/contract/render-trace-sentence.ts +98 -0
  722. package/src/contract/render-trace-target.ts +68 -0
  723. package/src/contract/resolve-unit-trace-identities.ts +35 -0
  724. package/src/contract/trace/collect-trace-evidence.ts +109 -0
  725. package/src/contract/trace/identity-cache.ts +61 -0
  726. package/src/contract/trace/select-final-attempt.ts +70 -0
  727. package/src/contract/trace/snapshot-html-renderer.ts +136 -0
  728. package/src/contract/trace/snapshot-resolver.ts +66 -0
  729. package/src/contract/trace/snapshot-store.ts +151 -0
  730. package/src/contract/trace/target-identity.ts +104 -0
  731. package/src/contract/trace/test-step-join.ts +103 -0
  732. package/src/contract/trace/trace-binding.ts +56 -0
  733. package/src/contract/trace/trace-file-reader.ts +123 -0
  734. package/src/contract/trace/trace-fingerprint.ts +68 -0
  735. package/src/contract/trace/trace-identity-resolution.ts +74 -0
  736. package/src/contract/trace/trace-run-record.ts +74 -0
  737. package/src/contract/trace/trace-steps.ts +88 -0
  738. package/src/contract/trace/trace-zip-limits.ts +73 -0
  739. package/src/contract/trace/trace-zip-reader.ts +127 -0
  740. package/src/contract/verify-approval-decisions.ts +60 -0
  741. package/src/decisions/append-decision.ts +35 -0
  742. package/src/decisions/confirmed-decision-commands.ts +128 -0
  743. package/src/decisions/decision-file.ts +93 -0
  744. package/src/decisions/decision-identity.ts +73 -0
  745. package/src/decisions/decision-integrity-check.ts +61 -0
  746. package/src/decisions/decision-schema.ts +76 -0
  747. package/src/decisions/decision-source.ts +14 -0
  748. package/src/decisions/exclusive-file-create.ts +42 -0
  749. package/src/decisions/git-head-trust.ts +32 -0
  750. package/src/decisions/human-confirmation.ts +114 -0
  751. package/src/decisions/legacy-waiver-migration.ts +135 -0
  752. package/src/decisions/read-decisions.ts +61 -0
  753. package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
  754. package/src/decisions/waiver-decisions.ts +56 -0
  755. package/src/exporters/csv-exporter.ts +5 -1
  756. package/src/exporters/feature-parser.ts +12 -0
  757. package/src/exporters/matrix/build.ts +62 -18
  758. package/src/exporters/matrix/carry-manual-results.ts +70 -7
  759. package/src/exporters/matrix/export.ts +17 -2
  760. package/src/exporters/matrix/gates.ts +62 -129
  761. package/src/exporters/matrix/render-csv.ts +4 -1
  762. package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
  763. package/src/exporters/matrix/render-xlsx.ts +6 -0
  764. package/src/exporters/matrix/types.ts +9 -1
  765. package/src/exporters/playwright-report-parser.ts +1 -0
  766. package/src/exporters/scenario-merger.ts +2 -1
  767. package/src/exporters/types.ts +5 -0
  768. package/src/generators/test-generator/code-generator.ts +13 -0
  769. package/src/graph/evaluate-graph.ts +62 -0
  770. package/src/graph/locate-finding.ts +93 -0
  771. package/src/graph/node-decl.ts +65 -0
  772. package/src/graph/nodes/core-node-catalog.ts +15 -0
  773. package/src/graph/nodes/test-case-contract-nodes.ts +69 -0
  774. package/src/graph/nodes/test-case-nodes.ts +68 -0
  775. package/src/graph/nodes/unit-audit-nodes.ts +95 -0
  776. package/src/graph/nodes/unit-contract-node.ts +82 -0
  777. package/src/graph/nodes/unit-design-nodes.ts +88 -0
  778. package/src/graph/nodes/unit-execution-nodes.ts +77 -0
  779. package/src/graph/test-case-identity.ts +75 -0
  780. package/src/graph/test-case-results.ts +90 -0
  781. package/src/graph/test-case-satisfied.ts +55 -0
  782. package/src/graph/test-case-state-shape.ts +62 -0
  783. package/src/graph/test-case-states.ts +84 -0
  784. package/src/graph/unit-artifact-probes.ts +77 -0
  785. package/src/graph/unit-state-facts.ts +112 -0
  786. package/src/harness/audit.ts +46 -11
  787. package/src/harness/catalog/gate-rules.yaml +647 -0
  788. package/src/harness/counted-assertions.ts +33 -0
  789. package/src/harness/defect-draft.ts +115 -0
  790. package/src/harness/defects.ts +94 -0
  791. package/src/harness/gates/audit-gate-terms.ts +80 -0
  792. package/src/harness/gates/audit-gate-verdict.ts +78 -0
  793. package/src/harness/gates/audit-input-hash.ts +55 -0
  794. package/src/harness/gates/audit-report-verification.ts +173 -0
  795. package/src/harness/gates/decisions-hash.ts +42 -0
  796. package/src/harness/gates/delivery-checklist.ts +120 -0
  797. package/src/harness/gates/delivery-decision-gate.ts +111 -0
  798. package/src/harness/gates/delivery-decision-step.ts +73 -0
  799. package/src/harness/gates/gate-override-report.ts +114 -0
  800. package/src/harness/gates/gate-override-scope.ts +66 -0
  801. package/src/harness/gates/gate-override-validation.ts +75 -0
  802. package/src/harness/gates/gate-rule-catalog.ts +82 -0
  803. package/src/harness/gates/gate-terms.ts +59 -0
  804. package/src/harness/gates/in-run-decision-check.ts +99 -0
  805. package/src/harness/gates/journey-gate-inputs.ts +89 -0
  806. package/src/harness/gates/migrated-waiver-review.ts +68 -0
  807. package/src/harness/gates/resolve-rule.ts +94 -0
  808. package/src/harness/gates/unit-gate-overrides.ts +99 -0
  809. package/src/harness/journey.ts +122 -27
  810. package/src/harness/manifest.ts +69 -45
  811. package/src/harness/next-step.ts +60 -170
  812. package/src/harness/parse.ts +40 -13
  813. package/src/harness/script-check.ts +27 -6
  814. package/src/harness/sensors.ts +73 -47
  815. package/src/harness/triage-signals.ts +46 -0
  816. package/src/harness/triage-unit.ts +113 -0
  817. package/src/harness/triage.ts +127 -0
  818. package/src/harness/viewpoint-ledger.ts +2 -2
  819. package/src/hooks/bash-write-targets.ts +109 -0
  820. package/src/hooks/claude-hook-entry.ts +85 -0
  821. package/src/hooks/claude-transcript-turn.ts +96 -0
  822. package/src/hooks/guard-delivery-contract-rule.ts +110 -0
  823. package/src/hooks/guard-protected-paths.ts +70 -0
  824. package/src/hooks/guard-rules.ts +98 -0
  825. package/src/hooks/guard-tty-spoof-rule.ts +31 -0
  826. package/src/hooks/hand-back-core.ts +106 -0
  827. package/src/hooks/hook-cli-command.ts +17 -0
  828. package/src/hooks/hook-registry.ts +24 -0
  829. package/src/hooks/hook-result-contract.ts +114 -0
  830. package/src/hooks/hook-toggles.ts +66 -0
  831. package/src/hooks/pre-tool-guard-hook.ts +67 -0
  832. package/src/hooks/session-start-unit-state-hook.ts +54 -0
  833. package/src/hooks/stop-next-step-hook.ts +37 -0
  834. package/src/hooks/sungen-project-root.ts +80 -0
  835. package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
  836. package/src/orchestrator/ai-skills/commands.ts +22 -8
  837. package/src/orchestrator/ai-skills/golden-skills.test.ts +23 -0
  838. package/src/orchestrator/claude-hooks-install.ts +168 -0
  839. package/src/orchestrator/lockstep-version.ts +28 -15
  840. package/src/orchestrator/project-initializer.ts +21 -0
  841. package/src/orchestrator/screen-manager.ts +3 -1
  842. package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  843. package/src/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
  844. package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  845. package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  846. package/src/orchestrator/templates/ai-src/commands/create-test.md +14 -16
  847. package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  848. package/src/orchestrator/templates/ai-src/commands/delivery.md +2 -0
  849. package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
  850. package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  851. package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
  852. package/src/orchestrator/templates/ai-src/commands/review.md +2 -0
  853. package/src/orchestrator/templates/ai-src/commands/run-test.md +14 -10
  854. package/src/orchestrator/templates/ai-src/config/claude.md +20 -7
  855. package/src/orchestrator/templates/ai-src/config/copilot.md +20 -7
  856. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  857. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  858. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  859. package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
  860. package/src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
  861. package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
  862. package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
  863. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
  864. package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
  865. package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  866. package/src/utils/safe-yaml-parse.ts +44 -0
@@ -12,32 +12,45 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
12
12
  | `sungen-tc-generation` | Test case generation strategy, output format |
13
13
  | `sungen-test-design-techniques` | EP, BVA, Decision Table, State Transition — systematic scenario generation |
14
14
  | `sungen-tc-review` | Review scoring, quality rules, checklist |
15
- | `sungen-viewpoint` | 17 UI patterns x 4 viewpoints — coverage checklists |
15
+ | `sungen-viewpoint` | 32 UI patterns (17 web + 15 mobile-native) x 4 viewpoints — coverage checklists |
16
16
  | `sungen-selector-keys` | YAML key generation from `[Reference]` names, suffixes, lookup priority |
17
17
  | `sungen-selector-fix` | Selector generation from live page, auto-fix strategy |
18
- | `sungen-delivery` | Export Gherkin + Playwright results → CSV test case deliverable |
18
+ | `sungen-delivery` | Export the Test Case & Coverage Matrix (or the legacy per-scenario CSV) from Gherkin + Playwright results |
19
19
  | `sungen-capture` | Acquire visual/design context — one skill, 4 modes: figma-mcp (Dev Mode MCP), figma-pat (URL → spec_figma.md), live (Playwright MCP scan), local (images in `requirements/ui/`) |
20
20
  | `sungen-locale` | Bootstrap i18n — audit selectors, detect locale switch mechanism, generate test-data overlay |
21
21
  | `sungen-data-factory` | Standardized test-data — field-type/security catalog, 4-source method, `.overwrite`, blind-spot prompts |
22
+ | `sungen-harness-audit` | How to read `sungen audit` output and repair test-design findings (the create-test quality loop) |
23
+ | `sungen-capture-mobile` | Capture a live mobile screen via Appium MCP — locator tree + screenshot (`@platform:mobile/android/ios`) |
24
+ | `sungen-mobile-gestures` | Mobile gesture patterns (swipe, long-press, scroll-to, pinch, pull-to-refresh) — Gherkin + Appium MCP mapping |
25
+ | `sungen-selector-fix-mobile` | Mobile selector fixing — Appium MCP exploration, accessibility-id-first strategy, run via wdio |
26
+ | `sungen-api-design` | API-first design loop for an api unit — catalog, API viewpoints, `@api`/`@cases`/flow scenarios, audit gate + repair |
27
+ | `sungen-api-coverage-model` | Per-endpoint API coverage model — tiered case set expanded from the catalog's `fields:` metadata |
28
+ | `sungen-ingest-legacy` | Import a legacy manual test-case suite (Google Sheets or local file) via `sungen ingest` |
29
+ | `sungen-dashboard` | Single-file HTML dashboard of test cases + results (`sungen dashboard`) |
22
30
 
23
- ## Workflow (8 AI commands)
31
+ ## Workflow (12 AI commands)
24
32
 
25
33
  | Command | What it does |
26
34
  |---|---|
27
35
  | `/sungen:add-screen <name> <path>` | Scaffold `qa/screens/<name>/` directories |
28
36
  | `/sungen:add-flow <name> [--path <url>]` | Scaffold `qa/flows/<name>/` directories for E2E cross-screen testing |
29
- | `/sungen:create-test <name>` | Generate `.feature` + `test-data.yaml` (auto-detects screen or flow) |
37
+ | `/sungen:add-api <name> [--base-url <url>] [--flow <name>] [--import <spec>]` | Scaffold an API area (`qa/api/<name>/`), or an ordered `@api` chain with `--flow` (`qa/api/flows/<name>/`); `--base-url` is needed only until the project has an API datasource; `--import` an OpenAPI/CSV spec to populate the endpoint catalog |
38
+ | `/sungen:create-test <name>` | Generate `.feature` + `test-data.yaml`, then run the quality harness (auto-detects screen / flow / API) |
39
+ | `/sungen:design <name>` | Alias of `create-test` |
30
40
  | `/sungen:create-data-test <name>` | Generate standardized test-data (valid/boundary/invalid + CHK trace) from the Data Factory catalog; no name = all units (asks to confirm) |
31
41
  | `/sungen:review <name>` | Score syntax, coverage, viewpoint quality (auto-detects screen or flow) |
32
- | `/sungen:run-test <name>` | Generate `selectors.yaml`, compile, run, auto-fix (auto-detects screen or flow) |
33
- | `/sungen:delivery [name...]` | Export the Test Case & Coverage Matrix (review/manual/customer deliverable; `--legacy` = classic CSV; all screens if no arg) |
42
+ | `/sungen:run-test <name>` | Generate `selectors.yaml`, compile, run, auto-fix (auto-detects screen / flow / API) |
43
+ | `/sungen:delivery [name...]` | Export the Test Case & Coverage Matrix (review/manual/customer deliverable; `--legacy` = classic CSV; all units if no arg) |
44
+ | `/sungen:dashboard [name...]` | Build the single-file HTML dashboard (`qa/dashboard/index.html`) — results, trends, run compare, CSV/XLSX export |
34
45
  | `/sungen:locale <name> <locale>` | Bootstrap i18n for a screen — audit selectors, detect locale switch, generate overlay (run before `/sungen:run-test --env <locale>`) |
46
+ | `/sungen:feedback [message]` | Record QA feedback locally (`.sungen/feedback/`) with context attached |
35
47
 
36
48
  **Screen path:** add-screen → create-test → review → run-test → delivery.
37
49
  **Flow path:** add-flow → create-test → review → run-test → delivery.
50
+ **API path:** add-api (`--import <openapi|csv>` for accuracy) → create-test → run-test → delivery. API units carry no selectors and no visual capture; create-test runs the audit + reviewer loop itself.
38
51
  **i18n path:** (after run-test passes for base locale) → locale → run-test --env <locale> → delivery --env <locale>.
39
52
 
40
- `create-test`, `review`, and `run-test` auto-detect context: if `qa/flows/<name>/` exists → flow mode, else `qa/screens/<name>/` → screen mode.
53
+ `create-test` and `run-test` auto-detect context: if `qa/api/<name>/` (or `qa/api/flows/<name>/`) exists → API mode, else if `qa/flows/<name>/` → flow mode, else `qa/screens/<name>/` → screen mode. `review` covers screen and flow units.
41
54
 
42
55
  After each command completes, use `AskUserQuestion` to present the next actions as selectable options. Never just print text — always give clickable choices so the user can continue the workflow seamlessly.
43
56
 
@@ -12,32 +12,45 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
12
12
  | `sungen-tc-generation` | Test case generation strategy, output format |
13
13
  | `sungen-test-design-techniques` | EP, BVA, Decision Table, State Transition — systematic scenario generation |
14
14
  | `sungen-tc-review` | Review scoring, quality rules, checklist |
15
- | `sungen-viewpoint` | 17 UI patterns x 4 viewpoints — coverage checklists |
15
+ | `sungen-viewpoint` | 32 UI patterns (17 web + 15 mobile-native) x 4 viewpoints — coverage checklists |
16
16
  | `sungen-selector-keys` | YAML key generation from `[Reference]` names, suffixes, lookup priority |
17
17
  | `sungen-selector-fix` | Selector generation from live page, auto-fix strategy |
18
- | `sungen-delivery` | Export Gherkin + Playwright results → CSV test case deliverable |
18
+ | `sungen-delivery` | Export the Test Case & Coverage Matrix (or the legacy per-scenario CSV) from Gherkin + Playwright results |
19
19
  | `sungen-capture` | Acquire visual/design context — one skill, 4 modes: figma-mcp (Dev Mode MCP), figma-pat (URL → spec_figma.md), live (Playwright MCP scan), local (images in `requirements/ui/`) |
20
20
  | `sungen-locale` | Bootstrap i18n — audit selectors, detect locale switch mechanism, generate test-data overlay |
21
21
  | `sungen-data-factory` | Standardized test-data — field-type/security catalog, 4-source method, `.overwrite`, blind-spot prompts |
22
+ | `sungen-harness-audit` | How to read `sungen audit` output and repair test-design findings (the create-test quality loop) |
23
+ | `sungen-capture-mobile` | Capture a live mobile screen via Appium MCP — locator tree + screenshot (`@platform:mobile/android/ios`) |
24
+ | `sungen-mobile-gestures` | Mobile gesture patterns (swipe, long-press, scroll-to, pinch, pull-to-refresh) — Gherkin + Appium MCP mapping |
25
+ | `sungen-selector-fix-mobile` | Mobile selector fixing — Appium MCP exploration, accessibility-id-first strategy, run via wdio |
26
+ | `sungen-api-design` | API-first design loop for an api unit — catalog, API viewpoints, `@api`/`@cases`/flow scenarios, audit gate + repair |
27
+ | `sungen-api-coverage-model` | Per-endpoint API coverage model — tiered case set expanded from the catalog's `fields:` metadata |
28
+ | `sungen-ingest-legacy` | Import a legacy manual test-case suite (Google Sheets or local file) via `sungen ingest` |
29
+ | `sungen-dashboard` | Single-file HTML dashboard of test cases + results (`sungen dashboard`) |
22
30
 
23
- ## Workflow (8 AI commands)
31
+ ## Workflow (12 AI commands)
24
32
 
25
33
  | Command | What it does |
26
34
  |---|---|
27
35
  | `/sungen-add-screen <name> <path>` | Scaffold `qa/screens/<name>/` directories |
28
36
  | `/sungen-add-flow <name> [--path <url>]` | Scaffold `qa/flows/<name>/` directories for E2E cross-screen testing |
29
- | `/sungen-create-test <name>` | Generate `.feature` + `test-data.yaml` (auto-detects screen or flow) |
37
+ | `/sungen-add-api <name> [--base-url <url>] [--flow <name>] [--import <spec>]` | Scaffold an API area (`qa/api/<name>/`), or an ordered `@api` chain with `--flow` (`qa/api/flows/<name>/`); `--base-url` is needed only until the project has an API datasource; `--import` an OpenAPI/CSV spec to populate the endpoint catalog |
38
+ | `/sungen-create-test <name>` | Generate `.feature` + `test-data.yaml`, then run the quality harness (auto-detects screen / flow / API) |
39
+ | `/sungen-design <name>` | Alias of `create-test` |
30
40
  | `/sungen-create-data-test <name>` | Generate standardized test-data (valid/boundary/invalid + CHK trace) from the Data Factory catalog; no name = all units (asks to confirm) |
31
41
  | `/sungen-review <name>` | Score syntax, coverage, viewpoint quality (auto-detects screen or flow) |
32
- | `/sungen-run-test <name>` | Generate `selectors.yaml`, compile, run, auto-fix (auto-detects screen or flow) |
33
- | `/sungen-delivery [name...]` | Export the Test Case & Coverage Matrix (review/manual/customer deliverable; `--legacy` = classic CSV; all screens if no arg) |
42
+ | `/sungen-run-test <name>` | Generate `selectors.yaml`, compile, run, auto-fix (auto-detects screen / flow / API) |
43
+ | `/sungen-delivery [name...]` | Export the Test Case & Coverage Matrix (review/manual/customer deliverable; `--legacy` = classic CSV; all units if no arg) |
44
+ | `/sungen-dashboard [name...]` | Build the single-file HTML dashboard (`qa/dashboard/index.html`) — results, trends, run compare, CSV/XLSX export |
34
45
  | `/sungen-locale <name> <locale>` | Bootstrap i18n for a screen — audit selectors, detect locale switch, generate overlay (run before `/sungen-run-test --env <locale>`) |
46
+ | `/sungen-feedback [message]` | Record QA feedback locally (`.sungen/feedback/`) with context attached |
35
47
 
36
48
  **Screen path:** add-screen → create-test → review → run-test → delivery.
37
49
  **Flow path:** add-flow → create-test → review → run-test → delivery.
50
+ **API path:** add-api (`--import <openapi|csv>` for accuracy) → create-test → run-test → delivery. API units carry no selectors and no visual capture; create-test runs the audit + reviewer loop itself.
38
51
  **i18n path:** (after run-test passes for base locale) → locale → run-test --env <locale> → delivery --env <locale>.
39
52
 
40
- `create-test`, `review`, and `run-test` auto-detect context: if `qa/flows/<name>/` exists → flow mode, else `qa/screens/<name>/` → screen mode.
53
+ `create-test` and `run-test` auto-detect context: if `qa/api/<name>/` (or `qa/api/flows/<name>/`) exists → API mode, else if `qa/flows/<name>/` → flow mode, else `qa/screens/<name>/` → screen mode. `review` covers screen and flow units.
41
54
 
42
55
  After each command completes, present the next actions as selectable options. Never just print text — always give clickable choices so the user can continue the workflow seamlessly.
43
56
 
@@ -0,0 +1,20 @@
1
+ <!-- sungen:hand-back-rule v1 -->
2
+ ## ⛔ HARD RULE — the run's LAST action is the next-step hand-back
3
+
4
+ A run is NOT finished when its files are written or its output prints. The final action of EVERY
5
+ run — success, partial, failed, or aborted — is the next-step hand-back.
6
+
7
+ **Ask `sungen next {{unitArg}}` rather than deciding from memory.** It derives the answer from what
8
+ the project actually holds (artifacts on disk, the audit report, the accepted viewpoint baseline,
9
+ the compiled spec, the run results and how many of them failed), so the hand-back stays correct
10
+ even when the run ended somewhere unexpected — a failed install, a driver that turned out not to
11
+ support this unit kind, an aborted repair loop. Every `sungen` command also prints
12
+ `Next: sungen next …` as its own last line, on stderr when the command failed.
13
+
14
+ **Hand back with `AskUserQuestion`** — one option per step `sungen next` lists. A `decide` step is
15
+ a QA decision: offer it, never run it yourself. Ending with a prose summary and no choices is a
16
+ broken run.
17
+
18
+ If a step turns out to be impossible, that is still a hand-back: say what blocked it, run
19
+ `sungen next {{unitArg}}`, and offer what remains.
20
+ <!-- /sungen:hand-back-rule -->
@@ -0,0 +1,20 @@
1
+ <!-- sungen:hand-back-rule v1 -->
2
+ ## ⛔ HARD RULE — the run's LAST action is the next-step hand-back
3
+
4
+ A run is NOT finished when its files are written or its output prints. The final action of EVERY
5
+ run — success, partial, failed, or aborted — is the next-step hand-back.
6
+
7
+ **Ask `sungen next {{unitArg}}` rather than deciding from memory.** It derives the answer from what
8
+ the project actually holds (artifacts on disk, the audit report, the accepted viewpoint baseline,
9
+ the compiled spec, the run results and how many of them failed), so the hand-back stays correct
10
+ even when the run ended somewhere unexpected — a failed install, a driver that turned out not to
11
+ support this unit kind, an aborted repair loop. Every `sungen` command also prints
12
+ `Next: sungen next …` as its own last line, on stderr when the command failed.
13
+
14
+ **Hand back as a numbered list and stop** — one item per step `sungen next` lists, then end your
15
+ turn and wait for the user's pick. A `decide` step is a QA decision: list it, never run it
16
+ yourself. Ending with a prose summary and no numbered choices is a broken run.
17
+
18
+ If a step turns out to be impossible, that is still a hand-back: say what blocked it, run
19
+ `sungen next {{unitArg}}`, and list what remains.
20
+ <!-- /sungen:hand-back-rule -->
@@ -0,0 +1,20 @@
1
+ <!-- sungen:hand-back-rule v1 -->
2
+ ## ⛔ HARD RULE — the run's LAST action is the next-step hand-back
3
+
4
+ A run is NOT finished when its files are written or its output prints. The final action of EVERY
5
+ run — success, partial, failed, or aborted — is the next-step hand-back.
6
+
7
+ **Ask `sungen next {{unitArg}}` rather than deciding from memory.** It derives the answer from what
8
+ the project actually holds (artifacts on disk, the audit report, the accepted viewpoint baseline,
9
+ the compiled spec, the run results and how many of them failed), so the hand-back stays correct
10
+ even when the run ended somewhere unexpected — a failed install, a driver that turned out not to
11
+ support this unit kind, an aborted repair loop. Every `sungen` command also prints
12
+ `Next: sungen next …` as its own last line, on stderr when the command failed.
13
+
14
+ **Hand back as a numbered list and stop** — one item per step `sungen next` lists, then end your
15
+ turn and wait for the user's pick. A `decide` step is a QA decision: list it, never run it
16
+ yourself. Ending with a prose summary and no numbered choices is a broken run.
17
+
18
+ If a step turns out to be impossible, that is still a hand-back: say what blocked it, run
19
+ `sungen next {{unitArg}}`, and list what remains.
20
+ <!-- /sungen:hand-back-rule -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sungen-api-coverage-model
3
- description: The per-endpoint API coverage model — the systematic case set to enumerate for each endpoint (read / mutating / flow), keyed to the catalog's fields: metadata, tiered so a first pass is complete (not "happy path + 1 error"). Load this in API unit mode alongside sungen-api-design; it turns endpoints × field constraints into a concrete case list, mechanically, instead of guessing.
3
+ description: 'The per-endpoint API coverage model — the systematic case set to enumerate for each endpoint (read / mutating / flow), keyed to the catalog''s fields: metadata, tiered so a first pass is complete (not "happy path + 1 error"). Load this in API unit mode alongside sungen-api-design; it turns endpoints × field constraints into a concrete case list, mechanically, instead of guessing.'
4
4
  ---
5
5
 
6
6
  # API coverage model (what to test per endpoint)
@@ -6,7 +6,7 @@ user-invocable: false
6
6
 
7
7
  ## Purpose
8
8
 
9
- Launch a mobile app on a device/emulator, capture **one locator tree** (`generate_locators`) and **one screenshot**, and save them as visual context for test generation. The mobile analogue of `sungen-capture-live` — same job, Appium MCP instead of Playwright MCP.
9
+ Launch a mobile app on a device/emulator, capture **one locator tree** (`generate_locators`) and **one screenshot**, and save them as visual context for test generation. The mobile analogue of `sungen-capture` mode `live` — same job, Appium MCP instead of Playwright MCP.
10
10
 
11
11
  Use when the target is a native/Flutter/React-Native app (`@platform:android` or `@platform:ios`) running on a connected device or emulator.
12
12
 
@@ -188,8 +188,8 @@ Flutter/RN expose the same Semantics on each, so one exploration covers most of
188
188
 
189
189
  ## Relationship to other capture skills
190
190
 
191
- - `sungen-capture-figma` / `sungen-capture-local` — design/image sources (platform-agnostic)
192
- - `sungen-capture-live` — web (Playwright MCP)
191
+ - `sungen-capture` (modes `figma-mcp` / `figma-pat` / `local`) — design/image sources (platform-agnostic)
192
+ - `sungen-capture` (mode `live`) — web (Playwright MCP)
193
193
  - `sungen-capture-mobile` — this skill, mobile (Appium MCP)
194
194
 
195
195
  All write to `requirements/ui/` and report back to the caller.
@@ -69,6 +69,15 @@ Rules:
69
69
  catalog defaults).
70
70
  - Map every `errorRef` placeholder (`M13`, `M39`, …) to the spec's real code via `errorMap`. Leave
71
71
  one unmapped **only** if the spec has none — the lint flags it as an open point to confirm.
72
+ - Some catalog constraints are only placeholders (string `minLength: 1` / `maxLength: 255`, phone
73
+ `8..15`, …). A field that does not set its own value is warned **`PLACEHOLDER_CONSTRAINT`** — the
74
+ boundary cases are built from that number, so take it from the spec.
75
+ - An **empty value** is judged by `required`, not by `minLength`: `required: false` → `""` is valid
76
+ (no "below minimum" case for it); `required: true` **or unset** → `""` is invalid. `minLength: 0`
77
+ has no min-1 case. So an optional field must say `required: false`.
78
+ - To drop **one** generated case for **one** field, list its id under the field's **`disable:`**
79
+ (e.g. `disable: [CHK-STR-I2]` drops min-1 and keeps max+1 `CHK-STR-I2a`). It is reported as
80
+ not applicable. The overwrite's `disable:` drops a case for every field of the type.
72
81
  - **Complex forms:** a **group** field takes nested **`fields:`** (recursive; no `type` on the group → renders a nested object like `address.city`). A field whose rule depends on another takes **`dependsOn: { field, value }`** — recorded as a `_depends_on` note (the generator doesn't resolve the runtime condition; weave it into the scenario/`@cases`).
73
82
  - Set **`unique: true`** on a field that must be fresh every run (register email/username, anything
74
83
  that would clash with a record a previous run left behind). Its valid value then carries a runtime
@@ -73,6 +73,8 @@ reason comment); the Given/When/Then stay **exactly** as QA approved them:
73
73
 
74
74
  > **Cardinal sin (do NOT do this):** a `password > 8 chars` rule fails on a 6-char input → "fix" it to `>= 6` so the test passes. The logic is now meaningless. A failing assertion is a **finding**, not a chore.
75
75
 
76
+ **`sungen triage` makes the first pass for you.** Its classes are this section's split: `test-defect` = selector-resolution / test-data failure (auto-fix scope), `product-candidate` = assertion-value failure with an Expected and a Received (apply the spec question above), `environment` = the run itself (fix the setup, not the test), `unclassified` = yours to judge — an assertion on an element that never appeared lands here, because a wrong selector and a missing message look the same.
77
+
76
78
  **Auto-fix loop scope:** the run-test auto-fix loop engages ONLY on **selector-resolution** failures. On an assertion-value failure where the app contradicts the spec → **HALT and report**, do not loop it into passing.
77
79
 
78
80
  **Never hand-edit the generated `.spec.ts`** (e.g. inserting `page.evaluate`/`fetch` to bypass a broken control). `sungen script-check` regenerates the spec from `.feature` and flags any edit as DRIFT — regenerate, don't patch.
@@ -631,7 +631,7 @@ on mobile a dialog-scoped ref still resolves against the whole screen (`SG-W021`
631
631
  | `@spec:<id>` | **Traceability**: this scenario proves requirement `<id>` from `requirements/spec.md` (`@spec:FR-003`). Repeatable — a scenario may prove several. Read by `sungen audit` (requirement coverage) and by delivery (the Coverage sheet's requirement table). Without it the link is only inferred from wording and cannot survive an edit. |
632
632
  | `@ui:<UI-NNN>` | **Design traceability**: this scenario proves design item `UI-NNN` from `requirements/ui-inventory.md` (`@ui:UI-014`). Repeatable. Read by `sungen audit` (`UI-ITEM-UNCOVERED`). An item deliberately not tested is recorded as a comment instead: `# UI-DEFERRED: UI-002..013 — <reason>`. Rules: `sungen-tc-generation` § Design Inventory. |
633
633
  | `@manual` | Skip in generation |
634
- | `@known-defect` | The scenario is EXPECTED to be red — it asserts a live defect. It still runs and still reports as failed (never skipped, never "fixed"), and it stays a pass-through tag so `--grep @known-defect` selects it. **`[mobile]`** Its failure does NOT escalate the next scenario's `@reset:` tier: a red that was designed in is not evidence of leftover state |
634
+ | `@known-defect` | The scenario is EXPECTED to be red — it asserts a live defect. It still runs and still reports as failed (never skipped, never "fixed"), and it stays a pass-through tag so `--grep @known-defect` selects it. `@known-defect:DEF-NNN` names the record in `qa/defects/DEF-NNN-*.md` (`sungen defect draft` writes it); `sungen audit` reports `DEFECT-REF-MISSING` when that file does not exist. **`[mobile]`** Its failure does NOT escalate the next scenario's `@reset:` tier: a red that was designed in is not evidence of leftover state |
635
635
  | `@auth:role` | Use auth storage state for role |
636
636
  | `@no-auth` | Disable inherited auth |
637
637
  | `@steps:name` | Define reusable step block (base scenario) |
@@ -35,6 +35,8 @@ user-invocable: false
35
35
  | **BALANCE** | secondary viewpoints (UI/validation/security) outweigh business-core | **Stop expanding** secondary viewpoints; generate the missing business-core scenarios first. Do not add more subscription/UI variants while core is thin. |
36
36
  | **TRACE** | scenarios use ad-hoc `VP-<CAT>-NNN` codes not linked to the viewpoint-overview | Make each scenario map to a viewpoint-overview id (align category codes, or add a mapping comment). |
37
37
  | **ORACLE-URL-ONLY** | every `Then` in the scenario is a page/URL assertion — it proves a path was pushed, not that the page rendered; on a permission/guard scenario a late 403 redirect turns it falsely green | Add `anchor:` to the page selector (one line per screen; every `see [X] page` on it becomes a content oracle) or a content assertion after the page step. Never delete the page step to silence it. |
38
+ | **DEFECT-REF-MISSING** | a `@known-defect:DEF-NNN` tag names no file in `qa/defects/` | Draft the record (`sungen defect draft --screen <name> --scenario "<title>"`) or correct the id. Never drop the tag to silence it — the scenario still asserts a live defect. |
39
+ | **DEFECT-ORPHAN** (info) | an open defect record names a scenario this unit no longer has | Update the record's `scenarios:` to the renamed title, or close the record if the scenario was removed on purpose. Nothing in the suite to repair. |
38
40
  | **UNIVERSAL** | a universal theme (error/empty-state, accessibility) is absent | Low priority — add if in scope; otherwise note as out-of-scope with reason. |
39
41
 
40
42
  ## P5 steps for deep cross-screen / list coverage
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * sungen — Claude Code hook launcher. Written by `sungen init` / `sungen update`; edits are
5
+ * overwritten. `.claude/settings.json` runs it in exec form (no shell):
6
+ * { "command": "node", "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/sungen-hook.cjs", "<hook>"] }
7
+ *
8
+ * Finds the installed sungen and runs one hook IN-PROCESS (node on dist — no npx — so a hook costs
9
+ * one Node start). Lookup: $SUNGEN_HOOK_ENTRY when set (exactly that file), else the project's own
10
+ * dependency, else the global npm prefix.
11
+ *
12
+ * FAILS OPEN: kill-switch set, sungen not found, or any error → prints `{}` and exits 0. A hook can
13
+ * never block or derail a session.
14
+ *
15
+ * Off switches: SUNGEN_HOOKS=off (all) · SUNGEN_HOOK_<NAME>=off (one) · qa/sungen.config.yaml `hooks:`.
16
+ */
17
+ const fs = require('fs');
18
+ const os = require('os');
19
+ const path = require('path');
20
+
21
+ const ENTRY = ['@sun-asterisk', 'sungen', 'dist', 'hooks', 'claude-hook-entry.js'];
22
+
23
+ function noop() {
24
+ process.stdout.write('{}\n', () => process.exit(0));
25
+ }
26
+
27
+ function npmrcPrefix() {
28
+ try {
29
+ const m = fs.readFileSync(path.join(os.homedir(), '.npmrc'), 'utf8').match(/^\s*prefix\s*=\s*(.+?)\s*$/m);
30
+ return m ? m[1].replace(/^~(?=$|[\\/])/, os.homedir()) : null;
31
+ } catch (_) {
32
+ return null;
33
+ }
34
+ }
35
+
36
+ function findEntry() {
37
+ const override = process.env.SUNGEN_HOOK_ENTRY;
38
+ if (override) return fs.existsSync(override) ? override : null;
39
+ const project = process.env.CLAUDE_PROJECT_DIR || process.cwd();
40
+ try {
41
+ return require.resolve(ENTRY.join('/'), { paths: [project] });
42
+ } catch (_) { /* not a project dependency — try the global install */ }
43
+ const bin = path.dirname(process.execPath);
44
+ const prefixes = [process.env.npm_config_prefix, npmrcPrefix(), path.join(bin, '..'), bin].filter(Boolean);
45
+ for (const prefix of prefixes) {
46
+ for (const lib of [path.join(prefix, 'lib', 'node_modules'), path.join(prefix, 'node_modules')]) {
47
+ const candidate = path.join(lib, ...ENTRY);
48
+ if (fs.existsSync(candidate)) return candidate;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+
54
+ try {
55
+ if (/^(?:off|0|false|no|disabled?)$/i.test(String(process.env.SUNGEN_HOOKS || '').trim())) {
56
+ noop();
57
+ } else {
58
+ const entry = findEntry();
59
+ if (!entry) noop();
60
+ else Promise.resolve(require(entry).main(process.argv[2] || '')).then(() => process.exit(0), noop);
61
+ }
62
+ } catch (_) {
63
+ noop();
64
+ }
@@ -0,0 +1,8 @@
1
+ export declare const SAFE_YAML_MAX_ALIAS_COUNT = 10;
2
+ export declare const SAFE_YAML_MAX_BYTES: number;
3
+ export declare class UnsafeYamlError extends Error {
4
+ readonly source: string;
5
+ constructor(source: string, detail: string);
6
+ }
7
+ export declare function safeYamlParse(text: string, source?: string): unknown;
8
+ //# sourceMappingURL=safe-yaml-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-yaml-parse.d.ts","sourceRoot":"","sources":["../../src/utils/safe-yaml-parse.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,mBAAmB,QAAc,CAAC;AAE/C,qBAAa,eAAgB,SAAQ,KAAK;aACZ,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI3D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAiBtE"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnsafeYamlError = exports.SAFE_YAML_MAX_BYTES = exports.SAFE_YAML_MAX_ALIAS_COUNT = void 0;
4
+ exports.safeYamlParse = safeYamlParse;
5
+ /**
6
+ * Parse YAML that a person or an agent wrote into `qa/` — decisions, test-basis, locks — without
7
+ * letting the file attack the reader (red-team #14, DOS-13.8).
8
+ *
9
+ * - `maxAliasCount` small: a "billion laughs" document that multiplies one anchor through nested
10
+ * aliases is refused instead of expanding to gigabytes. None of these files has a reason to
11
+ * alias at all; a handful is allowed so a hand-written file with one shared block still reads.
12
+ * - YAML **core** schema and nothing else: `!!binary`, `!!timestamp`, `!!js/…` or any custom tag is
13
+ * an error (the library would otherwise resolve "known" extra tags even under core), and yaml-1.1
14
+ * merge keys (`<<`) are not merged. `2026-10-21` stays the string it was written as, so a hash
15
+ * over the parsed value equals a hash over the text's intent.
16
+ * - duplicate keys are an error: two `reason:` lines must not let the second silently win.
17
+ * - a byte cap: these files are a few hundred bytes; a 100 MB one is an attack or an accident.
18
+ */
19
+ const yaml_1 = require("yaml");
20
+ exports.SAFE_YAML_MAX_ALIAS_COUNT = 10;
21
+ exports.SAFE_YAML_MAX_BYTES = 1024 * 1024;
22
+ class UnsafeYamlError extends Error {
23
+ constructor(source, detail) {
24
+ super(`${source}: ${detail}`);
25
+ this.source = source;
26
+ this.name = 'UnsafeYamlError';
27
+ }
28
+ }
29
+ exports.UnsafeYamlError = UnsafeYamlError;
30
+ function safeYamlParse(text, source = '<yaml>') {
31
+ if (Buffer.byteLength(text, 'utf8') > exports.SAFE_YAML_MAX_BYTES) {
32
+ throw new UnsafeYamlError(source, `larger than ${exports.SAFE_YAML_MAX_BYTES} bytes`);
33
+ }
34
+ let doc;
35
+ try {
36
+ doc = (0, yaml_1.parseDocument)(text, { schema: 'core', resolveKnownTags: false, merge: false, uniqueKeys: true, strict: true, prettyErrors: false });
37
+ }
38
+ catch (err) {
39
+ throw new UnsafeYamlError(source, err instanceof Error ? err.message : String(err));
40
+ }
41
+ const problem = doc.errors[0] ?? doc.warnings[0]; // an unresolved tag is only a warning to the library
42
+ if (problem)
43
+ throw new UnsafeYamlError(source, problem.message);
44
+ try {
45
+ return doc.toJS({ maxAliasCount: exports.SAFE_YAML_MAX_ALIAS_COUNT });
46
+ }
47
+ catch (err) {
48
+ throw new UnsafeYamlError(source, err instanceof Error ? err.message : String(err));
49
+ }
50
+ }
51
+ //# sourceMappingURL=safe-yaml-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-yaml-parse.js","sourceRoot":"","sources":["../../src/utils/safe-yaml-parse.ts"],"names":[],"mappings":";;;AA0BA,sCAiBC;AA3CD;;;;;;;;;;;;;GAaG;AACH,+BAAqC;AAExB,QAAA,yBAAyB,GAAG,EAAE,CAAC;AAC/B,QAAA,mBAAmB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAA4B,MAAc,EAAE,MAAc;QACxD,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;QADJ,WAAM,GAAN,MAAM,CAAQ;QAExC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED,SAAgB,aAAa,CAAC,IAAY,EAAE,MAAM,GAAG,QAAQ;IAC3D,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,2BAAmB,EAAE,CAAC;QAC1D,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,eAAe,2BAAmB,QAAQ,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,GAAqC,CAAC;IAC1C,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,oBAAa,EAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5I,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAG,qDAAqD;IACzG,IAAI,OAAO;QAAE,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,iCAAyB,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sungen",
3
- "version": "3.2.34",
3
+ "version": "3.3.0-alpha.1",
4
4
  "description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -40,8 +40,8 @@
40
40
  "@babel/types": "^7.28.5",
41
41
  "@cucumber/gherkin": "^37.0.0",
42
42
  "@cucumber/messages": "^31.0.0",
43
- "@sungen/driver-data-factory": "3.2.34",
44
- "@sungen/driver-ui": "3.2.34",
43
+ "@sungen/driver-data-factory": "3.3.0-alpha.1",
44
+ "@sungen/driver-ui": "3.3.0-alpha.1",
45
45
  "chalk": "^5.6.2",
46
46
  "commander": "^14.0.2",
47
47
  "dotenv": "^17.2.3",
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Anchor grammar and the shared trace vocabulary (DOS-12.1, DOS-12.2; takumi T7).
3
+ *
4
+ * | anchor | example | label |
5
+ * |----------------------------|--------------------------|-------------|
6
+ * | `<docId>#<itemId>` | `SPEC-AUTH-001#A-2` | `EXTRACTED` |
7
+ * | `<docId>#<itemId>/val` | `SPEC-AUTH-001#A-2/val` | `EXTRACTED` |
8
+ * | `sec-<slug>` | `sec-login-form` | `INFERRED` |
9
+ * | duplicate id / fuzzy match | — | `AMBIGUOUS` |
10
+ *
11
+ * docId is the spec frontmatter `id`; itemId is COMPOSED from BM-51 §4.1 (`2.0` under section row
12
+ * `A` → `A-2`). BM-51 has no `VAL-xx` codes: a Validation row is keyed by its item. `screen_id` is
13
+ * metadata and never part of an anchor. Every anchor is cited as `repo@SHA:path#Lx-Ly`.
14
+ */
15
+ import { createHash } from 'crypto';
16
+
17
+ export type AnchorKind = 'item' | 'validation' | 'section';
18
+ export type AnchorConfidence = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
19
+
20
+ /** Score band per label (takumi confidence taxonomy): inclusive lower, inclusive upper. */
21
+ export const CONFIDENCE_BANDS: Record<AnchorConfidence, readonly [number, number]> = {
22
+ EXTRACTED: [0.9, 1],
23
+ INFERRED: [0.5, 0.89],
24
+ AMBIGUOUS: [0, 0.49],
25
+ };
26
+
27
+ const DOC_ID = '[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+';
28
+ const ITEM_ID = '[A-Z]+-\\d+(?:\\.\\d+)?';
29
+ const ITEM_ANCHOR_RE = new RegExp(`^(${DOC_ID})#(${ITEM_ID})(/val)?$`);
30
+ const SECTION_ANCHOR_RE = /^sec-[a-z0-9]+(?:-[a-z0-9]+)*$/;
31
+ const CITATION_RE = /^([^@\s]+)@([^:\s]+):([^#\s]+)#L(\d+)-L(\d+)$/;
32
+
33
+ export interface ParsedAnchorId { kind: AnchorKind; docId?: string; itemId?: string; slug?: string }
34
+
35
+ export function parseAnchorId(id: string): ParsedAnchorId | null {
36
+ const item = ITEM_ANCHOR_RE.exec(id);
37
+ if (item) return { kind: item[3] ? 'validation' : 'item', docId: item[1], itemId: item[2] };
38
+ if (SECTION_ANCHOR_RE.test(id)) return { kind: 'section', slug: id.slice(4) };
39
+ return null;
40
+ }
41
+
42
+ export function isItemAnchorId(id: string): boolean {
43
+ return ITEM_ANCHOR_RE.test(id);
44
+ }
45
+
46
+ export function isDocId(id: string): boolean {
47
+ return new RegExp(`^${DOC_ID}$`).test(id);
48
+ }
49
+
50
+ export function itemAnchorId(docId: string, itemId: string, validation = false): string {
51
+ return `${docId}#${itemId}${validation ? '/val' : ''}`;
52
+ }
53
+
54
+ /**
55
+ * BM-51 §4.1 numbers items `1.0, 2.0 …` under a bold section row; the composed id drops the `.0`
56
+ * (`2.0` under `A` → `A-2`) and keeps a real sub-number (`2.1` → `A-2.1`). No section → null.
57
+ */
58
+ export function composeItemId(section: string | null, itemNumber: string): string | null {
59
+ if (!section || !/^[A-Z]+$/.test(section)) return null;
60
+ const n = itemNumber.trim().replace(/\.0+$/, '');
61
+ return /^\d+(?:\.\d+)?$/.test(n) ? `${section}-${n}` : null;
62
+ }
63
+
64
+ /** `sec-<slug>` from a heading: accents folded, ASCII kebab-case; a script with no ASCII gets a hash. */
65
+ export function sectionAnchorId(heading: string): string {
66
+ const slug = heading.normalize('NFKD').replace(/\p{M}/gu, '').replace(/[đĐ]/g, 'd').toLowerCase()
67
+ .replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
68
+ return `sec-${slug || createHash('sha1').update(heading).digest('hex').slice(0, 8)}`;
69
+ }
70
+
71
+ export interface CitationBase { repo: string; sha: string; path: string }
72
+
73
+ export function formatCitation(base: CitationBase, startLine: number, endLine: number): string {
74
+ return `${base.repo}@${base.sha}:${base.path.replace(/\\/g, '/')}#L${startLine}-L${endLine}`;
75
+ }
76
+
77
+ export function parseCitation(s: string): (CitationBase & { start: number; end: number }) | null {
78
+ const m = CITATION_RE.exec(s);
79
+ if (!m) return null;
80
+ const start = Number(m[4]);
81
+ const end = Number(m[5]);
82
+ return start >= 1 && end >= start ? { repo: m[1], sha: m[2], path: m[3], start, end } : null;
83
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Hash by anchor kind (DOS-12.3, red-team #1).
3
+ *
4
+ * | anchor kind | hash | why |
5
+ * |------------------------------|-------------|----------------------------------------------------------|
6
+ * | section `sec-<slug>` (legacy) | `sha1-12` | every manifest already on disk holds these; a new algorithm would read "changed" everywhere |
7
+ * | item `<docId>#<itemId>` | `sha256-12` | new in schema 2, so nothing old depends on it |
8
+ *
9
+ * `sectionHash` is the exact computation the manifest has always used: sha1 over the section
10
+ * body joined with LF and trimmed, first 12 hex. Do not "improve" it.
11
+ */
12
+ import { createHash } from 'crypto';
13
+
14
+ export type HashAlgo = 'sha1-12' | 'sha256-12';
15
+
16
+ export function sectionHash(bodyLines: string[]): string {
17
+ return createHash('sha1').update(bodyLines.join('\n').trim()).digest('hex').slice(0, 12);
18
+ }
19
+
20
+ /** One table row as compared: cells trimmed, inner whitespace collapsed, joined by `|`. */
21
+ export function normalizeRow(cells: string[]): string {
22
+ return cells.map((c) => c.normalize('NFC').replace(/\s+/g, ' ').trim()).join('|');
23
+ }
24
+
25
+ export function itemRowHash(cells: string[]): string {
26
+ return createHash('sha256').update(normalizeRow(cells)).digest('hex').slice(0, 12);
27
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Read the BM-51 screen-spec tables that carry item ids (company standard, DOS-12.0).
3
+ *
4
+ * `reports/mng/specs/_templates/BM-2-901-51-screen-specification-template.md`:
5
+ * §4.1 Item `| ID | Item Name | Item Type | Required | Note |` — bold section row `A`, then `1.0`, `2.0` …
6
+ * §4.2 Validation `| ID | Type | Min | Max | Default | … |` — rows keyed by the composed id `A-2`
7
+ * §4.3 Data Mapping `| ID | Data Source | API ID | … |` — same key
8
+ * §5 Event `| ID | Given (Pre-condition) | … |` — same key, or `-`
9
+ *
10
+ * Tables are recognised by their header (first column `ID` plus the second column's name), not by
11
+ * heading numbers, so a translated heading still reads. Rows keep their 1-based source line.
12
+ */
13
+ import { composeItemId } from './anchor-grammar';
14
+
15
+ export type Bm51TableKind = 'item' | 'validation' | 'mapping' | 'event';
16
+
17
+ export interface Bm51Row { table: Bm51TableKind; cells: string[]; id: string; line: number }
18
+ export interface Bm51ItemRow extends Bm51Row { section: string | null; itemId: string | null }
19
+ export interface Bm51Tables { items: Bm51ItemRow[]; validations: Bm51Row[]; mappings: Bm51Row[]; events: Bm51Row[] }
20
+
21
+ const SEPARATOR = /^\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/;
22
+ const COMPOSED_ID = /^[A-Z]+-\d+(?:\.\d+)?$/;
23
+
24
+ function splitRow(line: string): string[] {
25
+ const body = line.trim().replace(/^\|/, '').replace(/\|$/, '');
26
+ return body.split(/(?<!\\)\|/).map((c) => c.replace(/\\\|/g, '|').trim());
27
+ }
28
+ const bare = (cell: string): string => cell.replace(/\*\*|__|`/g, '').trim();
29
+
30
+ function kindOf(header: string[]): Bm51TableKind | null {
31
+ if (bare(header[0] ?? '').toUpperCase() !== 'ID') return null;
32
+ const second = bare(header[1] ?? '').toLowerCase();
33
+ if (second === 'item name') return 'item';
34
+ if (second === 'type') return 'validation';
35
+ if (second === 'data source') return 'mapping';
36
+ if (second.startsWith('given')) return 'event';
37
+ return null;
38
+ }
39
+
40
+ /** `lines` are the spec's lines; `firstLine` is the 1-based number of `lines[0]`. */
41
+ export function readBm51Tables(lines: string[], firstLine = 1): Bm51Tables {
42
+ const out: Bm51Tables = { items: [], validations: [], mappings: [], events: [] };
43
+ for (let i = 0; i < lines.length - 1; i++) {
44
+ if (!lines[i].trim().startsWith('|') || !SEPARATOR.test(lines[i + 1].trim())) continue;
45
+ const kind = kindOf(splitRow(lines[i]));
46
+ let j = i + 2;
47
+ let section: string | null = null;
48
+ for (; j < lines.length && lines[j].trim().startsWith('|'); j++) {
49
+ if (!kind) continue;
50
+ const cells = splitRow(lines[j]);
51
+ const id = bare(cells[0] ?? '');
52
+ const line = firstLine + j;
53
+ if (kind === 'item') {
54
+ if (/^[A-Z]+$/.test(id)) { section = id; continue; }
55
+ if (!/^\d+(?:\.\d+)?$/.test(id)) continue;
56
+ out.items.push({ table: kind, cells, id, line, section, itemId: composeItemId(section, id) });
57
+ } else if (COMPOSED_ID.test(id)) {
58
+ const row: Bm51Row = { table: kind, cells, id, line };
59
+ (kind === 'validation' ? out.validations : kind === 'mapping' ? out.mappings : out.events).push(row);
60
+ }
61
+ }
62
+ i = j - 1;
63
+ }
64
+ return out;
65
+ }