create-yss-spec 2.2.2 → 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 (356) 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 +9 -9
  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 +3 -3
  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 +8 -5
  11. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +9 -4
  12. package/template/.agents/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  50. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +9 -4
  51. package/template/.claude/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  89. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +9 -4
  90. package/template/.codex/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  128. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +9 -4
  129. package/template/.cursor/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  167. package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +9 -4
  168. package/template/.hermes/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  206. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +9 -4
  207. package/template/.pi/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  245. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +9 -4
  246. package/template/.qoder/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +9 -9
  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 +3 -3
  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 +8 -5
  284. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +9 -4
  285. package/template/.trae/skills/yss-router/SKILL.md +5 -3
  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 +59 -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 +8 -4
  318. package/template/CONTEXT.md +14 -2
  319. package/template/docs/agents/digital-human-roles.md +83 -0
  320. package/template/docs/agents/digital-human-roles.yaml +259 -0
  321. package/template/docs/agents/triage-labels.md +5 -5
  322. package/template/docs/agents/yss-skill-registry.yaml +12 -0
  323. package/template/docs/architecture/templates/system-overview-design-template.md +1 -0
  324. package/template/docs/process/lifecycle-artifact-map.md +8 -0
  325. package/template/docs/process/lifecycle-registry-baseline.json +11 -1
  326. package/template/docs/process/lifecycle-registry.yaml +46 -2
  327. package/template/docs/process/schemas/digital-human-task-package.schema.json +107 -0
  328. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +2 -1
  329. package/template/docs/process/schemas/subagent-task-package.schema.json +6 -0
  330. package/template/docs/process/subagent-collaboration.md +5 -3
  331. package/template/docs/process/templates/stage-checkpoint-template.md +3 -1
  332. package/template/docs/templates/approval-record-template.yaml +14 -0
  333. package/template/docs/templates/digital-human-runtime-profile-template.md +38 -0
  334. package/template/docs/templates/grok-bot-profile-template.md +24 -0
  335. package/template/docs/templates/implementation-routing-template.md +3 -3
  336. package/template/docs/templates/local-parent-ticket-template.md +8 -0
  337. package/template/docs/templates/subagent-task-package-template.md +43 -1
  338. package/template/docs/templates/vertical-slice-ticket-template.md +7 -0
  339. package/template/docs/user-guide//344/272/247/345/223/201/347/240/224/345/217/221/345/205/250/347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +2 -0
  340. package/template/scripts/lib/approval-record.mjs +123 -0
  341. package/template/scripts/lib/digital-human-roles.mjs +398 -0
  342. package/template/scripts/lib/lifecycle-transition.mjs +259 -0
  343. package/template/scripts/lib/scenario-checks.mjs +96 -2
  344. package/template/scripts/lib/task-package.mjs +214 -0
  345. package/template/scripts/verify-approval-record +13 -0
  346. package/template/scripts/verify-digital-human-roles +10 -0
  347. package/template/scripts/verify-digital-human-roles-scenarios +147 -0
  348. package/template/scripts/verify-digital-human-task-package +14 -0
  349. package/template/scripts/verify-digital-human-task-package-scenarios +8 -0
  350. package/template/scripts/verify-lifecycle-checkpoint +2 -0
  351. package/template/scripts/verify-lifecycle-transition-scenarios +105 -0
  352. package/template/scripts/verify-subagent-task-package +8 -0
  353. package/template/scripts/verify-subagent-task-package-scenarios +196 -0
  354. package/template/scripts/verify-template +16 -2
  355. package/template/skills-lock.json +35 -3
  356. package/template.snapshot.json +4 -4
