ai-delivery-workflow 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/README.md +45 -14
  2. package/bin/ai-delivery.mjs +181 -6
  3. package/bin/benchmark-autonomy.mjs +217 -0
  4. package/bin/release-check.mjs +382 -0
  5. package/docs/CLI-PARAMETER-REFERENCE.zh-CN.md +346 -0
  6. package/docs/CODEGRAPH-INTEGRATION.zh-CN.md +89 -0
  7. package/docs/DUAL-REPOSITORY-WORKSPACE.zh-CN.md +2 -2
  8. package/docs/EVOLUTION-MAINTENANCE.zh-CN.md +7 -7
  9. package/docs/EVOLUTION-USER-GUIDE.zh-CN.md +2 -2
  10. package/docs/FILE-REFERENCE.zh-CN.md +120 -39
  11. package/docs/MAINTENANCE-VERIFICATION.zh-CN.md +51 -0
  12. package/docs/MOCK-SYSTEM.zh-CN.md +141 -0
  13. package/docs/NPM-RELEASE-MANAGEMENT.zh-CN.md +106 -0
  14. package/docs/PROJECT-MANUAL.zh-CN.md +154 -95
  15. package/docs/PROTOTYPE-MIGRATION.zh-CN.md +164 -0
  16. package/docs/STATE-CLI-MAINTENANCE.zh-CN.md +35 -17
  17. package/docs/STATE-CLI-USER-GUIDE.zh-CN.md +115 -39
  18. package/docs/VIEWER-MAINTENANCE.zh-CN.md +101 -324
  19. package/docs/VIEWER-USER-GUIDE.zh-CN.md +68 -190
  20. package/docs/adr/0001-prototype-first-ui-governance.md +3 -0
  21. package/docs/adr/0002-microcks-as-default-mock-system.md +3 -0
  22. package/docs/adr/0003-workflow-manager-governed-control-surface.md +46 -0
  23. package/docs/adr/0004-operational-carbon-visual-standard.md +9 -0
  24. package/docs/adr/0005-prototype-management-as-routed-pages.md +7 -0
  25. package/docs/agents/domain.md +12 -0
  26. package/docs/agents/issue-tracker.md +27 -0
  27. package/docs/agents/triage-labels.md +11 -0
  28. package/docs/agents/workflow-manager-acceptance-matrix.md +93 -0
  29. package/docs/agents/workflow-manager-agent-interface.md +145 -0
  30. package/docs/agents/workflow-manager-current-state.md +205 -0
  31. package/lib/artifact-files.mjs +47 -0
  32. package/lib/codegraph.mjs +405 -0
  33. package/lib/delivery-state.mjs +3079 -198
  34. package/lib/frontend-guard.mjs +288 -0
  35. package/lib/fs-utils.mjs +53 -0
  36. package/lib/history-anchor.mjs +98 -0
  37. package/lib/mock-scenario-pack.mjs +687 -0
  38. package/lib/mock-system.mjs +897 -0
  39. package/lib/npm-package-result.mjs +11 -0
  40. package/lib/png-evidence.mjs +149 -0
  41. package/lib/project-bootstrap.mjs +96 -55
  42. package/lib/project-installer.mjs +1484 -164
  43. package/lib/project-migration.mjs +1193 -0
  44. package/lib/prototype-migration.mjs +713 -0
  45. package/lib/prototype-page-review.mjs +384 -0
  46. package/lib/prototype-review-target.mjs +334 -0
  47. package/lib/prototype-revision.mjs +812 -0
  48. package/lib/stable-value.mjs +15 -0
  49. package/lib/toml-hooks.mjs +69 -0
  50. package/lib/ui-acceptance.mjs +565 -0
  51. package/lib/visual-standard.mjs +232 -0
  52. package/lib/workflow-manager-contracts.mjs +367 -0
  53. package/lib/workflow-manager-facts.mjs +778 -0
  54. package/lib/workflow-manager-governance.mjs +514 -0
  55. package/lib/workflow-manager-mock.mjs +183 -0
  56. package/lib/workflow-manager-prototypes.mjs +1847 -0
  57. package/lib/workflow-manager-public/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  58. package/lib/workflow-manager-public/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  59. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  60. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  61. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  62. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  63. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  64. package/lib/workflow-manager-public/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  65. package/lib/workflow-manager-public/assets/index-Chlg6r8f.css +1 -0
  66. package/lib/workflow-manager-public/assets/index-E-hGB5ZD.js +13 -0
  67. package/lib/workflow-manager-public/fonts/OFL-1.1.txt +90 -0
  68. package/lib/workflow-manager-public/index.html +14 -0
  69. package/lib/workflow-manager-systems.mjs +519 -0
  70. package/lib/workflow-manager-transaction.mjs +397 -0
  71. package/lib/workflow-manager.mjs +745 -0
  72. package/package.json +8 -2
  73. package/skills/ai-delivery-assemble-release/agents/openai.yaml +3 -3
  74. package/skills/ai-delivery-assemble-release/assets/release-material-index.csv +1 -1
  75. package/skills/ai-delivery-assemble-release/assets/version-inclusion.csv +1 -1
  76. package/skills/ai-delivery-bootstrap/SKILL.md +4 -4
  77. package/skills/ai-delivery-bootstrap/agents/openai.yaml +3 -3
  78. package/skills/ai-delivery-bootstrap/references/bootstrap-contract.md +4 -2
  79. package/skills/ai-delivery-checkpoint-task/SKILL.md +17 -3
  80. package/skills/ai-delivery-checkpoint-task/agents/openai.yaml +3 -3
  81. package/skills/ai-delivery-checkpoint-task/assets/runtime-template/task.json +7 -1
  82. package/skills/ai-delivery-checkpoint-task/references/checkpoint-contract.md +22 -8
  83. package/skills/ai-delivery-checkpoint-task/scripts/hook-event.mjs +91 -0
  84. package/skills/ai-delivery-checkpoint-task/scripts/task-state.mjs +1086 -51
  85. package/skills/ai-delivery-close-version/SKILL.md +9 -8
  86. package/skills/ai-delivery-close-version/agents/openai.yaml +3 -3
  87. package/skills/ai-delivery-close-version/assets/version-lineage.yaml +1 -1
  88. package/skills/ai-delivery-close-version/references/version-closeout-contract.md +2 -2
  89. package/skills/ai-delivery-define-product/SKILL.md +8 -4
  90. package/skills/ai-delivery-define-product/agents/openai.yaml +4 -4
  91. package/skills/ai-delivery-define-product/references/product-contract.md +2 -2
  92. package/skills/ai-delivery-deploy-production/agents/openai.yaml +3 -3
  93. package/skills/ai-delivery-design-architecture/SKILL.md +9 -5
  94. package/skills/ai-delivery-design-architecture/assets/architecture-template/prototype-architecture-validation.yaml +16 -16
  95. package/skills/ai-delivery-design-architecture/references/architecture-contract.md +1 -1
  96. package/skills/ai-delivery-design-experience/SKILL.md +36 -30
  97. package/skills/ai-delivery-design-experience/agents/openai.yaml +4 -4
  98. package/skills/ai-delivery-design-experience/assets/experience-template/LEGACY-COMPATIBILITY.md +16 -0
  99. package/skills/ai-delivery-design-experience/assets/experience-template/design-reference-selection.yaml +32 -0
  100. package/skills/ai-delivery-design-experience/assets/experience-template/experience-baseline.yaml +2 -2
  101. package/skills/ai-delivery-design-experience/assets/experience-template/formal-ui-confirmation.yaml +16 -3
  102. package/skills/ai-delivery-design-experience/assets/experience-template/frontend-change-scope.yaml +30 -0
  103. package/skills/ai-delivery-design-experience/assets/experience-template/interaction-contract.csv +1 -1
  104. package/skills/ai-delivery-design-experience/assets/experience-template/mock-admin-export.yaml +8 -0
  105. package/skills/ai-delivery-design-experience/assets/experience-template/mock-scenario-mappings.csv +1 -0
  106. package/skills/ai-delivery-design-experience/assets/experience-template/mock-scenario-pack-request.yaml +24 -0
  107. package/skills/ai-delivery-design-experience/assets/experience-template/product-prototype-reconciliation.yaml +2 -1
  108. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-adjustment-log.csv +1 -1
  109. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-component-bindings.csv +1 -0
  110. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-component-candidates.csv +1 -0
  111. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-components.csv +1 -0
  112. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-confirmation.yaml +18 -18
  113. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-data-contracts.csv +1 -0
  114. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-impact-assessment.yaml +5 -5
  115. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-implementation-bindings.csv +1 -0
  116. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-manifest.yaml +2 -0
  117. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-pages.csv +1 -0
  118. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-product-coverage.csv +1 -1
  119. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-comments.csv +1 -1
  120. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-decision.yaml +13 -12
  121. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-scenes.csv +1 -0
  122. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-sessions.csv +1 -1
  123. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-unit-pages.csv +1 -0
  124. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-review-units.csv +1 -0
  125. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-revision.yaml +88 -0
  126. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-routes.csv +1 -0
  127. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-set.yaml +2 -0
  128. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-source-inspection-snapshots.csv +1 -0
  129. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-terminals.csv +1 -0
  130. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-tool-candidates.csv +1 -1
  131. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-tool-selection.yaml +2 -3
  132. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-traceability.csv +1 -1
  133. package/skills/ai-delivery-design-experience/assets/experience-template/prototype-trigger-conditions.csv +1 -0
  134. package/skills/ai-delivery-design-experience/assets/experience-template/prototype.yaml +6 -0
  135. package/skills/ai-delivery-design-experience/assets/experience-template/ui-framework-selection.yaml +17 -1
  136. package/skills/ai-delivery-design-experience/assets/experience-template/ui-handoff.yaml +6 -5
  137. package/skills/ai-delivery-design-experience/assets/experience-template/ui-mapping.csv +1 -0
  138. package/skills/ai-delivery-design-experience/assets/experience-template/visual-direction.yaml +4 -0
  139. package/skills/ai-delivery-design-experience/assets/experience-template/visual-reference-manifest.yaml +23 -0
  140. package/skills/ai-delivery-design-experience/assets/experience-template/visual-reference.html +163 -0
  141. package/skills/ai-delivery-design-experience/assets/experience-template/visual-system-confirmation.yaml +11 -0
  142. package/skills/ai-delivery-design-experience/references/experience-contract.md +26 -27
  143. package/skills/ai-delivery-design-experience/references/prototype-management-contract.md +42 -21
  144. package/skills/ai-delivery-design-tests/SKILL.md +13 -7
  145. package/skills/ai-delivery-design-tests/assets/test-design-template/prototype-test-scope.csv +1 -1
  146. package/skills/ai-delivery-design-tests/assets/test-design-template/prototype-test-validation.yaml +17 -16
  147. package/skills/ai-delivery-design-tests/references/test-design-contract.md +7 -5
  148. package/skills/ai-delivery-develop-iteration/SKILL.md +18 -11
  149. package/skills/ai-delivery-develop-iteration/agents/openai.yaml +3 -3
  150. package/skills/ai-delivery-develop-iteration/assets/development-template/candidate-manifest.yaml +36 -0
  151. package/skills/ai-delivery-develop-iteration/assets/development-template/task-prototype-traceability.csv +1 -1
  152. package/skills/ai-delivery-develop-iteration/references/development-contract.md +5 -3
  153. package/skills/ai-delivery-evolve-workflow/agents/openai.yaml +3 -3
  154. package/skills/ai-delivery-execute-test/SKILL.md +6 -2
  155. package/skills/ai-delivery-execute-test/agents/openai.yaml +4 -4
  156. package/skills/ai-delivery-execute-work-package/SKILL.md +10 -3
  157. package/skills/ai-delivery-execute-work-package/agents/openai.yaml +4 -4
  158. package/skills/ai-delivery-execute-work-package/references/work-package-contract.md +1 -1
  159. package/skills/ai-delivery-manage-git/agents/openai.yaml +3 -3
  160. package/skills/ai-delivery-manage-standards/agents/openai.yaml +4 -4
  161. package/skills/ai-delivery-orchestrate/SKILL.md +47 -29
  162. package/skills/ai-delivery-orchestrate/agents/openai.yaml +3 -3
  163. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/control/migrations/.gitkeep +0 -0
  164. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/control/repairs/.gitkeep +0 -0
  165. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/delivery/project.yaml +1 -0
  166. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/delivery/workflow-state.yaml +2 -0
  167. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/frontend-guard/frontend-guard.mjs +50 -0
  168. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/hooks/hook-event.mjs +91 -0
  169. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/manager/manager.mjs +64 -0
  170. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/manager/start.cmd +4 -0
  171. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/manager/start.ps1 +2 -0
  172. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/{viewer → manager}/start.sh +1 -1
  173. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/mock/mock.mjs +50 -0
  174. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/ui-acceptance/ui-acceptance.mjs +37 -0
  175. package/skills/ai-delivery-orchestrate/assets/project-template/AGENTS.md +32 -6
  176. package/skills/ai-delivery-orchestrate/assets/project-template/gitignore.template +1 -0
  177. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/CONTRIBUTING.md +25 -0
  178. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/LICENSE +21 -0
  179. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/README.md +250 -0
  180. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/UPSTREAM.yaml +19 -0
  181. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/airbnb/DESIGN.md +545 -0
  182. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/airbnb/README.md +5 -0
  183. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/airtable/DESIGN.md +554 -0
  184. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/airtable/README.md +5 -0
  185. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/apple/DESIGN.md +562 -0
  186. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/apple/README.md +5 -0
  187. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/binance/DESIGN.md +634 -0
  188. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/binance/README.md +5 -0
  189. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bmw/DESIGN.md +544 -0
  190. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bmw/README.md +5 -0
  191. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bmw-m/DESIGN.md +503 -0
  192. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bmw-m/README.md +5 -0
  193. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bugatti/DESIGN.md +454 -0
  194. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/bugatti/README.md +5 -0
  195. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cal/DESIGN.md +542 -0
  196. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cal/README.md +5 -0
  197. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/claude/DESIGN.md +589 -0
  198. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/claude/README.md +5 -0
  199. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/clay/DESIGN.md +541 -0
  200. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/clay/README.md +5 -0
  201. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/clickhouse/DESIGN.md +544 -0
  202. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/clickhouse/README.md +5 -0
  203. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cohere/DESIGN.md +451 -0
  204. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cohere/README.md +5 -0
  205. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/coinbase/DESIGN.md +570 -0
  206. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/coinbase/README.md +5 -0
  207. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/composio/DESIGN.md +506 -0
  208. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/composio/README.md +5 -0
  209. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cursor/DESIGN.md +537 -0
  210. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/cursor/README.md +5 -0
  211. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/dell-1996/DESIGN.md +632 -0
  212. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/dell-1996/README.md +5 -0
  213. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/elevenlabs/DESIGN.md +504 -0
  214. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/elevenlabs/README.md +5 -0
  215. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/expo/DESIGN.md +526 -0
  216. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/expo/README.md +5 -0
  217. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ferrari/DESIGN.md +531 -0
  218. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ferrari/README.md +5 -0
  219. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/figma/DESIGN.md +578 -0
  220. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/figma/README.md +5 -0
  221. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/framer/DESIGN.md +544 -0
  222. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/framer/README.md +5 -0
  223. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/hashicorp/DESIGN.md +575 -0
  224. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/hashicorp/README.md +5 -0
  225. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/hp/DESIGN.md +670 -0
  226. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/hp/README.md +5 -0
  227. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ibm/DESIGN.md +550 -0
  228. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ibm/README.md +5 -0
  229. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/intercom/DESIGN.md +546 -0
  230. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/intercom/README.md +5 -0
  231. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/kraken/DESIGN.md +125 -0
  232. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/kraken/README.md +5 -0
  233. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/lamborghini/DESIGN.md +288 -0
  234. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/lamborghini/README.md +5 -0
  235. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/linear.app/DESIGN.md +548 -0
  236. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/linear.app/README.md +5 -0
  237. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/lovable/DESIGN.md +298 -0
  238. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/lovable/README.md +5 -0
  239. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mastercard/DESIGN.md +365 -0
  240. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mastercard/README.md +5 -0
  241. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/meta/DESIGN.md +683 -0
  242. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/meta/README.md +5 -0
  243. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/minimax/DESIGN.md +746 -0
  244. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/minimax/README.md +5 -0
  245. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mintlify/DESIGN.md +852 -0
  246. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mintlify/README.md +5 -0
  247. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/miro/DESIGN.md +825 -0
  248. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/miro/README.md +5 -0
  249. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mistral.ai/DESIGN.md +773 -0
  250. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mistral.ai/README.md +5 -0
  251. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mongodb/DESIGN.md +767 -0
  252. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/mongodb/README.md +5 -0
  253. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nike/DESIGN.md +575 -0
  254. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nike/README.md +5 -0
  255. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nintendo-2001/DESIGN.md +649 -0
  256. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nintendo-2001/README.md +5 -0
  257. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/notion/DESIGN.md +821 -0
  258. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/notion/README.md +5 -0
  259. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nvidia/DESIGN.md +640 -0
  260. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/nvidia/README.md +5 -0
  261. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ollama/DESIGN.md +539 -0
  262. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/ollama/README.md +5 -0
  263. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/opencode.ai/DESIGN.md +521 -0
  264. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/opencode.ai/README.md +5 -0
  265. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/pinterest/DESIGN.md +597 -0
  266. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/pinterest/README.md +5 -0
  267. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/playstation/DESIGN.md +661 -0
  268. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/playstation/README.md +5 -0
  269. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/posthog/DESIGN.md +690 -0
  270. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/posthog/README.md +5 -0
  271. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/raycast/DESIGN.md +669 -0
  272. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/raycast/README.md +5 -0
  273. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/renault/DESIGN.md +589 -0
  274. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/renault/README.md +5 -0
  275. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/replicate/DESIGN.md +616 -0
  276. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/replicate/README.md +5 -0
  277. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/resend/DESIGN.md +585 -0
  278. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/resend/README.md +5 -0
  279. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/revolut/DESIGN.md +636 -0
  280. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/revolut/README.md +5 -0
  281. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/runwayml/DESIGN.md +244 -0
  282. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/runwayml/README.md +5 -0
  283. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/sanity/DESIGN.md +357 -0
  284. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/sanity/README.md +5 -0
  285. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/sentry/DESIGN.md +551 -0
  286. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/sentry/README.md +5 -0
  287. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/shopify/DESIGN.md +516 -0
  288. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/shopify/README.md +5 -0
  289. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/slack/DESIGN.md +482 -0
  290. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/spacex/DESIGN.md +363 -0
  291. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/spacex/README.md +5 -0
  292. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/spotify/DESIGN.md +246 -0
  293. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/spotify/README.md +5 -0
  294. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/starbucks/DESIGN.md +580 -0
  295. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/starbucks/README.md +5 -0
  296. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/stripe/DESIGN.md +487 -0
  297. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/stripe/README.md +5 -0
  298. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/supabase/DESIGN.md +462 -0
  299. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/supabase/README.md +5 -0
  300. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/superhuman/DESIGN.md +448 -0
  301. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/superhuman/README.md +5 -0
  302. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/tesla/DESIGN.md +286 -0
  303. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/tesla/README.md +5 -0
  304. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/theverge/DESIGN.md +339 -0
  305. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/theverge/README.md +5 -0
  306. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/together.ai/DESIGN.md +633 -0
  307. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/together.ai/README.md +5 -0
  308. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/uber/DESIGN.md +636 -0
  309. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/uber/README.md +5 -0
  310. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/vercel/DESIGN.md +736 -0
  311. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/vercel/README.md +5 -0
  312. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/vodafone/DESIGN.md +538 -0
  313. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/vodafone/README.md +5 -0
  314. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/voltagent/DESIGN.md +521 -0
  315. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/voltagent/README.md +5 -0
  316. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/warp/DESIGN.md +526 -0
  317. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/warp/README.md +5 -0
  318. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/webflow/DESIGN.md +588 -0
  319. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/webflow/README.md +5 -0
  320. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/wired/DESIGN.md +497 -0
  321. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/wired/README.md +5 -0
  322. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/wise/DESIGN.md +544 -0
  323. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/wise/README.md +5 -0
  324. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/x.ai/DESIGN.md +465 -0
  325. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/x.ai/README.md +5 -0
  326. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/zapier/DESIGN.md +537 -0
  327. package/skills/ai-delivery-orchestrate/assets/project-template/ref/ui/design-md/zapier/README.md +5 -0
  328. package/skills/ai-delivery-orchestrate/references/formal-state-contract.md +65 -20
  329. package/skills/ai-delivery-orchestrate/references/workflow-model.md +7 -5
  330. package/skills/ai-delivery-orchestrate-release/SKILL.md +2 -2
  331. package/skills/ai-delivery-orchestrate-release/agents/openai.yaml +4 -4
  332. package/skills/ai-delivery-orchestrate-release/references/release-workflow-contract.md +1 -1
  333. package/skills/ai-delivery-plan-iteration/SKILL.md +11 -4
  334. package/skills/ai-delivery-plan-iteration/agents/openai.yaml +4 -4
  335. package/skills/ai-delivery-plan-iteration/assets/planning-template/scope-manifest.yaml +17 -0
  336. package/skills/ai-delivery-plan-iteration/assets/planning-template/slice-prototype-traceability.csv +1 -1
  337. package/skills/ai-delivery-plan-iteration/references/planning-contract.md +8 -2
  338. package/skills/ai-delivery-prepare-platform/SKILL.md +5 -1
  339. package/skills/ai-delivery-prepare-platform/agents/openai.yaml +4 -4
  340. package/skills/ai-delivery-prepare-release/agents/openai.yaml +4 -4
  341. package/skills/ai-delivery-review-change/SKILL.md +14 -4
  342. package/skills/ai-delivery-review-change/agents/openai.yaml +4 -4
  343. package/skills/ai-delivery-review-change/references/review-contract.md +6 -0
  344. package/skills/ai-delivery-triage-failure/SKILL.md +5 -1
  345. package/skills/ai-delivery-triage-failure/agents/openai.yaml +4 -4
  346. package/skills/ai-delivery-validate-artifacts/SKILL.md +6 -3
  347. package/skills/ai-delivery-validate-artifacts/agents/openai.yaml +4 -4
  348. package/skills/ai-delivery-validate-artifacts/references/artifact-contract.md +13 -13
  349. package/skills/ai-delivery-verify-candidate/SKILL.md +13 -6
  350. package/skills/ai-delivery-verify-candidate/agents/openai.yaml +3 -3
  351. package/skills/ai-delivery-verify-candidate/assets/verification-template/ui-acceptance-request.yaml +19 -0
  352. package/skills/ai-delivery-verify-candidate/assets/verification-template/ui-acceptance-results.yaml +53 -0
  353. package/skills/ai-delivery-verify-candidate/references/candidate-verification-contract.md +10 -2
  354. package/skills/ai-delivery-verify-production/agents/openai.yaml +3 -3
  355. package/skills/ai-delivery-design-experience/assets/experience-template/low-fidelity-confirmation.yaml +0 -32
  356. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/public/app.js +0 -546
  357. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/public/index.html +0 -199
  358. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/public/styles.css +0 -529
  359. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/server.mjs +0 -780
  360. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/start.cmd +0 -4
  361. package/skills/ai-delivery-orchestrate/assets/project-template/.workflow/tools/viewer/start.ps1 +0 -2
