create-yss-spec 2.2.3 → 2.2.4

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 (339) hide show
  1. package/README.md +17 -1
  2. package/package.json +1 -1
  3. package/src/cli.js +15 -1
  4. package/src/self-update.js +277 -0
  5. package/template/.agents/skills/yss-domain/SKILL.md +5 -4
  6. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +5 -5
  7. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  8. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  9. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  10. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  11. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +7 -2
  12. package/template/.agents/skills/yss-router/SKILL.md +4 -2
  13. package/template/.agents/skills/yss-router/references/router-contract.yaml +18 -3
  14. package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +58 -1
  15. package/template/.agents/skills/yss-stage-decision/SKILL.md +50 -0
  16. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  17. package/template/.agents/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  18. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  19. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  20. package/template/.agents/skills/yss-stage-decision/references/validation-rules.md +18 -0
  21. package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  22. package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  23. package/template/.agents/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  24. package/template/.agents/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  25. package/template/.agents/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  26. package/template/.agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  27. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  28. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  29. package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  30. package/template/.agents/skills/yss-tactical-design/SKILL.md +33 -0
  31. package/template/.agents/skills/yss-tactical-design/agents/openai.yaml +4 -0
  32. package/template/.agents/skills/yss-tactical-design/references/output-template.md +28 -0
  33. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  34. package/template/.agents/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  35. package/template/.agents/skills/yss-tactical-design/references/validation-rules.md +13 -0
  36. package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  37. package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  38. package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  39. package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  40. package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  41. package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  42. package/template/.agents/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  43. package/template/.agents/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  44. package/template/.claude/skills/yss-domain/SKILL.md +5 -4
  45. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +5 -5
  46. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  47. package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  48. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  49. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  50. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +7 -2
  51. package/template/.claude/skills/yss-router/SKILL.md +4 -2
  52. package/template/.claude/skills/yss-router/references/router-contract.yaml +18 -3
  53. package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +58 -1
  54. package/template/.claude/skills/yss-stage-decision/SKILL.md +50 -0
  55. package/template/.claude/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  56. package/template/.claude/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  57. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  58. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  59. package/template/.claude/skills/yss-stage-decision/references/validation-rules.md +18 -0
  60. package/template/.claude/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  61. package/template/.claude/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  62. package/template/.claude/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  63. package/template/.claude/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  64. package/template/.claude/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  65. package/template/.claude/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  66. package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  67. package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  68. package/template/.claude/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  69. package/template/.claude/skills/yss-tactical-design/SKILL.md +33 -0
  70. package/template/.claude/skills/yss-tactical-design/agents/openai.yaml +4 -0
  71. package/template/.claude/skills/yss-tactical-design/references/output-template.md +28 -0
  72. package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  73. package/template/.claude/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  74. package/template/.claude/skills/yss-tactical-design/references/validation-rules.md +13 -0
  75. package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  76. package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  77. package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  78. package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  79. package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  80. package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  81. package/template/.claude/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  82. package/template/.claude/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  83. package/template/.codex/skills/yss-domain/SKILL.md +5 -4
  84. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +5 -5
  85. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  86. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  87. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  88. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  89. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +7 -2
  90. package/template/.codex/skills/yss-router/SKILL.md +4 -2
  91. package/template/.codex/skills/yss-router/references/router-contract.yaml +18 -3
  92. package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +58 -1
  93. package/template/.codex/skills/yss-stage-decision/SKILL.md +50 -0
  94. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  95. package/template/.codex/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  96. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  97. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  98. package/template/.codex/skills/yss-stage-decision/references/validation-rules.md +18 -0
  99. package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  100. package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  101. package/template/.codex/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  102. package/template/.codex/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  103. package/template/.codex/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  104. package/template/.codex/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  105. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  106. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  107. package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  108. package/template/.codex/skills/yss-tactical-design/SKILL.md +33 -0
  109. package/template/.codex/skills/yss-tactical-design/agents/openai.yaml +4 -0
  110. package/template/.codex/skills/yss-tactical-design/references/output-template.md +28 -0
  111. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  112. package/template/.codex/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  113. package/template/.codex/skills/yss-tactical-design/references/validation-rules.md +13 -0
  114. package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  115. package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  116. package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  117. package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  118. package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  119. package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  120. package/template/.codex/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  121. package/template/.codex/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  122. package/template/.cursor/skills/yss-domain/SKILL.md +5 -4
  123. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +5 -5
  124. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  125. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  126. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  127. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  128. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +7 -2
  129. package/template/.cursor/skills/yss-router/SKILL.md +4 -2
  130. package/template/.cursor/skills/yss-router/references/router-contract.yaml +18 -3
  131. package/template/.cursor/skills/yss-router/references/slice-implementation-contract.md +58 -1
  132. package/template/.cursor/skills/yss-stage-decision/SKILL.md +50 -0
  133. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  134. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  135. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  136. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  137. package/template/.cursor/skills/yss-stage-decision/references/validation-rules.md +18 -0
  138. package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  139. package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  140. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  141. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  142. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  143. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  144. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  145. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  146. package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  147. package/template/.cursor/skills/yss-tactical-design/SKILL.md +33 -0
  148. package/template/.cursor/skills/yss-tactical-design/agents/openai.yaml +4 -0
  149. package/template/.cursor/skills/yss-tactical-design/references/output-template.md +28 -0
  150. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  151. package/template/.cursor/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  152. package/template/.cursor/skills/yss-tactical-design/references/validation-rules.md +13 -0
  153. package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  154. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  155. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  156. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  157. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  158. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  159. package/template/.cursor/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  160. package/template/.cursor/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  161. package/template/.hermes/skills/yss-domain/SKILL.md +5 -4
  162. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +5 -5
  163. package/template/.hermes/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  164. package/template/.hermes/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  165. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  166. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  167. package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +7 -2
  168. package/template/.hermes/skills/yss-router/SKILL.md +4 -2
  169. package/template/.hermes/skills/yss-router/references/router-contract.yaml +18 -3
  170. package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +58 -1
  171. package/template/.hermes/skills/yss-stage-decision/SKILL.md +50 -0
  172. package/template/.hermes/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  173. package/template/.hermes/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  174. package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  175. package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  176. package/template/.hermes/skills/yss-stage-decision/references/validation-rules.md +18 -0
  177. package/template/.hermes/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  178. package/template/.hermes/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  179. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  180. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  181. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  182. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  183. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  184. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  185. package/template/.hermes/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  186. package/template/.hermes/skills/yss-tactical-design/SKILL.md +33 -0
  187. package/template/.hermes/skills/yss-tactical-design/agents/openai.yaml +4 -0
  188. package/template/.hermes/skills/yss-tactical-design/references/output-template.md +28 -0
  189. package/template/.hermes/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  190. package/template/.hermes/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  191. package/template/.hermes/skills/yss-tactical-design/references/validation-rules.md +13 -0
  192. package/template/.hermes/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  193. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  194. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  195. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  196. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  197. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  198. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  199. package/template/.hermes/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  200. package/template/.pi/skills/yss-domain/SKILL.md +5 -4
  201. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +5 -5
  202. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  203. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  204. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  205. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  206. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +7 -2
  207. package/template/.pi/skills/yss-router/SKILL.md +4 -2
  208. package/template/.pi/skills/yss-router/references/router-contract.yaml +18 -3
  209. package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +58 -1
  210. package/template/.pi/skills/yss-stage-decision/SKILL.md +50 -0
  211. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  212. package/template/.pi/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  213. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  214. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  215. package/template/.pi/skills/yss-stage-decision/references/validation-rules.md +18 -0
  216. package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  217. package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  218. package/template/.pi/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  219. package/template/.pi/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  220. package/template/.pi/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  221. package/template/.pi/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  222. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  223. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  224. package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  225. package/template/.pi/skills/yss-tactical-design/SKILL.md +33 -0
  226. package/template/.pi/skills/yss-tactical-design/agents/openai.yaml +4 -0
  227. package/template/.pi/skills/yss-tactical-design/references/output-template.md +28 -0
  228. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  229. package/template/.pi/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  230. package/template/.pi/skills/yss-tactical-design/references/validation-rules.md +13 -0
  231. package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  232. package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  233. package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  234. package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  235. package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  236. package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  237. package/template/.pi/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  238. package/template/.pi/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  239. package/template/.qoder/skills/yss-domain/SKILL.md +5 -4
  240. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +5 -5
  241. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  242. package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  243. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  244. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  245. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +7 -2
  246. package/template/.qoder/skills/yss-router/SKILL.md +4 -2
  247. package/template/.qoder/skills/yss-router/references/router-contract.yaml +18 -3
  248. package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +58 -1
  249. package/template/.qoder/skills/yss-stage-decision/SKILL.md +50 -0
  250. package/template/.qoder/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  251. package/template/.qoder/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  252. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  253. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  254. package/template/.qoder/skills/yss-stage-decision/references/validation-rules.md +18 -0
  255. package/template/.qoder/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  256. package/template/.qoder/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  257. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  258. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  259. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  260. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  261. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  262. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  263. package/template/.qoder/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  264. package/template/.qoder/skills/yss-tactical-design/SKILL.md +33 -0
  265. package/template/.qoder/skills/yss-tactical-design/agents/openai.yaml +4 -0
  266. package/template/.qoder/skills/yss-tactical-design/references/output-template.md +28 -0
  267. package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  268. package/template/.qoder/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  269. package/template/.qoder/skills/yss-tactical-design/references/validation-rules.md +13 -0
  270. package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  271. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  272. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  273. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  274. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  275. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  276. package/template/.qoder/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  277. package/template/.qoder/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  278. package/template/.trae/skills/yss-domain/SKILL.md +5 -4
  279. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +5 -5
  280. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
  281. package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
  282. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
  283. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +6 -3
  284. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +7 -2
  285. package/template/.trae/skills/yss-router/SKILL.md +4 -2
  286. package/template/.trae/skills/yss-router/references/router-contract.yaml +18 -3
  287. package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +58 -1
  288. package/template/.trae/skills/yss-stage-decision/SKILL.md +50 -0
  289. package/template/.trae/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
  290. package/template/.trae/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
  291. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
  292. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
  293. package/template/.trae/skills/yss-stage-decision/references/validation-rules.md +18 -0
  294. package/template/.trae/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
  295. package/template/.trae/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
  296. package/template/.trae/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
  297. package/template/.trae/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
  298. package/template/.trae/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
  299. package/template/.trae/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
  300. package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
  301. package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
  302. package/template/.trae/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
  303. package/template/.trae/skills/yss-tactical-design/SKILL.md +33 -0
  304. package/template/.trae/skills/yss-tactical-design/agents/openai.yaml +4 -0
  305. package/template/.trae/skills/yss-tactical-design/references/output-template.md +28 -0
  306. package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
  307. package/template/.trae/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
  308. package/template/.trae/skills/yss-tactical-design/references/validation-rules.md +13 -0
  309. package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
  310. package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
  311. package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
  312. package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
  313. package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
  314. package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
  315. package/template/.trae/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
  316. package/template/.trae/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
  317. package/template/AGENTS.md +2 -1
  318. package/template/docs/agents/digital-human-roles.md +2 -2
  319. package/template/docs/agents/digital-human-roles.yaml +7 -1
  320. package/template/docs/agents/yss-skill-registry.yaml +12 -0
  321. package/template/docs/architecture/templates/system-overview-design-template.md +1 -0
  322. package/template/docs/process/lifecycle-artifact-map.md +8 -0
  323. package/template/docs/process/lifecycle-registry-baseline.json +11 -1
  324. package/template/docs/process/lifecycle-registry.yaml +46 -2
  325. package/template/docs/process/schemas/digital-human-task-package.schema.json +107 -0
  326. package/template/docs/process/schemas/subagent-task-package.schema.json +6 -0
  327. package/template/docs/process/subagent-collaboration.md +2 -2
  328. package/template/docs/templates/subagent-task-package-template.md +39 -1
  329. package/template/scripts/lib/lifecycle-transition.mjs +259 -0
  330. package/template/scripts/lib/scenario-checks.mjs +96 -2
  331. package/template/scripts/lib/task-package.mjs +214 -0
  332. package/template/scripts/verify-digital-human-task-package +14 -0
  333. package/template/scripts/verify-digital-human-task-package-scenarios +8 -0
  334. package/template/scripts/verify-lifecycle-transition-scenarios +105 -0
  335. package/template/scripts/verify-subagent-task-package +8 -0
  336. package/template/scripts/verify-subagent-task-package-scenarios +196 -0
  337. package/template/scripts/verify-template +13 -2
  338. package/template/skills-lock.json +35 -3
  339. package/template.snapshot.json +4 -4