@@ -0,0 +1,213 @@
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
+
6
+ const required = [
7
+ "schema_version", "tactical_design_id", "tactical_version", "status", "context_ref",
8
+ "aggregate_catalog", "entity_catalog", "value_object_catalog", "behavior_catalog",
9
+ "invariant_catalog", "state_transition_catalog", "consistency_policy", "domain_event_catalog",
10
+ "gateway_catalog", "persistence_mapping", "test_seams", "adr_candidates", "upstream_impact",
11
+ "version", "digest", "evidence_refs"
12
+ ];
13
+ const statuses = new Set(["draft", "ready-for-human", "approved", "blocked", "stale", "drift", "new_impacts", "not-applicable"]);
14
+ const idPatterns = {
15
+ tactical_design_id: /^tactical-design\.[a-z0-9][a-z0-9-]*$/,
16
+ aggregate_id: /^aggregate\.[a-z0-9][a-z0-9-]*$/,
17
+ entity_id: /^entity\.[a-z0-9][a-z0-9-]*$/,
18
+ value_object_id: /^value-object\.[a-z0-9][a-z0-9-]*$/,
19
+ behavior_id: /^behavior\.[a-z0-9][a-z0-9-]*$/,
20
+ invariant_id: /^invariant\.[a-z0-9][a-z0-9-]*$/,
21
+ transition_id: /^transition\.[a-z0-9][a-z0-9-]*$/,
22
+ event_id: /^domain-event\.[a-z0-9][a-z0-9-]*$/,
23
+ gateway_id: /^gateway\.[a-z0-9][a-z0-9-]*$/,
24
+ seam_id: /^test-seam\.[a-z0-9][a-z0-9-]*$/,
25
+ version: /^v[0-9]+$/
26
+ };
27
+
28
+ const isObject = (value) => value && typeof value === "object" && !Array.isArray(value);
29
+ const nonEmpty = (value) => typeof value === "string" && value.trim().length > 0;
30
+ const list = (value) => Array.isArray(value);
31
+
32
+ function unique(items, label, errors) {
33
+ const seen = new Set();
34
+ for (const item of items) {
35
+ if (seen.has(item)) errors.push(`${label} 重复: ${item}`);
36
+ seen.add(item);
37
+ }
38
+ }
39
+
40
+ function requireField(object, field, path, errors) {
41
+ if (!Object.prototype.hasOwnProperty.call(object ?? {}, field) || object[field] === null || object[field] === undefined) {
42
+ errors.push(`${path}.${field} 缺失`);
43
+ }
44
+ }
45
+
46
+ function requireString(object, field, path, errors) {
47
+ requireField(object, field, path, errors);
48
+ if (Object.prototype.hasOwnProperty.call(object ?? {}, field) && !nonEmpty(object[field])) errors.push(`${path}.${field} 必须是非空字符串`);
49
+ }
50
+
51
+ function requireArray(object, field, path, errors, minimum = 0) {
52
+ requireField(object, field, path, errors);
53
+ if (Object.prototype.hasOwnProperty.call(object ?? {}, field) && (!list(object[field]) || object[field].length < minimum)) {
54
+ errors.push(`${path}.${field} 必须是至少 ${minimum} 项的数组`);
55
+ }
56
+ }
57
+
58
+ function requireId(value, kind, path, errors) {
59
+ if (value !== undefined && value !== null && !idPatterns[kind].test(String(value))) errors.push(`${path} 格式非法`);
60
+ }
61
+
62
+ function refsExist(values, known, path, errors) {
63
+ for (const [index, value] of (values ?? []).entries()) {
64
+ if (!known.has(value)) errors.push(`${path}[${index}] 引用了未声明对象: ${value}`);
65
+ }
66
+ }
67
+
68
+ function validate(data) {
69
+ const errors = [];
70
+ if (!isObject(data)) return ["合同必须是对象"];
71
+ for (const field of required) requireField(data, field, "root", errors);
72
+ if (data.schema_version !== 1) errors.push("schema_version 必须为 1");
73
+ requireId(data.tactical_design_id, "tactical_design_id", "tactical_design_id", errors);
74
+ for (const field of ["tactical_version", "version"]) if (data[field] !== undefined && !idPatterns.version.test(String(data[field]))) errors.push(`${field} 必须形如 v1`);
75
+ if (data.status !== undefined && !statuses.has(data.status)) errors.push(`status 非法: ${data.status}`);
76
+ if (data.digest !== undefined && !/^sha256:[A-Fa-f0-9]{64}$/.test(String(data.digest))) errors.push("digest 必须为 sha256 加 64 位十六进制");
77
+
78
+ for (const field of ["aggregate_catalog", "entity_catalog", "behavior_catalog", "invariant_catalog", "state_transition_catalog", "gateway_catalog", "persistence_mapping", "test_seams"]) {
79
+ requireArray(data, field, "root", errors, 1);
80
+ }
81
+ for (const field of ["value_object_catalog", "domain_event_catalog", "adr_candidates", "evidence_refs"]) requireArray(data, field, "root", errors);
82
+ if (!isObject(data.consistency_policy)) errors.push("consistency_policy 必须是对象");
83
+ if (!isObject(data.upstream_impact)) errors.push("upstream_impact 必须是对象");
84
+ if (isObject(data.consistency_policy)) {
85
+ for (const field of ["transaction_boundary", "concurrency", "idempotency", "cross_aggregate_strategy"]) requireString(data.consistency_policy, field, "consistency_policy", errors);
86
+ }
87
+ if (isObject(data.upstream_impact)) {
88
+ for (const field of ["spec_ref", "strategic_ref", "api_ref", "data_ref"]) requireString(data.upstream_impact, field, "upstream_impact", errors);
89
+ if (data.upstream_impact.upstream_current === false && data.status !== "stale") errors.push("上游已过期时 status 必须为 stale");
90
+ }
91
+
92
+ const aggregates = list(data.aggregate_catalog) ? data.aggregate_catalog : [];
93
+ const entities = list(data.entity_catalog) ? data.entity_catalog : [];
94
+ const values = list(data.value_object_catalog) ? data.value_object_catalog : [];
95
+ const behaviors = list(data.behavior_catalog) ? data.behavior_catalog : [];
96
+ const invariants = list(data.invariant_catalog) ? data.invariant_catalog : [];
97
+ const transitions = list(data.state_transition_catalog) ? data.state_transition_catalog : [];
98
+ const events = list(data.domain_event_catalog) ? data.domain_event_catalog : [];
99
+ const gateways = list(data.gateway_catalog) ? data.gateway_catalog : [];
100
+ const mappings = list(data.persistence_mapping) ? data.persistence_mapping : [];
101
+ const seams = list(data.test_seams) ? data.test_seams : [];
102
+ const ids = (items, field, kind, label) => {
103
+ const result = new Set();
104
+ unique(items.map((item) => item?.[field]).filter(Boolean), label, errors);
105
+ for (const [index, item] of items.entries()) {
106
+ if (item?.[field]) { requireId(item[field], kind, `${label}[${index}].${field}`, errors); result.add(item[field]); }
107
+ }
108
+ return result;
109
+ };
110
+ const aggregateIds = ids(aggregates, "aggregate_id", "aggregate_id", "aggregate_id");
111
+ const entityIds = ids(entities, "entity_id", "entity_id", "entity_id");
112
+ const valueIds = ids(values, "value_object_id", "value_object_id", "value_object_id");
113
+ const behaviorIds = ids(behaviors, "behavior_id", "behavior_id", "behavior_id");
114
+ const invariantIds = ids(invariants, "invariant_id", "invariant_id", "invariant_id");
115
+ const transitionIds = ids(transitions, "transition_id", "transition_id", "transition_id");
116
+ const eventIds = ids(events, "event_id", "event_id", "event_id");
117
+ const gatewayIds = ids(gateways, "gateway_id", "gateway_id", "gateway_id");
118
+ ids(seams, "seam_id", "seam_id", "seam_id");
119
+
120
+ for (const [index, aggregate] of aggregates.entries()) {
121
+ const path = `aggregate_catalog[${index}]`;
122
+ if (!isObject(aggregate)) { errors.push(`${path} 必须是对象`); continue; }
123
+ for (const field of ["aggregate_id", "name", "context_ref", "root_entity", "consistency_boundary"]) requireString(aggregate, field, path, errors);
124
+ requireArray(aggregate, "invariant_refs", path, errors, 1); requireArray(aggregate, "behavior_refs", path, errors, 1);
125
+ if (aggregate.model_origin === "strategic-concept") errors.push(`${path}.model_origin 不得直接把战略概念当作 Aggregate`);
126
+ if (aggregate.api_exposure !== "internal-only") errors.push(`${path}.api_exposure 必须为 internal-only`);
127
+ if (aggregate.root_entity && !entityIds.has(aggregate.root_entity)) errors.push(`${path}.root_entity 未引用 Entity`);
128
+ const rootEntity = entities.find((entity) => entity?.entity_id === aggregate.root_entity);
129
+ if (rootEntity && rootEntity.aggregate_id !== aggregate.aggregate_id) errors.push(`${path}.root_entity 的 aggregate_id 必须与当前 Aggregate 一致`);
130
+ refsExist(aggregate.invariant_refs, invariantIds, `${path}.invariant_refs`, errors);
131
+ refsExist(aggregate.behavior_refs, behaviorIds, `${path}.behavior_refs`, errors);
132
+ }
133
+ for (const [index, entity] of entities.entries()) {
134
+ const path = `entity_catalog[${index}]`;
135
+ if (!isObject(entity)) { errors.push(`${path} 必须是对象`); continue; }
136
+ for (const field of ["entity_id", "name", "aggregate_id", "identity", "lifecycle"]) requireString(entity, field, path, errors);
137
+ if (entity.aggregate_id && !aggregateIds.has(entity.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
138
+ }
139
+ for (const [index, value] of values.entries()) {
140
+ const path = `value_object_catalog[${index}]`;
141
+ if (!isObject(value)) { errors.push(`${path} 必须是对象`); continue; }
142
+ for (const field of ["value_object_id", "name", "aggregate_id", "immutable"]) requireField(value, field, path, errors);
143
+ if (typeof value.immutable !== "boolean" || value.immutable !== true) errors.push(`${path}.immutable 必须为 true`);
144
+ if (value.aggregate_id && !aggregateIds.has(value.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
145
+ }
146
+ for (const [index, behavior] of behaviors.entries()) {
147
+ const path = `behavior_catalog[${index}]`;
148
+ if (!isObject(behavior)) { errors.push(`${path} 必须是对象`); continue; }
149
+ for (const field of ["behavior_id", "name", "aggregate_id", "command"]) requireString(behavior, field, path, errors);
150
+ for (const field of ["preconditions", "invariant_refs", "postconditions", "event_refs"]) requireArray(behavior, field, path, errors, field === "invariant_refs" ? 1 : 0);
151
+ if (behavior.aggregate_id && !aggregateIds.has(behavior.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
152
+ refsExist(behavior.invariant_refs, invariantIds, `${path}.invariant_refs`, errors);
153
+ refsExist(behavior.event_refs, eventIds, `${path}.event_refs`, errors);
154
+ }
155
+ for (const [index, invariant] of invariants.entries()) {
156
+ const path = `invariant_catalog[${index}]`;
157
+ if (!isObject(invariant)) { errors.push(`${path} 必须是对象`); continue; }
158
+ for (const field of ["invariant_id", "aggregate_id", "statement"]) requireString(invariant, field, path, errors);
159
+ if (invariant.aggregate_id && !aggregateIds.has(invariant.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
160
+ }
161
+ for (const [index, transition] of transitions.entries()) {
162
+ const path = `state_transition_catalog[${index}]`;
163
+ if (!isObject(transition)) { errors.push(`${path} 必须是对象`); continue; }
164
+ for (const field of ["transition_id", "aggregate_id", "from", "to", "behavior_id"]) requireString(transition, field, path, errors);
165
+ if (transition.aggregate_id && !aggregateIds.has(transition.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
166
+ if (transition.behavior_id && !behaviorIds.has(transition.behavior_id)) errors.push(`${path}.behavior_id 未引用行为`);
167
+ }
168
+ for (const [index, event] of events.entries()) {
169
+ const path = `domain_event_catalog[${index}]`;
170
+ if (!isObject(event)) { errors.push(`${path} 必须是对象`); continue; }
171
+ for (const field of ["event_id", "name", "aggregate_id", "delivery"]) requireString(event, field, path, errors);
172
+ requireArray(event, "consumers", path, errors, 0);
173
+ if (event.aggregate_id && !aggregateIds.has(event.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
174
+ }
175
+ for (const [index, gateway] of gateways.entries()) {
176
+ const path = `gateway_catalog[${index}]`;
177
+ if (!isObject(gateway)) { errors.push(`${path} 必须是对象`); continue; }
178
+ for (const field of ["gateway_id", "name", "context_ref", "layer"]) requireString(gateway, field, path, errors);
179
+ requireArray(gateway, "capabilities", path, errors, 1);
180
+ if (gateway.layer !== "Domain") errors.push(`${path}.layer 必须为 Domain,Infrastructure 只实现 Gateway`);
181
+ }
182
+ for (const [index, mapping] of mappings.entries()) {
183
+ const path = `persistence_mapping[${index}]`;
184
+ if (!isObject(mapping)) { errors.push(`${path} 必须是对象`); continue; }
185
+ for (const field of ["aggregate_id", "storage_model", "notes"]) requireString(mapping, field, path, errors);
186
+ if (mapping.aggregate_id && !aggregateIds.has(mapping.aggregate_id)) errors.push(`${path}.aggregate_id 未引用 Aggregate`);
187
+ }
188
+ for (const [index, seam] of seams.entries()) {
189
+ const path = `test_seams[${index}]`;
190
+ if (!isObject(seam)) { errors.push(`${path} 必须是对象`); continue; }
191
+ for (const field of ["seam_id", "kind", "subject_ref", "assertion"]) requireString(seam, field, path, errors);
192
+ if (seam.subject_ref && !new Set([...aggregateIds, ...entityIds, ...valueIds, ...behaviorIds, ...invariantIds, ...transitionIds, ...gatewayIds]).has(seam.subject_ref)) errors.push(`${path}.subject_ref 未引用已声明领域对象`);
193
+ }
194
+ if (isObject(data.complexity) && data.complexity.escalate_to_standalone === true && !nonEmpty(data.complexity.standalone_ref)) errors.push("complexity.escalate_to_standalone 为 true 时必须提供 standalone_ref");
195
+ return errors;
196
+ }
197
+
198
+ async function main() {
199
+ const file = process.argv[2];
200
+ if (!file) throw new Error("用法: validate-tactical-design.mjs <contract.yaml>");
201
+ const source = await readFile(file, "utf8");
202
+ const document = parseDocument(source, { maxAliasCount: 0, uniqueKeys: true });
203
+ if (document.errors.length) throw new Error(`无法解析合同: ${document.errors[0].message}`);
204
+ const errors = validate(document.toJS({ maxAliasCount: 0 }));
205
+ if (errors.length) {
206
+ process.stderr.write(`${JSON.stringify({ result: "blocked", errors }, null, 2)}\n`);
207
+ process.exitCode = 1;
208
+ return;
209
+ }
210
+ process.stdout.write(`${JSON.stringify({ result: "ready-for-lifecycle-review", tactical_design_id: document.get("tactical_design_id"), status: document.get("status") }, null, 2)}\n`);
211
+ }
212
+
213
+ main().catch((error) => { process.stderr.write(`${error.message}\n`); process.exitCode = 1; });
@@ -0,0 +1,21 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.invalid-api
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog: [{aggregate_id: aggregate.example, name: Example, context_ref: context.example, root_entity: entity.example-root, invariant_refs: [invariant.example], behavior_refs: [behavior.example], consistency_boundary: single, api_exposure: public-aggregate}]
7
+ entity_catalog: [{entity_id: entity.example-root, name: Root, aggregate_id: aggregate.example, identity: id, lifecycle: active}]
8
+ value_object_catalog: []
9
+ behavior_catalog: [{behavior_id: behavior.example, name: Do, aggregate_id: aggregate.example, command: do, preconditions: [ready], invariant_refs: [invariant.example], postconditions: [done], event_refs: []}]
10
+ invariant_catalog: [{invariant_id: invariant.example, aggregate_id: aggregate.example, statement: required}]
11
+ state_transition_catalog: [{transition_id: transition.example, aggregate_id: aggregate.example, from: draft, to: done, behavior_id: behavior.example}]
12
+ consistency_policy: {transaction_boundary: single, concurrency: optimistic, idempotency: guarded, cross_aggregate_strategy: none}
13
+ domain_event_catalog: []
14
+ gateway_catalog: [{gateway_id: gateway.example, name: Gateway, context_ref: context.example, layer: Domain, capabilities: [load]}]
15
+ persistence_mapping: [{aggregate_id: aggregate.example, storage_model: example, notes: mapping}]
16
+ test_seams: [{seam_id: test-seam.example, kind: domain, subject_ref: invariant.example, assertion: behavior}]
17
+ adr_candidates: []
18
+ upstream_impact: {spec_ref: spec@v1, strategic_ref: strategy@v1, api_ref: api@draft, data_ref: data@v1, upstream_current: true}
19
+ version: v1
20
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
21
+ evidence_refs: []
@@ -0,0 +1,21 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.invalid-consistency
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog: [{aggregate_id: aggregate.example, name: Example, context_ref: context.example, root_entity: entity.example-root, invariant_refs: [invariant.example], behavior_refs: [behavior.example], consistency_boundary: single, api_exposure: internal-only}]
7
+ entity_catalog: [{entity_id: entity.example-root, name: Root, aggregate_id: aggregate.example, identity: id, lifecycle: active}]
8
+ value_object_catalog: []
9
+ behavior_catalog: [{behavior_id: behavior.example, name: Do, aggregate_id: aggregate.example, command: do, preconditions: [ready], invariant_refs: [invariant.example], postconditions: [done], event_refs: []}]
10
+ invariant_catalog: [{invariant_id: invariant.example, aggregate_id: aggregate.example, statement: required}]
11
+ state_transition_catalog: [{transition_id: transition.example, aggregate_id: aggregate.example, from: draft, to: done, behavior_id: behavior.example}]
12
+ consistency_policy: {}
13
+ domain_event_catalog: []
14
+ gateway_catalog: [{gateway_id: gateway.example, name: Gateway, context_ref: context.example, layer: Domain, capabilities: [load]}]
15
+ persistence_mapping: [{aggregate_id: aggregate.example, storage_model: example, notes: mapping}]
16
+ test_seams: [{seam_id: test-seam.example, kind: domain, subject_ref: invariant.example, assertion: behavior}]
17
+ adr_candidates: []
18
+ upstream_impact: {spec_ref: spec@v1, strategic_ref: strategy@v1, api_ref: api@draft, data_ref: data@v1, upstream_current: true}
19
+ version: v1
20
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
21
+ evidence_refs: []
@@ -0,0 +1,21 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.invalid-missing-invariant
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog: [{aggregate_id: aggregate.example, name: Example, context_ref: context.example, root_entity: entity.example-root, invariant_refs: [], behavior_refs: [behavior.example], consistency_boundary: single, api_exposure: internal-only}]
7
+ entity_catalog: [{entity_id: entity.example-root, name: Root, aggregate_id: aggregate.example, identity: id, lifecycle: active}]
8
+ value_object_catalog: []
9
+ behavior_catalog: [{behavior_id: behavior.example, name: Do, aggregate_id: aggregate.example, command: do, preconditions: [], invariant_refs: [], postconditions: [], event_refs: []}]
10
+ invariant_catalog: []
11
+ state_transition_catalog: [{transition_id: transition.example, aggregate_id: aggregate.example, from: draft, to: done, behavior_id: behavior.example}]
12
+ consistency_policy: {transaction_boundary: single, concurrency: optimistic, idempotency: guarded, cross_aggregate_strategy: none}
13
+ domain_event_catalog: []
14
+ gateway_catalog: [{gateway_id: gateway.example, name: Gateway, context_ref: context.example, layer: Domain, capabilities: [load]}]
15
+ persistence_mapping: [{aggregate_id: aggregate.example, storage_model: example, notes: mapping}]
16
+ test_seams: [{seam_id: test-seam.example, kind: domain, subject_ref: aggregate.example, assertion: behavior}]
17
+ adr_candidates: []
18
+ upstream_impact: {spec_ref: spec@v1, strategic_ref: strategy@v1, api_ref: api@draft, data_ref: data@v1, upstream_current: true}
19
+ version: v1
20
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
21
+ evidence_refs: []
@@ -0,0 +1,21 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.invalid-stale
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog: [{aggregate_id: aggregate.example, name: Example, context_ref: context.example, root_entity: entity.example-root, invariant_refs: [invariant.example], behavior_refs: [behavior.example], consistency_boundary: single, api_exposure: internal-only}]
7
+ entity_catalog: [{entity_id: entity.example-root, name: Root, aggregate_id: aggregate.example, identity: id, lifecycle: active}]
8
+ value_object_catalog: []
9
+ behavior_catalog: [{behavior_id: behavior.example, name: Do, aggregate_id: aggregate.example, command: do, preconditions: [ready], invariant_refs: [invariant.example], postconditions: [done], event_refs: []}]
10
+ invariant_catalog: [{invariant_id: invariant.example, aggregate_id: aggregate.example, statement: required}]
11
+ state_transition_catalog: [{transition_id: transition.example, aggregate_id: aggregate.example, from: draft, to: done, behavior_id: behavior.example}]
12
+ consistency_policy: {transaction_boundary: single, concurrency: optimistic, idempotency: guarded, cross_aggregate_strategy: none}
13
+ domain_event_catalog: []
14
+ gateway_catalog: [{gateway_id: gateway.example, name: Gateway, context_ref: context.example, layer: Domain, capabilities: [load]}]
15
+ persistence_mapping: [{aggregate_id: aggregate.example, storage_model: example, notes: mapping}]
16
+ test_seams: [{seam_id: test-seam.example, kind: domain, subject_ref: invariant.example, assertion: behavior}]
17
+ adr_candidates: []
18
+ upstream_impact: {spec_ref: spec@v1, strategic_ref: strategy@v1, api_ref: api@draft, data_ref: data@v1, upstream_current: false}
19
+ version: v1
20
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
21
+ evidence_refs: []
@@ -0,0 +1,21 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.invalid-strategic
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog: [{aggregate_id: aggregate.example, name: Example, context_ref: context.example, root_entity: entity.example-root, model_origin: strategic-concept, invariant_refs: [invariant.example], behavior_refs: [behavior.example], consistency_boundary: single, api_exposure: internal-only}]
7
+ entity_catalog: [{entity_id: entity.example-root, name: Root, aggregate_id: aggregate.example, identity: id, lifecycle: active}]
8
+ value_object_catalog: []
9
+ behavior_catalog: [{behavior_id: behavior.example, name: Do, aggregate_id: aggregate.example, command: do, preconditions: [ready], invariant_refs: [invariant.example], postconditions: [done], event_refs: []}]
10
+ invariant_catalog: [{invariant_id: invariant.example, aggregate_id: aggregate.example, statement: required}]
11
+ state_transition_catalog: [{transition_id: transition.example, aggregate_id: aggregate.example, from: draft, to: done, behavior_id: behavior.example}]
12
+ consistency_policy: {transaction_boundary: single, concurrency: optimistic, idempotency: guarded, cross_aggregate_strategy: none}
13
+ domain_event_catalog: []
14
+ gateway_catalog: [{gateway_id: gateway.example, name: Gateway, context_ref: context.example, layer: Domain, capabilities: [load]}]
15
+ persistence_mapping: [{aggregate_id: aggregate.example, storage_model: example, notes: mapping}]
16
+ test_seams: [{seam_id: test-seam.example, kind: domain, subject_ref: invariant.example, assertion: behavior}]
17
+ adr_candidates: []
18
+ upstream_impact: {spec_ref: spec@v1, strategic_ref: strategy@v1, api_ref: api@draft, data_ref: data@v1, upstream_current: true}
19
+ version: v1
20
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
21
+ evidence_refs: []
@@ -0,0 +1,80 @@
1
+ schema_version: 1
2
+ tactical_design_id: tactical-design.example-feature
3
+ tactical_version: v1
4
+ status: ready-for-human
5
+ context_ref: context.example
6
+ aggregate_catalog:
7
+ - aggregate_id: aggregate.example
8
+ name: ExampleAggregate
9
+ context_ref: context.example
10
+ root_entity: entity.example-root
11
+ invariant_refs: [invariant.example-required]
12
+ behavior_refs: [behavior.example-publish]
13
+ consistency_boundary: single-aggregate-transaction
14
+ api_exposure: internal-only
15
+ entity_catalog:
16
+ - entity_id: entity.example-root
17
+ name: ExampleRoot
18
+ aggregate_id: aggregate.example
19
+ identity: stable-id
20
+ lifecycle: draft-published
21
+ value_object_catalog:
22
+ - value_object_id: value-object.example-code
23
+ name: ExampleCode
24
+ aggregate_id: aggregate.example
25
+ immutable: true
26
+ behavior_catalog:
27
+ - behavior_id: behavior.example-publish
28
+ name: Publish
29
+ aggregate_id: aggregate.example
30
+ command: publish
31
+ preconditions: ["状态为 draft"]
32
+ invariant_refs: [invariant.example-required]
33
+ postconditions: ["状态变为 published"]
34
+ event_refs: [domain-event.example-published]
35
+ invariant_catalog:
36
+ - invariant_id: invariant.example-required
37
+ aggregate_id: aggregate.example
38
+ statement: "发布前必须满足业务前置条件"
39
+ state_transition_catalog:
40
+ - transition_id: transition.example-publish
41
+ aggregate_id: aggregate.example
42
+ from: draft
43
+ to: published
44
+ behavior_id: behavior.example-publish
45
+ consistency_policy:
46
+ transaction_boundary: single aggregate
47
+ concurrency: optimistic version check
48
+ idempotency: repeated publish is rejected by state guard
49
+ cross_aggregate_strategy: domain event with retry
50
+ domain_event_catalog:
51
+ - event_id: domain-event.example-published
52
+ name: ExamplePublished
53
+ aggregate_id: aggregate.example
54
+ consumers: [downstream-context]
55
+ delivery: outbox-at-least-once
56
+ gateway_catalog:
57
+ - gateway_id: gateway.example
58
+ name: ExampleGateway
59
+ context_ref: context.example
60
+ layer: Domain
61
+ capabilities: [save aggregate, load aggregate]
62
+ persistence_mapping:
63
+ - aggregate_id: aggregate.example
64
+ storage_model: example_aggregate_snapshot
65
+ notes: "持久化结构不泄漏到领域模型"
66
+ test_seams:
67
+ - seam_id: test-seam.example-invariant
68
+ kind: domain-behavior
69
+ subject_ref: invariant.example-required
70
+ assertion: "不满足前置条件时 publish 失败"
71
+ adr_candidates: []
72
+ upstream_impact:
73
+ spec_ref: docs/.scratch/example/spec.yaml@v1
74
+ strategic_ref: docs/.scratch/example/domain-strategy.yaml@v1
75
+ api_ref: docs/.scratch/example/openapi.yaml@draft
76
+ data_ref: docs/.scratch/example/data-architecture.md@v1
77
+ upstream_current: true
78
+ version: v1
79
+ digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
80
+ evidence_refs: [docs/.scratch/example/tactical-review.yaml]
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { spawnSync } from "node:child_process";
6
+ import { tmpdir } from "node:os";
7
+
8
+ const root = dirname(fileURLToPath(import.meta.url));
9
+ const validator = join(root, "..", "scripts", "validate-tactical-design.mjs");
10
+ const fixture = (name) => join(root, "fixtures", name);
11
+ const run = (file) => spawnSync(process.execPath, [validator, file], { encoding: "utf8" });
12
+ const pass = run(fixture("valid-tactical-design.yaml"));
13
+ if (pass.status !== 0) throw new Error(`valid tactical design should pass: ${pass.stderr}`);
14
+
15
+ const blockedCases = [
16
+ ["invalid-missing-invariant.yaml", "invariant_refs 必须是至少 1 项的数组"],
17
+ ["invalid-api-leaks-aggregate.yaml", "api_exposure 必须为 internal-only"],
18
+ ["invalid-stale-upstream-ref.yaml", "status 必须为 stale"],
19
+ ["invalid-strategic-as-tactical.yaml", "不得直接把战略概念当作 Aggregate"],
20
+ ["invalid-missing-consistency-policy.yaml", "consistency_policy.transaction_boundary 缺失"]
21
+ ];
22
+ for (const [name, message] of blockedCases) {
23
+ const result = run(fixture(name));
24
+ if (result.status === 0 || !result.stderr.includes(message)) throw new Error(`${name} should be blocked: ${result.stderr}`);
25
+ }
26
+
27
+ const temporaryRoot = await mkdtemp(join(tmpdir(), "yss-tactical-design-pressure-"));
28
+ try {
29
+ const source = await readFile(fixture("valid-tactical-design.yaml"), "utf8");
30
+ const escalated = join(temporaryRoot, "missing-standalone-ref.yaml");
31
+ await writeFile(escalated, `${source}\ncomplexity:\n escalate_to_standalone: true\n`);
32
+ const result = run(escalated);
33
+ if (result.status === 0 || !result.stderr.includes("standalone_ref")) throw new Error("complexity escalation without standalone_ref should be blocked");
34
+
35
+ const wrongGateway = join(temporaryRoot, "wrong-gateway-layer.yaml");
36
+ await writeFile(wrongGateway, source.replace("layer: Domain", "layer: Infrastructure"));
37
+ const gatewayResult = run(wrongGateway);
38
+ if (gatewayResult.status === 0 || !gatewayResult.stderr.includes("layer 必须为 Domain")) throw new Error("Infrastructure gateway should be blocked");
39
+
40
+ const crossAggregateRoot = join(temporaryRoot, "cross-aggregate-root.yaml");
41
+ await writeFile(crossAggregateRoot, source.replace("aggregate_id: aggregate.example\n identity", "aggregate_id: aggregate.other\n identity"));
42
+ const crossAggregateResult = run(crossAggregateRoot);
43
+ if (crossAggregateResult.status === 0 || !crossAggregateResult.stderr.includes("root_entity 的 aggregate_id 必须与当前 Aggregate 一致")) throw new Error("cross-aggregate root should be blocked");
44
+ } finally {
45
+ await rm(temporaryRoot, { recursive: true, force: true });
46
+ }
47
+ process.stdout.write("DDD tactical design scenarios passed\n");
@@ -23,6 +23,7 @@
23
23
  | 模板维护强度触发与最低等级 | `docs/process/maintenance-intensity.yaml` |
24
24
  | 技能清单、来源、版本、哈希和投影目标 | `skills-lock.json` |
25
25
  | 技能分层、别名、默认可发现性和运行时入口 | `docs/agents/yss-skill-registry.yaml`(当前 `status: shadow`,不作为 Router / 生命周期运行时入口) |
26
+ | 数字人角色、阶段协作组、运行时绑定与生命周期会签 | `docs/agents/digital-human-roles.yaml`;`docs/agents/digital-human-roles.md` 为操作说明 |
26
27
 
27
28
  README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或解释上述事实,不重复定义同一规则。`CLAUDE.md` 是 Claude Code 入口指针,不是第二套 Agent 规则。
28
29
 
@@ -31,7 +32,8 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
31
32
  - 所有面向业务、产品、架构、实施、审查、发布和复盘的落地文档,正文统一使用简体中文。
32
33
  - 英文专有名词、代码标识、API 路径、schema、类名、方法名、枚举值、错误码、命令、文件名和协议 metadata 保持原样。
33
34
  - 新流程统一使用 Spec、Ticket、`to-spec`、`to-tickets`。过时术语和技能名只能出现在迁移指南或明确标注的旧项目上下文。
34
- - 实施前读取 `CONTEXT.md`。业务术语必须已有 PascalCase `英文标识`;代码类型 / 字段与契约 property 使用该词干按 `CONTEXT.md` 文首规则变形。改中文术语或英文标识都先回写 `CONTEXT.md`。与词汇或 ADR 冲突时立即指出并先解决冲突。
35
+ - `CONTEXT.md` 是 Spec 构建及其落地工具链的统一语言输入,也是所有会创建或修改稳定业务、产品、架构、实施、审查、发布和复盘资产的强制前置上下文。`yss-product-lifecycle`、其原生 work unit,以及 `grill-with-docs`、`to-spec`、`to-tickets`、`implement` 等显式兼容入口,在规划、起草、评审、拆 Ticket 或实现前都必须读取并持续消费它;工具无法读取或消费时必须暂停并返回 `blocked`,不得凭临场翻译、同义词或局部上下文继续。
36
+ - 稳定业务术语必须先在 `CONTEXT.md` 中登记 PascalCase `英文标识`,再进入 Spec、原型、契约、Ticket、代码或验证资产;代码类型 / 字段与契约 property 使用该词干按 `CONTEXT.md` 文首规则变形。改中文术语或英文标识都先回写 `CONTEXT.md`,并重新检查受影响资产;与词汇或 ADR 冲突时立即指出并先解决冲突。
35
37
 
36
38
  ## 4. `template-source` 模板维护路由
37
39
 
@@ -83,6 +85,7 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
83
85
  | merge / rebase 冲突 | `resolving-merge-conflicts` |
84
86
  | 架构治理、难测模块或深模块设计 | `improve-codebase-architecture` / `codebase-design` |
85
87
  | 跨线程、跨仓库、上下文过长或原型结论回流 | `handoff` 或等价交接记录 |
88
+ | 数字人角色、Agent 运行时协同或生命周期会签 | 先读 `docs/agents/digital-human-roles.yaml`。职称实例叠加在编排器上,不另起生命周期,不批准 Slice 合同、不设 `ready-for-agent`、不宣布可发布 |
86
89
  | 本地知识库 init / refresh / rebuild,或要把研究结果落成持久 wiki | `llm-wiki`(落成持久 wiki 用 `ingest`;已映射 live 源变了用 `refresh`)。`template-source` 的 wiki-root 为 `.template-source/wiki`;`project-instance` 不附带源仓库编译树,需要时在仓库根 `wiki/` 执行 `init` |
87
90
 
88
91
  业务行为默认按 `tdd` 使用已确认的公开 seam 逐切片实现。一次性生成、纯配置或流程文档不适用代码 TDD 时,必须记录例外理由和可执行验证方式。
@@ -95,15 +98,16 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
95
98
 
96
99
  ## 10. 独立审查、验证和追踪
97
100
 
98
- - 实现者不能承担命中的独立审查。模板维护按 L1 / L2 / L3 分别使用 self-check / 人工 checkpoint、聚焦独立审查、正式独立审查;模板发布、代码切片和高风险变更仍必须由其他 Agent 或人工独立审查。
101
+ - 实现者不能承担命中的独立审查(含数字人)。模板维护按 L1 / L2 / L3 分别使用 self-check / 人工 checkpoint、聚焦独立审查、正式独立审查;模板发布、代码切片和高风险变更仍必须由其他 Agent 或独立审查者完成。
99
102
  - 任何“完成 / 可合并 / 可发布”结论必须基于 fresh verification,不接受“之前跑过”或实现者自述。
100
- - 在人工暂停、handoff、进入实现、合并或发布边界集中同步范围、验证证据、风险、人工审查点、Ticket 状态和下一步;阻塞、责任人变化或资产单独批准时立即同步。
103
+ - 会签门禁按 `docs/agents/digital-human-roles.yaml` 的 `gate_policy` 关闭,会签文件经 `scripts/verify-approval-record` 核验;`gate.release-ready`、对外商务承诺和运行时外部副作用仍须生物人。
104
+ - 在会签暂停、handoff、进入实现、合并或发布边界集中同步范围、验证证据、风险、会签点、Ticket 状态和下一步;阻塞、责任人变化或资产单独批准时立即同步。
101
105
  - Git checkpoint 只包含本轮明确范围;获得用户授权后才提交或推送。
102
106
  - 发布后或阶段性完成后做复盘判断;出现架构返工、验证返工、IMPORTANT / CRITICAL review finding 或人工确认延期时,落简体中文复盘并修订权威资产。
103
107
 
104
108
  ## 11. Subagent 协同
105
109
 
106
- 使用 subagent 前按 `docs/process/subagent-collaboration.md` 定义任务包和不重叠的写入范围。实现者不担任独立审查者;仓库身份、需求 / 契约冻结、Ticket 最终状态、Git checkpoint 和完成结论仍由主控 Agent 或人工决定。
110
+ 使用 subagent 或其它 Agent 运行时前按 `docs/process/subagent-collaboration.md` 定义任务包和不重叠的写入范围,并同时写明数字人角色、`runtime_id`、从角色表复制的 `core_skills` / `forbidden_skills` 与 Explorer / Drafter / Worker / Reviewer / Verifier 执行态。实现者不担任独立审查者;仓库身份、Ticket 最终状态、Git checkpoint、Slice 合同批准和完成结论仍由主控数字人按编排器规则决定。会签恢复前校验 `scripts/verify-approval-record`。写隔离靠任务包;共享工作区不是默认沙箱。
107
111
 
108
112
  ## 12. 测试质量基线
109
113
 
@@ -12,7 +12,19 @@
12
12
 
13
13
  | 术语 | 含义 | 英文标识 | 避免 / 备注 |
14
14
  |---|---|---|---|
15
- | Agent | 执行特定工作流步骤的 AI 协作者。 | — | 不要与人工审查者混用。 |
15
+ | Agent | 执行特定工作流步骤的 AI 协作者。 | — | 不要与生物人审查者、数字人角色或 Ticket 状态混用。运行时实例(Cursor Agent、Claude Code、Grok Bot 等)是 Agent 的承载,不是角色本身。 |
16
+ | 运行时绑定 | 把数字人角色落到某个 Agent 平台的适配声明,权威清单在数字人角色注册表的 `runtimes`。 | — | 不要为每个平台复制一套职称职责。 |
17
+ | Grok Bot | Grok 平台上的持久数字队友实例;对应 `runtime.grok`。 | — | 不是数字人角色、技能或门禁。 |
18
+ | 数字人角色 | 叠加在生命周期编排器上的职称配置;一个运行时实例绑定一种。v1 清单以 `docs/agents/digital-human-roles.yaml` 为准。 | — | 不要称为 Ticket「标准角色」、职能 Agent 或某个平台的产品名。 |
19
+ | 主控数字人 | 运行 `yss-product-lifecycle` 的协调实例。 | — | 不是第八个业务职称;默认兼任项目经理。 |
20
+ | 角色配置 | 某数字人角色的关注阶段、技能包、可起草产物和禁止事项。 | — | 不是独立编排器,也不含平台群聊人数。 |
21
+ | 生命周期会签 | 指定数字人或生物人关闭 `gate.*` / 独立审查并写入 `evidence.approval-record`。 | — | 不是运行时副作用审批。会签人由 `docs/agents/digital-human-roles.yaml` 的 `gate_policy` 指定。起草者不得会签自己起草的资产。`paused-human-gate` 表示等待该会签人,不是必须生物人。 |
22
+ | 运行时副作用审批 | 对发消息、改生产、付款、删数据等工具动作的账号级确认。 | — | 点 Allow 不等于门禁已批准或可发布。避免只称「Grok 平台审批」。 |
23
+ | Ticket 状态 | Tracker 五态:`needs-triage`、`needs-info`、`ready-for-agent`、`ready-for-human`、`wontfix`。 | — | 不要称为数字人角色或「标准角色」。 |
24
+ | 阶段协作组 | 某阶段需要共同可见会签的逻辑成员集合。 | — | 不是某个产品的群聊;平台人数上限只写在对应 `runtimes`。 |
25
+ | 需求经理 | 主责 Discovery 语言、用户/MVP/非目标、Spec 正文与测试 seam 的数字人角色。 | — | 不拥有原型视觉定稿,不 Freeze API,不写实现。 |
26
+ | 产品经理 | 主责优先级、产品设计影响、原型确认建议和范围裁剪的数字人角色。 | — | 不写生产代码,不单独 Freeze API。 |
27
+ | 商务 | 主责机会调研商业约束、交付承诺和发布窗口商务非目标的数字人角色。 | — | 不参与 Spec 定稿、契约、代码或 Ticket 状态推进。 |
16
28
  | Agent 入口规则 | Agent 启动任务时必须先遵守的全局路由、硬门禁和禁止事项。 | — | 不作为 YSS 后端、前端或其他专项编码规范的完整手册。 |
17
29
  | 标准文档语言 | 面向业务、产品、架构、实施、审查、发布和复盘的持久化文档所使用的默认语言。 | — | 统一使用简体中文;英文专有名词、代码标识、API 路径、schema、文件名和协议 metadata 保持原样。 |
18
30
  | Matt Engineering Skills | 来自 `mattpocock/skills` 的轻量工程流程技能集合。 | — | 用于澄清、Spec、Ticket、实现、TDD、诊断、审查和架构治理,不替代 YSS 专项规范。 |
@@ -25,7 +37,7 @@
25
37
  | Ticket | 在追踪平台上承载功能生命周期或可实现工作单元的通用追踪对象。 | — | GitHub Issues / GitLab Issues 是具体平台对象名称;领域资产统一称为 Ticket。 |
26
38
  | 功能父 Ticket | 汇总一个功能从 Spec 到契约冻结的阶段状态、资产链接、审查结论和阻塞项的 Ticket。 | — | 不作为 Agent 直接实现的垂直切片。 |
27
39
  | 垂直切片 Ticket | 契约冻结后生成的可独立验证实现单元,记录范围、阻塞关系、验收标准和验证证据。 | — | 只有通过必要门禁并具备直接实现条件时才能标记 `ready-for-agent`。 |
28
- | `ready-for-human` | 表示 Spec、设计、契约草案或其他资产仍需人工审查或确认的流程状态。 | — | 此状态不表示可以直接进入实现。 |
40
+ | `ready-for-human` | 表示 Spec、设计、契约草案或其他资产仍需会签(指定数字人或生物人)。 | — | 此状态不表示可以直接进入实现;也不等于某个数字人角色。 |
29
41
  | `ready-for-agent` | 表示垂直切片已通过必要门禁并具备直接实现条件的流程状态。 | — | 不得用于 Spec 初稿、原型、OpenAPI Draft 或其他未冻结资产。 |
30
42
  | OpenAPI Draft | review-only 的 OpenAPI 3.1 契约草案。 | — | Freeze 前不得作为前后端稳定实现契约。 |
31
43
  | OpenAPI Freeze | 已通过评审、可作为前后端实现和契约测试输入的 OpenAPI 3.1 契约。 | — | Freeze 后变更必须回到 API 影响分析和设计审查。 |
@@ -0,0 +1,83 @@
1
+ # 数字人角色
2
+
3
+ 结构化事实源是 `docs/agents/digital-human-roles.yaml`。角色、技能、协作组和会签级别与运行时无关。Claude Code、Cursor、Codex、Hermes、Grok Bot 等只通过 YAML `runtimes` 绑定。冲突时以 YAML 为准。
4
+
5
+ ## 何时读本文
6
+
7
+ 按职称派活、写会签、把数字人角色和 Ticket 状态 / 职能 Agent / 执行态弄混,或要在某个 Agent 平台上实例化这些角色时。
8
+
9
+ ## 四条正交轴
10
+
11
+ | 轴 | 是什么 | 不是什么 |
12
+ |---|---|---|
13
+ | 数字人角色 | 职称配置(需求经理、前端工程师…) | Ticket 五态、某个平台的 Bot |
14
+ | 主控数字人 | 生命周期编排器的运行时实例 | 第八个业务职称 |
15
+ | 职能工作单元 | Discovery / Spec / Code / Review | 职称 |
16
+ | 执行态 | Explorer / Drafter / Worker / Reviewer / Verifier | 数字人角色 |
17
+ | 运行时绑定 | 如何在 Cursor / Claude / Grok 等落地 | 角色职责本身 |
18
+
19
+ 一次数字人任务包同时写明 `task_id`、`work_unit_id`、`actor_id`、数字人角色、执行态、当前 `runtime_id`,以及从角色表复制的 `core_skills` / `forbidden_skills`。可用 `taskPackageDefaults(roleId)`(`scripts/lib/digital-human-roles.mjs`)读取,禁止手写第二套技能包。任务包 canonical Schema 为 `docs/process/schemas/digital-human-task-package.schema.json`,按 `contract.kind` 选择生命周期、切片实现或模板维护合同。
20
+
21
+ ## 会签人
22
+
23
+ `gate_policy.digital_human_review` 与 `dual_digital_human` 是「门禁 × 起草者 × 会签人」规则,不是门禁名单。主控按 `countersigners` 派会签任务。
24
+
25
+ | 门禁 / 工作单元 | 起草 | 会签 |
26
+ |---|---|---|
27
+ | `gate.prototype-reviewed` | `role.product-manager` | `role.frontend-engineer` |
28
+ | `gate.openapi-draft-reviewed` | `role.backend-engineer` | `role.frontend-engineer` |
29
+ | `gate.engineering-baseline-accepted` | (实现者) | `role.test-engineer` |
30
+ | `gate.frontend-implementation-verified` | `role.frontend-engineer` | `role.test-engineer` |
31
+ | `work-unit.code-review` | 实现者 | `role.test-engineer`(必须不同实例) |
32
+ | `gate.spec-baseline-approved` | `role.requirements-manager` | `role.product-manager` |
33
+ | `gate.openapi-frozen` | `role.backend-engineer` | `role.product-manager`、`role.test-engineer` |
34
+ | `gate.user-confirmation` | — | `role.product-manager`;生物人可否决 |
35
+ | `gate.release-ready` | — | 生物人(`role.biological-human`) |
36
+
37
+ 未列入表的门禁(含 `gate.design-reviewed`、`gate.architecture-reviewed`)走 `default_if_unlisted: biological-human`。
38
+
39
+ 会签写入 `docs/.scratch/<feature>/gates/<gate-id>-approval.yaml`,形状见 `docs/templates/approval-record-template.yaml`。恢复前运行 `scripts/verify-approval-record`。错误会签只能得到 `blocked`,不能把门禁标成 `approved`。Checkpoint 里会签桶门禁为 `approved` 时必须有可读 `approval_ref`。
40
+
41
+ `paused-human-gate` 表示等待上述指定会签人,不是「必须是生物人」。
42
+
43
+ 主控默认兼任项目经理,直到 `dual_hat_split_when`(`cross-repo-load` 或 `responsibility-conflict`)要求分体。
44
+
45
+ ## 跨平台协同(默认)
46
+
47
+ 1. 人默认只跟主控说话。
48
+ 2. 主控按阶段 1:1 指定一个 owner,并给任务包(输入、写范围、禁止 skill、验收、验证命令)。
49
+ 3. 需要可见会签时使用 YAML `stage_groups` 的**逻辑协作组**。这不是某个产品的群聊人数限制。
50
+ 4. 权威结论写回 git。运行时记忆只记该数字人的稳定偏好。
51
+ 5. 写隔离一律靠任务包。某运行时若共享磁盘或会话,适配器必须声明 `shared_workspace_is_not_security_boundary: true`,不得把实例当成沙箱。
52
+ 6. `project-instance` 复制角色实例并绑定仓库路径。禁止按功能再拆实例。
53
+ 7. 技能权威仍是 `.agents/skills`。已有投影根走 `runtime.skill-projection`,不要为职称再维护一份 skill。任务包的技能列表必须从角色表复制。
54
+
55
+ ## 运行时绑定
56
+
57
+ | ID | 覆盖 | 落地方式 |
58
+ |---|---|---|
59
+ | `runtime.generic` | 任何能加载 `core_skills` 并接受任务包的 Agent | 通用会话 / 人设 / system prompt |
60
+ | `runtime.skill-projection` | `yss-skill-registry.yaml` 的 `agent_runtime_roots`(claude、codex、cursor、hermes、pi、qoder、trae) | 投影技能 + subagent 任务包 |
61
+ | `runtime.grok` | Grok Bot | 持久 Bot、群聊或 1:1 交接;群超过 6 人改 1:1,不改逻辑协作组 |
62
+
63
+ 新增平台:先加 `runtimes` 条目,再写适配说明。不要把平台限制写进 `roles`。
64
+
65
+ Grok 专用操作见 `docs/templates/grok-bot-profile-template.md`。通用实例化见 `docs/templates/digital-human-runtime-profile-template.md`。
66
+
67
+ ## 两套批准
68
+
69
+ | 名称 | 关闭什么 | 谁点 |
70
+ |---|---|---|
71
+ | 运行时副作用审批 | 发消息、改生产、付款、删数据等工具动作 | 生物人(各平台自己的 Allow / 确认框) |
72
+ | 生命周期会签 | `gate.*` 与独立 code review | 见 YAML `gate_policy` |
73
+
74
+ 会签写入 `docs/templates/approval-record-template.yaml`,带 `runtime_id`、`principal_ref` 与实例引用。起草者不得出现在会签人里。`gate.release-ready`、对外商务合同、运行时外部副作用,以及未列入会签表的 `gate.design-reviewed` / `gate.architecture-reviewed` 仍须生物人。
75
+
76
+ ## 实例化
77
+
78
+ - 模板仓:`publish-singleton-profiles`。账户级只发布一套职称 profile,不按功能再拆。
79
+ - `project-instance`:`duplicate-and-bind-repo-path`。复制 YAML 的 `title` / `description` / `core_skills`,写入本仓库路径,选择 `runtime_id`。步骤见 `docs/templates/digital-human-runtime-profile-template.md`。外部 `create-yss-spec` 尚未接管此步骤。
80
+
81
+ ## 任务包最低字段
82
+
83
+ `task_id`、`work_unit_id`、`actor_id`、数字人角色 ID、`runtime_id`、执行态、从角色表复制的 `core_skills` / `forbidden_skills`、`contract.kind/id/version`、输入资产、允许写路径、禁止事项、验收、验证命令、证据、下游消费者和汇合方式。