@@ -0,0 +1,687 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { requireSha256, sha256File } from "./artifact-files.mjs";
5
+ import { assertPathInside, atomicWrite } from "./fs-utils.mjs";
6
+ import {
7
+ parsePrototypeCatalogCsv,
8
+ validatePrototypeRevision,
9
+ } from "./prototype-revision.mjs";
10
+ import { parse as parseYaml, stringify as stringifyYaml } from "./yaml-runtime.mjs";
11
+ import { sameStableValue } from "./stable-value.mjs";
12
+
13
+ const mappingHeader = [
14
+ "review_scene_id",
15
+ "mock_id",
16
+ "mock_kind",
17
+ "scenario_id",
18
+ "data_source",
19
+ "data_classification",
20
+ "sanitization_status",
21
+ "sanitization_evidence_ref",
22
+ ].join(",");
23
+
24
+ function sha256Bytes(value) {
25
+ return crypto.createHash("sha256").update(value).digest("hex");
26
+ }
27
+
28
+ function requireRelativeRef(value, label, prefix = null) {
29
+ const ref = String(value || "");
30
+ if (!ref
31
+ || ref.includes("\\")
32
+ || ref.includes("\0")
33
+ || path.posix.isAbsolute(ref)
34
+ || path.posix.normalize(ref) !== ref
35
+ || ref === ".."
36
+ || ref.startsWith("../")
37
+ || (prefix && !ref.startsWith(prefix))) {
38
+ throw new Error(`${label} is outside its allowed relative path boundary: ${ref || "<empty>"}`);
39
+ }
40
+ return ref;
41
+ }
42
+
43
+ function containedFile(root, ref, label, prefix = null) {
44
+ const normalized = requireRelativeRef(ref, label, prefix);
45
+ const file = path.resolve(root, ...normalized.split("/"));
46
+ assertPathInside(root, file);
47
+ if (!fs.existsSync(file) || !fs.statSync(file).isFile() || fs.lstatSync(file).isSymbolicLink()) {
48
+ throw new Error(`${label} is missing or is not a regular file: ${normalized}`);
49
+ }
50
+ return { ref: normalized, file };
51
+ }
52
+
53
+ function boundFile(root, binding, label, prefix = null) {
54
+ if (binding?.algorithm !== "sha256") throw new Error(`${label} must use sha256`);
55
+ const resolved = containedFile(root, binding.ref, label, prefix);
56
+ const checksum = requireSha256(binding.checksum, label);
57
+ if (sha256File(resolved.file) !== checksum) throw new Error(`${label} checksum mismatch`);
58
+ return { ...resolved, checksum };
59
+ }
60
+
61
+ function readYamlFile(file, label) {
62
+ try {
63
+ return parseYaml(fs.readFileSync(file, "utf8"));
64
+ } catch (error) {
65
+ throw new Error(`${label} is invalid YAML: ${error.message}`);
66
+ }
67
+ }
68
+
69
+ function requireExperienceRoot(projectRoot, relative) {
70
+ const ref = requireRelativeRef(relative, "Scenario Pack experience directory");
71
+ const root = path.resolve(projectRoot, ...ref.split("/"));
72
+ assertPathInside(projectRoot, root);
73
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory() || fs.lstatSync(root).isSymbolicLink()) {
74
+ throw new Error(`Scenario Pack experience directory is missing: ${ref}`);
75
+ }
76
+ return { ref, root };
77
+ }
78
+
79
+ function validateAdminExportMetadata(value) {
80
+ if (value?.schema_version !== 1 || value?.source !== "microcks-managed-ui") {
81
+ throw new Error("Mock admin export must use schema 1 and source microcks-managed-ui");
82
+ }
83
+ if (!value.exported_at || Number.isNaN(Date.parse(value.exported_at))) {
84
+ throw new Error("Mock admin export requires exported_at");
85
+ }
86
+ if (value.security?.production_traffic_recording !== false) {
87
+ throw new Error("Production traffic recording is prohibited in a Mock Scenario Pack");
88
+ }
89
+ if (value.security?.production_credentials !== false) {
90
+ throw new Error("Production credentials are prohibited in a Mock Scenario Pack");
91
+ }
92
+ if (value.security?.unsanitized_personal_data !== false) {
93
+ throw new Error("Unsanitized personal data is prohibited in a Mock Scenario Pack");
94
+ }
95
+ }
96
+
97
+ function validateAdminExportArtifacts(
98
+ experienceRoot,
99
+ adminExport,
100
+ catalogs,
101
+ mappings,
102
+ validateMockDefinition,
103
+ ) {
104
+ if (!Array.isArray(adminExport.artifacts) || adminExport.artifacts.length === 0) {
105
+ throw new Error("Mock admin export requires bound export artifacts");
106
+ }
107
+ const requiredIdentities = new Map();
108
+ for (const mapping of mappings) {
109
+ const key = `${mapping.mock_kind}:${mapping.mock_id}`;
110
+ if (!requiredIdentities.has(key)) requiredIdentities.set(key, new Set());
111
+ requiredIdentities.get(key).add(mapping.scenario_id);
112
+ }
113
+ const entriesByIdentity = new Map();
114
+ for (const { catalogEntry } of catalogs.entries) {
115
+ const key = `${catalogEntry.mock_kind}:${catalogEntry.mock_id}`;
116
+ if (!entriesByIdentity.has(key)) entriesByIdentity.set(key, []);
117
+ entriesByIdentity.get(key).push(catalogEntry);
118
+ }
119
+ const seen = new Set();
120
+ const artifacts = adminExport.artifacts.map((artifact, index) => {
121
+ const label = `Mock admin export artifact ${index + 1}`;
122
+ const mockKind = requireText(artifact?.mock_kind, `${label} mock_kind`);
123
+ const mockId = requireText(artifact?.mock_id, `${label} mock_id`);
124
+ const protocol = requireText(artifact?.protocol, `${label} protocol`);
125
+ const key = `${mockKind}:${mockId}`;
126
+ const scenarioIds = requiredIdentities.get(key);
127
+ if (!scenarioIds) throw new Error(`${label} is not used by an active Review Scene: ${key}`);
128
+ if (seen.has(key)) throw new Error(`Duplicate Mock admin export artifact identity: ${key}`);
129
+ seen.add(key);
130
+ const catalogEntries = entriesByIdentity.get(key) || [];
131
+ if (catalogEntries.some((entry) => entry.protocol !== protocol)) {
132
+ throw new Error(`Mock admin export artifact ${mockId} protocol does not match its catalog`);
133
+ }
134
+ const binding = boundFile(
135
+ experienceRoot,
136
+ artifact,
137
+ `Mock admin export artifact ${mockId}`,
138
+ "mock-admin-exports/",
139
+ );
140
+ const definition = readYamlFile(binding.file, `Mock admin export artifact ${mockId}`);
141
+ for (const scenarioId of scenarioIds) {
142
+ const entry = catalogEntries.find((candidate) => candidate.scenario_id === scenarioId);
143
+ if (!entry) throw new Error(`Mock admin export artifact ${mockId} has no catalog entry for ${scenarioId}`);
144
+ validateMockDefinition(definition, entry);
145
+ }
146
+ return {
147
+ mock_kind: mockKind,
148
+ mock_id: mockId,
149
+ protocol,
150
+ ref: binding.ref,
151
+ algorithm: "sha256",
152
+ checksum: binding.checksum,
153
+ scenario_ids: [...scenarioIds].sort(),
154
+ };
155
+ });
156
+ for (const key of requiredIdentities.keys()) {
157
+ if (!seen.has(key)) throw new Error(`Mock admin export has no artifact for ${key}`);
158
+ }
159
+ return artifacts.sort((left, right) =>
160
+ `${left.mock_kind}:${left.mock_id}`.localeCompare(`${right.mock_kind}:${right.mock_id}`));
161
+ }
162
+
163
+ function readActiveReviewScenes(experienceRoot, revisionFile, revision) {
164
+ const revisionRoot = path.dirname(revisionFile);
165
+ const bundleRef = requireRelativeRef(revision.review_bundle?.ref, "Prototype review bundle");
166
+ const bundleRoot = path.resolve(revisionRoot, ...bundleRef.split("/"));
167
+ assertPathInside(experienceRoot, bundleRoot);
168
+ const sceneBinding = revision.catalogs?.review_scenes;
169
+ if (sceneBinding?.algorithm !== "sha256") {
170
+ throw new Error("Prototype Review Scene catalog must use sha256");
171
+ }
172
+ const sceneCatalog = containedFile(
173
+ bundleRoot,
174
+ sceneBinding.ref,
175
+ "Prototype Review Scene catalog",
176
+ );
177
+ if (sha256File(sceneCatalog.file) !== requireSha256(
178
+ sceneBinding.checksum,
179
+ "Prototype Review Scene catalog",
180
+ )) {
181
+ throw new Error("Prototype Review Scene catalog checksum mismatch");
182
+ }
183
+ const parsed = parsePrototypeCatalogCsv(
184
+ fs.readFileSync(sceneCatalog.file, "utf8"),
185
+ "Prototype Review Scene catalog",
186
+ );
187
+ return parsed.rows.filter((row) => row.lifecycle_status === "active");
188
+ }
189
+
190
+ function requireText(value, label) {
191
+ if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is required`);
192
+ return value.trim();
193
+ }
194
+
195
+ function normalizeMappings(experienceRoot, rows, activeScenes, catalogs) {
196
+ const activeSceneIds = new Set(activeScenes.map((scene) => scene.review_scene_id));
197
+ const mappings = new Map();
198
+ const catalogEntries = new Map(catalogs.entries.map(({ catalogEntry, contractFile }) => [
199
+ `${catalogEntry.mock_kind}:${catalogEntry.mock_id}:${catalogEntry.scenario_id}`,
200
+ { catalogEntry, contractFile },
201
+ ]));
202
+ for (const row of rows) {
203
+ const reviewSceneId = requireText(row.review_scene_id, "Mock Scenario mapping review_scene_id");
204
+ if (!activeSceneIds.has(reviewSceneId)) {
205
+ throw new Error(`Mock Scenario mapping references an inactive or unknown Review Scene: ${reviewSceneId}`);
206
+ }
207
+ if (mappings.has(reviewSceneId)) {
208
+ throw new Error(`Duplicate Mock Scenario mapping for Review Scene ${reviewSceneId}`);
209
+ }
210
+ const mockKind = requireText(row.mock_kind, `Review Scene ${reviewSceneId} mock_kind`);
211
+ if (!new Set(["external-dependency", "product-backend"]).has(mockKind)) {
212
+ throw new Error(`Review Scene ${reviewSceneId} has invalid mock_kind ${mockKind}`);
213
+ }
214
+ const mockId = requireText(row.mock_id, `Review Scene ${reviewSceneId} mock_id`);
215
+ const scenarioId = requireText(row.scenario_id, `Review Scene ${reviewSceneId} scenario_id`);
216
+ const selected = catalogEntries.get(`${mockKind}:${mockId}:${scenarioId}`);
217
+ if (!selected) {
218
+ throw new Error(
219
+ `Review Scene ${reviewSceneId} Mock Scenario ${mockKind}:${mockId}:${scenarioId} is not present in a validated catalog`,
220
+ );
221
+ }
222
+ const dataSource = requireText(row.data_source, `Review Scene ${reviewSceneId} data_source`);
223
+ const dataClassification = requireText(
224
+ row.data_classification,
225
+ `Review Scene ${reviewSceneId} data_classification`,
226
+ );
227
+ const sanitizationStatus = requireText(
228
+ row.sanitization_status,
229
+ `Review Scene ${reviewSceneId} sanitization_status`,
230
+ );
231
+ let sanitizationEvidence = null;
232
+ if (dataSource === "explicit-import") {
233
+ if (!new Set(["anonymized", "public"]).has(dataClassification)
234
+ || sanitizationStatus !== "passed"
235
+ || !row.sanitization_evidence_ref) {
236
+ throw new Error(
237
+ `Review Scene ${reviewSceneId} explicit import requires anonymized/public classification, sanitization passed, and evidence`,
238
+ );
239
+ }
240
+ const evidence = containedFile(
241
+ experienceRoot,
242
+ row.sanitization_evidence_ref,
243
+ `Review Scene ${reviewSceneId} sanitization evidence`,
244
+ );
245
+ sanitizationEvidence = {
246
+ ref: evidence.ref,
247
+ algorithm: "sha256",
248
+ checksum: sha256File(evidence.file),
249
+ };
250
+ } else if (dataSource === "synthetic") {
251
+ if (!new Set(["synthetic", "public"]).has(dataClassification)
252
+ || sanitizationStatus !== "not-required"
253
+ || row.sanitization_evidence_ref) {
254
+ throw new Error(
255
+ `Review Scene ${reviewSceneId} synthetic data must use synthetic/public classification and sanitization not-required without evidence`,
256
+ );
257
+ }
258
+ } else {
259
+ throw new Error(`Review Scene ${reviewSceneId} has forbidden data_source ${dataSource}`);
260
+ }
261
+ const entry = selected.catalogEntry;
262
+ mappings.set(reviewSceneId, {
263
+ review_scene_id: reviewSceneId,
264
+ mock_id: mockId,
265
+ mock_kind: mockKind,
266
+ scenario_id: scenarioId,
267
+ owner: entry.owner,
268
+ protocol: entry.protocol,
269
+ operation_or_channel: entry.operation_or_channel,
270
+ replacement_condition: entry.replacement_condition,
271
+ contract: {
272
+ ref: entry.contract_ref,
273
+ algorithm: "sha256",
274
+ checksum: sha256File(selected.contractFile),
275
+ approval_ref: entry.contract_approval_ref,
276
+ },
277
+ data: {
278
+ source: dataSource,
279
+ classification: dataClassification,
280
+ sanitization_status: sanitizationStatus,
281
+ sanitization_evidence: sanitizationEvidence,
282
+ },
283
+ });
284
+ }
285
+ for (const scene of activeScenes) {
286
+ if (!mappings.has(scene.review_scene_id)) {
287
+ throw new Error(`Review Scene ${scene.review_scene_id} has no Mock Scenario mapping`);
288
+ }
289
+ }
290
+ return [...mappings.values()].sort((left, right) =>
291
+ left.review_scene_id.localeCompare(right.review_scene_id));
292
+ }
293
+
294
+ function requireRequestIdentity(request, revision) {
295
+ if (request?.schema_version !== 1
296
+ || request?.artifact_type !== "mock-scenario-pack-request"
297
+ || !/^MOCK-SCENARIO-PACK-[A-Z0-9][A-Z0-9-]*$/.test(String(request?.artifact_id || ""))
298
+ || !Number.isInteger(request?.version)
299
+ || request.version < 1) {
300
+ throw new Error("Mock Scenario Pack request identity or schema is invalid");
301
+ }
302
+ if (request.iteration_id !== revision.iteration_id) {
303
+ throw new Error("Mock Scenario Pack iteration_id does not match its Prototype revision");
304
+ }
305
+ }
306
+
307
+ function validateHumanConfirmation(value, candidateChecksum) {
308
+ if (value?.required !== true
309
+ || value?.decision !== "approved"
310
+ || !/^human:[^\s]+$/.test(String(value?.actor || ""))
311
+ || !value?.decided_at
312
+ || Number.isNaN(Date.parse(value.decided_at))
313
+ || value?.candidate_checksum !== candidateChecksum) {
314
+ throw new Error("Mock Scenario Pack requires human confirmation bound to the exact candidate checksum");
315
+ }
316
+ }
317
+
318
+ const scenarioPackCandidateFields = Object.freeze([
319
+ "schema_version",
320
+ "artifact_id",
321
+ "version",
322
+ "iteration_id",
323
+ "prototype_revision",
324
+ "scenario_mapping",
325
+ "admin_export",
326
+ "scenario_mappings",
327
+ "data_policy",
328
+ "assurance",
329
+ ]);
330
+
331
+ function scenarioPackCandidate(value) {
332
+ return Object.fromEntries(scenarioPackCandidateFields.map((field) => [field, value[field]]));
333
+ }
334
+
335
+ export function validateFrozenMockScenarioPack(projectRoot, options = {}, dependencies = {}) {
336
+ const validateMockDefinition = dependencies.validateMockDefinition;
337
+ const protocolExpectation = dependencies.protocolExpectation;
338
+ if (typeof validateMockDefinition !== "function" || typeof protocolExpectation !== "function") {
339
+ throw new Error("Mock Scenario Pack protocol validators are unavailable");
340
+ }
341
+ const experience = requireExperienceRoot(projectRoot, options.experience);
342
+ const packBinding = containedFile(experience.root, options.scenarioPack, "Frozen Mock Scenario Pack");
343
+ const pack = readYamlFile(packBinding.file, "Frozen Mock Scenario Pack");
344
+ if (pack?.schema_version !== 1
345
+ || pack?.artifact_type !== "mock-scenario-pack"
346
+ || pack?.status !== "frozen"
347
+ || !/^MOCK-SCENARIO-PACK-[A-Z0-9][A-Z0-9-]*$/.test(String(pack?.artifact_id || ""))
348
+ || !Number.isInteger(pack?.version) || pack.version < 1) {
349
+ throw new Error("Frozen Mock Scenario Pack identity or schema is invalid");
350
+ }
351
+ const candidateChecksum = sha256Bytes(JSON.stringify(scenarioPackCandidate(pack)));
352
+ if (pack.candidate?.algorithm !== "sha256" || pack.candidate?.checksum !== candidateChecksum) {
353
+ throw new Error("Frozen Mock Scenario Pack candidate checksum mismatch");
354
+ }
355
+ validateHumanConfirmation(pack.human_confirmation, candidateChecksum);
356
+ if (pack.authority?.formal_registration_required !== true
357
+ || pack.authority?.registration_artifact_type !== "mock-scenario-pack"
358
+ || pack.authority?.registration_status !== "submitted"
359
+ || !sameStableValue(pack.data_policy, {
360
+ production_traffic_recording: "prohibited",
361
+ production_credentials: "prohibited",
362
+ unsanitized_personal_data: "prohibited",
363
+ explicit_imports: "sanitized-only",
364
+ })
365
+ || pack.assurance?.real_product_backend_evidence !== false
366
+ || pack.assurance?.end_to_end_acceptance_evidence !== false) {
367
+ throw new Error("Frozen Mock Scenario Pack authority, data policy, or assurance boundary is invalid");
368
+ }
369
+
370
+ const revisionBinding = boundFile(
371
+ experience.root,
372
+ pack.prototype_revision,
373
+ "Frozen Mock Scenario Pack Prototype revision",
374
+ );
375
+ const revisionReport = validatePrototypeRevision(projectRoot, {
376
+ experience: experience.ref,
377
+ revision: revisionBinding.ref,
378
+ });
379
+ const revision = readYamlFile(revisionBinding.file, "Frozen Mock Scenario Pack Prototype revision");
380
+ if (pack.prototype_revision.artifact_id !== revisionReport.revision_id
381
+ || pack.prototype_revision.source_checksum !== revision.source?.checksum
382
+ || pack.prototype_revision.review_bundle_checksum !== revision.review_bundle?.checksum
383
+ || pack.iteration_id !== revision.iteration_id) {
384
+ throw new Error("Frozen Mock Scenario Pack Prototype revision binding is inconsistent");
385
+ }
386
+ const mappingBinding = boundFile(
387
+ experience.root,
388
+ pack.scenario_mapping,
389
+ "Frozen Mock Scenario mapping",
390
+ );
391
+ const mappingCatalog = parsePrototypeCatalogCsv(
392
+ fs.readFileSync(mappingBinding.file, "utf8"),
393
+ "Frozen Mock Scenario mapping",
394
+ );
395
+ if (mappingCatalog.header !== mappingHeader) {
396
+ throw new Error("Frozen Mock Scenario mapping header is invalid");
397
+ }
398
+ const adminBinding = boundFile(
399
+ experience.root,
400
+ pack.admin_export,
401
+ "Frozen Mock admin export",
402
+ );
403
+ const adminExport = readYamlFile(adminBinding.file, "Frozen Mock admin export");
404
+ validateAdminExportMetadata(adminExport);
405
+ if (pack.admin_export.source !== adminExport.source
406
+ || pack.admin_export.exported_at !== adminExport.exported_at) {
407
+ throw new Error("Frozen Mock admin export metadata is inconsistent");
408
+ }
409
+
410
+ const activeScenes = readActiveReviewScenes(experience.root, revisionBinding.file, revision);
411
+ const activeSceneIds = new Set(activeScenes.map((scene) => scene.review_scene_id));
412
+ const rowsByScene = new Map(mappingCatalog.rows.map((row) => [row.review_scene_id, row]));
413
+ const mappings = Array.isArray(pack.scenario_mappings) ? pack.scenario_mappings : [];
414
+ const mappingsByScene = new Map();
415
+ for (const mapping of mappings) {
416
+ const sceneId = requireText(mapping?.review_scene_id, "Frozen Scenario review_scene_id");
417
+ if (!activeSceneIds.has(sceneId) || mappingsByScene.has(sceneId)) {
418
+ throw new Error(`Frozen Mock Scenario Pack has an unknown or duplicate Review Scene: ${sceneId}`);
419
+ }
420
+ const row = rowsByScene.get(sceneId);
421
+ if (!row || row.mock_id !== mapping.mock_id || row.mock_kind !== mapping.mock_kind
422
+ || row.scenario_id !== mapping.scenario_id
423
+ || row.data_source !== mapping.data?.source
424
+ || row.data_classification !== mapping.data?.classification
425
+ || row.sanitization_status !== mapping.data?.sanitization_status) {
426
+ throw new Error(`Frozen Mock Scenario mapping is inconsistent for Review Scene ${sceneId}`);
427
+ }
428
+ if (!new Set(["external-dependency", "product-backend"]).has(mapping.mock_kind)
429
+ || !mapping.owner || !mapping.operation_or_channel || !mapping.replacement_condition
430
+ || !mapping.contract?.approval_ref) {
431
+ throw new Error(`Frozen Mock Scenario ${sceneId} is missing its authority or protocol identity`);
432
+ }
433
+ if (mapping.data?.sanitization_evidence) {
434
+ boundFile(
435
+ experience.root,
436
+ mapping.data.sanitization_evidence,
437
+ `Frozen Mock Scenario ${sceneId} sanitization evidence`,
438
+ );
439
+ }
440
+ mappingsByScene.set(sceneId, mapping);
441
+ }
442
+ if (mappingsByScene.size !== activeSceneIds.size
443
+ || [...activeSceneIds].some((sceneId) => !mappingsByScene.has(sceneId))) {
444
+ throw new Error("Frozen Mock Scenario Pack does not cover every active Review Scene");
445
+ }
446
+
447
+ const adminArtifacts = Array.isArray(adminExport.artifacts) ? adminExport.artifacts : [];
448
+ const packedArtifacts = Array.isArray(pack.admin_export.artifacts) ? pack.admin_export.artifacts : [];
449
+ const actualByIdentity = new Map(adminArtifacts.map((artifact) => [
450
+ `${artifact.mock_kind}:${artifact.mock_id}`,
451
+ artifact,
452
+ ]));
453
+ const packedByIdentity = new Map(packedArtifacts.map((artifact) => [
454
+ `${artifact.mock_kind}:${artifact.mock_id}`,
455
+ artifact,
456
+ ]));
457
+ if (actualByIdentity.size !== adminArtifacts.length
458
+ || packedByIdentity.size !== packedArtifacts.length
459
+ || actualByIdentity.size !== packedByIdentity.size) {
460
+ throw new Error("Frozen Mock admin export artifacts are missing or duplicated");
461
+ }
462
+ const expectations = new Map();
463
+ for (const [sceneId, mapping] of mappingsByScene) {
464
+ const identity = `${mapping.mock_kind}:${mapping.mock_id}`;
465
+ const actualArtifact = actualByIdentity.get(identity);
466
+ const packedArtifact = packedByIdentity.get(identity);
467
+ if (!actualArtifact || !packedArtifact
468
+ || actualArtifact.protocol !== mapping.protocol
469
+ || packedArtifact.protocol !== mapping.protocol
470
+ || actualArtifact.ref !== packedArtifact.ref
471
+ || actualArtifact.algorithm !== packedArtifact.algorithm
472
+ || actualArtifact.checksum !== packedArtifact.checksum
473
+ || !Array.isArray(packedArtifact.scenario_ids)
474
+ || !packedArtifact.scenario_ids.includes(mapping.scenario_id)) {
475
+ throw new Error(`Frozen Mock admin export does not bind Scenario ${mapping.scenario_id}`);
476
+ }
477
+ const contractBinding = boundFile(
478
+ projectRoot,
479
+ mapping.contract,
480
+ `Frozen Mock Scenario contract ${mapping.mock_id}`,
481
+ ".workflow/mock-system/definitions/",
482
+ );
483
+ const contractDefinition = readYamlFile(
484
+ contractBinding.file,
485
+ `Frozen Mock Scenario contract ${mapping.mock_id}`,
486
+ );
487
+ const entry = { ...mapping, contract_ref: mapping.contract.ref };
488
+ validateMockDefinition(contractDefinition, entry);
489
+ const exportBinding = boundFile(
490
+ experience.root,
491
+ packedArtifact,
492
+ `Mock admin export artifact ${mapping.mock_id}`,
493
+ "mock-admin-exports/",
494
+ );
495
+ const exportDefinition = readYamlFile(
496
+ exportBinding.file,
497
+ `Mock admin export artifact ${mapping.mock_id}`,
498
+ );
499
+ validateMockDefinition(exportDefinition, entry);
500
+ const contractExpectation = protocolExpectation(contractDefinition, entry);
501
+ const exportExpectation = protocolExpectation(exportDefinition, entry);
502
+ if (!sameStableValue(contractExpectation, exportExpectation)) {
503
+ throw new Error(`Mock admin export artifact ${mapping.mock_id} differs from its frozen contract`);
504
+ }
505
+ expectations.set(sceneId, exportExpectation);
506
+ }
507
+ return {
508
+ pack,
509
+ file: packBinding.file,
510
+ checksum: sha256File(packBinding.file),
511
+ revisionReport,
512
+ expectations,
513
+ };
514
+ }
515
+
516
+ export function freezeMockScenarioPack(projectRoot, options = {}, dependencies = {}) {
517
+ const readMockCatalogs = dependencies.readMockCatalogs;
518
+ const validateMockDefinition = dependencies.validateMockDefinition;
519
+ if (typeof readMockCatalogs !== "function") throw new Error("Mock catalog reader is unavailable");
520
+ if (typeof validateMockDefinition !== "function") {
521
+ throw new Error("Mock protocol validator is unavailable");
522
+ }
523
+ const experience = requireExperienceRoot(projectRoot, options.experience);
524
+ const requestBinding = containedFile(
525
+ experience.root,
526
+ options.scenarioPack,
527
+ "Mock Scenario Pack request",
528
+ );
529
+ const request = readYamlFile(requestBinding.file, "Mock Scenario Pack request");
530
+ const revisionBinding = boundFile(
531
+ experience.root,
532
+ request.prototype_revision,
533
+ "Mock Scenario Pack Prototype revision",
534
+ );
535
+ const revisionReport = validatePrototypeRevision(projectRoot, {
536
+ experience: experience.ref,
537
+ revision: revisionBinding.ref,
538
+ });
539
+ const revision = readYamlFile(revisionBinding.file, "Mock Scenario Pack Prototype revision");
540
+ requireRequestIdentity(request, revision);
541
+ const mappingBinding = boundFile(
542
+ experience.root,
543
+ request.scenario_mapping,
544
+ "Mock Scenario mapping",
545
+ );
546
+ const mappingCatalog = parsePrototypeCatalogCsv(
547
+ fs.readFileSync(mappingBinding.file, "utf8"),
548
+ "Mock Scenario mapping",
549
+ );
550
+ if (mappingCatalog.header !== mappingHeader) {
551
+ throw new Error("Mock Scenario mapping header is invalid");
552
+ }
553
+ const exportBinding = boundFile(
554
+ experience.root,
555
+ request.admin_export,
556
+ "Mock admin export",
557
+ );
558
+ const adminExport = readYamlFile(exportBinding.file, "Mock admin export");
559
+ validateAdminExportMetadata(adminExport);
560
+ const catalogs = readMockCatalogs(projectRoot);
561
+ const activeScenes = readActiveReviewScenes(experience.root, revisionBinding.file, revision);
562
+ const mappings = normalizeMappings(
563
+ experience.root,
564
+ mappingCatalog.rows,
565
+ activeScenes,
566
+ catalogs,
567
+ );
568
+ const exportArtifacts = validateAdminExportArtifacts(
569
+ experience.root,
570
+ adminExport,
571
+ catalogs,
572
+ mappings,
573
+ validateMockDefinition,
574
+ );
575
+ const candidate = scenarioPackCandidate({
576
+ schema_version: 1,
577
+ artifact_id: request.artifact_id,
578
+ version: request.version,
579
+ iteration_id: request.iteration_id,
580
+ prototype_revision: {
581
+ artifact_id: revisionReport.revision_id,
582
+ ref: revisionBinding.ref,
583
+ algorithm: "sha256",
584
+ checksum: revisionBinding.checksum,
585
+ source_checksum: revision.source.checksum,
586
+ review_bundle_checksum: revision.review_bundle.checksum,
587
+ },
588
+ scenario_mapping: {
589
+ ref: mappingBinding.ref,
590
+ algorithm: "sha256",
591
+ checksum: mappingBinding.checksum,
592
+ },
593
+ admin_export: {
594
+ ref: exportBinding.ref,
595
+ algorithm: "sha256",
596
+ checksum: exportBinding.checksum,
597
+ source: adminExport.source,
598
+ exported_at: adminExport.exported_at,
599
+ artifacts: exportArtifacts,
600
+ },
601
+ scenario_mappings: mappings,
602
+ data_policy: {
603
+ production_traffic_recording: "prohibited",
604
+ production_credentials: "prohibited",
605
+ unsanitized_personal_data: "prohibited",
606
+ explicit_imports: "sanitized-only",
607
+ },
608
+ assurance: {
609
+ real_product_backend_evidence: false,
610
+ end_to_end_acceptance_evidence: false,
611
+ },
612
+ });
613
+ const candidateChecksum = sha256Bytes(JSON.stringify(candidate));
614
+ const mockKinds = [...new Set(mappings.map((mapping) => mapping.mock_kind))].sort();
615
+ const planned = {
616
+ provider: "microcks",
617
+ action: "freeze",
618
+ dry_run: true,
619
+ artifact_id: request.artifact_id,
620
+ candidate_checksum: candidateChecksum,
621
+ prototype_revision_id: revisionReport.revision_id,
622
+ review_scene_count: activeScenes.length,
623
+ mock_kinds: mockKinds,
624
+ confirmation_required: true,
625
+ output_ref: request.output_ref,
626
+ };
627
+ if (options.dryRun) return planned;
628
+
629
+ validateHumanConfirmation(request.human_confirmation, candidateChecksum);
630
+ const output = containedFileForWrite(
631
+ experience.root,
632
+ request.output_ref,
633
+ request.artifact_id,
634
+ );
635
+ const pack = {
636
+ artifact_id: request.artifact_id,
637
+ artifact_type: "mock-scenario-pack",
638
+ version: request.version,
639
+ iteration_id: request.iteration_id,
640
+ status: "frozen",
641
+ candidate: { algorithm: "sha256", checksum: candidateChecksum },
642
+ ...candidate,
643
+ human_confirmation: {
644
+ required: true,
645
+ decision: "approved",
646
+ actor: request.human_confirmation.actor,
647
+ decided_at: request.human_confirmation.decided_at,
648
+ candidate_checksum: candidateChecksum,
649
+ },
650
+ authority: {
651
+ formal_registration_required: true,
652
+ registration_artifact_type: "mock-scenario-pack",
653
+ registration_status: "submitted",
654
+ },
655
+ };
656
+ const text = stringifyYaml(pack, { lineWidth: 0 });
657
+ if (fs.existsSync(output.file)) {
658
+ if (fs.readFileSync(output.file, "utf8") !== text) {
659
+ throw new Error(`Immutable Mock Scenario Pack already exists with different content: ${output.ref}`);
660
+ }
661
+ } else {
662
+ fs.mkdirSync(path.dirname(output.file), { recursive: true });
663
+ atomicWrite(output.file, text);
664
+ }
665
+ return {
666
+ ...planned,
667
+ dry_run: false,
668
+ frozen: true,
669
+ output_ref: output.ref,
670
+ file_checksum: sha256File(output.file),
671
+ formal_registration_required: true,
672
+ };
673
+ }
674
+
675
+ function containedFileForWrite(experienceRoot, ref, artifactId) {
676
+ const normalized = requireRelativeRef(
677
+ ref,
678
+ "Mock Scenario Pack output",
679
+ "mock-scenario-packs/",
680
+ );
681
+ if (normalized !== `mock-scenario-packs/${artifactId}.yaml`) {
682
+ throw new Error("Mock Scenario Pack output_ref must match its immutable artifact_id");
683
+ }
684
+ const file = path.resolve(experienceRoot, ...normalized.split("/"));
685
+ assertPathInside(experienceRoot, file);
686
+ return { ref: normalized, file };
687
+ }