@@ -0,0 +1,19 @@
1
+ # 阶段决策包合同
2
+
3
+ `stage_decision_package` 是 Discovery、需求/产品/商务决策与 DDD 战略设计之间的冻结入口。它记录“做什么、为什么做、范围是什么、哪些仍未决”,不复制领域模型事实。
4
+
5
+ ## 必须包含
6
+
7
+ - 问题陈述、目标用户、MVP、非目标、成功标准和可执行的测试 seam;
8
+ - 已确认决策、假设、约束和未决项;
9
+ - `domain_strategy_ref`:领域战略合同的稳定 ID、版本、digest 和批准状态;
10
+ - UI/API/Data/Backend/Frontend/跨仓/高风险影响面布尔值;
11
+ - 每个下游消费者的传播方式、重新批准条件、证据引用和批准记录。`approval.approval_ref` 必须指向可读取且通过 `scripts/verify-approval-record` 的 `gate.stage-decision-package-approved` 会签记录;`approval.approver` 必须与记录中的 `role_id` 一致。
12
+
13
+ ## 未决项规则
14
+
15
+ `blocker` 必须阻断批准;`deferred` 必须同时记录责任人、下一动作和目标版本/发布日期。没有责任人或恢复路径的未决项不得隐藏在备注中。
16
+
17
+ ## 下游消费规则
18
+
19
+ 只有 `approved` 且引用的领域战略为 `approved`、版本当前的阶段包,才可以进入 Spec synthesis。任何领域战略 digest、版本或影响面变化都使阶段包 `stale`,并要求重新评估。
@@ -0,0 +1,86 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://yss.local/schemas/stage-decision-package-v1.json",
4
+ "title": "YSS Stage Decision Package",
5
+ "type": "object",
6
+ "required": ["schema_version", "stage_decision_id", "package_version", "status", "problem_statement", "target_users", "mvp", "non_goals", "success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints", "unresolved_items", "terminology_refs", "domain_strategy_ref", "impact_assessment", "downstream_mapping", "evidence_refs", "approval"],
7
+ "properties": {
8
+ "schema_version": {"const": 1},
9
+ "stage_decision_id": {"type": "string", "pattern": "^stage-decision\\.[a-z0-9][a-z0-9-]*$"},
10
+ "package_version": {"type": "string", "pattern": "^v[0-9]+$"},
11
+ "status": {"enum": ["draft", "ready-for-human", "approved", "stale", "blocked"]},
12
+ "problem_statement": {"type": "string", "minLength": 1},
13
+ "target_users": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
14
+ "mvp": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
15
+ "non_goals": {"type": "array", "items": {"type": "string", "minLength": 1}},
16
+ "success_criteria": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
17
+ "test_seams": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
18
+ "confirmed_decisions": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
19
+ "assumptions": {"type": "array", "items": {"type": "string", "minLength": 1}},
20
+ "constraints": {"type": "array", "items": {"type": "string", "minLength": 1}},
21
+ "unresolved_items": {"type": "array", "items": {"$ref": "#/$defs/unresolved"}},
22
+ "terminology_refs": {"type": "array", "items": {"type": "string", "minLength": 1}},
23
+ "domain_strategy_ref": {"$ref": "#/$defs/domainRef"},
24
+ "impact_assessment": {"$ref": "#/$defs/impact"},
25
+ "downstream_mapping": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/mapping"}},
26
+ "evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
27
+ "approval": {"$ref": "#/$defs/approval"}
28
+ },
29
+ "$defs": {
30
+ "unresolved": {
31
+ "type": "object",
32
+ "required": ["item", "type", "owner", "next_action", "target_version"],
33
+ "properties": {
34
+ "item": {"type": "string", "minLength": 1},
35
+ "type": {"enum": ["blocker", "deferred"]},
36
+ "owner": {"type": "string", "minLength": 1},
37
+ "next_action": {"type": "string", "minLength": 1},
38
+ "target_version": {"type": "string", "minLength": 1}
39
+ }
40
+ },
41
+ "domainRef": {
42
+ "type": "object",
43
+ "required": ["domain_strategy_id", "domain_version", "digest", "status", "persisted_ref"],
44
+ "properties": {
45
+ "domain_strategy_id": {"type": "string", "pattern": "^domain-strategy\\.[a-z0-9][a-z0-9-]*$"},
46
+ "domain_version": {"type": "string", "pattern": "^v[0-9]+$"},
47
+ "digest": {"type": "string", "minLength": 1},
48
+ "status": {"enum": ["approved", "stale", "blocked"]},
49
+ "persisted_ref": {"type": "string", "minLength": 1}
50
+ }
51
+ },
52
+ "impact": {
53
+ "type": "object",
54
+ "required": ["ui", "api", "data", "backend", "frontend", "cross_repo", "high_risk"],
55
+ "properties": {
56
+ "ui": {"type": "boolean"},
57
+ "api": {"type": "boolean"},
58
+ "data": {"type": "boolean"},
59
+ "backend": {"type": "boolean"},
60
+ "frontend": {"type": "boolean"},
61
+ "cross_repo": {"type": "boolean"},
62
+ "high_risk": {"type": "boolean"}
63
+ }
64
+ },
65
+ "mapping": {
66
+ "type": "object",
67
+ "required": ["domain_change", "consumer", "propagation", "reapproval_condition"],
68
+ "properties": {
69
+ "domain_change": {"type": "string", "minLength": 1},
70
+ "consumer": {"type": "string", "minLength": 1},
71
+ "propagation": {"enum": ["direct", "transitive", "not-applicable", "stale"]},
72
+ "reapproval_condition": {"type": "string", "minLength": 1}
73
+ }
74
+ },
75
+ "approval": {
76
+ "type": "object",
77
+ "required": ["approval_ref", "approver", "persisted_ref", "current_version"],
78
+ "properties": {
79
+ "approval_ref": {"type": "string", "minLength": 1},
80
+ "approver": {"type": "string", "minLength": 1},
81
+ "persisted_ref": {"type": "string", "minLength": 1},
82
+ "current_version": {"type": "string", "pattern": "^v[0-9]+$"}
83
+ }
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,18 @@
1
+ # 验证规则
2
+
3
+ 验证分为结构、引用和语义三层:
4
+
5
+ 1. **结构**:Schema 版本、稳定 ID、状态枚举、必填字段、条件字段和证据格式。
6
+ 2. **引用**:上下文端点、场景、不变量、术语和下游资产引用必须可解析。
7
+ 3. **语义**:禁止关系自环、未知上下文、未批准 Shared Kernel、未解释的语义/技术方向差异、职责重叠、无责任人的不变量和跨上下文直接共享实体。
8
+
9
+ 以下情况必须 `blocked`:关键规则所有权未知、关键术语冲突、上下文边界未定、关键失败场景缺失、事件语义无法解释、领域专家确认缺失。
10
+
11
+ 以下变化应触发精确传播:
12
+
13
+ - 术语含义变化 → Spec、验收、原型或 API;
14
+ - 上下文边界变化 → 系统架构、OpenAPI、数据和切片;
15
+ - Context Map 关系变化 → 集成契约和模型翻译;
16
+ - 不变量变化 → 测试 seam、实现合同和验证策略。
17
+
18
+ 验证器允许“语义方向 ≠ 技术方向”,但要求 `direction_explanation` 和翻译责任非空。
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import process from "node:process";
4
+ import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
5
+ import { loadApprovalRecord, resolveApprovalRef, validateApprovalRecordFile } from "../../../../scripts/lib/approval-record.mjs";
6
+
7
+ const required = ["schema_version", "domain_strategy_id", "domain_version", "status", "contexts", "subdomains", "relationships", "scenarios", "concept_candidates", "invariants", "terminology_refs", "downstream_mapping", "evidence_refs", "approval"];
8
+ const idPatterns = {
9
+ context_id: /^[A-Z][A-Za-z0-9]+$/,
10
+ domain_strategy_id: /^domain-strategy\.[a-z0-9][a-z0-9-]*$/,
11
+ subdomain_id: /^subdomain\.[a-z0-9][a-z0-9-]*$/,
12
+ relationship_id: /^relationship\.[a-z0-9][a-z0-9-]*$/,
13
+ scenario_id: /^scenario\.[a-z0-9][a-z0-9-]*$/,
14
+ concept_id: /^domain-concept\.[a-z0-9][a-z0-9-]*$/,
15
+ invariant_id: /^invariant\.[a-z0-9][a-z0-9-]*$/
16
+ };
17
+ const relationshipPatterns = new Set(["Partnership", "Customer/Supplier", "Conformist", "Anti-Corruption Layer", "Open Host Service", "Published Language", "Shared Kernel", "Separate Ways"]);
18
+
19
+ function fail(errors) {
20
+ process.stderr.write(`${JSON.stringify({ result: "blocked", errors }, null, 2)}\n`);
21
+ process.exitCode = 1;
22
+ }
23
+
24
+ function nonEmpty(value) { return typeof value === "string" && value.trim().length > 0; }
25
+ function list(value) { return Array.isArray(value); }
26
+ function unique(items, label, errors) {
27
+ const seen = new Set();
28
+ for (const item of items) {
29
+ if (seen.has(item)) errors.push(`${label} 重复: ${item}`);
30
+ seen.add(item);
31
+ }
32
+ }
33
+ function requireField(object, field, path, errors) {
34
+ if (!(field in object) || object[field] === null || object[field] === undefined) errors.push(`${path}.${field} 缺失`);
35
+ }
36
+ function requireString(object, field, path, errors) {
37
+ requireField(object, field, path, errors);
38
+ if (field in object && !nonEmpty(object[field])) errors.push(`${path}.${field} 必须是非空字符串`);
39
+ }
40
+ function requireArray(object, field, path, errors, min = 0, itemKind = "string") {
41
+ requireField(object, field, path, errors);
42
+ if (field in object && (!list(object[field]) || object[field].length < min)) errors.push(`${path}.${field} 必须是至少 ${min} 项的数组`);
43
+ if (field in object && list(object[field]) && itemKind === "string") object[field].forEach((item, index) => { if (!nonEmpty(item)) errors.push(`${path}.${field}[${index}] 必须是非空字符串`); });
44
+ }
45
+
46
+ function validate(data) {
47
+ const errors = [];
48
+ if (!data || typeof data !== "object" || Array.isArray(data)) return ["合同必须是对象"];
49
+ for (const field of required) requireField(data, field, "root", errors);
50
+ if (data.schema_version !== 1) errors.push("schema_version 必须为 1");
51
+ if (!idPatterns.domain_strategy_id.test(String(data.domain_strategy_id ?? ""))) errors.push("domain_strategy_id 格式非法");
52
+ if (!/^v[0-9]+$/.test(String(data.domain_version ?? ""))) errors.push("domain_version 必须形如 v1");
53
+ if (!["draft", "ready-for-human", "approved", "stale", "blocked"].includes(data.status)) errors.push("status 非法");
54
+
55
+ requireArray(data, "contexts", "root", errors, 1, "object");
56
+ const contexts = list(data.contexts) ? data.contexts : [];
57
+ const contextIds = contexts.map((item) => item?.context_id).filter(Boolean);
58
+ unique(contextIds, "context_id", errors);
59
+ for (const [index, context] of contexts.entries()) {
60
+ const path = `contexts[${index}]`;
61
+ for (const field of ["context_id", "name", "owner", "status", "subdomain_type"]) requireString(context ?? {}, field, path, errors);
62
+ for (const field of ["responsibilities", "non_responsibilities"]) requireArray(context ?? {}, field, path, errors, field === "responsibilities" ? 1 : 0);
63
+ if (context?.context_id && !idPatterns.context_id.test(context.context_id)) errors.push(`${path}.context_id 格式非法`);
64
+ if (context?.status && !["candidate", "confirmed", "stale"].includes(context.status)) errors.push(`${path}.status 非法`);
65
+ if (context?.subdomain_type && !["Core Domain", "Supporting Subdomain", "Generic Subdomain"].includes(context.subdomain_type)) errors.push(`${path}.subdomain_type 非法`);
66
+ }
67
+
68
+ requireArray(data, "subdomains", "root", errors, 1, "object");
69
+ const subdomains = list(data.subdomains) ? data.subdomains : [];
70
+ unique(subdomains.map((item) => item?.subdomain_id).filter(Boolean), "subdomain_id", errors);
71
+ for (const [index, item] of subdomains.entries()) {
72
+ const path = `subdomains[${index}]`;
73
+ for (const field of ["subdomain_id", "name", "type", "rationale"]) requireString(item ?? {}, field, path, errors);
74
+ requireArray(item ?? {}, "evidence_refs", path, errors, 1);
75
+ if (item?.subdomain_id && !idPatterns.subdomain_id.test(item.subdomain_id)) errors.push(`${path}.subdomain_id 格式非法`);
76
+ if (item?.type && !["Core Domain", "Supporting Subdomain", "Generic Subdomain"].includes(item.type)) errors.push(`${path}.type 非法`);
77
+ }
78
+
79
+ const relationships = list(data.relationships) ? data.relationships : [];
80
+ unique(relationships.map((item) => item?.relationship_id).filter(Boolean), "relationship_id", errors);
81
+ for (const [index, relationship] of relationships.entries()) {
82
+ const path = `relationships[${index}]`;
83
+ for (const field of ["relationship_id", "from_context", "to_context", "relationship_pattern", "semantic_upstream", "semantic_downstream", "business_authority", "model_change_impact", "transport_direction", "translation_responsibility", "direction_explanation"]) requireString(relationship ?? {}, field, path, errors);
84
+ if (relationship?.relationship_id && !idPatterns.relationship_id.test(relationship.relationship_id)) errors.push(`${path}.relationship_id 格式非法`);
85
+ for (const field of ["from_context", "to_context", "semantic_upstream", "semantic_downstream"]) {
86
+ if (relationship?.[field] && !contextIds.includes(relationship[field])) errors.push(`${path}.${field} 未引用已声明上下文`);
87
+ }
88
+ if (relationship?.from_context === relationship?.to_context) errors.push(`${path} 不允许上下文自环`);
89
+ if (relationship?.semantic_upstream && ![relationship.from_context, relationship.to_context].includes(relationship.semantic_upstream)) errors.push(`${path}.semantic_upstream 必须是关系端点`);
90
+ if (relationship?.semantic_downstream && ![relationship.from_context, relationship.to_context].includes(relationship.semantic_downstream)) errors.push(`${path}.semantic_downstream 必须是关系端点`);
91
+ if (relationship?.relationship_pattern && !relationshipPatterns.has(relationship.relationship_pattern)) errors.push(`${path}.relationship_pattern 非法`);
92
+ if (relationship?.relationship_pattern === "Shared Kernel" && !nonEmpty(relationship.shared_kernel_approval_ref)) errors.push(`${path} Shared Kernel 必须有 shared_kernel_approval_ref`);
93
+ if (relationship?.semantic_upstream && relationship?.semantic_downstream && relationship.semantic_upstream === relationship.semantic_downstream) errors.push(`${path} semantic_upstream 与 semantic_downstream 不能相同`);
94
+ }
95
+
96
+ requireArray(data, "scenarios", "root", errors, 1, "object");
97
+ const scenarios = list(data.scenarios) ? data.scenarios : [];
98
+ const scenarioIds = scenarios.map((item) => item?.scenario_id).filter(Boolean);
99
+ unique(scenarioIds, "scenario_id", errors);
100
+ for (const [index, scenario] of scenarios.entries()) {
101
+ const path = `scenarios[${index}]`;
102
+ for (const field of ["scenario_id", "actor", "responsible_context", "status"]) requireString(scenario ?? {}, field, path, errors);
103
+ for (const field of ["preconditions", "commands", "rules", "events", "failure_results", "consumers"]) requireArray(scenario ?? {}, field, path, errors, field === "commands" || field === "rules" || field === "failure_results" ? 1 : 0);
104
+ if (scenario?.scenario_id && !idPatterns.scenario_id.test(scenario.scenario_id)) errors.push(`${path}.scenario_id 格式非法`);
105
+ if (scenario?.responsible_context && !contextIds.includes(scenario.responsible_context)) errors.push(`${path}.responsible_context 未声明`);
106
+ for (const consumer of scenario?.consumers ?? []) if (!contextIds.includes(consumer)) errors.push(`${path}.consumers 引用了未声明上下文: ${consumer}`);
107
+ }
108
+
109
+ const concepts = list(data.concept_candidates) ? data.concept_candidates : [];
110
+ unique(concepts.map((item) => item?.concept_id).filter(Boolean), "concept_id", errors);
111
+ for (const [index, concept] of concepts.entries()) {
112
+ const path = `concept_candidates[${index}]`;
113
+ for (const field of ["concept_id", "name", "context_id", "confidence", "status"]) requireString(concept ?? {}, field, path, errors);
114
+ for (const field of ["identity_features", "lifecycle"]) requireArray(concept ?? {}, field, path, errors, 1);
115
+ if (concept?.concept_id && !idPatterns.concept_id.test(concept.concept_id)) errors.push(`${path}.concept_id 格式非法`);
116
+ if (concept?.context_id && !contextIds.includes(concept.context_id)) errors.push(`${path}.context_id 未声明`);
117
+ if (concept?.confidence && !["low", "medium", "high"].includes(concept.confidence)) errors.push(`${path}.confidence 非法`);
118
+ }
119
+
120
+ const invariants = list(data.invariants) ? data.invariants : [];
121
+ unique(invariants.map((item) => item?.invariant_id).filter(Boolean), "invariant_id", errors);
122
+ for (const [index, invariant] of invariants.entries()) {
123
+ const path = `invariants[${index}]`;
124
+ for (const field of ["invariant_id", "statement", "responsible_context", "verification_method"]) requireString(invariant ?? {}, field, path, errors);
125
+ requireArray(invariant ?? {}, "scenario_refs", path, errors, 1);
126
+ if (invariant?.invariant_id && !idPatterns.invariant_id.test(invariant.invariant_id)) errors.push(`${path}.invariant_id 格式非法`);
127
+ if (invariant?.responsible_context && !contextIds.includes(invariant.responsible_context)) errors.push(`${path}.responsible_context 未声明`);
128
+ for (const reference of invariant?.scenario_refs ?? []) if (!scenarioIds.includes(reference)) errors.push(`${path}.scenario_refs 引用了未声明场景: ${reference}`);
129
+ }
130
+
131
+ requireArray(data, "terminology_refs", "root", errors, 0);
132
+ requireArray(data, "evidence_refs", "root", errors, 1);
133
+ const mappings = list(data.downstream_mapping) ? data.downstream_mapping : [];
134
+ for (const [index, mapping] of mappings.entries()) {
135
+ const path = `downstream_mapping[${index}]`;
136
+ for (const field of ["domain_change", "propagation", "reapproval_condition"]) requireString(mapping ?? {}, field, path, errors);
137
+ requireArray(mapping ?? {}, "impacts", path, errors, 1);
138
+ if (mapping?.propagation && !["direct", "transitive", "stale"].includes(mapping.propagation)) errors.push(`${path}.propagation 非法`);
139
+ }
140
+ const approval = data.approval ?? {};
141
+ for (const field of ["approval_ref", "approver", "persisted_ref", "current_version"]) requireString(approval, field, "approval", errors);
142
+ if (data.status === "approved") {
143
+ if (contexts.some((context) => context.status !== "confirmed")) errors.push("approved 合同要求所有上下文 status=confirmed");
144
+ if (approval.current_version !== data.domain_version) errors.push("approval.current_version 必须等于 domain_version");
145
+ try {
146
+ const approvalPath = resolveApprovalRef(approval.approval_ref);
147
+ validateApprovalRecordFile(approvalPath, { requireApproved: true });
148
+ const record = loadApprovalRecord(approvalPath);
149
+ if (record.gate_id !== "gate.domain-strategy-approved") errors.push("approval.approval_ref 的 gate_id 必须为 gate.domain-strategy-approved");
150
+ if (record.role_id !== approval.approver) errors.push("approval.approver 必须与会签记录 role_id 一致");
151
+ } catch (error) { errors.push(`approval.approval_ref 会签记录无效: ${error.message}`); }
152
+ }
153
+ return errors;
154
+ }
155
+
156
+ const file = process.argv[2];
157
+ if (!file) fail(["用法: validate-domain-strategy.mjs <contract.yaml>"]);
158
+ else {
159
+ try {
160
+ const source = await readFile(file, "utf8");
161
+ const document = parseDocument(source, { maxAliasCount: 0, uniqueKeys: true });
162
+ if (document.errors.length) fail([document.errors[0].message]);
163
+ else {
164
+ const errors = validate(document.toJS({ maxAliasCount: 0 }));
165
+ if (errors.length) fail(errors);
166
+ else process.stdout.write(JSON.stringify({ result: "completed", contract: file }, null, 2) + "\n");
167
+ }
168
+ } catch (error) { fail([error.message]); }
169
+ }
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { createHash } from "node:crypto";
4
+ import { resolve } from "node:path";
5
+ import process from "node:process";
6
+ import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
7
+ import { loadApprovalRecord, resolveApprovalRef, validateApprovalRecordFile } from "../../../../scripts/lib/approval-record.mjs";
8
+
9
+ const required = ["schema_version", "stage_decision_id", "package_version", "status", "problem_statement", "target_users", "mvp", "non_goals", "success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints", "unresolved_items", "terminology_refs", "domain_strategy_ref", "impact_assessment", "downstream_mapping", "evidence_refs", "approval"];
10
+ const idPattern = /^stage-decision\.[a-z0-9][a-z0-9-]*$/;
11
+
12
+ function fail(errors) {
13
+ process.stderr.write(`${JSON.stringify({ result: "blocked", errors }, null, 2)}\n`);
14
+ process.exitCode = 1;
15
+ }
16
+ function nonEmpty(value) { return typeof value === "string" && value.trim().length > 0; }
17
+ function requireField(object, field, path, errors) { if (!(field in object) || object[field] === null || object[field] === undefined) errors.push(`${path}.${field} 缺失`); }
18
+ function requireString(object, field, path, errors) { requireField(object, field, path, errors); if (field in object && !nonEmpty(object[field])) errors.push(`${path}.${field} 必须是非空字符串`); }
19
+ function requireArray(object, field, path, errors, min = 0) { requireField(object, field, path, errors); if (field in object && (!Array.isArray(object[field]) || object[field].length < min)) errors.push(`${path}.${field} 必须是至少 ${min} 项的数组`); if (field in object && Array.isArray(object[field])) object[field].forEach((item, index) => { if (!nonEmpty(item)) errors.push(`${path}.${field}[${index}] 必须是非空字符串`); }); }
20
+ function canonical(value) { if (Array.isArray(value)) return value.map(canonical); if (value && typeof value === "object") return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical(value[key])])); return value; }
21
+ function digest(value) { return `sha256:${createHash("sha256").update(JSON.stringify(canonical(value))).digest("hex")}`; }
22
+
23
+ async function validate(data) {
24
+ const errors = [];
25
+ if (!data || typeof data !== "object" || Array.isArray(data)) return ["合同必须是对象"];
26
+ for (const field of required) requireField(data, field, "root", errors);
27
+ if (data.schema_version !== 1) errors.push("schema_version 必须为 1");
28
+ if (!idPattern.test(String(data.stage_decision_id ?? ""))) errors.push("stage_decision_id 格式非法");
29
+ if (!/^v[0-9]+$/.test(String(data.package_version ?? ""))) errors.push("package_version 必须形如 v1");
30
+ if (!["draft", "ready-for-human", "approved", "stale", "blocked"].includes(data.status)) errors.push("status 非法");
31
+ for (const field of ["problem_statement"]) requireString(data, field, "root", errors);
32
+ for (const field of ["target_users", "mvp", "non_goals", "success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints", "terminology_refs", "evidence_refs"]) requireArray(data, field, "root", errors, ["target_users", "mvp", "success_criteria", "test_seams", "confirmed_decisions", "evidence_refs"].includes(field) ? 1 : 0);
33
+
34
+ const unresolved = Array.isArray(data.unresolved_items) ? data.unresolved_items : [];
35
+ for (const [index, item] of unresolved.entries()) {
36
+ const path = `unresolved_items[${index}]`;
37
+ for (const field of ["item", "type", "owner", "next_action", "target_version"]) requireString(item ?? {}, field, path, errors);
38
+ if (item?.type && !["blocker", "deferred"].includes(item.type)) errors.push(`${path}.type 非法`);
39
+ }
40
+ const domainRef = data.domain_strategy_ref ?? {};
41
+ for (const field of ["domain_strategy_id", "domain_version", "digest", "status", "persisted_ref"]) requireString(domainRef, field, "domain_strategy_ref", errors);
42
+ if (domainRef.status && !["approved", "stale", "blocked"].includes(domainRef.status)) errors.push("domain_strategy_ref.status 非法");
43
+ if (data.status === "approved" && domainRef.status !== "approved") errors.push("approved 阶段包必须引用 approved 的 domain strategy");
44
+ if (nonEmpty(domainRef.persisted_ref)) {
45
+ try {
46
+ const strategySource = await readFile(resolve(process.cwd(), domainRef.persisted_ref), "utf8");
47
+ const strategyDocument = parseDocument(strategySource, { maxAliasCount: 0, uniqueKeys: true });
48
+ if (strategyDocument.errors.length) errors.push(`domain_strategy_ref.persisted_ref YAML 非法: ${strategyDocument.errors[0].message}`);
49
+ else {
50
+ const strategy = strategyDocument.toJS({ maxAliasCount: 0 });
51
+ if (strategy.domain_strategy_id !== domainRef.domain_strategy_id) errors.push("domain_strategy_ref.domain_strategy_id 与实际文件不一致");
52
+ if (strategy.domain_version !== domainRef.domain_version) errors.push("domain_strategy_ref.domain_version 与实际文件不一致");
53
+ if (strategy.status !== domainRef.status) errors.push("domain_strategy_ref.status 与实际文件不一致");
54
+ if (domainRef.digest !== digest(strategy)) errors.push("domain_strategy_ref.digest 与实际领域战略内容不一致");
55
+ }
56
+ } catch (error) { errors.push(`domain_strategy_ref.persisted_ref 无法读取: ${error.message}`); }
57
+ }
58
+
59
+ const impact = data.impact_assessment ?? {};
60
+ for (const field of ["ui", "api", "data", "backend", "frontend", "cross_repo", "high_risk"]) {
61
+ requireField(impact, field, "impact_assessment", errors);
62
+ if (field in impact && typeof impact[field] !== "boolean") errors.push(`impact_assessment.${field} 必须是 boolean`);
63
+ }
64
+ const mappings = Array.isArray(data.downstream_mapping) ? data.downstream_mapping : [];
65
+ if (mappings.length < 1) errors.push("downstream_mapping 至少需要一项");
66
+ for (const [index, mapping] of mappings.entries()) {
67
+ const path = `downstream_mapping[${index}]`;
68
+ for (const field of ["domain_change", "consumer", "propagation", "reapproval_condition"]) requireString(mapping ?? {}, field, path, errors);
69
+ if (mapping?.propagation && !["direct", "transitive", "not-applicable", "stale"].includes(mapping.propagation)) errors.push(`${path}.propagation 非法`);
70
+ }
71
+ const approval = data.approval ?? {};
72
+ for (const field of ["approval_ref", "approver", "persisted_ref", "current_version"]) requireString(approval, field, "approval", errors);
73
+ if (data.status === "approved" && approval.current_version !== data.package_version) errors.push("approval.current_version 必须等于 package_version");
74
+ if (unresolved.some((item) => item?.type === "blocker") && data.status === "approved") errors.push("存在 blocker 未决项时不得 approved");
75
+ if (data.status === "approved" && nonEmpty(approval.approval_ref)) {
76
+ try {
77
+ const approvalPath = resolveApprovalRef(approval.approval_ref);
78
+ validateApprovalRecordFile(approvalPath, { requireApproved: true });
79
+ const record = loadApprovalRecord(approvalPath);
80
+ if (record.gate_id !== "gate.stage-decision-package-approved") errors.push("approval_ref 的 gate_id 必须为 gate.stage-decision-package-approved");
81
+ if (record.role_id !== approval.approver) errors.push("approval.approver 必须与会签记录 role_id 一致");
82
+ } catch (error) { errors.push(`approval_ref 会签记录无效: ${error.message}`); }
83
+ }
84
+ return errors;
85
+ }
86
+
87
+ const file = process.argv[2];
88
+ if (!file) fail(["用法: validate-stage-decision-package.mjs <package.yaml>"]);
89
+ else {
90
+ try {
91
+ const source = await readFile(file, "utf8");
92
+ const document = parseDocument(source, { maxAliasCount: 0, uniqueKeys: true });
93
+ if (document.errors.length) fail([document.errors[0].message]);
94
+ else {
95
+ const errors = await validate(document.toJS({ maxAliasCount: 0 }));
96
+ if (errors.length) fail(errors);
97
+ else process.stdout.write(JSON.stringify({ result: "completed", contract: file }, null, 2) + "\n");
98
+ }
99
+ } catch (error) { fail([error.message]); }
100
+ }
@@ -0,0 +1,15 @@
1
+ schema_version: 1
2
+ gate_id: gate.domain-strategy-approved
3
+ decision: approved
4
+ actor_kind: digital-human
5
+ role_id: role.product-manager
6
+ runtime_id: runtime.generic
7
+ runtime_instance_ref: "runtime.generic:role.product-manager"
8
+ principal_ref: "instance:role.product-manager"
9
+ drafter_role_id: role.requirements-manager
10
+ countersigner_role_ids:
11
+ - role.product-manager
12
+ evidence_refs:
13
+ - evidence.domain-strategy-review.supplier
14
+ biological_veto: false
15
+ notes: DDD 战略设计由需求经理起草,产品经理独立会签。
@@ -0,0 +1,58 @@
1
+ schema_version: 1
2
+ domain_strategy_id: domain-strategy.invalid-direction
3
+ domain_version: v1
4
+ status: ready-for-human
5
+ contexts:
6
+ - context_id: A
7
+ name: A
8
+ responsibilities: [rule]
9
+ non_responsibilities: []
10
+ subdomain_type: Supporting Subdomain
11
+ owner: owner
12
+ status: confirmed
13
+ - context_id: B
14
+ name: B
15
+ responsibilities: [consume]
16
+ non_responsibilities: []
17
+ subdomain_type: Supporting Subdomain
18
+ owner: owner
19
+ status: confirmed
20
+ subdomains:
21
+ - subdomain_id: subdomain.a
22
+ name: A
23
+ type: Supporting Subdomain
24
+ rationale: test
25
+ evidence_refs: [e]
26
+ relationships:
27
+ - relationship_id: relationship.a-b
28
+ from_context: A
29
+ to_context: B
30
+ relationship_pattern: Published Language
31
+ semantic_upstream: A
32
+ semantic_downstream: B
33
+ business_authority: A
34
+ model_change_impact: B adapts
35
+ transport_direction: B calls A
36
+ translation_responsibility: B
37
+ direction_explanation: ""
38
+ scenarios:
39
+ - scenario_id: scenario.test
40
+ actor: actor
41
+ preconditions: []
42
+ commands: [command]
43
+ rules: [rule]
44
+ events: []
45
+ failure_results: [failure]
46
+ responsible_context: A
47
+ consumers: [B]
48
+ status: confirmed
49
+ concept_candidates: []
50
+ invariants: []
51
+ terminology_refs: [t]
52
+ downstream_mapping: []
53
+ evidence_refs: [e]
54
+ approval:
55
+ approval_ref: a
56
+ approver: a
57
+ persisted_ref: p
58
+ current_version: v1
@@ -0,0 +1,44 @@
1
+ schema_version: 1
2
+ stage_decision_id: stage-decision.invalid-blocker
3
+ package_version: v1
4
+ status: approved
5
+ problem_statement: 示例
6
+ target_users: [用户]
7
+ mvp: [功能]
8
+ non_goals: []
9
+ success_criteria: [标准]
10
+ test_seams: [seam]
11
+ confirmed_decisions: [决定]
12
+ assumptions: []
13
+ constraints: []
14
+ unresolved_items:
15
+ - item: 规则所有权未确认
16
+ type: blocker
17
+ owner: role.product-manager
18
+ next_action: 召开领域评审
19
+ target_version: 2026-Q4
20
+ terminology_refs: [CONTEXT.md#Example]
21
+ domain_strategy_ref:
22
+ domain_strategy_id: domain-strategy.invalid
23
+ domain_version: v1
24
+ digest: sha256:invalid
25
+ status: approved
26
+ impact_assessment:
27
+ ui: false
28
+ api: false
29
+ data: false
30
+ backend: true
31
+ frontend: false
32
+ cross_repo: false
33
+ high_risk: false
34
+ downstream_mapping:
35
+ - domain_change: example
36
+ consumer: spec-synthesis
37
+ propagation: direct
38
+ reapproval_condition: 规则确认
39
+ evidence_refs: [evidence.invalid]
40
+ approval:
41
+ approval_ref: docs/.scratch/invalid/gate.yaml
42
+ approver: role.lifecycle-orchestrator
43
+ persisted_ref: docs/.scratch/invalid/package.yaml
44
+ current_version: v1
@@ -0,0 +1,15 @@
1
+ schema_version: 1
2
+ gate_id: gate.stage-decision-package-approved
3
+ decision: approved
4
+ actor_kind: digital-human
5
+ role_id: role.product-manager
6
+ runtime_id: runtime.generic
7
+ runtime_instance_ref: "runtime.generic:role.product-manager"
8
+ principal_ref: "instance:role.product-manager"
9
+ drafter_role_id: role.requirements-manager
10
+ countersigner_role_ids:
11
+ - role.product-manager
12
+ evidence_refs:
13
+ - evidence.stage-decision-package.supplier
14
+ biological_veto: false
15
+ notes: 阶段决策包由需求经理起草,产品经理独立会签。
@@ -0,0 +1,49 @@
1
+ schema_version: 1
2
+ stage_decision_id: stage-decision.supplier-admission
3
+ package_version: v1
4
+ status: approved
5
+ problem_statement: 合规准入决定分散,采购无法稳定判断当前有效资格。
6
+ target_users: [采购专员、合规专员]
7
+ mvp: [提交供应商申请、合规准入决定、采购侧有效性校验]
8
+ non_goals: [供应商结算、采购付款、通用工作流平台]
9
+ success_criteria: [新采购订单 100% 校验当前有效准入决定]
10
+ test_seams: [supplier-application-submit, admission-validity-check]
11
+ confirmed_decisions: [ComplianceReview 拥有准入规则语义,ProcurementExecution 只消费决定]
12
+ assumptions: [供应商已有唯一 subject_ref]
13
+ constraints: [保留现有采购订单流程]
14
+ unresolved_items:
15
+ - item: 供应商历史资料迁移范围
16
+ type: deferred
17
+ owner: role.product-manager
18
+ next_action: 在 Spec synthesis 前完成数据盘点
19
+ target_version: 2026-Q4
20
+ terminology_refs: [CONTEXT.md#SupplierAdmission]
21
+ domain_strategy_ref:
22
+ domain_strategy_id: domain-strategy.supplier-admission
23
+ domain_version: v1
24
+ digest: sha256:a1a4df23fdb59ab8b4433cedba8271c8a7f11bc8a38abe675d3c7b645d51d7a1
25
+ status: approved
26
+ persisted_ref: .agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml
27
+ impact_assessment:
28
+ ui: true
29
+ api: true
30
+ data: true
31
+ backend: true
32
+ frontend: true
33
+ cross_repo: false
34
+ high_risk: false
35
+ downstream_mapping:
36
+ - domain_change: admission-decision-validity
37
+ consumer: spec-synthesis
38
+ propagation: direct
39
+ reapproval_condition: 领域策略版本或有效性规则变化
40
+ - domain_change: admission-decision-validity
41
+ consumer: ticket-decomposition
42
+ propagation: transitive
43
+ reapproval_condition: Spec 基线变更
44
+ evidence_refs: [evidence.discovery.supplier, evidence.domain-strategy-review.supplier]
45
+ approval:
46
+ approval_ref: .agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml
47
+ approver: role.product-manager
48
+ persisted_ref: docs/.scratch/supplier/stage-decision/stage-decision-package-v1.yaml
49
+ current_version: v1