create-yss-spec 3.2.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/README.md +2 -2
  2. package/package.json +3 -2
  3. package/src/command-runner.mjs +107 -0
  4. package/src/self-update.js +7 -4
  5. package/src/template/instance-runtime.js +1 -1
  6. package/template/.agents/skills/.strategic-design-skills-manifest.json +2 -2
  7. package/template/.agents/skills/code-review/SKILL.md +4 -0
  8. package/template/.agents/skills/code-review/agents/openai.yaml +1 -1
  9. package/template/.agents/skills/code-review/references/yss-review-standards.md +9 -2
  10. package/template/.agents/skills/competitive-intelligence/SKILL.md +4 -4
  11. package/template/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  12. package/template/.agents/skills/grill-with-docs/SKILL.md +1 -1
  13. package/template/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  14. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  15. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  16. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  17. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  18. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  19. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  20. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  21. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  22. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  23. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  24. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  25. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  26. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  27. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  28. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  29. package/template/.agents/skills/yss-mybatis/SKILL.md +34 -58
  30. package/template/.agents/skills/yss-mybatis/agents/openai.yaml +2 -2
  31. package/template/.agents/skills/yss-mybatis/references/source-index.md +88 -68
  32. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +50 -42
  33. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  34. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  35. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  36. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  37. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +5 -2
  38. package/template/.agents/skills/yss-repository/SKILL.md +28 -70
  39. package/template/.agents/skills/yss-repository/agents/openai.yaml +2 -2
  40. package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  41. package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  42. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  43. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  44. package/template/.agents/skills/yss-research/SKILL.md +1 -1
  45. package/template/.agents/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  46. package/template/.agents/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  47. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  48. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  49. package/template/.agents/skills/yss-stage-decision/SKILL.md +5 -3
  50. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  51. package/template/.claude/skills/code-review/SKILL.md +4 -0
  52. package/template/.claude/skills/code-review/agents/openai.yaml +1 -1
  53. package/template/.claude/skills/code-review/references/yss-review-standards.md +9 -2
  54. package/template/.claude/skills/competitive-intelligence/SKILL.md +4 -4
  55. package/template/.claude/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  56. package/template/.claude/skills/grill-with-docs/SKILL.md +1 -1
  57. package/template/.claude/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  58. package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  59. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  60. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  61. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  62. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  63. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  64. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  65. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  66. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  67. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  68. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  69. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  70. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  71. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  72. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  73. package/template/.claude/skills/yss-mybatis/SKILL.md +34 -58
  74. package/template/.claude/skills/yss-mybatis/agents/openai.yaml +2 -2
  75. package/template/.claude/skills/yss-mybatis/references/source-index.md +88 -68
  76. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +50 -42
  77. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  78. package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  79. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  80. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  81. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +5 -2
  82. package/template/.claude/skills/yss-repository/SKILL.md +28 -70
  83. package/template/.claude/skills/yss-repository/agents/openai.yaml +2 -2
  84. package/template/.claude/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  85. package/template/.claude/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  86. package/template/.claude/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  87. package/template/.claude/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  88. package/template/.claude/skills/yss-research/SKILL.md +1 -1
  89. package/template/.claude/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  90. package/template/.claude/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  91. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  92. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  93. package/template/.claude/skills/yss-stage-decision/SKILL.md +5 -3
  94. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  95. package/template/.codex/skills/code-review/SKILL.md +4 -0
  96. package/template/.codex/skills/code-review/agents/openai.yaml +1 -1
  97. package/template/.codex/skills/code-review/references/yss-review-standards.md +9 -2
  98. package/template/.codex/skills/competitive-intelligence/SKILL.md +4 -4
  99. package/template/.codex/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  100. package/template/.codex/skills/grill-with-docs/SKILL.md +1 -1
  101. package/template/.codex/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  102. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  103. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  104. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  105. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  106. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  107. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  108. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  109. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  110. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  111. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  112. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  113. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  114. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  115. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  116. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  117. package/template/.codex/skills/yss-mybatis/SKILL.md +34 -58
  118. package/template/.codex/skills/yss-mybatis/agents/openai.yaml +2 -2
  119. package/template/.codex/skills/yss-mybatis/references/source-index.md +88 -68
  120. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +50 -42
  121. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  122. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  123. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  124. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  125. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +5 -2
  126. package/template/.codex/skills/yss-repository/SKILL.md +28 -70
  127. package/template/.codex/skills/yss-repository/agents/openai.yaml +2 -2
  128. package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  129. package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  130. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  131. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  132. package/template/.codex/skills/yss-research/SKILL.md +1 -1
  133. package/template/.codex/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  134. package/template/.codex/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  135. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  136. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  137. package/template/.codex/skills/yss-stage-decision/SKILL.md +5 -3
  138. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  139. package/template/.cursor/skills/code-review/SKILL.md +4 -0
  140. package/template/.cursor/skills/code-review/agents/openai.yaml +1 -1
  141. package/template/.cursor/skills/code-review/references/yss-review-standards.md +9 -2
  142. package/template/.cursor/skills/competitive-intelligence/SKILL.md +4 -4
  143. package/template/.cursor/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  144. package/template/.cursor/skills/grill-with-docs/SKILL.md +1 -1
  145. package/template/.cursor/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  146. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  147. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  148. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  149. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  150. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  151. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  152. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  153. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  154. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  155. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  156. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  157. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  158. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  159. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  160. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  161. package/template/.cursor/skills/yss-mybatis/SKILL.md +34 -58
  162. package/template/.cursor/skills/yss-mybatis/agents/openai.yaml +2 -2
  163. package/template/.cursor/skills/yss-mybatis/references/source-index.md +88 -68
  164. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +50 -42
  165. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  166. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  167. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  168. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  169. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +5 -2
  170. package/template/.cursor/skills/yss-repository/SKILL.md +28 -70
  171. package/template/.cursor/skills/yss-repository/agents/openai.yaml +2 -2
  172. package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  173. package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  174. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  175. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  176. package/template/.cursor/skills/yss-research/SKILL.md +1 -1
  177. package/template/.cursor/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  178. package/template/.cursor/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  179. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  180. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  181. package/template/.cursor/skills/yss-stage-decision/SKILL.md +5 -3
  182. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  183. package/template/.pi/skills/code-review/SKILL.md +4 -0
  184. package/template/.pi/skills/code-review/agents/openai.yaml +1 -1
  185. package/template/.pi/skills/code-review/references/yss-review-standards.md +9 -2
  186. package/template/.pi/skills/competitive-intelligence/SKILL.md +4 -4
  187. package/template/.pi/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  188. package/template/.pi/skills/grill-with-docs/SKILL.md +1 -1
  189. package/template/.pi/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  190. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  191. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  192. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  193. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  194. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  195. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  196. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  197. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  198. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  199. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  200. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  201. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  202. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  203. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  204. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  205. package/template/.pi/skills/yss-mybatis/SKILL.md +34 -58
  206. package/template/.pi/skills/yss-mybatis/agents/openai.yaml +2 -2
  207. package/template/.pi/skills/yss-mybatis/references/source-index.md +88 -68
  208. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +50 -42
  209. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  210. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  211. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  212. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  213. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +5 -2
  214. package/template/.pi/skills/yss-repository/SKILL.md +28 -70
  215. package/template/.pi/skills/yss-repository/agents/openai.yaml +2 -2
  216. package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  217. package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  218. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  219. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  220. package/template/.pi/skills/yss-research/SKILL.md +1 -1
  221. package/template/.pi/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  222. package/template/.pi/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  223. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  224. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  225. package/template/.pi/skills/yss-stage-decision/SKILL.md +5 -3
  226. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  227. package/template/.qoder/skills/code-review/SKILL.md +4 -0
  228. package/template/.qoder/skills/code-review/agents/openai.yaml +1 -1
  229. package/template/.qoder/skills/code-review/references/yss-review-standards.md +9 -2
  230. package/template/.qoder/skills/competitive-intelligence/SKILL.md +4 -4
  231. package/template/.qoder/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  232. package/template/.qoder/skills/grill-with-docs/SKILL.md +1 -1
  233. package/template/.qoder/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  234. package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  235. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  236. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  237. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  238. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  239. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  240. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  241. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  242. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  243. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  244. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  245. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  246. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  247. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  248. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  249. package/template/.qoder/skills/yss-mybatis/SKILL.md +34 -58
  250. package/template/.qoder/skills/yss-mybatis/agents/openai.yaml +2 -2
  251. package/template/.qoder/skills/yss-mybatis/references/source-index.md +88 -68
  252. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +50 -42
  253. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  254. package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  255. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  256. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  257. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +5 -2
  258. package/template/.qoder/skills/yss-repository/SKILL.md +28 -70
  259. package/template/.qoder/skills/yss-repository/agents/openai.yaml +2 -2
  260. package/template/.qoder/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  261. package/template/.qoder/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  262. package/template/.qoder/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  263. package/template/.qoder/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  264. package/template/.qoder/skills/yss-research/SKILL.md +1 -1
  265. package/template/.qoder/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  266. package/template/.qoder/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  267. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  268. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  269. package/template/.qoder/skills/yss-stage-decision/SKILL.md +5 -3
  270. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  271. package/template/.trae/skills/code-review/SKILL.md +4 -0
  272. package/template/.trae/skills/code-review/agents/openai.yaml +1 -1
  273. package/template/.trae/skills/code-review/references/yss-review-standards.md +9 -2
  274. package/template/.trae/skills/competitive-intelligence/SKILL.md +4 -4
  275. package/template/.trae/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  276. package/template/.trae/skills/grill-with-docs/SKILL.md +1 -1
  277. package/template/.trae/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  278. package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  279. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  280. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  281. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  282. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  283. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  284. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  285. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  286. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  287. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  288. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  289. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  290. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  291. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  292. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  293. package/template/.trae/skills/yss-mybatis/SKILL.md +34 -58
  294. package/template/.trae/skills/yss-mybatis/agents/openai.yaml +2 -2
  295. package/template/.trae/skills/yss-mybatis/references/source-index.md +88 -68
  296. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +50 -42
  297. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  298. package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  299. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  300. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  301. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +5 -2
  302. package/template/.trae/skills/yss-repository/SKILL.md +28 -70
  303. package/template/.trae/skills/yss-repository/agents/openai.yaml +2 -2
  304. package/template/.trae/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  305. package/template/.trae/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  306. package/template/.trae/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  307. package/template/.trae/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  308. package/template/.trae/skills/yss-research/SKILL.md +1 -1
  309. package/template/.trae/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  310. package/template/.trae/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  311. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  312. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  313. package/template/.trae/skills/yss-stage-decision/SKILL.md +5 -3
  314. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  315. package/template/AGENTS.md +2 -2
  316. package/template/CONTEXT.md +3 -2
  317. package/template/README.md +3 -3
  318. package/template/docs/agents/digital-human-roles.md +1 -1
  319. package/template/docs/agents/digital-human-roles.yaml +13 -11
  320. package/template/docs/agents/issue-tracker.md +1 -1
  321. package/template/docs/agents/strategic-design-skills-integration.md +2 -0
  322. package/template/docs/agents/yss-skill-registry.yaml +5 -0
  323. package/template/docs/architecture/README.md +1 -1
  324. package/template/docs/architecture/templates/business-architecture-template.md +1 -1
  325. package/template/docs/architecture/templates/functional-architecture-template.md +1 -1
  326. package/template/docs/design/README.md +1 -1
  327. package/template/docs/design/templates/interaction-spec-template.md +1 -1
  328. package/template/docs/design/templates/product-overview-design-template.md +1 -1
  329. package/template/docs/{discovery → plan}/IDEATION.md +5 -5
  330. package/template/docs/plan/README.md +9 -0
  331. package/template/docs/plan/entry-review.md +23 -0
  332. package/template/docs/plan/templates/plan-template.md +58 -0
  333. package/template/docs/process/harness-process-tailoring.md +1 -1
  334. package/template/docs/process/lifecycle-artifact-map.md +10 -6
  335. package/template/docs/process/lifecycle-registry-baseline.json +10 -1
  336. package/template/docs/process/lifecycle-registry.yaml +48 -20
  337. package/template/docs/process/plan-migration.md +13 -0
  338. package/template/docs/process/schemas/digital-human-task-package.schema.json +2 -0
  339. package/template/docs/process/schemas/implementation-repository-preparation-result.schema.json +38 -0
  340. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +3 -0
  341. package/template/docs/process/schemas/lifecycle-registry.schema.json +1 -1
  342. package/template/docs/process/schemas/project-scaffold-contract.schema.json +113 -0
  343. package/template/docs/process/template-engineering-overview.md +2 -2
  344. package/template/docs/process/template-verification-profiles.yaml +25 -0
  345. package/template/docs/process/templates/context-reconciliation-template.yaml +2 -2
  346. package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +1 -1
  347. package/template/docs/requirements/README.md +2 -2
  348. package/template/docs/templates/implementation-repo-registry-template.md +8 -0
  349. package/template/docs/templates/local-parent-ticket-template.md +1 -1
  350. package/template/docs/templates/review-report-template.md +7 -3
  351. package/template/docs/templates/subagent-task-package-template.md +1 -1
  352. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +1 -1
  353. package/template/scripts/cache-template-commit +2 -2
  354. package/template/scripts/fixtures/strategic-handoff/source-roles.json +7 -7
  355. package/template/scripts/fixtures/user-decision/plan-fixture.mjs +30 -0
  356. package/template/scripts/lib/backend-delivery.mjs +5 -2
  357. package/template/scripts/lib/command-runner.mjs +107 -0
  358. package/template/scripts/lib/context-reconciliation.mjs +34 -0
  359. package/template/scripts/lib/json-schema.mjs +42 -13
  360. package/template/scripts/lib/lifecycle-context-query.mjs +141 -0
  361. package/template/scripts/lib/lifecycle-transition.mjs +118 -6
  362. package/template/scripts/lib/plan-spec-entry.mjs +87 -0
  363. package/template/scripts/lib/scenario-checks.mjs +44 -38
  364. package/template/scripts/lib/skill-registry.mjs +9 -0
  365. package/template/scripts/lib/skill-supply-chain.mjs +18 -2
  366. package/template/scripts/lib/strategic-handoff-io.mjs +5 -4
  367. package/template/scripts/lib/strategic-handoff.mjs +10 -9
  368. package/template/scripts/lib/task-package.mjs +2 -0
  369. package/template/scripts/lib/template-commit-cache.mjs +7 -5
  370. package/template/scripts/query-lifecycle-context +25 -0
  371. package/template/scripts/run-template-verification +9 -3
  372. package/template/scripts/sync-strategic-handoff-tools +9 -0
  373. package/template/scripts/verify-business-language-scenarios +0 -7
  374. package/template/scripts/verify-context-reconciliation +2 -48
  375. package/template/scripts/verify-context-reconciliation-scenarios +1 -1
  376. package/template/scripts/verify-frontend-scaffold-generator-scenarios +2 -0
  377. package/template/scripts/verify-lifecycle-checkpoint +2 -0
  378. package/template/scripts/verify-lifecycle-context-query-scenarios +88 -0
  379. package/template/scripts/verify-lifecycle-transition-scenarios +44 -4
  380. package/template/scripts/verify-plan-spec-entry +11 -0
  381. package/template/scripts/verify-plan-spec-entry-scenarios +79 -0
  382. package/template/scripts/verify-script-performance-scenarios +56 -0
  383. package/template/scripts/verify-subagent-task-package-scenarios +9 -8
  384. package/template/scripts/verify-template-cache-scenarios +11 -1
  385. package/template/scripts/verify-user-decision-scenarios +4 -4
  386. package/template/skills-lock.json +23 -23
  387. package/template.manifest.json +2 -1
  388. package/template.snapshot.json +5 -5
  389. package/template/.agents/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  390. package/template/.agents/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  391. package/template/.agents/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  392. package/template/.agents/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  393. package/template/.agents/skills/yss-mybatis/references/README.md +0 -57
  394. package/template/.agents/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  395. package/template/.claude/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  396. package/template/.claude/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  397. package/template/.claude/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  398. package/template/.claude/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  399. package/template/.claude/skills/yss-mybatis/references/README.md +0 -57
  400. package/template/.claude/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  401. package/template/.codex/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  402. package/template/.codex/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  403. package/template/.codex/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  404. package/template/.codex/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  405. package/template/.codex/skills/yss-mybatis/references/README.md +0 -57
  406. package/template/.codex/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  407. package/template/.cursor/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  408. package/template/.cursor/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  409. package/template/.cursor/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  410. package/template/.cursor/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  411. package/template/.cursor/skills/yss-mybatis/references/README.md +0 -57
  412. package/template/.cursor/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  413. package/template/.pi/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  414. package/template/.pi/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  415. package/template/.pi/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  416. package/template/.pi/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  417. package/template/.pi/skills/yss-mybatis/references/README.md +0 -57
  418. package/template/.pi/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  419. package/template/.qoder/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  420. package/template/.qoder/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  421. package/template/.qoder/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  422. package/template/.qoder/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  423. package/template/.qoder/skills/yss-mybatis/references/README.md +0 -57
  424. package/template/.qoder/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  425. package/template/.trae/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  426. package/template/.trae/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  427. package/template/.trae/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  428. package/template/.trae/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  429. package/template/.trae/skills/yss-mybatis/references/README.md +0 -57
  430. package/template/.trae/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  431. package/template/docs/discovery/README.md +0 -87
  432. package/template/docs/discovery/reports/.gitkeep +0 -0
  433. package/template/docs/discovery/reports/agent-governance-options.md +0 -71
  434. package/template/docs/discovery/reports/competitor-deep-dive/.gitkeep +0 -0
  435. package/template/docs/discovery/templates/discovery-template.md +0 -94
  436. /package/template/docs/{discovery → plan}/templates/competitive-analysis-template.md +0 -0
  437. /package/template/docs/{discovery → plan}/templates/competitive-matrix-template.md +0 -0
  438. /package/template/docs/{discovery → plan}/templates/market-analysis-template.md +0 -0
  439. /package/template/docs/{discovery → plan}/templates/user-pain-points-template.md +0 -0
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ import assert from "node:assert/strict";
3
+ import { readFileSync } from "node:fs";
4
+ import { spawnSync } from "node:child_process";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { queryLifecycleContext } from "./lib/lifecycle-context-query.mjs";
8
+
9
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
10
+
11
+ const query = {
12
+ mode: "route",
13
+ stageId: "stage.plan",
14
+ workUnitId: "work-unit.plan-requirements",
15
+ include: ["grill_exit"],
16
+ };
17
+ const first = queryLifecycleContext(query);
18
+ const second = queryLifecycleContext(query);
19
+
20
+ assert.deepEqual(first, second, "同一查询必须产生确定性结果");
21
+ // 合并调用须保留原来三次查询的路由、阶段和技能信息。
22
+ const modeOnly = queryLifecycleContext({ mode: query.mode });
23
+ const stageOnly = queryLifecycleContext({ stageId: query.stageId });
24
+ const unitOnly = queryLifecycleContext({ workUnitId: query.workUnitId });
25
+ assert.deepEqual(first.execution.mode, modeOnly.execution.mode);
26
+ for (const key of ["stage", "gates", "artifacts", "evidence"]) {
27
+ assert.deepEqual(first.lifecycle[key], stageOnly.lifecycle[key]);
28
+ }
29
+ assert.deepEqual(first.lifecycle.work_unit, unitOnly.lifecycle.work_unit);
30
+ assert.deepEqual(first.execution.work_unit_route, unitOnly.execution.work_unit_route);
31
+ assert.deepEqual(first.execution.transition, unitOnly.execution.transition);
32
+ assert.deepEqual(first.skills, unitOnly.skills);
33
+ const efficient = queryLifecycleContext({ ...query, include: ["grill_exit", "execution_efficiency"] });
34
+ assert.deepEqual(efficient.lifecycle, first.lifecycle, "执行成本策略不得改变阶段门禁");
35
+ assert.deepEqual(efficient.skills, first.skills);
36
+ assert.deepEqual(efficient.execution.transition, first.execution.transition);
37
+ assert.equal(efficient.execution.selected.execution_efficiency.verification.skip_triggered_gates, "forbidden");
38
+ assert.equal("execution_efficiency" in first.execution.selected, false, "成本策略仍按需加载");
39
+ assert.equal(first.query.mode, "route");
40
+ assert.equal(first.lifecycle.stage.id, "stage.plan");
41
+ assert.ok(first.lifecycle.gates.every((gate) => gate.stage === "stage.plan"));
42
+ assert.ok(first.lifecycle.artifacts.every((artifact) => artifact.stage === "stage.plan"));
43
+ assert.equal(first.lifecycle.work_unit.id, "work-unit.plan-requirements");
44
+ assert.equal(first.execution.mode, "read_only");
45
+ assert.equal(first.execution.work_unit_route.primary_skill, "yss-product-lifecycle");
46
+ assert.ok(first.execution.selected.grill_exit.required.includes("frontier_empty"));
47
+ assert.equal("review_input" in first.execution.selected, false, "不得返回未请求的合同子树");
48
+ assert.ok(first.skills.some((skill) => skill.id === "grilling"));
49
+ assert.throws(() => queryLifecycleContext({ stageId: "stage.discovery" }), /未知阶段/);
50
+ assert.throws(() => queryLifecycleContext({ workUnitId: "work-unit.discovery-requirements" }), /未知工作单元/);
51
+ assert.match(first.sources.lifecycle_registry.semantic_sha256, /^[0-9a-f]{64}$/);
52
+ assert.match(first.sources.orchestration_contract.sha256, /^[0-9a-f]{64}$/);
53
+
54
+ for (const invalid of [
55
+ { mode: "invalid" },
56
+ { stageId: "stage.missing" },
57
+ { workUnitId: "work-unit.missing" },
58
+ { include: ["missing_contract_section"] },
59
+ ]) {
60
+ assert.throws(() => queryLifecycleContext(invalid), /未知|至少提供/);
61
+ }
62
+
63
+ const cli = spawnSync("node", [
64
+ "scripts/query-lifecycle-context",
65
+ "--mode", "route",
66
+ "--stage", "stage.plan",
67
+ "--work-unit", "work-unit.plan-requirements",
68
+ "--include", "grill_exit",
69
+ ], { cwd: ROOT, encoding: "utf8" });
70
+ assert.equal(cli.status, 0, cli.stderr);
71
+ assert.deepEqual(JSON.parse(cli.stdout), first, "CLI 输出必须等于库函数的规范投影");
72
+
73
+ const skillPath = path.join(ROOT, ".agents/skills/yss-product-lifecycle/SKILL.md");
74
+ const skill = readFileSync(skillPath, "utf8");
75
+ assert.ok(Buffer.byteLength(skill) <= 8192, "生命周期入口 Skill 必须保持在 8KB 软预算内");
76
+ assert.equal(skill.includes("| 主阶段 |"), false, "入口 Skill 不得复制完整阶段表");
77
+ for (const marker of [
78
+ "docs/process/lifecycle-registry.yaml",
79
+ "references/orchestration-contract.yaml",
80
+ "docs/agents/yss-skill-registry.yaml",
81
+ "scripts/query-lifecycle-context",
82
+ "### 仓库身份",
83
+ "### 流转与实现",
84
+ "### 用户决定",
85
+ "### 外部副作用与 Git",
86
+ ]) assert.match(skill, new RegExp(marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
87
+
88
+ process.stdout.write("生命周期按需上下文查询场景验证通过\n");
@@ -3,16 +3,24 @@ import assert from "node:assert/strict";
3
3
  import { mkdtempSync, rmSync, readFileSync, existsSync } from "node:fs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
- import { buildImplementationFixture } from "./fixtures/user-decision/build-fixture.mjs";
6
+ import { buildDecisionFixture, buildImplementationFixture } from "./fixtures/user-decision/build-fixture.mjs";
7
7
  const temp = mkdtempSync(path.join(os.tmpdir(), "lifecycle-decision-test-"));
8
8
  process.on("exit", () => rmSync(temp, { recursive: true, force: true }));
9
9
  const approval = buildImplementationFixture(temp, "docs/.scratch/demo/issues/01-valid-slice.md");
10
- import { validateImplementationEntry, validateNextRoute, validateTicketFormalization } from "./lib/lifecycle-transition.mjs";
10
+ const scaffoldApproval = buildDecisionFixture(path.join(temp, "scaffold-choice"), { boundary: "scaffold-choice", scope: ["backend", "frontend"] });
11
+ import { validateImplementationEntry, validateImplementationRepositoriesReady, validateNextRoute, validateTicketFormalization } from "./lib/lifecycle-transition.mjs";
11
12
 
12
13
  const exists = (ref) => [
13
14
  "docs/process/lifecycle-registry.yaml",
14
15
  "docs/.scratch/demo/issues/01-valid-slice.md",
15
16
  "docs/.scratch/demo/evidence/ticket-decomposition-result.yaml",
17
+ "docs/.scratch/demo/evidence/repository-preparation.yaml",
18
+ "docs/.scratch/demo/evidence/backend-onboarding.yaml",
19
+ "docs/.scratch/demo/evidence/frontend-onboarding.yaml",
20
+ "docs/.scratch/demo/evidence/backend-manifest.json",
21
+ "docs/.scratch/demo/evidence/backend-verification.json",
22
+ "docs/.scratch/demo/evidence/frontend-manifest.json",
23
+ "docs/.scratch/demo/evidence/frontend-verification.json",
16
24
  ].includes(ref) || existsSync(ref);
17
25
  const decompositionResult = `result_schema: workflow-execution-result-v1\nwork_unit: work-unit.ticket-decomposition\nresult: completed\nevidence_refs:\n - docs/.scratch/demo/evidence/ticket-decomposition-result.yaml\n`;
18
26
  const read = (ref) => ref === "docs/.scratch/demo/evidence/ticket-decomposition-result.yaml" ? decompositionResult : readFileSync(ref, "utf8");
@@ -20,6 +28,17 @@ const options = { exists, read };
20
28
 
21
29
  const validTicketState = {
22
30
  ...approval.state,
31
+ user_decisions: [...approval.state.user_decisions, scaffoldApproval.requirement],
32
+ delivery_impacts: { backend: true, frontend: true },
33
+ implementation_repository_preparation: {
34
+ result: "completed",
35
+ current_version: true,
36
+ evidence_refs: ["docs/.scratch/demo/evidence/repository-preparation.yaml"],
37
+ projects: [
38
+ { project_id: "backend", delivery_role: "backend", status: "existing-and-onboarded", repository_ref: "git://backend", project_root: "/workspace/backend", repository_scope: "external-repository", onboarding_result: { status: "completed", ref: "docs/.scratch/demo/evidence/backend-onboarding.yaml" } },
39
+ { project_id: "frontend", delivery_role: "frontend", status: "existing-and-onboarded", repository_ref: "git://frontend", project_root: "/workspace/frontend", repository_scope: "external-repository", onboarding_result: { status: "completed", ref: "docs/.scratch/demo/evidence/frontend-onboarding.yaml" } },
40
+ ],
41
+ },
23
42
  predecessor_work_unit: "work-unit.ticket-decomposition",
24
43
  tracker_kind: "local-markdown",
25
44
  ticket_decomposition_result_ref: "docs/.scratch/demo/evidence/ticket-decomposition-result.yaml",
@@ -45,6 +64,19 @@ const validTicketState = {
45
64
 
46
65
  const valid = validateTicketFormalization(validTicketState, options);
47
66
  assert.equal(valid.result, "allowed");
67
+ assert.equal(validateImplementationRepositoriesReady(validTicketState, options).result, "allowed");
68
+ const initializedState = {
69
+ delivery_impacts: { backend: true, frontend: true },
70
+ implementation_repository_preparation: {
71
+ result: "completed", current_version: true, evidence_refs: ["docs/.scratch/demo/evidence/repository-preparation.yaml"],
72
+ projects: [
73
+ { project_id: "backend-ddd", delivery_role: "backend", status: "initialized-and-verified", repository_ref: "git://backend", project_root: "/workspace/backend", repository_scope: "external-repository", architecture_family: "domain-driven", scaffold_contract: { schema_version: 4, status: "approved", persisted: true, current_version: true }, scaffold_manifest_ref: "docs/.scratch/demo/evidence/backend-manifest.json", scaffold_verification: { status: "passed", ref: "docs/.scratch/demo/evidence/backend-verification.json" } },
74
+ { project_id: "frontend", delivery_role: "frontend", status: "initialized-and-verified", repository_ref: "git://frontend", project_root: "/workspace/frontend", repository_scope: "external-repository", template_available: true, scaffold_contract: { schema_version: 4, status: "approved", persisted: true, current_version: true }, scaffold_manifest_ref: "docs/.scratch/demo/evidence/frontend-manifest.json", scaffold_verification: { status: "passed", ref: "docs/.scratch/demo/evidence/frontend-verification.json" } },
75
+ ],
76
+ },
77
+ };
78
+ assert.equal(validateImplementationRepositoriesReady(initializedState, options).result, "allowed");
79
+ assert.equal(validateImplementationRepositoriesReady({ delivery_impacts: { backend: false, frontend: false }, implementation_repository_preparation: { result: "completed", current_version: true, evidence_refs: ["docs/.scratch/demo/evidence/repository-preparation.yaml"], projects: [{ project_id: "backend-na", delivery_role: "backend", status: "not-applicable", reason: "no backend impact" }, { project_id: "frontend-na", delivery_role: "frontend", status: "not-applicable", reason: "no frontend impact" }] } }, options).result, "allowed");
48
80
 
49
81
  const implementation = validateImplementationEntry({
50
82
  ...validTicketState,
@@ -53,6 +85,11 @@ const implementation = validateImplementationEntry({
53
85
  assert.equal(implementation.result, "allowed");
54
86
 
55
87
  const cases = [
88
+ ["missing repository preparation", { ...validTicketState, implementation_repository_preparation: undefined }, "implementation-repository-decision-required"],
89
+ ["stale repository preparation", { ...validTicketState, implementation_repositories_stale: true }, "implementation-repositories-stale"],
90
+ ["missing frontend decision", { ...validTicketState, implementation_repository_preparation: { ...validTicketState.implementation_repository_preparation, projects: validTicketState.implementation_repository_preparation.projects.filter((item) => item.delivery_role !== "frontend") } }, "implementation-repository-decision-required"],
91
+ ["missing repository location", { ...validTicketState, implementation_repository_preparation: { ...validTicketState.implementation_repository_preparation, projects: validTicketState.implementation_repository_preparation.projects.map((item) => item.delivery_role === "backend" ? { ...item, project_root: undefined } : item) } }, "implementation-repository-location-required"],
92
+ ["incomplete onboarding", { ...validTicketState, implementation_repository_preparation: { ...validTicketState.implementation_repository_preparation, projects: validTicketState.implementation_repository_preparation.projects.map((item) => item.delivery_role === "backend" ? { ...item, onboarding_result: { status: "blocked" } } : item) } }, "implementation-repository-onboarding-incomplete"],
56
93
  ["missing decomposition result ref", { ...validTicketState, ticket_decomposition_result_ref: undefined }, "ticket-decomposition-result-ref-missing"],
57
94
  ["missing slice ref", { ...validTicketState, vertical_slice_ticket_ref: undefined }, "vertical-slice-ticket-ref-missing"],
58
95
  ["missing slice role", { ...validTicketState, vertical_slice_ticket_role: undefined }, "vertical-slice-ticket-role-missing"],
@@ -90,7 +127,10 @@ for (const current of ["work-unit.spec-synthesis", "work-unit.prototype-design",
90
127
  assert.equal(result.result, "blocked", current);
91
128
  assert.ok(result.blocking_signals.includes("ticket-formalization-required"), current);
92
129
  }
93
- assert.equal(validateNextRoute("work-unit.spec-synthesis", "work-unit.ticket-decomposition").result, "allowed");
130
+ assert.equal(validateNextRoute("work-unit.spec-synthesis", "work-unit.ticket-decomposition").result, "blocked");
131
+ assert.equal(validateNextRoute("work-unit.technical-analysis", "work-unit.implementation-repository-preparation").result, "allowed");
132
+ assert.equal(validateNextRoute("work-unit.implementation-repository-preparation", "work-unit.ticket-decomposition", validTicketState, options).result, "allowed");
133
+ assert.ok(validateNextRoute("work-unit.implementation-repository-preparation", "work-unit.ticket-decomposition", {}, options).blocking_signals.includes("implementation-repository-decision-required"));
94
134
  assert.equal(validateNextRoute("work-unit.intensity-aware-verification", "work-unit.intensity-aware-review").result, "allowed");
95
135
  assert.equal(validateNextRoute("work-unit.release-and-rollback", null).result, "allowed");
96
136
  const arbitraryReadable = validateTicketFormalization({
@@ -110,6 +150,6 @@ assert.equal(validateTicketFormalization({
110
150
  vertical_slice_ticket_ref: "https://github.com/example/project/issues/1",
111
151
  vertical_slice_ticket: { ref: "https://github.com/example/project/issues/1", kind: "vertical-slice-ticket", role: "ready-for-agent" },
112
152
  slice_contract: { ...validTicketState.slice_contract, ticket_ref: "https://github.com/example/project/issues/1" },
113
- }, { ...options, exists: (ref) => ref === "https://github.com/example/project/issues/1", read: (ref) => ref === "https://github.com/example/project/issues/1" ? decompositionResult.replace("docs/.scratch/demo/evidence/ticket-decomposition-result.yaml", "https://github.com/example/project/issues/1") : readFileSync(ref, "utf8") }).result, "allowed");
153
+ }, { ...options, exists: (ref) => ref === "https://github.com/example/project/issues/1" || exists(ref), read: (ref) => ref === "https://github.com/example/project/issues/1" ? decompositionResult.replace("docs/.scratch/demo/evidence/ticket-decomposition-result.yaml", "https://github.com/example/project/issues/1") : readFileSync(ref, "utf8") }).result, "allowed");
114
154
 
115
155
  process.stdout.write("生命周期转换压力场景验证通过\n");
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { decisionIO } from './lib/user-decision.mjs';
3
+ import { assertPlanSpecEntry } from './lib/plan-spec-entry.mjs';
4
+ try {
5
+ if (process.argv.length !== 3) throw new TypeError('用法: node scripts/verify-plan-spec-entry <state.yaml|json>');
6
+ assertPlanSpecEntry(decisionIO().document(process.argv[2]));
7
+ process.stdout.write('Plan → Spec 入口检查通过(不授权实现)\n');
8
+ } catch (error) {
9
+ process.stderr.write(`${error.message}\n`);
10
+ process.exitCode = 1;
11
+ }
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+ import { validateNextRoute } from './lib/lifecycle-transition.mjs';
4
+ import { queryLifecycleContext } from './lib/lifecycle-context-query.mjs';
5
+ import { mkdtempSync, rmSync } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import path from 'node:path';
8
+ import { buildPlanFixture } from './fixtures/user-decision/plan-fixture.mjs';
9
+ import { assertPlanSpecEntry, assertPlanCheckpoint } from './lib/plan-spec-entry.mjs';
10
+ import { readFileSync } from 'node:fs';
11
+ import { decisionDigest } from './lib/user-decision.mjs';
12
+ import { buildDecisionFixture } from './fixtures/user-decision/build-fixture.mjs';
13
+ import { loadDigitalHumanRoles, countersignRuleForGate } from './lib/digital-human-roles.mjs';
14
+
15
+ for (const unit of ['plan-opportunity', 'plan-requirements', 'domain-strategy-design', 'stage-decision']) {
16
+ for (const state of [undefined, {}, { gates: {}, user_decisions: [] }]) {
17
+ assert.equal(validateNextRoute(`work-unit.${unit}`, 'work-unit.spec-synthesis', state).result, 'blocked', `${unit}: missing Plan review must block`);
18
+ }
19
+ }
20
+ const query = queryLifecycleContext({ workUnitId: 'work-unit.plan-requirements' });
21
+ assert.ok(query.execution.selected.planning);
22
+ assert.ok(query.execution.selected.grill_exit);
23
+ assert.ok(query.lifecycle.gates.length);
24
+ assert.ok(query.execution.plan_checks.every(check => check.status === 'pending'));
25
+ const specQuery = queryLifecycleContext({ stageId: 'stage.spec-architecture' });
26
+ assert.ok(specQuery.execution.selected.planning);
27
+ assert.ok(specQuery.execution.plan_checks.every(check => check.status === 'pending'));
28
+ assert.ok(specQuery.lifecycle.gates.some(gate => gate.stage === 'stage.plan'));
29
+ const temp = mkdtempSync(path.join(tmpdir(), 'yss-plan-entry-'));
30
+ try {
31
+ const mutations = [
32
+ ['缺检查项', f => delete f.review.checks.goals],
33
+ ['默认 pending', f => f.review.checks.goals.status = 'pending'],
34
+ ['检查项不能 N/A', f => f.review.checks.goals.status = 'not-applicable'],
35
+ ['缺证据', f => f.review.checks.goals.evidence_refs = []],
36
+ ['缺影响面', f => delete f.review.impacts.domain_strategy],
37
+ ['缺门禁', f => delete f.review.gates['gate.domain-strategy-approved']],
38
+ ['命中门禁不能 N/A', f => f.review.impacts.domain_strategy = true],
39
+ ['N/A 无原因', f => delete f.review.gates['gate.domain-strategy-approved'].reason],
40
+ ['关键问题延期', f => f.review.open_items.push({ id: 'q1', critical: true, runnable_blocker: false, status: 'deferred' })],
41
+ ['可执行阻塞延期', f => f.review.open_items.push({ id: 'q1', critical: false, runnable_blocker: true, status: 'deferred' })],
42
+ ['延期未交接', f => f.review.open_items.push({ id: 'q1', critical: false, runnable_blocker: false, status: 'deferred' })],
43
+ ['无回复', f => { f.approval.record.responses = []; f.approval.save(); }],
44
+ ['过期依据', f => f.write('plan.md', '变更后的范围')],
45
+ ['错误范围', f => f.state.feature_id = 'feature.other'],
46
+ ['调和未通过', f => f.review.context_reconciliation_ref = 'plan.md'],
47
+ ];
48
+ const valid = buildPlanFixture(path.join(temp, 'valid'));
49
+ assert.equal(assertPlanSpecEntry(valid.state, { root: valid.root }).result, 'allowed');
50
+ assert.equal(validateNextRoute('work-unit.plan-opportunity', 'work-unit.spec-synthesis', valid.state, { root: valid.root }).result, 'allowed');
51
+ valid.review.open_items = [{ id: 'q-detail', critical: false, runnable_blocker: false, status: 'deferred', noncritical_reason: '不影响范围或关键规则', owner: '测试负责人', resolution_point: 'Spec 评审前', downstream_recipient: '测试需求负责人', evidence_refs: ['plan.md'] }];
52
+ valid.reapprove();
53
+ assert.equal(assertPlanSpecEntry(valid.state, { root: valid.root }).result, 'allowed', '用户确认后的非关键延期可通过');
54
+ for (const [gateId, impact] of Object.entries({ 'gate.domain-strategy-approved': 'domain_strategy', 'gate.stage-decision-package-approved': 'stage_decision' })) {
55
+ const subjectRef = path.join(valid.root, 'plan.md');
56
+ const reply = buildDecisionFixture(path.join(valid.root, impact), { boundary: gateId, subjectRef });
57
+ const rule = countersignRuleForGate(loadDigitalHumanRoles().gate_policy, gateId);
58
+ const approvalRef = path.join(valid.root, `${impact}.json`);
59
+ valid.write(approvalRef, { schema_version: 1, gate_id: gateId, decision: 'approved', actor_kind: 'digital-human', role_id: rule.countersigners[0], runtime_id: 'runtime.skill-projection', principal_ref: 'test-only.reviewer', subject_ref: subjectRef, approval_scope: ['feature.demo'], user_decision_ref: reply.ref });
60
+ valid.review.impacts[impact] = true;
61
+ valid.review.gates[gateId] = { status: 'approved', approval_ref: approvalRef, subject_ref: subjectRef, approval_scope: ['feature.demo'], evidence_refs: [approvalRef, subjectRef] };
62
+ for (const ref of [approvalRef, subjectRef]) if (!valid.review.basis.some(asset => asset.ref === ref)) valid.review.basis.push({ ref, digest: decisionDigest(readFileSync(ref)) });
63
+ }
64
+ valid.reapprove();
65
+ assert.equal(assertPlanSpecEntry(valid.state, { root: valid.root }).result, 'allowed', '命中门禁、真实回复来源与当前资产绑定均通过');
66
+ valid.review.gates['gate.domain-strategy-approved'].approval_scope = ['feature.other']; valid.reapprove();
67
+ assert.throws(() => assertPlanSpecEntry(valid.state, { root: valid.root }), /会签资产或范围不匹配/);
68
+ for (const [name, mutate] of mutations) {
69
+ const f = buildPlanFixture(path.join(temp, name)); mutate(f); f.save();
70
+ assert.throws(() => assertPlanSpecEntry(f.state, { root: f.root }), undefined, name);
71
+ }
72
+ for (const checkpoint of [{ next_work_unit: 'work-unit.spec-synthesis' }, { stage: 'stage.spec-architecture' }, { stage_trace: { completed_work_unit: 'work-unit.spec-synthesis' } }]) {
73
+ assert.throws(() => assertPlanCheckpoint({ repository_mode: 'project-instance', ...checkpoint }), /plan-spec-entry-blocked/);
74
+ }
75
+ const stale = buildPlanFixture(path.join(temp, 'stale-review'));
76
+ stale.review.gates['gate.domain-strategy-approved'].reason += ' changed'; stale.save();
77
+ assert.throws(() => assertPlanSpecEntry(stale.state, { root: stale.root }), /user-decision-stale/);
78
+ } finally { rmSync(temp, { recursive: true, force: true }); }
79
+ process.stdout.write('Plan → Spec 无状态绕过与默认加载检查通过\n');
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+ import * as fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { spawn, spawnSync } from 'node:child_process';
7
+ import { once } from 'node:events';
8
+ import { pathToFileURL } from 'node:url';
9
+ import { validateJsonSchemas, validateJsonSchema } from './lib/json-schema.mjs';
10
+ import { runCommand, runCommandSync } from './lib/command-runner.mjs';
11
+ const temp=fs.mkdtempSync(path.join(os.tmpdir(),'yss-performance-scenarios-'));
12
+ try {
13
+ const schema=path.join(temp,'schema.json');
14
+ fs.writeFileSync(schema,JSON.stringify({$defs:{name:{type:'string',minLength:2}},type:'object',required:['name'],properties:{name:{$ref:'#/$defs/name'},email:{type:'string',format:'email'},items:{type:'array',items:{type:'integer'}}},additionalProperties:false}));
15
+ const values=[{name:'okay'},{name:'x'},{name:'okay',email:'wrong'},null,{name:'okay',items:['bad']},{name:'okay',unknown:1}];
16
+ for(const formatChecker of [true,false])for(const errorStyle of ['compact','verbose']) {
17
+ const jobs=values.map(value=>({value,schemaPath:schema,formatChecker,errorStyle}));
18
+ const results=validateJsonSchemas(jobs);
19
+ // Independent original Python behavior, not the new single-item wrapper.
20
+ const legacy=spawnSync('python3',['-c',`import json,sys\nfrom jsonschema import Draft202012Validator,FormatChecker\ns=json.load(open(sys.argv[1])); rows=[]\nfor v in json.load(sys.stdin):\n e=list(Draft202012Validator(s,format_checker=${formatChecker?'FormatChecker()':'None'}).iter_errors(v))\n ${errorStyle==='compact'?"e.sort(key=lambda x:list(x.absolute_path))":"pass"}\n message=${errorStyle==='compact'?`'\\n'.join(f"{'.'.join(str(p) for p in x.absolute_path) or '<root>'}: {x.message}" for x in e)`:`'\\n'.join(str(x) for x in e)`}\n rows.append({'valid':not e,'error':message})\njson.dump(rows,sys.stdout)`,schema],{input:JSON.stringify(values),encoding:'utf8'});
21
+ assert.equal(legacy.status,0,legacy.stderr);
22
+ assert.deepEqual(results,JSON.parse(legacy.stdout));
23
+ }
24
+ assert.deepEqual(validateJsonSchemas([]),[]);
25
+ assert.throws(()=>validateJsonSchema({},path.join(temp,'missing.json')),/缺少/);
26
+ fs.writeFileSync(schema,JSON.stringify({type:'number'}));
27
+ assert.throws(()=>validateJsonSchema({name:'okay'},schema),/not of type/,'schema 改变后必须重新读取');
28
+ const log=path.join(temp,'stdout.log');
29
+ const split=await runCommand(process.execPath,['-e',"process.stdout.write('ab');setTimeout(()=>process.stdout.write('aba!'),20)"],{stdoutFile:log,secrets:['ababa']});
30
+ assert.equal(split.stdout,'[REDACTED]!');assert.equal(fs.readFileSync(log,'utf8'),'[REDACTED]!');
31
+ const timed=await runCommand(process.execPath,['-e',"setInterval(()=>{},1000)"],{timeoutMs:100});
32
+ assert.equal(timed.status,124);assert.equal(timed.termination,'timeout');
33
+ const controller=new AbortController();
34
+ const cancelled=runCommand(process.execPath,['-e',"setInterval(()=>{},1000)"],{signal:controller.signal});
35
+ setTimeout(()=>controller.abort(),50);assert.equal((await cancelled).termination,'cancelled');
36
+ const missing=await runCommand(path.join(temp,'missing'),[]);assert.notEqual(missing.status,0);
37
+ assert.equal(runCommandSync(process.execPath,['-e',"process.stdout.write('sync')"]).stdout,'sync');
38
+ const pidFile=path.join(temp,'pid');
39
+ const tree=await runCommand(process.execPath,['-e',`const {spawn}=require('node:child_process');const fs=require('node:fs');const c=spawn(process.execPath,['-e','setInterval(()=>{},1000)'],{stdio:'ignore'});fs.writeFileSync(${JSON.stringify(pidFile)},String(c.pid));setInterval(()=>{},1000)`],{timeoutMs:250});
40
+ assert.equal(tree.termination,'timeout');
41
+ const pid=Number(fs.readFileSync(pidFile,'utf8'));
42
+ // A reparented zombie may briefly exist; it must never remain a running child.
43
+ const state=spawnSync('ps',['-o','stat=','-p',String(pid)],{encoding:'utf8'});
44
+ assert.ok(state.status!==0 || !state.stdout.trim() || state.stdout.trim().startsWith('Z'),state.stdout);
45
+ const orphanPid=path.join(temp,'orphan-pid'), scratch=path.join(temp,'owned-fetch');fs.mkdirSync(scratch);
46
+ const parent=spawn(process.execPath,['--input-type=module','-e',`import {runCommandSync} from ${JSON.stringify(pathToFileURL(path.join(import.meta.dirname,'lib/command-runner.mjs')).href)};runCommandSync(process.execPath,['-e',${JSON.stringify(`require('node:fs').writeFileSync(${JSON.stringify(orphanPid)},String(process.pid));setInterval(()=>{},1000)`)}],{cleanupPathsOnFailure:[${JSON.stringify(scratch)}]});`],{stdio:'ignore'});
47
+ const exited=once(parent,'exit');
48
+ for(let n=0;n<150&&!fs.existsSync(orphanPid);n++)await new Promise(resolve=>setTimeout(resolve,20));
49
+ assert.ok(fs.existsSync(orphanPid),'worker 子进程应启动');
50
+ parent.kill('SIGTERM');await exited;
51
+ for(let n=0;n<150&&fs.existsSync(scratch);n++)await new Promise(resolve=>setTimeout(resolve,20));
52
+ assert.equal(fs.existsSync(scratch),false,'同步调用者退出后 worker 应清理其临时资源');
53
+ const orphanState=spawnSync('ps',['-o','stat=','-p',fs.readFileSync(orphanPid,'utf8')],{encoding:'utf8'});
54
+ assert.ok(orphanState.status!==0 || !orphanState.stdout.trim() || orphanState.stdout.trim().startsWith('Z'),orphanState.stdout);
55
+ console.log('schema 批量差分、重新读取、日志脱敏、超时、取消与进程树清理通过');
56
+ } finally { fs.rmSync(temp,{recursive:true,force:true}); }
@@ -83,7 +83,7 @@ function packageBase(roleId, taskId, workUnitId, kind, contractFields, stageId)
83
83
  }
84
84
 
85
85
  function lifecyclePackage() {
86
- return packageBase("role.requirements-manager", "task-discovery", "work-unit.discovery-opportunity", "lifecycle-work-unit", { lifecycle_ref: "docs/process/lifecycle-registry.yaml", artifact_refs: ["artifact.discovery-record"] , gate_refs: [] , contract_id: "lifecycle-discovery", contract_version: 1 }, "stage.discovery");
86
+ return packageBase("role.requirements-manager", "task-discovery", "work-unit.plan-opportunity", "lifecycle-work-unit", { lifecycle_ref: "docs/process/lifecycle-registry.yaml", artifact_refs: ["artifact.plan-record"] , gate_refs: [] , contract_id: "lifecycle-discovery", contract_version: 1 }, "stage.plan");
87
87
  }
88
88
 
89
89
  function lifecycleStagePackage(roleId, taskId, workUnitId, stageId) {
@@ -134,7 +134,7 @@ function completedResult(pkg, overrides = {}) {
134
134
  violation: [],
135
135
  new_impacts: [],
136
136
  stale_candidates: [],
137
- next_route: "work-unit.spec-synthesis",
137
+ next_route: "work-unit.plan-requirements",
138
138
  blocking_signals: [],
139
139
  ...overrides
140
140
  };
@@ -160,18 +160,19 @@ try {
160
160
  maintenance.review_context = { implementation_actor_id: "role.lifecycle-orchestrator.instance-1" };
161
161
  const frontend = slicePackage("role.frontend-engineer", "task-frontend", "work-unit.slice-frontend", "apps/frontend/todo/");
162
162
  const backend = slicePackage("role.backend-engineer", "task-backend", "work-unit.slice-backend", "apps/backend/todo/");
163
- [discovery, spec, prototype, technical, tickets, review].forEach((pkg) => validateTaskPackage(pkg));
163
+ [discovery, prototype, technical, tickets, review].forEach((pkg) => validateTaskPackage(pkg));
164
+ assert.throws(() => validateTaskPackage(spec), /plan-spec-entry-blocked/, "直接派发 Spec 缺 Plan 审阅须阻断");
164
165
  validateTaskPackage(maintenance);
165
166
  validateTaskPackage(frontend);
166
167
  assert.throws(() => validateTaskPackage({ ...frontend, user_decisions: [] }), /user-decision-scope-mismatch/, "Worker 派发前必须有当前实施范围批准");
167
168
  validateTaskPackage(backend);
168
169
  validateTaskPackageSet([frontend, backend]);
169
170
 
170
- const completedDiscovery = lifecyclePackage();
171
- completedDiscovery.workflow_status = "resolved";
172
- completedDiscovery.verification_results = [{ command: "scripts/verify-template", exit_code: 0, executed_at: "now", evidence_ref: evidenceRef }];
173
- completedDiscovery.result = completedResult(completedDiscovery);
174
- validateTaskPackage(completedDiscovery);
171
+ const completedPlan = lifecyclePackage();
172
+ completedPlan.workflow_status = "resolved";
173
+ completedPlan.verification_results = [{ command: "scripts/verify-template", exit_code: 0, executed_at: "now", evidence_ref: evidenceRef }];
174
+ completedPlan.result = completedResult(completedPlan);
175
+ validateTaskPackage(completedPlan);
175
176
 
176
177
  const validFile = path.join(ROOT, ".template-source/evidence/.task-package-valid.json");
177
178
  writeFileSync(validFile, JSON.stringify(discovery));
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import assert from "node:assert/strict";
3
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { chmodSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { tmpdir } from "node:os";
5
5
  import path from "node:path";
6
6
  import { spawnSync } from "node:child_process";
@@ -40,6 +40,16 @@ try {
40
40
  assert.throws(() => acquireTemplateCommit({ repository: remote, commit, cacheRoot, allowLocal: true }), /缓存不完整/);
41
41
  assert.throws(() => acquireTemplateCommit({ repository: path.join(root, "offline"), commit, cacheRoot: path.join(root, "offline-cache"), allowLocal: true }), /执行失败|does not appear to be a git repository/);
42
42
  assert.throws(() => acquireTemplateCommit({ repository: remote, commit: "main", cacheRoot, allowLocal: true }), /40 位 commit/);
43
+ const realGit = spawnSync("which", ["git"], { encoding: "utf8" }).stdout.trim();
44
+ const bin = path.join(root, "bin"), timeoutCache = path.join(root, "timeout-cache"), previousPath = process.env.PATH;
45
+ mkdirSync(bin);
46
+ writeFileSync(path.join(bin, "git"), `#!/usr/bin/env node\nconst {spawnSync}=require('node:child_process');const args=process.argv.slice(2);if(args.includes('fetch'))setTimeout(()=>{},10000);else process.exit(spawnSync(${JSON.stringify(realGit)},args,{stdio:'inherit'}).status ?? 1);\n`);
47
+ chmodSync(path.join(bin, "git"), 0o755);
48
+ try {
49
+ process.env.PATH = bin + path.delimiter + previousPath;
50
+ assert.throws(() => acquireTemplateCommit({ repository: remote, commit, cacheRoot: timeoutCache, allowLocal: true, timeoutMs: 100 }), /timeout/);
51
+ assert.deepEqual(readdirSync(timeoutCache), [], "超时 fetch 不遗留临时缓存或伪成功条目");
52
+ } finally { process.env.PATH = previousPath; }
43
53
  } finally {
44
54
  rmSync(root, { recursive: true, force: true });
45
55
  }
@@ -88,10 +88,10 @@ check("历史数字人记录可读但不能关闭关键门禁", () => {
88
88
  const f = fixture("approval"); Object.assign(record, { subject_ref: f.requirement.subject_ref, approval_scope: f.requirement.scope, user_decision_ref: f.ref }); validateApprovalRecord(record, { requireApproved: true });
89
89
  });
90
90
  check("等待期间可保存状态但不能流转依赖工作", () => {
91
- const f = fixture("workflow", { boundary: "discovery-conclusion" }); const state = { user_decisions: [f.requirement] };
92
- assert.equal(validateNextRoute("work-unit.discovery-requirements", "work-unit.spec-synthesis", state).result, "allowed");
93
- f.record.responses = []; f.save(); assert.equal(validateNextRoute("work-unit.discovery-requirements", "work-unit.spec-synthesis", state).result, "blocked");
94
- assert.equal(validateNextRoute("work-unit.discovery-opportunity", "work-unit.discovery-requirements", state).result, "allowed");
91
+ const f = fixture("workflow", { boundary: "plan-conclusion" }); const state = { user_decisions: [f.requirement] };
92
+ assert.equal(validateNextRoute("work-unit.plan-requirements", "work-unit.spec-synthesis", state).result, "blocked", "仅用户确认不能代替完整 Plan 入口审阅");
93
+ f.record.responses = []; f.save(); assert.equal(validateNextRoute("work-unit.plan-requirements", "work-unit.spec-synthesis", state).result, "blocked");
94
+ assert.equal(validateNextRoute("work-unit.plan-opportunity", "work-unit.plan-requirements", state).result, "allowed");
95
95
  assertCheckpointUserDecisions({ repository_mode: "project-instance", status: "paused-human-gate", human_review: { required_decisions: [f.requirement] } });
96
96
  assert.throws(() => assertCheckpointUserDecisions({ repository_mode: "project-instance", status: "running", human_review: { required_decisions: [f.requirement] } }), /user-decision-response-required/);
97
97
  });
@@ -21,7 +21,7 @@
21
21
  "revision": "c4d958f18cc947cb91cbe1bd48783fa4601cc18f"
22
22
  },
23
23
  "iloveZzz/yss-harness-design-agent": {
24
- "revision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab"
24
+ "revision": "3a358684c5684ada433dca4fd97ee187050ca6d8"
25
25
  }
26
26
  },
27
27
  "skills": {
@@ -63,7 +63,7 @@
63
63
  "source": "mattpocock/skills",
64
64
  "sourceType": "github",
65
65
  "skillPath": "skills/engineering/code-review/SKILL.md",
66
- "effectiveHash": "a9839b761443bcb9bf46b886630378e53dfb748ed77fc46b96e5777e701a438e",
66
+ "effectiveHash": "660ca39ab37b65099940b2e6a197089291e2fb74494ec93bbeb8e2fde6559465",
67
67
  "sourceRevision": "0ab1b63a410a03d3627979a109c8695de27af954",
68
68
  "upstreamHash": "12daafb9c4f77deb3c3303dc2e6f8a3c2a0ff7928fc004af959ba18b8bd38068",
69
69
  "adaptationRef": "docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md",
@@ -99,7 +99,7 @@
99
99
  "source": "competitive-intelligence",
100
100
  "sourceType": "local",
101
101
  "skillPath": "sales/skills/competitive-intelligence/SKILL.md",
102
- "effectiveHash": "d4b83600889b6045182232f0c11a9d6a563030b5f60faa4385a7886843ef0109",
102
+ "effectiveHash": "df1473dfd96b1a3ba63ef929917973b613988edf62193b5b82d734de2e8418cd",
103
103
  "targets": [
104
104
  ".agents/skills",
105
105
  ".claude/skills",
@@ -164,7 +164,7 @@
164
164
  "source": "mattpocock/skills",
165
165
  "sourceType": "github",
166
166
  "skillPath": "skills/engineering/domain-modeling/SKILL.md",
167
- "effectiveHash": "02989ac6fd21562ba87af7a88b5d34f11661f86a3a42014e366613ecdb81bd81",
167
+ "effectiveHash": "7e691aeef60ee61c423f224acd3c4481a8764d3d336c8c49585b36d1a9bca9be",
168
168
  "sourceRevision": "0ab1b63a410a03d3627979a109c8695de27af954",
169
169
  "upstreamHash": "2bc3bb0a64ea9c6f5c3bcf78fc17f0fcdc7c062edc547ef006441de0b576d248",
170
170
  "adaptationRef": "docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md",
@@ -304,7 +304,7 @@
304
304
  "source": "mattpocock/skills",
305
305
  "sourceType": "github",
306
306
  "skillPath": "skills/engineering/grill-with-docs/SKILL.md",
307
- "effectiveHash": "c0f724b8cb4be22d10d8e8de3dfd49eb024cf131a3bcf5e7b89e109ad3d80b32",
307
+ "effectiveHash": "2006f65f386e79ff37c2c3294efe146e2e546845cf52e1571340dcb2a81a0df3",
308
308
  "sourceRevision": "0ab1b63a410a03d3627979a109c8695de27af954",
309
309
  "upstreamHash": "6b1292031c4f38a11309b9dad9be1141c1921c6edf86d1ae6da8b048fa71a349",
310
310
  "adaptationRef": "docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md",
@@ -559,7 +559,7 @@
559
559
  "sourceType": "git-submodule",
560
560
  "skillPath": ".agents/skills/prototype-review/SKILL.md",
561
561
  "effectiveHash": "51021f119697dbff644d70c3d6ba3314147c47f412c6f56e4b5540ea3bf554a1",
562
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
562
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
563
563
  "upstreamHash": "2e77b3093a758bb692fb3bda453c5c020d0523f875975e17e2731365f67432e1",
564
564
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
565
565
  "targets": [
@@ -594,7 +594,7 @@
594
594
  "source": "mattpocock/skills",
595
595
  "sourceType": "github",
596
596
  "skillPath": "skills/engineering/setup-matt-pocock-skills/SKILL.md",
597
- "effectiveHash": "c1463ecc928789308855e9995e9787cf311128a8567f8ed671b83d696a9b4cc9",
597
+ "effectiveHash": "1f63e63e8036a08ac6d0626b4dbbd16d8fbe1ae171cae31b36e82c606552396e",
598
598
  "sourceRevision": "0ab1b63a410a03d3627979a109c8695de27af954",
599
599
  "upstreamHash": "80cd6b5be4f67913f1b10f5acd97fccaeb6401682ae7ff3a971460cb73d86cbe",
600
600
  "adaptationRef": "docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md",
@@ -824,7 +824,7 @@
824
824
  "sourceType": "git-submodule",
825
825
  "skillPath": ".agents/skills/yss-antd-design/SKILL.md",
826
826
  "effectiveHash": "917099caa9b76ca3cfd1d0f81f61b28111c1c54ed93e92891f81012dcd0662e2",
827
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
827
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
828
828
  "upstreamHash": "08ce99d45586d5ea19e25fdd9e9a6ede16e66f18992b70b87e0cd23f92343b16",
829
829
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
830
830
  "targets": [
@@ -842,7 +842,7 @@
842
842
  "sourceType": "git-submodule",
843
843
  "skillPath": ".agents/skills/yss-antdv-next-design/SKILL.md",
844
844
  "effectiveHash": "8c55e3a815ace34fbf591e931a58970b3d58cb657e00432ca6c72938d307563b",
845
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
845
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
846
846
  "upstreamHash": "2942ed52dd58a38e51f09eb11254809334aeaed08f21cd081f09f35e6647a68c",
847
847
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
848
848
  "targets": [
@@ -937,7 +937,7 @@
937
937
  "source": "project",
938
938
  "sourceType": "local",
939
939
  "skillPath": ".agents/skills/yss-ddd-scaffold-generator/SKILL.md",
940
- "effectiveHash": "438b92a03e9e0c80ac68db65096fd499275ad16cb69d4d751571754a97aa38a8",
940
+ "effectiveHash": "ab1bd70b73a148d57a8e3f88e9a94be57b81f59bbfb81849e6e1dba16bfc7e16",
941
941
  "targets": [
942
942
  ".agents/skills",
943
943
  ".claude/skills",
@@ -953,7 +953,7 @@
953
953
  "sourceType": "git-submodule",
954
954
  "skillPath": ".agents/skills/yss-design-system/SKILL.md",
955
955
  "effectiveHash": "e69597b8b6a5ce4de5bd40f67630443b8176202f6b028b2ce146a2a1d062816f",
956
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
956
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
957
957
  "upstreamHash": "90aaf06b2514353152464a4d032076fa9d5ef56272d8ad526f5544f3c22a2b00",
958
958
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
959
959
  "targets": [
@@ -1078,7 +1078,7 @@
1078
1078
  "source": "project",
1079
1079
  "sourceType": "local",
1080
1080
  "skillPath": ".agents/skills/yss-frontend-scaffold-generator/SKILL.md",
1081
- "effectiveHash": "87bc0d2f0c279d3fff14ded7a07ba7b9f72a61080e7b9ca826bb452894877e4e",
1081
+ "effectiveHash": "2f829e4e2a9cb42e123e8de37fe812bc65eef1308758e077b52f0698de9b68ab",
1082
1082
  "targets": [
1083
1083
  ".agents/skills",
1084
1084
  ".claude/skills",
@@ -1108,7 +1108,7 @@
1108
1108
  "source": "project",
1109
1109
  "sourceType": "local",
1110
1110
  "skillPath": ".agents/skills/yss-implementation-contract-compiler/SKILL.md",
1111
- "effectiveHash": "4f9ec75e4484bc2794ea057037890d2bcb96512c8c64bef9d9fdae7c66abe46d",
1111
+ "effectiveHash": "96582c950a13f26a7c16b2087d0614cb28a99f0f805190fc64cfc80e6456c335",
1112
1112
  "targets": [
1113
1113
  ".agents/skills",
1114
1114
  ".claude/skills",
@@ -1123,7 +1123,7 @@
1123
1123
  "source": "project",
1124
1124
  "sourceType": "local",
1125
1125
  "skillPath": ".agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md",
1126
- "effectiveHash": "360389486d6bd07949c0b11ab30e266fbf073169d8ee447d89581fe583228950",
1126
+ "effectiveHash": "50d0f704326fc523c29f4b728c08148cde372c674b9e8686829bee3e74b66fdc",
1127
1127
  "targets": [
1128
1128
  ".agents/skills",
1129
1129
  ".claude/skills",
@@ -1183,7 +1183,7 @@
1183
1183
  "source": "project",
1184
1184
  "sourceType": "local",
1185
1185
  "skillPath": ".agents/skills/yss-mybatis/SKILL.md",
1186
- "effectiveHash": "1f70b00dcc6be6fde9c32ebf4ee41a86f2b348ca4bb789a3f2f32a7a24258ff4",
1186
+ "effectiveHash": "8ab792d519c045a8a682942185f9aae3dcabfe86dbd8a4a9a444d7f657798701",
1187
1187
  "targets": [
1188
1188
  ".agents/skills",
1189
1189
  ".claude/skills",
@@ -1228,7 +1228,7 @@
1228
1228
  "source": "project",
1229
1229
  "sourceType": "local",
1230
1230
  "skillPath": ".agents/skills/yss-product-lifecycle/SKILL.md",
1231
- "effectiveHash": "c262bd69e978eee24b49526043b2439c30ce006f4fbbcb56e881c903ba6f3d51",
1231
+ "effectiveHash": "a54a583c92621aede69e2f7db99f7373e0724b3187acd44c6d20c0144ca9943b",
1232
1232
  "targets": [
1233
1233
  ".agents/skills",
1234
1234
  ".claude/skills",
@@ -1244,7 +1244,7 @@
1244
1244
  "sourceType": "git-submodule",
1245
1245
  "skillPath": ".agents/skills/yss-prototype-stage/SKILL.md",
1246
1246
  "effectiveHash": "0ecf3125a73d15e4c9b6b665f92535180df82ccb2255fa863ec59f3ff5d460aa",
1247
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
1247
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
1248
1248
  "upstreamHash": "e8f2f3a507da6bf7be0582e4a4dd9659381da8e291755070698a1f51a4e33808",
1249
1249
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
1250
1250
  "targets": [
@@ -1261,7 +1261,7 @@
1261
1261
  "source": "project",
1262
1262
  "sourceType": "local",
1263
1263
  "skillPath": ".agents/skills/yss-repository/SKILL.md",
1264
- "effectiveHash": "19f4380ba81f6cf373b737a4b17316f35bf2be27646be38707d52cfd6c1c7aef",
1264
+ "effectiveHash": "0abe4e8f4896613985074615281f11711b807fcfc5727a6e6d2e7d2ebcf7ddc7",
1265
1265
  "targets": [
1266
1266
  ".agents/skills",
1267
1267
  ".claude/skills",
@@ -1276,7 +1276,7 @@
1276
1276
  "source": "mattpocock/skills",
1277
1277
  "sourceType": "github",
1278
1278
  "skillPath": "skills/engineering/research/SKILL.md",
1279
- "effectiveHash": "a0c69c6cff59bdb6d36b03d24cceb29698e76cd6aae88919bf864284737c3aaa",
1279
+ "effectiveHash": "0d8f94e6379ad56897a7821b4803a3ba72910e617aab730e47db719e6eb02807",
1280
1280
  "sourceRevision": "0ab1b63a410a03d3627979a109c8695de27af954",
1281
1281
  "upstreamHash": "75b7f9bbd7ccff6755a006f8b25d319a46ecbf6bd4b4c3323965ed9cb65e78ff",
1282
1282
  "adaptationRef": "docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md",
@@ -1324,7 +1324,7 @@
1324
1324
  "source": "project",
1325
1325
  "sourceType": "local",
1326
1326
  "skillPath": ".agents/skills/yss-skill-source-index-refresh/SKILL.md",
1327
- "effectiveHash": "4c95ec664da1d3515ac49b80c063df20bf69d352c6892f66ceb29d0a12b55458",
1327
+ "effectiveHash": "96ff974a0f7b3db8de09680daf9ecada94dd19f608341dcc85a32d40c02591b0",
1328
1328
  "targets": [
1329
1329
  ".agents/skills",
1330
1330
  ".claude/skills",
@@ -1339,9 +1339,9 @@
1339
1339
  "source": "iloveZzz/yss-harness-design-agent",
1340
1340
  "sourceType": "git-submodule",
1341
1341
  "skillPath": ".agents/skills/yss-stage-decision/SKILL.md",
1342
- "effectiveHash": "63e222ec2bc572c8d66fc52143ba3862650d243f57e1e9c71214b533eba37c23",
1343
- "sourceRevision": "8a67e0f5a56aa5085d18c2b42bb540c8f36c2fab",
1344
- "upstreamHash": "1eadf230f0e17bf6d209c1df1249acef3520ab29c26a80c476a2a557a224c10a",
1342
+ "effectiveHash": "ad5180d162c6f9484aac556ed114e1447f93715d2d7e3c4bc1a53430adae65f1",
1343
+ "sourceRevision": "3a358684c5684ada433dca4fd97ee187050ca6d8",
1344
+ "upstreamHash": "2ec63f66aaf799d693cec0f0b5d71b8c4917e4e2822e0ddd519bc9b711fa3c95",
1345
1345
  "adaptationRef": "docs/agents/strategic-design-skills-integration.md",
1346
1346
  "targets": [
1347
1347
  ".agents/skills",