create-yss-spec 3.5.0 → 3.5.2

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 (513) hide show
  1. package/README.md +6 -2
  2. package/package.json +1 -1
  3. package/src/api/_sync-service.js +31 -6
  4. package/src/cli/args.js +2 -0
  5. package/src/cli/help.js +4 -1
  6. package/src/commands/attach.js +9 -3
  7. package/src/commands/diff.js +1 -0
  8. package/src/commands/doctor.js +1 -0
  9. package/src/commands/init.js +2 -1
  10. package/src/commands/sync.js +1 -0
  11. package/src/family-identity.js +1 -1
  12. package/src/template/asset-runtime.js +57 -49
  13. package/src/template/attach-planner.js +1 -1
  14. package/src/template/distribution-runtime.js +9 -9
  15. package/src/template/instance-runtime.js +9 -9
  16. package/src/template/layout-migration.js +160 -0
  17. package/src/template/migration-runtime.js +2 -2
  18. package/src/template/sync-planner.js +1 -1
  19. package/template/.agents/rules/yss-ai-skills.md +1 -1
  20. package/template/.agents/skills/.strategic-design-skills-manifest.json +7 -8
  21. package/template/.agents/skills/.yss-skills-manifest.json +2 -2
  22. package/template/.agents/skills/alibaba-java-code-style/SKILL.md +1 -1
  23. package/template/.agents/skills/code-review/SKILL.md +6 -6
  24. package/template/.agents/skills/code-review/references/yss-review-standards.md +1 -1
  25. package/template/.agents/skills/cross-repo-implementation-routing/SKILL.md +2 -2
  26. package/template/.agents/skills/i-have-adhd/SKILL.md +1 -1
  27. package/template/.agents/skills/i-have-adhd/references/yss-adaptation.md +1 -1
  28. package/template/.agents/skills/i-have-adhd/tests/verify-integration.mjs +2 -2
  29. package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +2 -2
  30. package/template/.agents/skills/llm-wiki/references/discover.md +3 -3
  31. package/template/.agents/skills/prototype-review/SKILL.md +4 -4
  32. package/template/.agents/skills/setup-matt-pocock-skills/SKILL.md +10 -10
  33. package/template/.agents/skills/triage/SKILL.md +1 -1
  34. package/template/.agents/skills/yss-application/references/profiles/layered-mvc-service.md +1 -1
  35. package/template/.agents/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +1 -1
  36. package/template/.agents/skills/yss-backend-spec-review/SKILL.md +1 -1
  37. package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +1 -1
  38. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
  39. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  40. package/template/.agents/skills/yss-design-system/SKILL.md +10 -10
  41. package/template/.agents/skills/yss-design-system/references/design-qa-theme.md +3 -3
  42. package/template/.agents/skills/yss-design-system/references/design-system.md +3 -3
  43. package/template/.agents/skills/yss-exception/SKILL.md +1 -1
  44. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +2 -2
  45. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  46. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/refresh_baseline.mjs +2 -2
  47. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +9 -9
  48. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -1
  49. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +9 -9
  50. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract-v2.md +3 -3
  51. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +1 -1
  52. package/template/.agents/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +1 -1
  53. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  54. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/data-analysis-profile.mjs +5 -5
  55. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +2 -2
  56. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +42 -0
  57. package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +2 -2
  58. package/template/.agents/skills/yss-openapi-governance/SKILL.md +7 -7
  59. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +11 -11
  60. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  61. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +65 -43
  62. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +22 -14
  63. package/template/.agents/skills/yss-product-lifecycle/references/request-triage.md +2 -0
  64. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +3 -3
  65. package/template/.agents/skills/yss-product-lifecycle/references/user-decisions.md +2 -2
  66. package/template/.agents/skills/yss-prototype-stage/SKILL.md +7 -7
  67. package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +1 -1
  68. package/template/.agents/skills/yss-prototype-stage/scripts/build-antd-prototype.mjs +1 -1
  69. package/template/.agents/skills/yss-prototype-stage/scripts/offline-html.mjs +3 -3
  70. package/template/.agents/skills/yss-prototype-stage/tests/browser-smoke.mjs +2 -2
  71. package/template/.agents/skills/yss-prototype-stage/tests/run-scenarios.mjs +4 -4
  72. package/template/.agents/skills/yss-prototype-stage/tests/workbench-smoke.mjs +1 -1
  73. package/template/.agents/skills/yss-repository/SKILL.md +2 -2
  74. package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +1 -1
  75. package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +1 -1
  76. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +2 -2
  77. package/template/.agents/skills/yss-research/SKILL.md +2 -2
  78. package/template/.agents/skills/yss-skill-source-index-refresh/references/backend-component-platform-compatibility.md +1 -1
  79. package/template/.agents/skills/yss-stage-decision/SKILL.md +5 -5
  80. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +1 -1
  81. package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +1 -1
  82. package/template/.agents/skills/yss-tactical-design/SKILL.md +2 -2
  83. package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +1 -1
  84. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +1 -1
  85. package/template/.agents/skills/yss-technical-design/SKILL.md +6 -6
  86. package/template/.agents/skills/yss-technical-design/references/technical-design-contract.md +1 -1
  87. package/template/.agents/skills/yss-ui/SKILL.md +1 -1
  88. package/template/.agents/skills/yss-up-springboot3/SKILL.md +1 -1
  89. package/template/.agents/skills/yss-web-controller/SKILL.md +1 -1
  90. package/template/.agents/skills/yss-web-controller/references/profiles/layered-mvc-service.md +1 -1
  91. package/template/.codex/skills/alibaba-java-code-style/SKILL.md +1 -1
  92. package/template/.codex/skills/code-review/SKILL.md +6 -6
  93. package/template/.codex/skills/code-review/references/yss-review-standards.md +1 -1
  94. package/template/.codex/skills/cross-repo-implementation-routing/SKILL.md +2 -2
  95. package/template/.codex/skills/i-have-adhd/SKILL.md +1 -1
  96. package/template/.codex/skills/i-have-adhd/references/yss-adaptation.md +1 -1
  97. package/template/.codex/skills/i-have-adhd/tests/verify-integration.mjs +2 -2
  98. package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +2 -2
  99. package/template/.codex/skills/llm-wiki/references/discover.md +3 -3
  100. package/template/.codex/skills/prototype-review/SKILL.md +4 -4
  101. package/template/.codex/skills/setup-matt-pocock-skills/SKILL.md +10 -10
  102. package/template/.codex/skills/triage/SKILL.md +1 -1
  103. package/template/.codex/skills/yss-application/references/profiles/layered-mvc-service.md +1 -1
  104. package/template/.codex/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +1 -1
  105. package/template/.codex/skills/yss-backend-spec-review/SKILL.md +1 -1
  106. package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +1 -1
  107. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
  108. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  109. package/template/.codex/skills/yss-design-system/SKILL.md +10 -10
  110. package/template/.codex/skills/yss-design-system/references/design-qa-theme.md +3 -3
  111. package/template/.codex/skills/yss-design-system/references/design-system.md +3 -3
  112. package/template/.codex/skills/yss-exception/SKILL.md +1 -1
  113. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +2 -2
  114. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  115. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/refresh_baseline.mjs +2 -2
  116. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +9 -9
  117. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -1
  118. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +9 -9
  119. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract-v2.md +3 -3
  120. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +1 -1
  121. package/template/.codex/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +1 -1
  122. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  123. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/data-analysis-profile.mjs +5 -5
  124. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +2 -2
  125. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +42 -0
  126. package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +2 -2
  127. package/template/.codex/skills/yss-openapi-governance/SKILL.md +7 -7
  128. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +11 -11
  129. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  130. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +65 -43
  131. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +22 -14
  132. package/template/.codex/skills/yss-product-lifecycle/references/request-triage.md +2 -0
  133. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +3 -3
  134. package/template/.codex/skills/yss-product-lifecycle/references/user-decisions.md +2 -2
  135. package/template/.codex/skills/yss-prototype-stage/SKILL.md +7 -7
  136. package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +1 -1
  137. package/template/.codex/skills/yss-prototype-stage/scripts/build-antd-prototype.mjs +1 -1
  138. package/template/.codex/skills/yss-prototype-stage/scripts/offline-html.mjs +3 -3
  139. package/template/.codex/skills/yss-prototype-stage/tests/browser-smoke.mjs +2 -2
  140. package/template/.codex/skills/yss-prototype-stage/tests/run-scenarios.mjs +4 -4
  141. package/template/.codex/skills/yss-prototype-stage/tests/workbench-smoke.mjs +1 -1
  142. package/template/.codex/skills/yss-repository/SKILL.md +2 -2
  143. package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +1 -1
  144. package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +1 -1
  145. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +2 -2
  146. package/template/.codex/skills/yss-research/SKILL.md +2 -2
  147. package/template/.codex/skills/yss-skill-source-index-refresh/references/backend-component-platform-compatibility.md +1 -1
  148. package/template/.codex/skills/yss-stage-decision/SKILL.md +5 -5
  149. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +1 -1
  150. package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +1 -1
  151. package/template/.codex/skills/yss-tactical-design/SKILL.md +2 -2
  152. package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +1 -1
  153. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +1 -1
  154. package/template/.codex/skills/yss-technical-design/SKILL.md +6 -6
  155. package/template/.codex/skills/yss-technical-design/references/technical-design-contract.md +1 -1
  156. package/template/.codex/skills/yss-ui/SKILL.md +1 -1
  157. package/template/.codex/skills/yss-up-springboot3/SKILL.md +1 -1
  158. package/template/.codex/skills/yss-web-controller/SKILL.md +1 -1
  159. package/template/.codex/skills/yss-web-controller/references/profiles/layered-mvc-service.md +1 -1
  160. package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +1 -1
  161. package/template/.cursor/skills/code-review/SKILL.md +6 -6
  162. package/template/.cursor/skills/code-review/references/yss-review-standards.md +1 -1
  163. package/template/.cursor/skills/cross-repo-implementation-routing/SKILL.md +2 -2
  164. package/template/.cursor/skills/i-have-adhd/SKILL.md +1 -1
  165. package/template/.cursor/skills/i-have-adhd/references/yss-adaptation.md +1 -1
  166. package/template/.cursor/skills/i-have-adhd/tests/verify-integration.mjs +2 -2
  167. package/template/.cursor/skills/implementation-repo-onboarding/SKILL.md +2 -2
  168. package/template/.cursor/skills/llm-wiki/references/discover.md +3 -3
  169. package/template/.cursor/skills/prototype-review/SKILL.md +4 -4
  170. package/template/.cursor/skills/setup-matt-pocock-skills/SKILL.md +10 -10
  171. package/template/.cursor/skills/triage/SKILL.md +1 -1
  172. package/template/.cursor/skills/yss-application/references/profiles/layered-mvc-service.md +1 -1
  173. package/template/.cursor/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +1 -1
  174. package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +1 -1
  175. package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +1 -1
  176. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
  177. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  178. package/template/.cursor/skills/yss-design-system/SKILL.md +10 -10
  179. package/template/.cursor/skills/yss-design-system/references/design-qa-theme.md +3 -3
  180. package/template/.cursor/skills/yss-design-system/references/design-system.md +3 -3
  181. package/template/.cursor/skills/yss-exception/SKILL.md +1 -1
  182. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +2 -2
  183. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  184. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/refresh_baseline.mjs +2 -2
  185. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +9 -9
  186. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -1
  187. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +9 -9
  188. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract-v2.md +3 -3
  189. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +1 -1
  190. package/template/.cursor/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +1 -1
  191. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  192. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/data-analysis-profile.mjs +5 -5
  193. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +2 -2
  194. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +42 -0
  195. package/template/.cursor/skills/yss-openapi-draft-review/SKILL.md +2 -2
  196. package/template/.cursor/skills/yss-openapi-governance/SKILL.md +7 -7
  197. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +11 -11
  198. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  199. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +65 -43
  200. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +22 -14
  201. package/template/.cursor/skills/yss-product-lifecycle/references/request-triage.md +2 -0
  202. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +3 -3
  203. package/template/.cursor/skills/yss-product-lifecycle/references/user-decisions.md +2 -2
  204. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +7 -7
  205. package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +1 -1
  206. package/template/.cursor/skills/yss-prototype-stage/scripts/build-antd-prototype.mjs +1 -1
  207. package/template/.cursor/skills/yss-prototype-stage/scripts/offline-html.mjs +3 -3
  208. package/template/.cursor/skills/yss-prototype-stage/tests/browser-smoke.mjs +2 -2
  209. package/template/.cursor/skills/yss-prototype-stage/tests/run-scenarios.mjs +4 -4
  210. package/template/.cursor/skills/yss-prototype-stage/tests/workbench-smoke.mjs +1 -1
  211. package/template/.cursor/skills/yss-repository/SKILL.md +2 -2
  212. package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +1 -1
  213. package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +1 -1
  214. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +2 -2
  215. package/template/.cursor/skills/yss-research/SKILL.md +2 -2
  216. package/template/.cursor/skills/yss-skill-source-index-refresh/references/backend-component-platform-compatibility.md +1 -1
  217. package/template/.cursor/skills/yss-stage-decision/SKILL.md +5 -5
  218. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +1 -1
  219. package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +1 -1
  220. package/template/.cursor/skills/yss-tactical-design/SKILL.md +2 -2
  221. package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +1 -1
  222. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +1 -1
  223. package/template/.cursor/skills/yss-technical-design/SKILL.md +6 -6
  224. package/template/.cursor/skills/yss-technical-design/references/technical-design-contract.md +1 -1
  225. package/template/.cursor/skills/yss-ui/SKILL.md +1 -1
  226. package/template/.cursor/skills/yss-up-springboot3/SKILL.md +1 -1
  227. package/template/.cursor/skills/yss-web-controller/SKILL.md +1 -1
  228. package/template/.cursor/skills/yss-web-controller/references/profiles/layered-mvc-service.md +1 -1
  229. package/template/.cursorrules +1 -1
  230. package/template/.pi/skills/alibaba-java-code-style/SKILL.md +1 -1
  231. package/template/.pi/skills/code-review/SKILL.md +6 -6
  232. package/template/.pi/skills/code-review/references/yss-review-standards.md +1 -1
  233. package/template/.pi/skills/cross-repo-implementation-routing/SKILL.md +2 -2
  234. package/template/.pi/skills/i-have-adhd/SKILL.md +1 -1
  235. package/template/.pi/skills/i-have-adhd/references/yss-adaptation.md +1 -1
  236. package/template/.pi/skills/i-have-adhd/tests/verify-integration.mjs +2 -2
  237. package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +2 -2
  238. package/template/.pi/skills/llm-wiki/references/discover.md +3 -3
  239. package/template/.pi/skills/prototype-review/SKILL.md +4 -4
  240. package/template/.pi/skills/setup-matt-pocock-skills/SKILL.md +10 -10
  241. package/template/.pi/skills/triage/SKILL.md +1 -1
  242. package/template/.pi/skills/yss-application/references/profiles/layered-mvc-service.md +1 -1
  243. package/template/.pi/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +1 -1
  244. package/template/.pi/skills/yss-backend-spec-review/SKILL.md +1 -1
  245. package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +1 -1
  246. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
  247. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  248. package/template/.pi/skills/yss-design-system/SKILL.md +10 -10
  249. package/template/.pi/skills/yss-design-system/references/design-qa-theme.md +3 -3
  250. package/template/.pi/skills/yss-design-system/references/design-system.md +3 -3
  251. package/template/.pi/skills/yss-exception/SKILL.md +1 -1
  252. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +2 -2
  253. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +1 -1
  254. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/refresh_baseline.mjs +2 -2
  255. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +9 -9
  256. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -1
  257. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +9 -9
  258. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract-v2.md +3 -3
  259. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +1 -1
  260. package/template/.pi/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +1 -1
  261. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  262. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/data-analysis-profile.mjs +5 -5
  263. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +2 -2
  264. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +42 -0
  265. package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +2 -2
  266. package/template/.pi/skills/yss-openapi-governance/SKILL.md +7 -7
  267. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +11 -11
  268. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  269. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +65 -43
  270. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +22 -14
  271. package/template/.pi/skills/yss-product-lifecycle/references/request-triage.md +2 -0
  272. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +3 -3
  273. package/template/.pi/skills/yss-product-lifecycle/references/user-decisions.md +2 -2
  274. package/template/.pi/skills/yss-prototype-stage/SKILL.md +7 -7
  275. package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +1 -1
  276. package/template/.pi/skills/yss-prototype-stage/scripts/build-antd-prototype.mjs +1 -1
  277. package/template/.pi/skills/yss-prototype-stage/scripts/offline-html.mjs +3 -3
  278. package/template/.pi/skills/yss-prototype-stage/tests/browser-smoke.mjs +2 -2
  279. package/template/.pi/skills/yss-prototype-stage/tests/run-scenarios.mjs +4 -4
  280. package/template/.pi/skills/yss-prototype-stage/tests/workbench-smoke.mjs +1 -1
  281. package/template/.pi/skills/yss-repository/SKILL.md +2 -2
  282. package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +1 -1
  283. package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +1 -1
  284. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +2 -2
  285. package/template/.pi/skills/yss-research/SKILL.md +2 -2
  286. package/template/.pi/skills/yss-skill-source-index-refresh/references/backend-component-platform-compatibility.md +1 -1
  287. package/template/.pi/skills/yss-stage-decision/SKILL.md +5 -5
  288. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +1 -1
  289. package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +1 -1
  290. package/template/.pi/skills/yss-tactical-design/SKILL.md +2 -2
  291. package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +1 -1
  292. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +1 -1
  293. package/template/.pi/skills/yss-technical-design/SKILL.md +6 -6
  294. package/template/.pi/skills/yss-technical-design/references/technical-design-contract.md +1 -1
  295. package/template/.pi/skills/yss-ui/SKILL.md +1 -1
  296. package/template/.pi/skills/yss-up-springboot3/SKILL.md +1 -1
  297. package/template/.pi/skills/yss-web-controller/SKILL.md +1 -1
  298. package/template/.pi/skills/yss-web-controller/references/profiles/layered-mvc-service.md +1 -1
  299. package/template/{docs → .template-spec}/adr/README.md +1 -1
  300. package/template/{docs → .template-spec}/agents/README.md +1 -1
  301. package/template/{docs → .template-spec}/agents/backend-architecture-profiles.md +2 -2
  302. package/template/{docs → .template-spec}/agents/digital-human-roles.md +6 -6
  303. package/template/{docs → .template-spec}/agents/digital-human-roles.yaml +5 -5
  304. package/template/{docs → .template-spec}/agents/gitlab-workflow-skills.md +2 -2
  305. package/template/{docs → .template-spec}/agents/issue-tracker.md +1 -1
  306. package/template/{docs → .template-spec}/agents/skill-migrations.md +2 -2
  307. package/template/{docs → .template-spec}/agents/triage-labels.md +1 -1
  308. package/template/{docs → .template-spec}/agents/yss-skill-registry.yaml +2 -2
  309. package/template/{docs → .template-spec}/architecture/README.md +3 -3
  310. package/template/{docs → .template-spec}/architecture/templates/tech-design-template.md +3 -1
  311. package/template/{docs → .template-spec}/design/README.md +12 -11
  312. package/template/{docs → .template-spec}/design/design.md +19 -19
  313. package/template/{docs/design/templates/interaction-spec-template.md → .template-spec/design/templates/examples/model-publishing-interaction.example.md} +5 -3
  314. package/template/{docs/design/templates/state-matrix-template.md → .template-spec/design/templates/examples/model-publishing-state-matrix.example.md} +3 -1
  315. package/template/.template-spec/design/templates/interaction-spec-template.md +61 -0
  316. package/template/{docs → .template-spec}/design/templates/product-overview-design-template.md +11 -11
  317. package/template/{docs → .template-spec}/design/templates/prototype-evidence-template.yaml +4 -4
  318. package/template/{docs → .template-spec}/design/templates/prototype-review-checklist.md +1 -1
  319. package/template/.template-spec/design/templates/state-matrix-template.md +29 -0
  320. package/template/.template-spec/design/tokens/.design-md-projection.json +13 -0
  321. package/template/{docs → .template-spec}/engineering/backend-platforms.md +1 -1
  322. package/template/{docs → .template-spec}/plan/entry-review.md +8 -4
  323. package/template/{docs → .template-spec}/plan/templates/plan-template.md +1 -1
  324. package/template/{docs → .template-spec}/process/contract-reading.md +1 -1
  325. package/template/{docs → .template-spec}/process/lifecycle-artifact-map.md +5 -5
  326. package/template/.template-spec/process/lifecycle-registry-baseline.json +253 -0
  327. package/template/{docs → .template-spec}/process/lifecycle-registry.yaml +19 -12
  328. package/template/{docs → .template-spec}/process/plan-migration.md +1 -1
  329. package/template/{docs → .template-spec}/process/schemas/digital-human-task-package.schema.json +14 -1
  330. package/template/{docs → .template-spec}/process/schemas/lifecycle-checkpoint.schema.json +15 -0
  331. package/template/{docs → .template-spec}/process/schemas/lifecycle-registry.schema.json +1 -1
  332. package/template/{docs → .template-spec}/process/schemas/strategic-design-handoff-v3.schema.json +1 -1
  333. package/template/{docs → .template-spec}/process/schemas/strategic-design-handoff-v4.schema.json +1 -1
  334. package/template/{docs → .template-spec}/process/schemas/strategic-design-handoff-v5.schema.json +1 -1
  335. package/template/{docs → .template-spec}/process/schemas/strategic-design-handoff.schema.json +1 -1
  336. package/template/{docs → .template-spec}/process/stage-tracking.md +1 -1
  337. package/template/{docs → .template-spec}/process/subagent-collaboration.md +2 -2
  338. package/template/{docs → .template-spec}/templates/build-architecture-checklist-template.md +2 -2
  339. package/template/{docs → .template-spec}/templates/digital-human-runtime-profile-template.md +2 -2
  340. package/template/{docs → .template-spec}/templates/grok-bot-profile-template.md +1 -1
  341. package/template/{docs → .template-spec}/templates/local-parent-ticket-template.md +1 -1
  342. package/template/.template-spec/templates/release-note-template.md +29 -0
  343. package/template/.template-spec/templates/retro-report-template.md +24 -0
  344. package/template/{docs → .template-spec}/templates/subagent-task-package-template.md +3 -3
  345. package/template/.template-spec/templates/verification-record-template.md +64 -0
  346. package/template/{docs → .template-spec}/templates/vertical-slice-ticket-template.md +5 -10
  347. package/template/{docs → .template-spec}/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +1 -1
  348. package/template/{docs → .template-spec}/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +4 -4
  349. package/template/AGENTS.md +12 -12
  350. package/template/CONTEXT.md +3 -3
  351. package/template/README.md +21 -21
  352. package/template/scripts/backend-delivery +1 -1
  353. package/template/scripts/lib/api-contract-decision.mjs +1 -1
  354. package/template/scripts/lib/approved-execution-context.mjs +5 -5
  355. package/template/scripts/lib/backend-delivery.mjs +4 -4
  356. package/template/scripts/lib/backend-platform.mjs +1 -1
  357. package/template/scripts/lib/backend-review.mjs +1 -1
  358. package/template/scripts/lib/backend-scaffold-prerequisites.mjs +1 -1
  359. package/template/scripts/lib/backend-standards-coverage.mjs +2 -2
  360. package/template/scripts/lib/context-reconciliation.mjs +1 -1
  361. package/template/scripts/lib/contract-views.mjs +9 -9
  362. package/template/scripts/lib/delivery-preflight.mjs +6 -6
  363. package/template/scripts/lib/design-md.mjs +2 -2
  364. package/template/scripts/lib/digital-human-roles.mjs +2 -2
  365. package/template/scripts/lib/existing-backend-architecture.mjs +1 -1
  366. package/template/scripts/lib/existing-ui-baseline.mjs +1 -1
  367. package/template/scripts/lib/frontend-delivery.mjs +2 -2
  368. package/template/scripts/lib/governance-layout.mjs +74 -0
  369. package/template/scripts/lib/harness-execution-scope.mjs +2 -2
  370. package/template/scripts/lib/lifecycle-context-query.mjs +11 -3
  371. package/template/scripts/lib/lifecycle-registry.mjs +46 -7
  372. package/template/scripts/lib/lifecycle-status.mjs +111 -0
  373. package/template/scripts/lib/lifecycle-transition.mjs +71 -10
  374. package/template/scripts/lib/openapi-draft-validation.mjs +1 -1
  375. package/template/scripts/lib/plan-spec-entry-view.mjs +48 -0
  376. package/template/scripts/lib/plan-spec-entry.mjs +3 -3
  377. package/template/scripts/lib/skill-registry.mjs +8 -8
  378. package/template/scripts/lib/skill-supply-chain.mjs +1 -1
  379. package/template/scripts/lib/slice-contract-preparation.mjs +3 -3
  380. package/template/scripts/lib/slice-contract.mjs +1 -1
  381. package/template/scripts/lib/slice-repositories.mjs +1 -1
  382. package/template/scripts/lib/slice-task-package.mjs +3 -3
  383. package/template/scripts/lib/stage-tracking-migration.mjs +2 -2
  384. package/template/scripts/lib/stage-tracking.mjs +5 -5
  385. package/template/scripts/lib/strategic-feedback.mjs +2 -2
  386. package/template/scripts/lib/strategic-handoff-routing.mjs +2 -2
  387. package/template/scripts/lib/strategic-handoff.mjs +15 -15
  388. package/template/scripts/lib/task-package-schema.mjs +2 -2
  389. package/template/scripts/lib/task-package.mjs +1 -1
  390. package/template/scripts/lib/technical-design-boundary.mjs +1 -1
  391. package/template/scripts/lib/user-decision.mjs +2 -1
  392. package/template/scripts/lifecycle-status +14 -0
  393. package/template/scripts/plan-spec-entry +21 -0
  394. package/template/scripts/strategic-consumer-entry +1 -1
  395. package/template/scripts/strategic-handoff +1 -1
  396. package/template/scripts/verify-frontend-implementation-evidence +1 -1
  397. package/template/scripts/verify-governance-layout +15 -0
  398. package/template/scripts/verify-lifecycle-checkpoint +1 -1
  399. package/template/scripts/verify-project-instance +2 -0
  400. package/template/scripts/verify-scaffold-architecture-decisions +1 -1
  401. package/template/scripts/verify-strategic-context-import +3 -3
  402. package/template/skills-lock.json +77 -77
  403. package/template.manifest.json +19 -19
  404. package/template.snapshot.json +5 -5
  405. package/template/docs/agents/archify-integration.md +0 -19
  406. package/template/docs/design/design-system-sync.yaml +0 -13
  407. package/template/docs/design/preview-dark.html +0 -178
  408. package/template/docs/design/preview.css +0 -730
  409. package/template/docs/design/preview.html +0 -178
  410. package/template/docs/design/preview.js +0 -71
  411. package/template/docs/design/tokens/.design-md-projection.json +0 -13
  412. package/template/docs/engineering/evidence/aliyun-artifact-resolution.json +0 -446
  413. package/template/docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md +0 -13
  414. package/template/docs/process/github-workflows.md +0 -52
  415. package/template/docs/templates/release-note-template.md +0 -14
  416. package/template/docs/templates/retro-report-template.md +0 -16
  417. package/template/docs/templates/verification-record-template.md +0 -53
  418. /package/template/{docs → .template-spec}/agents/domain.md +0 -0
  419. /package/template/{docs → .template-spec}/api/templates/openapi-draft-review-checklist.md +0 -0
  420. /package/template/{docs → .template-spec}/api/templates/openapi-draft-validation-record-template.yaml +0 -0
  421. /package/template/{docs → .template-spec}/api/templates/openapi-freeze-record-template.md +0 -0
  422. /package/template/{docs → .template-spec}/api/templates/openapi-json-export-record-template.md +0 -0
  423. /package/template/{docs → .template-spec}/architecture/templates/architecture-deepening-template.md +0 -0
  424. /package/template/{docs → .template-spec}/architecture/templates/architecture-review-checklist.md +0 -0
  425. /package/template/{docs → .template-spec}/architecture/templates/business-architecture-template.md +0 -0
  426. /package/template/{docs → .template-spec}/architecture/templates/data-architecture-template.md +0 -0
  427. /package/template/{docs → .template-spec}/architecture/templates/engineering-baseline-review-template.md +0 -0
  428. /package/template/{docs → .template-spec}/architecture/templates/functional-architecture-template.md +0 -0
  429. /package/template/{docs → .template-spec}/architecture/templates/system-overview-design-template.md +0 -0
  430. /package/template/{docs → .template-spec}/design/diagrams/README.md +0 -0
  431. /package/template/{docs → .template-spec}/design/schemas/visual-baseline.schema.json +0 -0
  432. /package/template/{docs → .template-spec}/design/templates/prototype-confirmation-template.md +0 -0
  433. /package/template/{docs → .template-spec}/design/templates/visual-baseline-template.yaml +0 -0
  434. /package/template/{docs → .template-spec}/design/tokens/theme.json +0 -0
  435. /package/template/{docs → .template-spec}/design/tokens/tokens.compact.json +0 -0
  436. /package/template/{docs → .template-spec}/design/tokens/tokens.dark.json +0 -0
  437. /package/template/{docs → .template-spec}/design/tokens/tokens.default.json +0 -0
  438. /package/template/{docs → .template-spec}/design/tokens/variables.css +0 -0
  439. /package/template/{docs → .template-spec}/design/tokens/variables.dark.css +0 -0
  440. /package/template/{docs → .template-spec}/engineering/backend-platforms.json +0 -0
  441. /package/template/{docs → .template-spec}/plan/README.md +0 -0
  442. /package/template/{docs → .template-spec}/plan/templates/competitive-analysis-template.md +0 -0
  443. /package/template/{docs → .template-spec}/plan/templates/competitive-matrix-template.md +0 -0
  444. /package/template/{docs → .template-spec}/plan/templates/market-analysis-template.md +0 -0
  445. /package/template/{docs → .template-spec}/plan/templates/user-pain-points-template.md +0 -0
  446. /package/template/{docs → .template-spec}/process/delivery-preflight.md +0 -0
  447. /package/template/{docs → .template-spec}/process/document-writing.md +0 -0
  448. /package/template/{docs → .template-spec}/process/existing-backend-architecture.md +0 -0
  449. /package/template/{docs → .template-spec}/process/existing-ui-baseline.md +0 -0
  450. /package/template/{docs → .template-spec}/process/frontend-backend-delivery.md +0 -0
  451. /package/template/{docs → .template-spec}/process/harness-process-tailoring.md +0 -0
  452. /package/template/{docs → .template-spec}/process/implementation-repo-integration.md +0 -0
  453. /package/template/{docs/process/lifecycle-registry-baseline.json → .template-spec/process/lifecycle-registry-baseline-v1.json} +0 -0
  454. /package/template/{docs → .template-spec}/process/schemas/api-contract-decision-v2.schema.json +0 -0
  455. /package/template/{docs → .template-spec}/process/schemas/api-contract-decision.schema.json +0 -0
  456. /package/template/{docs → .template-spec}/process/schemas/backend-architecture-identity.schema.json +0 -0
  457. /package/template/{docs → .template-spec}/process/schemas/backend-delivery-verification.schema.json +0 -0
  458. /package/template/{docs → .template-spec}/process/schemas/backend-delivery.schema.json +0 -0
  459. /package/template/{docs → .template-spec}/process/schemas/context-reconciliation.schema.json +0 -0
  460. /package/template/{docs → .template-spec}/process/schemas/data-architecture-decision.schema.json +0 -0
  461. /package/template/{docs → .template-spec}/process/schemas/delivery-preflight-input.schema.json +0 -0
  462. /package/template/{docs → .template-spec}/process/schemas/delivery-preflight-result.schema.json +0 -0
  463. /package/template/{docs → .template-spec}/process/schemas/existing-ui-baseline.schema.json +0 -0
  464. /package/template/{docs → .template-spec}/process/schemas/frontend-delivery-acceptance-v1.schema.json +0 -0
  465. /package/template/{docs → .template-spec}/process/schemas/frontend-delivery-acceptance-v3.schema.json +0 -0
  466. /package/template/{docs → .template-spec}/process/schemas/frontend-delivery-acceptance.schema.json +0 -0
  467. /package/template/{docs → .template-spec}/process/schemas/frontend-implementation-evidence.schema.json +0 -0
  468. /package/template/{docs → .template-spec}/process/schemas/frontend-strategic-preflight-v2.schema.json +0 -0
  469. /package/template/{docs → .template-spec}/process/schemas/frontend-strategic-preflight.schema.json +0 -0
  470. /package/template/{docs → .template-spec}/process/schemas/implementation-repository-preparation-result.schema.json +0 -0
  471. /package/template/{docs → .template-spec}/process/schemas/openapi-draft-validation-record.schema.json +0 -0
  472. /package/template/{docs → .template-spec}/process/schemas/project-scaffold-contract.schema.json +0 -0
  473. /package/template/{docs → .template-spec}/process/schemas/review-bundle.schema.json +0 -0
  474. /package/template/{docs → .template-spec}/process/schemas/scaffold-architecture-decisions.schema.json +0 -0
  475. /package/template/{docs → .template-spec}/process/schemas/slice-implementation-contract-v3.schema.json +0 -0
  476. /package/template/{docs → .template-spec}/process/schemas/stage-tracking.schema.json +0 -0
  477. /package/template/{docs → .template-spec}/process/schemas/strategic-consumer-feedback.schema.json +0 -0
  478. /package/template/{docs → .template-spec}/process/schemas/strategic-feedback-adjudication.schema.json +0 -0
  479. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-delivery-verification.schema.json +0 -0
  480. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-delivery.schema.json +0 -0
  481. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-domain-strategy-v3.schema.json +0 -0
  482. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-domain-strategy.schema.json +0 -0
  483. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-export-v2.schema.json +0 -0
  484. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-export.schema.json +0 -0
  485. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-import-receipt-v3.schema.json +0 -0
  486. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-import-receipt.schema.json +0 -0
  487. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-package.schema.json +0 -0
  488. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-stage-decision-package-v3.schema.json +0 -0
  489. /package/template/{docs → .template-spec}/process/schemas/strategic-handoff-stage-decision-package.schema.json +0 -0
  490. /package/template/{docs → .template-spec}/process/schemas/subagent-task-package.schema.json +0 -0
  491. /package/template/{docs → .template-spec}/process/schemas/user-decision.schema.json +0 -0
  492. /package/template/{docs → .template-spec}/process/strategic-handoff-package.md +0 -0
  493. /package/template/{docs → .template-spec}/process/templates/context-reconciliation-template.yaml +0 -0
  494. /package/template/{docs → .template-spec}/process/templates/frontend-implementation-plan-template.yaml +0 -0
  495. /package/template/{docs → .template-spec}/process/templates/frontend-implementation-verification-template.yaml +0 -0
  496. /package/template/{docs → .template-spec}/process/templates/lifecycle-checkpoint-template.yaml +0 -0
  497. /package/template/{docs → .template-spec}/process/templates/scaffold-architecture-decisions-template.yaml +0 -0
  498. /package/template/{docs → .template-spec}/process/templates/stage-checkpoint-template.md +0 -0
  499. /package/template/{docs → .template-spec}/process/templates/user-decision-template.yaml +0 -0
  500. /package/template/{docs → .template-spec}/templates/adr-template.md +0 -0
  501. /package/template/{docs → .template-spec}/templates/approval-record-template.yaml +0 -0
  502. /package/template/{docs → .template-spec}/templates/cross-repo-slice-template.md +0 -0
  503. /package/template/{docs → .template-spec}/templates/examples/lifecycle-writing-examples.md +0 -0
  504. /package/template/{docs → .template-spec}/templates/implementation-repo-registry-template.md +0 -0
  505. /package/template/{docs → .template-spec}/templates/openapi-spec-template.yaml +0 -0
  506. /package/template/{docs → .template-spec}/templates/review-bundle-template.yaml +0 -0
  507. /package/template/{docs → .template-spec}/templates/review-report-template.md +0 -0
  508. /package/template/{docs → .template-spec}/templates/spec-delta-template.md +0 -0
  509. /package/template/{docs → .template-spec}/templates/spec-template.md +0 -0
  510. /package/template/{docs → .template-spec}/user-guide/yss-ui-mcp.md +0 -0
  511. /package/template/{docs → .template-spec}/user-guide//346/212/200/346/234/257/350/256/276/350/256/241/347/224/250/346/210/267/346/214/207/345/215/227.md" +0 -0
  512. /package/template/{docs → .template-spec}/user-guide//350/256/276/345/244/207/345/200/237/347/224/250/350/264/257/347/251/277/346/241/210/344/276/213.md" +0 -0
  513. /package/template/{docs → .template-spec}/user-guide//351/230/266/346/256/265/346/216/245/345/205/245/344/270/216/344/272/247/347/211/251/345/244/215/347/224/250/344/275/277/347/224/250/346/211/213/345/206/214.md" +0 -0
@@ -28,7 +28,7 @@ export function invalidPreflightInput(message) {
28
28
 
29
29
  /** Installed profile owns backend technical authoring; caller governance_root cannot grant it. */
30
30
  export function backendPreflightCapability() {
31
- const profileRef=path.join(ROOT,'docs/process/harness-profile.yaml');
31
+ const profileRef=path.join(ROOT,'.template-spec/process/harness-profile.yaml');
32
32
  const profile=existsSync(profileRef)?read(profileRef):null;
33
33
  const profileId=profile?.profile_id||'template.full';
34
34
  const ownsBackend=!profile||profileId==='harness.backend-delivery';
@@ -49,7 +49,7 @@ function requireBackendCapability(key) {
49
49
  /** Read-only: never executes input commands, starts services, unpacks archives or writes receipts. */
50
50
  export async function preflightDelivery(input,options={}) {return withValidationPhase({root:path.resolve(options.root||process.cwd(),typeof input?.governance_root==='string'?input.governance_root:'.'),purpose:`delivery-${options.stage}`,slice_id:input?.scope?.slice_id,work_unit_id:options.work_unit_id,readOnly:true,signal:options.signal},()=>preflight(input,options));}
51
51
  async function preflight(input,{stage,root=process.cwd(),work_unit_id}={}) {
52
- try { ensure(STAGES.includes(stage),'未知阶段;必须是 prepare|build|export|accept');schema(input,'docs/process/schemas/delivery-preflight-input.schema.json'); }
52
+ try { ensure(STAGES.includes(stage),'未知阶段;必须是 prepare|build|export|accept');schema(input,'.template-spec/process/schemas/delivery-preflight-input.schema.json'); }
53
53
  catch(error) { return invalidPreflightInput(error.message); }
54
54
  root=path.resolve(root,input.governance_root||'.');
55
55
  const deliveryKind=input.delivery_kind||'complete';
@@ -121,7 +121,7 @@ async function preflight(input,{stage,root=process.cwd(),work_unit_id}={}) {
121
121
  async function approved(root,binding,gates) {
122
122
  ensure(binding.approval_ref&&binding.id&&binding.version,'缺少当前资产 id/version/approval_ref');
123
123
  const record=read(safe(root,binding.approval_ref));
124
- const roles=sourceApprovalPolicy(read(safe(root,'docs/agents/digital-human-roles.yaml')));
124
+ const roles=sourceApprovalPolicy(read(safe(root,'.template-spec/agents/digital-human-roles.yaml')));
125
125
  validateApprovalRecord(record,{rolesDoc:roles,requireApproved:true,root,read:ref=>readFileSync(safe(root,path.relative(root,ref).split(path.sep).join('/')))});
126
126
  ensure(gates.includes(record.gate_id),'资产批准使用错误门禁');
127
127
  ensure(record.artifact_bindings?.some(x=>x.id===binding.id&&x.version===binding.version&&x.digest===binding.digest),'stale: 批准未绑定当前资产身份、版本及字节');
@@ -186,7 +186,7 @@ async function verifyAsset(key,data,binding,{root,input,documents,assets,executi
186
186
  await approved(root,binding,['gate.product-design-approved','gate.user-confirmation']);
187
187
  } else if(key==='build') {
188
188
  // Same build shape used by backend-delivery, captured independently before packaging.
189
- const deliverySchema=read(safe(ROOT,'docs/process/schemas/backend-delivery.schema.json'));
189
+ const deliverySchema=read(safe(ROOT,'.template-spec/process/schemas/backend-delivery.schema.json'));
190
190
  const buildRules=deliverySchema.properties.build;
191
191
  // Validate in memory to avoid writing a generated schema: check the published required fields.
192
192
  for(const field of buildRules.required||[])ensure(Object.hasOwn(data,field),`构建缺少交付协议字段: ${field}`);
@@ -195,7 +195,7 @@ async function verifyAsset(key,data,binding,{root,input,documents,assets,executi
195
195
  ensure(/^sha256:[0-9a-f]{64}$/.test(data.artifact_digest),'构建制品摘要无效');
196
196
  ensure(Object.keys(data).every(key=>Object.hasOwn(buildRules.properties,key)),'构建包含交付协议未定义字段');
197
197
  } else if(key==='deployment') {
198
- schema(data,'docs/process/schemas/backend-delivery-verification.schema.json');
198
+ schema(data,'.template-spec/process/schemas/backend-delivery-verification.schema.json');
199
199
  ensure(data.kind==='backend-deployment','部署证据 kind 必须为 backend-deployment');
200
200
  for(const result of data.results) {
201
201
  ensure(result.exit_code===0&&Number.isFinite(Date.parse(result.executed_at))&&Date.parse(result.executed_at)<=Date.now()+60000,'部署执行结果或时间无效');
@@ -206,7 +206,7 @@ async function verifyAsset(key,data,binding,{root,input,documents,assets,executi
206
206
  ensure(data.subject_digest===backendDeliveryBasis(documents.backend_delivery),'stale: 部署验证未绑定当前交付依据');
207
207
  }
208
208
  } else if(key==='backend_delivery') {
209
- schema(data,`docs/process/schemas/backend-delivery${data.schema_version===2?'-v2':''}.schema.json`);
209
+ schema(data,`.template-spec/process/schemas/backend-delivery${data.schema_version===2?'-v2':''}.schema.json`);
210
210
  ensure(data.scope.slice_id===input.scope.slice_id&&input.scope.operation_ids.every(id=>data.scope.operation_ids.includes(id)),'后端交付切片/接口范围不匹配');
211
211
  for(const asset of ['openapi','slice_contract'])if(assets[asset])ensure(data[asset].ref===assets[asset].ref&&data[asset].digest===assets[asset].digest,'后端交付引用与预检输入不一致');
212
212
  for(const asset of [data.environment.test_data,...Object.values(data.verification)])fileBinding(root,asset);
@@ -8,9 +8,9 @@ import { parseDocument } from "../vendor/yaml.mjs";
8
8
 
9
9
  const repositoryRoot = path.resolve(new URL("../..", import.meta.url).pathname);
10
10
  const designPath = path.join(repositoryRoot, "DESIGN.md");
11
- const projectionDir = path.join(repositoryRoot, "docs/design/tokens");
11
+ const projectionDir = path.join(repositoryRoot, ".template-spec/design/tokens");
12
12
  const manifestPath = path.join(projectionDir, ".design-md-projection.json");
13
- const syncMetadataPath = path.join(repositoryRoot, "docs/design/design-system-sync.yaml");
13
+ const syncMetadataPath = path.join(repositoryRoot, ".template-source/design/design-system-sync.yaml");
14
14
  const expectedSections = ["Overview", "Colors", "Typography", "Layout", "Elevation & Depth", "Shapes", "Components", "Do's and Don'ts"];
15
15
  const requiredFrontmatter = ["version", "name", "description", "colors", "typography", "rounded", "spacing", "components"];
16
16
  const componentProperties = new Set(["backgroundColor", "textColor", "typography", "rounded", "padding", "size", "height", "width"]);
@@ -4,7 +4,7 @@ import { parseDocument } from "../vendor/yaml.mjs";
4
4
  import { loadRegistry, ROOT } from "./lifecycle-registry.mjs";
5
5
  import { loadSkillRegistry } from "./skill-registry.mjs";
6
6
 
7
- export const DEFAULT_DIGITAL_HUMAN_ROLES = path.join(ROOT, "docs/agents/digital-human-roles.yaml");
7
+ export const DEFAULT_DIGITAL_HUMAN_ROLES = path.join(ROOT, ".template-spec/agents/digital-human-roles.yaml");
8
8
 
9
9
  const ROLE_ID = /^role\.[a-z0-9][a-z0-9-]*$/;
10
10
  const GROUP_ID = /^group\.[a-z0-9][a-z0-9-]*$/;
@@ -259,7 +259,7 @@ export function validateDigitalHumanRoles(doc, { skillIds, stageIds, gateIds, ar
259
259
  if (doc.registry_id !== "yss.digital-human-roles") fail("registry_id 必须为 yss.digital-human-roles");
260
260
  if (doc.status !== "active") fail("status 必须为 active");
261
261
  requireString(doc.description, "description");
262
- if (doc.canonical_path !== "docs/agents/digital-human-roles.yaml") fail("canonical_path 必须为 docs/agents/digital-human-roles.yaml");
262
+ if (doc.canonical_path !== ".template-spec/agents/digital-human-roles.yaml") fail("canonical_path 必须为 .template-spec/agents/digital-human-roles.yaml");
263
263
  rejectGrokCoupling(doc.runtime_policy, "runtime_policy");
264
264
  rejectGrokCoupling(doc.gate_policy, "gate_policy");
265
265
  const runtime = doc.runtime_policy;
@@ -111,7 +111,7 @@ export function verifyExistingArchitecture(identity,bindings,{root,registry,exec
111
111
  requireThat(Array.isArray(baseline.verification_commands)&&baseline.verification_commands.length&&Array.isArray(registration.verification_commands),'ARCH_VERIFICATION_MISSING','缺少登记验证命令');
112
112
  same(baseline.verification_commands,registration.verification_commands,'ARCH_VERIFICATION_CONFLICT','验证入口不一致');
113
113
  const review=bound(root,baseline.boundary_review);
114
- const rolesFile=path.join(root,'docs/agents/digital-human-roles.yaml');
114
+ const rolesFile=path.join(root,'.template-spec/agents/digital-human-roles.yaml');
115
115
  const roles=parse(readFileSync(rolesFile));
116
116
  validateApprovalRecord(review,{rolesDoc:roles,requireApproved:true,root});
117
117
  requireThat(['check.architecture-reviewed','gate.technical-design-approved'].includes(review.gate_id)&&text(baseline.id)&&text(baseline.version),'ARCH_REVIEW_MISSING','需要架构边界审查');
@@ -7,7 +7,7 @@ export function validateExistingUiBaseline(data,options={}) {return inValidation
7
7
  function validate(data, { bundleRoot } = {}) {
8
8
  const errors=[];
9
9
  try {
10
- schema(data,'docs/process/schemas/existing-ui-baseline.schema.json');
10
+ schema(data,'.template-spec/process/schemas/existing-ui-baseline.schema.json');
11
11
  ensure(bundleRoot,'existing-ui-baseline 需要原始 bundleRoot');
12
12
  const consumed=new Set(['existing-ui-baseline.json']);
13
13
  const allFiles=files(bundleRoot);
@@ -7,7 +7,7 @@ import { openBundle } from './strategic-handoff.mjs';
7
7
  import { verifyConsumption } from './strategic-handoff-consumption.mjs';
8
8
  import { read, safe, ensure, hash, schema, project, ROOT } from './strategic-handoff-io.mjs';
9
9
 
10
- const ACCEPTANCE_SCHEMAS=new Map([[1,'docs/process/schemas/frontend-delivery-acceptance-v1.schema.json'],[2,'docs/process/schemas/frontend-delivery-acceptance.schema.json'],[3,'docs/process/schemas/frontend-delivery-acceptance-v3.schema.json']]);
10
+ const ACCEPTANCE_SCHEMAS=new Map([[1,'.template-spec/process/schemas/frontend-delivery-acceptance-v1.schema.json'],[2,'.template-spec/process/schemas/frontend-delivery-acceptance.schema.json'],[3,'.template-spec/process/schemas/frontend-delivery-acceptance-v3.schema.json']]);
11
11
 
12
12
  function acceptanceSchema(version) {
13
13
  ensure(ACCEPTANCE_SCHEMAS.has(version),`Frontend Delivery Acceptance 未知 schema_version: ${String(version)};支持版本: 1, 2, 3;既有 UI 接收请使用 3`);
@@ -18,7 +18,7 @@ export async function verifyFrontendStrategicPreflight({root=process.cwd(),prefl
18
18
  project(root);
19
19
  const file=safe(root,preflightRef),preflight=read(file);
20
20
  ensure([1,2].includes(preflight.schema_version),'Frontend Strategic Preflight 未知 schema_version');
21
- schema(preflight,preflight.schema_version===2?'docs/process/schemas/frontend-strategic-preflight-v2.schema.json':'docs/process/schemas/frontend-strategic-preflight.schema.json');
21
+ schema(preflight,preflight.schema_version===2?'.template-spec/process/schemas/frontend-strategic-preflight-v2.schema.json':'.template-spec/process/schemas/frontend-strategic-preflight.schema.json');
22
22
  const preflightDigest=hash(readFileSync(file));
23
23
  if(expectedDigest)ensure(expectedDigest===preflightDigest,'前端战略预检摘要已变化,需重编译合同');
24
24
  ensure(preflight.status==='verified','前端战略预检尚未 verified');
@@ -0,0 +1,74 @@
1
+ import { existsSync, lstatSync, readdirSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { spawnSync } from "node:child_process";
4
+
5
+ const requiredShared = [
6
+ ".template-spec/agents/yss-skill-registry.yaml",
7
+ ".template-spec/agents/digital-human-roles.yaml",
8
+ ".template-spec/agents/issue-tracker.md",
9
+ ".template-spec/process/lifecycle-registry.yaml",
10
+ ".template-spec/process/lifecycle-artifact-map.md",
11
+ ];
12
+ const oldStaticDirs = [
13
+ "docs/agents", "docs/process", "docs/templates", "docs/user-guide",
14
+ "docs/plan/templates", "docs/api/templates", "docs/architecture/templates",
15
+ "docs/design/templates", "docs/design/tokens", "docs/design/schemas",
16
+ "docs/design/diagrams", "docs/discovery/templates",
17
+ ];
18
+ const oldStaticFiles = new Set([
19
+ "docs/adr/README.md", "docs/architecture/README.md",
20
+ "docs/plan/README.md", "docs/plan/entry-review.md",
21
+ "docs/discovery/README.md", "docs/discovery/IDEATION.md",
22
+ "docs/design/README.md", "docs/design/design.md",
23
+ "docs/design/design-system-sync.yaml", "docs/design/preview.html",
24
+ "docs/design/preview-dark.html", "docs/design/preview.css",
25
+ "docs/design/preview.js", "docs/engineering/backend-platforms.json",
26
+ "docs/engineering/backend-platforms.md",
27
+ ]);
28
+
29
+ function staticPath(ref) {
30
+ return oldStaticFiles.has(ref) || oldStaticDirs.some((directory) => ref.startsWith(`${directory}/`));
31
+ }
32
+
33
+ function filesBelow(root, relativePath) {
34
+ const full = path.join(root, relativePath);
35
+ if (!existsSync(full)) return [];
36
+ const entry = lstatSync(full);
37
+ if (!entry.isDirectory()) return [relativePath];
38
+ return readdirSync(full).filter((name) => name !== ".DS_Store")
39
+ .flatMap((name) => filesBelow(root, `${relativePath}/${name}`));
40
+ }
41
+
42
+ export function verifyGovernanceLayout(root, mode) {
43
+ if (!["template-source", "project-instance"].includes(mode)) {
44
+ throw new TypeError(`不支持的仓库身份: ${mode}`);
45
+ }
46
+ for (const ref of requiredShared) {
47
+ if (!existsSync(path.join(root, ref))) throw new TypeError(`缺少共享治理资产: ${ref}`);
48
+ }
49
+ let oldFiles;
50
+ if (mode === "template-source") {
51
+ const result = spawnSync("git", ["ls-files", "-z", "--", "docs"], { cwd: root, encoding: "utf8" });
52
+ if (result.status !== 0) throw new TypeError(result.stderr || "无法读取模板源受控文件清单");
53
+ oldFiles = result.stdout.split("\0").filter(Boolean).filter(staticPath);
54
+ for (const ref of [
55
+ ".template-source/process/maintenance-intensity.yaml",
56
+ ".template-source/process/template-verification-profiles.yaml",
57
+ ".template-source/agents/skills-maintenance.md",
58
+ ]) {
59
+ if (!existsSync(path.join(root, ref))) throw new TypeError(`缺少模板维护资产: ${ref}`);
60
+ }
61
+ } else {
62
+ oldFiles = [...new Set([
63
+ ...oldStaticDirs.flatMap((ref) => filesBelow(root, ref)),
64
+ ...[...oldStaticFiles].filter((ref) => existsSync(path.join(root, ref))),
65
+ ])];
66
+ if (existsSync(path.join(root, ".template-source"))) {
67
+ throw new TypeError("项目实例不得包含 .template-source");
68
+ }
69
+ }
70
+ if (oldFiles.length) {
71
+ throw new TypeError(`旧治理文件仍位于 docs/,需显式迁移: ${oldFiles.sort().join(", ")}`);
72
+ }
73
+ return { mode, shared: requiredShared.length, legacy: 0 };
74
+ }
@@ -6,9 +6,9 @@ import { ROOT, read, safe, ensure } from './strategic-handoff-io.mjs';
6
6
  export function loadDeliveryProfile(root=ROOT) {
7
7
  const metadata=['backend','frontend'].filter(side=>existsSync(path.join(root,`.yss-harness-${side}.json`)));
8
8
  ensure(metadata.length<=1,'专职 Harness metadata 身份冲突');
9
- const profilePath=path.join(root,'docs/process/harness-profile.yaml');
9
+ const profilePath=path.join(root,'.template-spec/process/harness-profile.yaml');
10
10
  ensure(!metadata.length||existsSync(profilePath),'专职 Harness 缺少 profile,不得绕过执行门禁');
11
- const profile=existsSync(profilePath)?read(safe(root,'docs/process/harness-profile.yaml')):null;
11
+ const profile=existsSync(profilePath)?read(safe(root,'.template-spec/process/harness-profile.yaml')):null;
12
12
  if(metadata.length) {
13
13
  const expected=`harness.${metadata[0]}-delivery`;
14
14
  const record=read(safe(root,`.yss-harness-${metadata[0]}.json`));
@@ -6,9 +6,9 @@ import { parseDocument } from "../vendor/yaml.mjs";
6
6
  import { ROOT, loadRegistry, semanticDigest, validateRegistry } from "./lifecycle-registry.mjs";
7
7
  import { loadSkillRegistry } from "./skill-registry.mjs";
8
8
 
9
- const LIFECYCLE_REGISTRY_REF = "docs/process/lifecycle-registry.yaml";
9
+ const LIFECYCLE_REGISTRY_REF = ".template-spec/process/lifecycle-registry.yaml";
10
10
  const ORCHESTRATION_CONTRACT_REF = ".agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml";
11
- const SKILL_REGISTRY_REF = "docs/agents/yss-skill-registry.yaml";
11
+ const SKILL_REGISTRY_REF = ".template-spec/agents/yss-skill-registry.yaml";
12
12
 
13
13
  function read(relativePath) {
14
14
  return readFileSync(path.join(ROOT, relativePath), "utf8");
@@ -88,6 +88,12 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
88
88
  }
89
89
 
90
90
  const route = workUnitId ? orchestration.work_unit_routes?.[workUnitId] ?? null : null;
91
+ if (workUnit?.scope === "project-instance" && workUnit.id !== "work-unit.entry-triage" && !route) {
92
+ throw new TypeError(`项目工作单元缺少执行路由: ${workUnit.id}`);
93
+ }
94
+ if (workUnit?.scope === "project-instance" && workUnit.id !== "work-unit.entry-triage" && !Object.hasOwn(orchestration.transition_graph?.routes ?? {}, workUnit.id)) {
95
+ throw new TypeError(`项目工作单元缺少流转路由: ${workUnit.id}`);
96
+ }
91
97
  const gates = lifecycle.gates.filter((gate) => gate.stage === stageId || (loadPlan && gate.stage === 'stage.plan'));
92
98
  const checks = lifecycle.checks.filter(check => check.stage === stageId || gates.some(gate => gate.requires_checks?.includes(check.id)));
93
99
  const artifacts = lifecycle.artifacts.filter((artifact) => artifact.stage === stageId || (loadPlan && artifact.stage === 'stage.plan'));
@@ -125,7 +131,9 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
125
131
  },
126
132
  lifecycle: {
127
133
  artifacts,
128
- evidence: lifecycle.evidence.filter((item) => evidenceIds.has(item.id)),
134
+ evidence: lifecycle.evidence.filter((item) => evidenceIds.has(item.id)).map(({ public_description, ...item }) => ({
135
+ ...item, description: public_description ?? item.description
136
+ })),
129
137
  gates,
130
138
  checks,
131
139
  stage,
@@ -6,8 +6,8 @@ import { fileURLToPath } from "node:url";
6
6
  import { parseDocument } from "../vendor/yaml.mjs";
7
7
 
8
8
  export const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
9
- export const DEFAULT_REGISTRY = path.join(ROOT, "docs/process/lifecycle-registry.yaml");
10
- export const DEFAULT_BASELINE = path.join(ROOT, "docs/process/lifecycle-registry-baseline.json");
9
+ export const DEFAULT_REGISTRY = path.join(ROOT, ".template-spec/process/lifecycle-registry.yaml");
10
+ export const DEFAULT_BASELINE = path.join(ROOT, ".template-spec/process/lifecycle-registry-baseline.json");
11
11
  const ID_PATTERN = /^(stage|gate|check|artifact|work-unit|evidence)\.[a-z0-9][a-z0-9-]*$/;
12
12
  const COLLECTIONS = ["stages", "gates", "checks", "artifacts", "work_units", "evidence"];
13
13
 
@@ -63,6 +63,12 @@ export function semanticDigest(registry) {
63
63
  return createHash("sha256").update(JSON.stringify(semanticProjection(registry))).digest("hex");
64
64
  }
65
65
 
66
+ export function semanticHashesById(registry) {
67
+ return Object.fromEntries(semanticProjection(registry).map(({ record }) => [
68
+ record.id, createHash("sha256").update(JSON.stringify(record)).digest("hex")
69
+ ]));
70
+ }
71
+
66
72
  function validateBaseline(registry, ids, baselinePath) {
67
73
  let baseline;
68
74
  try {
@@ -72,7 +78,7 @@ function validateBaseline(registry, ids, baselinePath) {
72
78
  if (error instanceof SyntaxError) fail(`无法解析生命周期已发布基线: ${error.message}`);
73
79
  throw error;
74
80
  }
75
- if (baseline.schema_version !== 1 || baseline.registry_id !== registry.registry_id) {
81
+ if (![1, 2].includes(baseline.schema_version) || baseline.registry_id !== registry.registry_id) {
76
82
  fail("生命周期已发布基线版本或 registry_id 不匹配");
77
83
  }
78
84
  const publishedIds = baseline.published_ids;
@@ -91,7 +97,26 @@ function validateBaseline(registry, ids, baselinePath) {
91
97
  if (JSON.stringify(activeIds) !== JSON.stringify(expected)) {
92
98
  fail("生命周期活跃 ID 与已发布基线不一致;新增、移除或弃用必须先更新发布基线");
93
99
  }
94
- if (baseline.semantic_sha256 !== semanticDigest(registry)) fail("生命周期稳定 ID 的语义快照已变化;不得复用已发布 ID");
100
+ if (baseline.schema_version === 1) {
101
+ if (baseline.semantic_sha256 !== semanticDigest(registry)) fail("生命周期稳定 ID 的语义快照已变化;不得复用已发布 ID");
102
+ return;
103
+ }
104
+ const archivedPath = path.resolve(ROOT, baseline.historical_baseline ?? "");
105
+ if (baseline.historical_baseline !== ".template-spec/process/lifecycle-registry-baseline-v1.json") fail("生命周期历史基线路径无效");
106
+ const archivedBytes = readFileSync(archivedPath);
107
+ if (createHash("sha256").update(archivedBytes).digest("hex") !== baseline.historical_sha256) fail("生命周期历史基线摘要不匹配");
108
+ const archived = JSON.parse(archivedBytes.toString("utf8"));
109
+ if (archived.schema_version !== 1 || archived.registry_id !== registry.registry_id || !archived.published_ids.every((id) => publishedIds.includes(id))) fail("生命周期历史基线与当前发布 ID 不兼容");
110
+ const migrations = baseline.migrations;
111
+ if (!migrations || typeof migrations !== "object" || Array.isArray(migrations)) fail("生命周期迁移映射无效");
112
+ for (const [oldId, newId] of Object.entries(migrations)) {
113
+ if (!archived.published_ids.includes(oldId) || !deprecated.includes(oldId) || !activeIds.includes(newId) || oldId.split(".")[0] !== newId.split(".")[0]) fail(`生命周期迁移映射无效: ${oldId} -> ${newId}`);
114
+ }
115
+ const hashes = semanticHashesById(registry);
116
+ if (!baseline.semantic_sha256_by_id || JSON.stringify(Object.keys(baseline.semantic_sha256_by_id).sort()) !== JSON.stringify(activeIds)) fail("生命周期逐 ID 语义基线与活跃 ID 不一致");
117
+ for (const [id, digest] of Object.entries(hashes)) {
118
+ if (baseline.semantic_sha256_by_id[id] !== digest) fail(`生命周期稳定 ID 的语义快照已变化: ${id}`);
119
+ }
95
120
  }
96
121
 
97
122
  export function validateRegistry(registry, { baseline = DEFAULT_BASELINE } = {}) {
@@ -108,7 +133,7 @@ export function validateRegistry(registry, { baseline = DEFAULT_BASELINE } = {})
108
133
  }
109
134
  if (policy.published_ids_immutable !== true) fail("published_ids_immutable 必须为 true");
110
135
  if (policy.pattern !== "^(stage|gate|check|artifact|work-unit|evidence)\\.[a-z0-9][a-z0-9-]*$") fail("id_policy.pattern 不符合固定命名空间");
111
- if (policy.baseline !== "docs/process/lifecycle-registry-baseline.json") fail("id_policy.baseline 必须指向发布基线");
136
+ if (policy.baseline !== ".template-spec/process/lifecycle-registry-baseline.json") fail("id_policy.baseline 必须指向发布基线");
112
137
  if (!Array.isArray(policy.deprecated_ids)) fail("deprecated_ids 必须是数组");
113
138
  const ids = new Map();
114
139
  for (const collection of COLLECTIONS) {
@@ -159,6 +184,20 @@ export function validateRegistry(registry, { baseline = DEFAULT_BASELINE } = {})
159
184
  for (const artifact of registry.artifacts) {
160
185
  requireReference(ids, artifact.stage, `${artifact.id}.stage`);
161
186
  if (ids.get(artifact.stage) !== "stages") fail(`${artifact.id}.stage 必须引用 stage.*`);
187
+ for (const reference of artifact.trigger.match(/\b(?:stage|gate|check|artifact|work-unit|evidence)\.[a-z0-9][a-z0-9-]*\b/g) ?? []) {
188
+ requireReference(ids, reference, `${artifact.id}.trigger`);
189
+ }
190
+ }
191
+ // Human-readable rules are execution instructions too. A retired control ID
192
+ // must never survive in an active trigger or completion sentence.
193
+ for (const collection of COLLECTIONS) for (const record of registry[collection]) {
194
+ for (const [field, value] of Object.entries(record)) {
195
+ if (field === "id" || typeof value !== "string") continue;
196
+ for (const reference of value.match(/\b(?:gate|check)\.[a-z0-9][a-z0-9-]*\b/g) ?? []) {
197
+ requireReference(ids, reference, `${record.id}.${field}`);
198
+ if (ids.get(reference) !== `${reference.split(".")[0]}s`) fail(`${record.id}.${field} 引用类型不匹配: ${reference}`);
199
+ }
200
+ }
162
201
  }
163
202
  if (baseline) validateBaseline(registry, ids, baseline);
164
203
  return registry;
@@ -168,7 +207,7 @@ export function renderLifecycleStructure(registry) {
168
207
  const display = (record, field) => record[`public_${field}`] ?? record[field];
169
208
  const lines = [
170
209
  "<!-- lifecycle-registry:structure:start -->",
171
- `> 此结构区由 \`docs/process/lifecycle-registry.yaml\` 生成。当前为 \`${registry.status}\` 模式:正式门禁、内部检查和派生文档共同消费此事实源。`, "",
210
+ `> 此结构区由 \`.template-spec/process/lifecycle-registry.yaml\` 生成。当前为 \`${registry.status}\` 模式:正式门禁、内部检查和派生文档共同消费此事实源。`, "",
172
211
  "## 1. 主阶段", "", "| 稳定 ID | 阶段 | 目标 | 退出标准 |", "|---|---|---|---|"
173
212
  ];
174
213
  for (const stage of registry.stages) lines.push(`| \`${stage.id}\` | ${display(stage, "name")} | ${display(stage, "goal")} | ${display(stage, "exit_criteria")} |`);
@@ -186,7 +225,7 @@ export function renderLifecycleStructure(registry) {
186
225
 
187
226
  export function renderWorkUnits(registry) {
188
227
  const display = (record, field) => record[`public_${field}`] ?? record[field];
189
- const lines = ["<!-- lifecycle-registry:work-units:start -->", "> 此表由 `docs/process/lifecycle-registry.yaml` 生成;工作单元按 `scope` 区分模板维护与项目实例流程。", "", "| 稳定 ID | 范围 | 工作单元 | 输入 | 输出 | 完成条件 |", "|---|---|---|---|---|---|"];
228
+ const lines = ["<!-- lifecycle-registry:work-units:start -->", "> 此表由 `.template-spec/process/lifecycle-registry.yaml` 生成;工作单元按 `scope` 区分模板维护与项目实例流程。", "", "| 稳定 ID | 范围 | 工作单元 | 输入 | 输出 | 完成条件 |", "|---|---|---|---|---|---|"];
190
229
  for (const unit of registry.work_units) lines.push(`| \`${unit.id}\` | ${unit.scope} | ${display(unit, "name")} | ${display(unit, "input")} | ${display(unit, "output")} | ${display(unit, "completion")} |`);
191
230
  lines.push("<!-- lifecycle-registry:work-units:end -->");
192
231
  return `${lines.join("\n")}\n`;
@@ -0,0 +1,111 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { parseDocument } from '../vendor/yaml.mjs';
5
+ import { safeTrackingPath, trackingDrift } from './stage-tracking.mjs';
6
+
7
+ const sha = bytes => `sha256:${createHash('sha256').update(bytes).digest('hex')}`;
8
+ function parse(bytes) {
9
+ const document = parseDocument(String(bytes), { uniqueKeys: true, maxAliasCount: 0 });
10
+ if (document.errors.length) throw new TypeError(document.errors[0].message);
11
+ return document.toJS({ maxAliasCount: 0 });
12
+ }
13
+ function source(root, ref) {
14
+ const bytes = readFileSync(safeTrackingPath(root, ref));
15
+ return { value: parse(bytes), digest: sha(bytes) };
16
+ }
17
+
18
+ /** Read-only projection; checkpoint, registry and orchestration remain authoritative. */
19
+ export function lifecycleStatus({ root, checkpointRef }) {
20
+ if (!root || !checkpointRef) throw new TypeError('root and checkpoint are required');
21
+ root = path.resolve(root);
22
+ const identity = source(root, 'yss-project.yaml').value;
23
+ if (identity.schema_version !== 1 || identity.repository_mode !== 'project-instance') throw new TypeError('生命周期状态仅适用于 project-instance');
24
+ const registryRef = '.template-spec/process/lifecycle-registry.yaml';
25
+ const contractRef = '.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml';
26
+ const checkpoint = source(root, checkpointRef), registry = source(root, registryRef), contract = source(root, contractRef);
27
+ const value = checkpoint.value;
28
+ if (value.schema_version !== 1 || value.repository_mode !== 'project-instance') throw new TypeError('checkpoint 身份或版本无效');
29
+ const items = value.stage_tracking?.items ?? [];
30
+ if (!Array.isArray(items)) throw new TypeError('阶段追踪 items 必须为数组');
31
+ const activeItems = items.filter(item => item.work_unit === value.next_work_unit && item.progress !== 'cancelled');
32
+ const owner = value.pause?.owner_or_authority ?? activeItems.find(item => item.progress !== 'completed')?.owner ?? '未登记';
33
+ const diagnostics = [], verification_scope = [];
34
+ const check = (id, status, refs, reason) => verification_scope.push({ id, status, refs, reason });
35
+ const issue = (code, message, source_ref, recovery, severity = 'error') => diagnostics.push({ code, message, source_ref, owner, recovery, severity });
36
+ if (!Object.hasOwn(value, 'blockers')) {
37
+ issue('registered-blockers-missing', 'checkpoint 缺少 blockers;不能据此判定无已登记阻塞', checkpointRef, '核对原始状态并补齐真实阻塞记录后重验');
38
+ } else if (!Array.isArray(value.blockers)) {
39
+ issue('registered-blockers-invalid', 'checkpoint.blockers 必须为数组;当前登记不可核验', checkpointRef, '修复阻塞记录类型,保留原有阻塞内容后重验');
40
+ } else {
41
+ for (const item of value.blockers) {
42
+ issue('registered-blocker', typeof item === 'string' ? item : JSON.stringify(item), checkpointRef, '按原阻塞证据处理并复验');
43
+ }
44
+ }
45
+ check('registered-blockers', diagnostics.length ? 'failed' : 'passed', [checkpointRef], '仅读取已登记阻塞,不代表完整就绪');
46
+ const stage = registry.value.stages?.find(item => item.id === value.stage);
47
+ const workUnit = registry.value.work_units?.find(item => item.id === value.next_work_unit);
48
+ if (!stage) issue('unknown-stage', `未知阶段: ${value.stage}`, registryRef, '按注册表核对当前阶段');
49
+ if (value.next_work_unit && !workUnit) issue('unknown-work-unit', `未知下一工作单元: ${value.next_work_unit}`, registryRef, '按注册表核对下一工作单元');
50
+ if (workUnit && workUnit.id !== 'work-unit.entry-triage' && !contract.value.work_unit_routes?.[workUnit.id]) issue('missing-route', `缺少执行路由: ${workUnit.id}`, contractRef, '修复当前合同路由后重验');
51
+ check('stage-and-route', diagnostics.some(x => ['unknown-stage', 'unknown-work-unit', 'missing-route'].includes(x.code)) ? 'failed' : 'passed', [registryRef, contractRef], '仅检查身份与路由存在,不计算完整 frontier');
52
+ if (value.context_reconciliation?.status === 'blocked') issue('context-blocked', 'Context reconciliation blocked', checkpointRef, '修复词汇对账并执行适用校验');
53
+ check('context-reconciliation', value.context_reconciliation?.status === 'blocked' ? 'failed' : 'not-checked', [value.context_reconciliation?.ref].filter(Boolean), '读取登记状态;当前对账内容和摘要仍须由原验证器核验');
54
+ for (const [id, gate] of Object.entries(value.gates ?? {})) {
55
+ if (['blocked', 'stale'].includes(gate?.status)) issue('gate-blocked', `${id}: ${gate.status}`, checkpointRef, '核对受影响依据和当前批准');
56
+ }
57
+ check('registered-gates', diagnostics.some(x => x.code === 'gate-blocked') ? 'failed' : 'passed', [checkpointRef], '仅检查登记的 blocked/stale 标志');
58
+ const evidenceRefs = [value.context_reconciliation?.ref, ...Object.values(value.artifacts ?? {}).filter(item => item?.status === 'approved').map(item => item.ref)].filter(Boolean);
59
+ for (const ref of evidenceRefs) {
60
+ try { readFileSync(safeTrackingPath(root, ref)); }
61
+ catch { issue('evidence-unreadable', `证据不可读: ${ref}`, ref, '恢复正确来源或重新取得证据,不伪造历史批准'); }
62
+ }
63
+ check('evidence-readable', diagnostics.some(x => x.code === 'evidence-unreadable') ? 'failed' : 'passed', evidenceRefs, '仅检查已引用证据可读,不证明证据完整或当前有效');
64
+ check('artifact-digests', 'not-checked', evidenceRefs, '未核验批准资产原字节摘要;恢复时运行资产所有者的适用预检');
65
+ check('approval-validity', 'not-checked', [checkpointRef], '未核验真实决定、延续、外部审批及完整执行授权');
66
+ if (value.stage_tracking?.items) {
67
+ try {
68
+ const drift = trackingDrift(root, value.stage_tracking);
69
+ for (const id of drift) issue('tracking-drift', `阶段工作项来源漂移: ${id}`, checkpointRef, '按依赖重验受影响项,保留未受影响记录');
70
+ check('stage-tracking', drift.length ? 'failed' : 'passed', [checkpointRef], '只核对已登记工作项来源及完成证据摘要;结构与流转仍须原预检');
71
+ } catch (error) {
72
+ issue('tracking-unverifiable', `阶段追踪不可核验: ${error.message}`, checkpointRef, '修复追踪输入后重新检查');
73
+ check('stage-tracking', 'failed', [checkpointRef], error.message);
74
+ }
75
+ } else {
76
+ check('stage-tracking', 'not-checked', [checkpointRef], '未登记追踪;按实例既有兼容或显式迁移入口处理,不自动补建');
77
+ }
78
+ if (value.status === 'blocked' && !diagnostics.some(x => x.severity === 'error')) issue('reason-missing', 'checkpoint 已标 blocked,原因未登记', checkpointRef, '补齐真实阻塞原因');
79
+ const blockers = [...new Set(diagnostics.filter(x => x.severity === 'error').map(x => x.message))];
80
+ const next_step = {
81
+ action_type: 'verify', work_unit: value.next_work_unit ?? null, cwd: root,
82
+ command: null, input_refs: [checkpointRef],
83
+ prerequisites: ['核验当前来源、Context、适用门禁与决定或延续', '核对当前范围、任务结果和允许写路径;输入变化时重验'],
84
+ };
85
+ let next_action;
86
+ if (blockers.length) {
87
+ next_step.action_type = 'repair';
88
+ next_action = `处理当前阻塞:${blockers[0]}`;
89
+ } else if (value.status === 'paused-human-gate') {
90
+ next_step.action_type = 'wait';
91
+ next_action = '核对当前会签责任方、资产与决定范围;满足已登记恢复条件后复验';
92
+ } else if (activeItems.some(item => item.progress === 'running')) {
93
+ next_step.action_type = 'inspect';
94
+ next_action = '核对运行中任务身份与实际结果;状态未知时不得重复派发';
95
+ } else if (activeItems.length && activeItems.every(item => item.progress === 'completed')) {
96
+ next_step.action_type = 'inspect';
97
+ next_action = '核验已有完成证据并重算下一工作单元,不直接重做';
98
+ } else {
99
+ next_action = value.next_work_unit ? `先核验当前输入及适用门禁,再由主控恢复 ${value.next_work_unit}` : '复核当前阶段验收与下一动作';
100
+ // Commands are argv arrays. They are recommendations, never executed by this view.
101
+ const script = value.next_work_unit === 'work-unit.spec-synthesis' ? 'scripts/verify-plan-spec-entry' : 'scripts/verify-lifecycle-checkpoint';
102
+ try { readFileSync(safeTrackingPath(root, script)); next_step.command = ['node', script, checkpointRef]; }
103
+ catch { issue('precheck-unavailable', `预检入口不可读: ${script}`, script, '补齐当前实例工具后执行预检', 'warning'); }
104
+ }
105
+ return {
106
+ schema_version: 1, read_only: true, stage: value.stage, checkpoint_status: value.status,
107
+ work_unit: value.next_work_unit ?? null, owner, blockers, next_action,
108
+ execution_authorization: 'not-evaluated', verification_scope, diagnostics, next_step,
109
+ source_digests: { checkpoint: { ref: checkpointRef, digest: checkpoint.digest }, registry: { ref: registryRef, digest: registry.digest }, orchestration: { ref: contractRef, digest: contract.digest } },
110
+ };
111
+ }
@@ -12,11 +12,13 @@ import path from "node:path";
12
12
  import { validateApiContractDecision } from "./api-contract-decision.mjs";
13
13
  import { loadApprovalRecord, validateApprovalRecord } from "./approval-record.mjs";
14
14
  import { validateBackendReview } from "./backend-review.mjs";
15
+ import { validateJsonSchema } from "./json-schema.mjs";
15
16
  import { ROOT } from "./lifecycle-registry.mjs";
16
17
 
17
18
  const IMPLEMENTATION_WORK_UNIT = "work-unit.slice-implementation";
18
19
  const TICKET_DECOMPOSITION_WORK_UNIT = "work-unit.ticket-decomposition";
19
20
  const REPOSITORY_PREPARATION_WORK_UNIT = "work-unit.implementation-repository-preparation";
21
+ const SERVICE_INITIALIZATION_WORK_UNIT = "work-unit.service-project-initialization";
20
22
 
21
23
  function deepFreeze(value) {
22
24
  if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
@@ -27,21 +29,22 @@ function deepFreeze(value) {
27
29
 
28
30
  const NEXT_ROUTES = deepFreeze({
29
31
  "work-unit.entry-triage": ["work-unit.plan-opportunity", "work-unit.plan-requirements"],
30
- "work-unit.ssot-update": ["work-unit.skill-projection-sync", "work-unit.intensity-aware-verification"],
31
- "work-unit.skill-projection-sync": ["work-unit.template-snapshot-build", "work-unit.intensity-aware-verification"],
32
- "work-unit.template-snapshot-build": ["work-unit.attach-sync-integration", "work-unit.intensity-aware-verification"],
33
- "work-unit.attach-sync-integration": ["work-unit.intensity-aware-verification"],
34
- "work-unit.intensity-aware-verification": ["work-unit.intensity-aware-review"],
35
- "work-unit.intensity-aware-review": ["work-unit.release-and-rollback"],
32
+ "work-unit.ssot-update": ["work-unit.skill-projection-sync", "work-unit.intensity-aware-verification-v2"],
33
+ "work-unit.skill-projection-sync": ["work-unit.template-snapshot-build", "work-unit.intensity-aware-verification-v2"],
34
+ "work-unit.template-snapshot-build": ["work-unit.attach-sync-integration", "work-unit.intensity-aware-verification-v2"],
35
+ "work-unit.attach-sync-integration": ["work-unit.intensity-aware-verification-v2"],
36
+ "work-unit.intensity-aware-verification-v2": ["work-unit.intensity-aware-review-v2"],
37
+ "work-unit.intensity-aware-review-v2": ["work-unit.release-and-rollback"],
36
38
  "work-unit.release-and-rollback": [],
37
39
  "work-unit.plan-opportunity": ["work-unit.plan-requirements", "work-unit.domain-strategy-design", "work-unit.stage-decision", "work-unit.spec-synthesis"],
38
40
  "work-unit.plan-requirements": ["work-unit.domain-strategy-design", "work-unit.stage-decision", "work-unit.spec-synthesis"],
39
41
  "work-unit.domain-strategy-design": ["work-unit.stage-decision", "work-unit.spec-synthesis"],
40
42
  "work-unit.stage-decision": ["work-unit.spec-synthesis"],
41
- "work-unit.spec-synthesis": ["work-unit.prototype-design", "work-unit.technical-analysis"],
42
- "work-unit.prototype-design": ["work-unit.technical-analysis"],
43
+ "work-unit.spec-synthesis": ["work-unit.prototype-design-v2", "work-unit.technical-analysis"],
44
+ "work-unit.prototype-design-v2": ["work-unit.technical-analysis"],
43
45
  "work-unit.technical-analysis": [REPOSITORY_PREPARATION_WORK_UNIT],
44
- [REPOSITORY_PREPARATION_WORK_UNIT]: [TICKET_DECOMPOSITION_WORK_UNIT],
46
+ [REPOSITORY_PREPARATION_WORK_UNIT]: [SERVICE_INITIALIZATION_WORK_UNIT, TICKET_DECOMPOSITION_WORK_UNIT],
47
+ [SERVICE_INITIALIZATION_WORK_UNIT]: [REPOSITORY_PREPARATION_WORK_UNIT],
45
48
  [TICKET_DECOMPOSITION_WORK_UNIT]: [IMPLEMENTATION_WORK_UNIT],
46
49
  [IMPLEMENTATION_WORK_UNIT]: ["work-unit.frontend-implementation-verification", "work-unit.code-review"],
47
50
  "work-unit.frontend-implementation-verification": ["work-unit.code-review"],
@@ -83,6 +86,8 @@ const BLOCKING_SIGNALS = Object.freeze({
83
86
  backendDesignPrerequisitesMissing: "backend-design-prerequisites-missing",
84
87
  legacyScaffoldReconciliationRequired: "legacy-scaffold-reconciliation-required",
85
88
  prematureImplementationDetected: "premature-implementation-detected",
89
+ serviceInitializationInvalid: "service-project-initialization-invalid",
90
+ serviceInitializationIncomplete: "service-project-initialization-incomplete",
86
91
  });
87
92
 
88
93
  const allowedResult = (evidenceRefs = []) => ({
@@ -121,6 +126,52 @@ function readDecompositionResult(ref, read) {
121
126
  }
122
127
  }
123
128
 
129
+ /** The service branch reuses the approved v4 scaffold contract and its real verification. */
130
+ export function validateServiceProjectInitialization(state, { root = ROOT, exists = existsSync, read = (ref) => readFileSync(ref, "utf8"), completed = false } = {}) {
131
+ const request = state?.service_project_initialization;
132
+ const resolved = ref => path.isAbsolute(ref) ? ref : path.resolve(root, ref);
133
+ const present = ref => hasText(ref) && exists(resolved(ref));
134
+ const contents = ref => read(resolved(ref));
135
+ const document = ref => readDecompositionResult(resolved(ref), contents);
136
+ const blocked = (detail, incomplete = false) => blockedResult(
137
+ [incomplete ? BLOCKING_SIGNALS.serviceInitializationIncomplete : BLOCKING_SIGNALS.serviceInitializationInvalid], [detail]);
138
+ if (!request || !hasText(request.project_id) || !hasText(request.contract_ref) || !hasText(request.contract_digest) || !hasText(request.project_root)) return blocked("project_id, contract_ref, contract_digest and project_root required");
139
+ const contractFile = resolved(request.contract_ref);
140
+ if (!present(contractFile)) return blocked("approved v4 scaffold contract must be readable");
141
+ let contractBytes;
142
+ try { contractBytes = contents(contractFile); } catch { return blocked("approved v4 scaffold contract must be readable"); }
143
+ const contract = document(contractFile);
144
+ if (!contract || request.contract_digest !== `sha256:${createHash("sha256").update(contractBytes).digest("hex")}`) return blocked("current scaffold contract digest mismatch");
145
+ try { validateJsonSchema(contract, path.join(ROOT, ".template-spec/process/schemas/project-scaffold-contract.schema.json")); }
146
+ catch (error) { return blocked(`scaffold contract schema: ${error.message}`); }
147
+ if (contract.schema_version !== 4 || contract.status !== "approved" || contract.current_version !== true || !hasText(contract.persisted_ref) || contract.architecture_profile !== "mvc-data-analysis-v1" || contract.scaffold_kind !== "backend-mvc-data-analysis" || contract.generator_skill !== "yss-layered-mvc-scaffold-generator" || contract.init_git !== true || contract.project_name !== request.project_id || path.resolve(contract.target_output_dir, contract.project_name) !== path.resolve(request.project_root)) return blocked("current approved mvc-data-analysis-v1 initialization contract required");
148
+ const contractRoot = path.dirname(contractFile);
149
+ const contractExists = ref => exists(path.isAbsolute(ref) ? ref : path.resolve(contractRoot, ref));
150
+ if (!backendDesignPrerequisitesReady(contract.design_prerequisites, contractExists, contractRoot, request.project_id)) return blocked("current technical, data, API and engineering approval bindings required");
151
+ const handoff = path.resolve(path.dirname(contractFile), contract.context_handoff_ref ?? "");
152
+ if (!handoff.startsWith(`${path.dirname(contractFile)}${path.sep}`) || !present(handoff)) return blocked("CONTEXT handoff must be inside the contract directory");
153
+ let handoffBytes;
154
+ try { handoffBytes = contents(handoff); } catch { return blocked("CONTEXT handoff must be readable"); }
155
+ const handoffDigest = `sha256:${createHash("sha256").update(handoffBytes).digest("hex")}`;
156
+ if (contract.context_handoff_digest !== handoffDigest || request.context_handoff_digest !== handoffDigest) return blocked("CONTEXT handoff digest mismatch");
157
+ if (!completed) {
158
+ if (present(request.project_root)) return blocked("service project already exists; initialization is not repeatable");
159
+ return allowedResult([request.contract_ref, contract.context_handoff_ref]);
160
+ }
161
+ for (const field of ["manifest_ref", "verification_ref", "result_ref"]) if (!present(request[field])) return blocked(`${field} must be readable`, true);
162
+ const manifest = document(request.manifest_ref);
163
+ const verification = document(request.verification_ref);
164
+ const result = document(request.result_ref);
165
+ if (result?.result_schema !== "workflow-execution-result-v1" || result.work_unit !== SERVICE_INITIALIZATION_WORK_UNIT || result.result !== "completed" || ![request.manifest_ref, request.verification_ref].every(ref => result.evidence_refs?.includes(ref))) return blocked("completed Workflow Execution Result with manifest and verification evidence required", true);
166
+ if (manifest?.schema_version !== 4 || manifest.kind !== "service-project-initialization" || manifest.architecture_profile !== "mvc-data-analysis-v1" || manifest.project_name !== request.project_id || manifest.contract_digest !== request.contract_digest || manifest.completion_level !== "empty-scaffold-verified") return blocked("current v4 service Manifest required", true);
167
+ const phases = ["validate", "test", "package"];
168
+ if (verification?.status !== "passed" || verification.completion_level !== "empty-scaffold-verified" || path.resolve(verification.project_root ?? "") !== path.resolve(request.project_root) || !Array.isArray(verification.commands) || phases.some(phase => !verification.commands.some(item => item.phase === phase && item.exit_code === 0 && item.command?.startsWith(`./mvnw ${phase}`) && present(item.stdout_ref) && present(item.stderr_ref)))) return blocked("real Maven Wrapper validate/test/package evidence required", true);
169
+ const childContext = path.join(request.project_root, "CONTEXT.md");
170
+ const initialization = document(path.join(request.project_root, ".template-spec/process/service-initialization.json"));
171
+ if (!present(childContext) || !present(path.join(request.project_root, ".git")) || !present(path.join(path.dirname(request.project_root), "skillUtils/skills-lock.json")) || contents(childContext) !== handoffBytes || initialization?.contract_id !== contract.contract_id || initialization.context_handoff_digest !== handoffDigest) return blocked("child project identity, CONTEXT and skillUtils must match the contract", true);
172
+ return allowedResult([request.result_ref, request.manifest_ref, request.verification_ref]);
173
+ }
174
+
124
175
  function artifactBindingReady(binding, exists) {
125
176
  return hasText(binding?.ref) && /^v[1-9][0-9]*$/.test(binding?.version ?? "") && /^sha256:[a-f0-9]{64}$/.test(binding?.digest ?? "") && isReadable(binding.ref, exists);
126
177
  }
@@ -271,7 +322,7 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
271
322
  }
272
323
  const routes = NEXT_ROUTES[currentWorkUnit] && scopedNextRoutes(currentWorkUnit, NEXT_ROUTES[currentWorkUnit], options);
273
324
  if (!routes) return blockedResult([BLOCKING_SIGNALS.invalidRoute], ["known_current_work_unit"]);
274
- if (nextRoute === REPOSITORY_PREPARATION_WORK_UNIT && currentWorkUnit !== "work-unit.technical-analysis") {
325
+ if (nextRoute === REPOSITORY_PREPARATION_WORK_UNIT && !["work-unit.technical-analysis", SERVICE_INITIALIZATION_WORK_UNIT].includes(currentWorkUnit)) {
275
326
  return blockedResult([BLOCKING_SIGNALS.technicalAnalysisRequired], ["work-unit.technical-analysis predecessor"]);
276
327
  }
277
328
  if (nextRoute === null && routes.length === 0) {
@@ -285,6 +336,12 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
285
336
  }
286
337
  return blockedResult(signals, ["allowed_next_route"]);
287
338
  }
339
+ if (nextRoute === SERVICE_INITIALIZATION_WORK_UNIT) {
340
+ return validateServiceProjectInitialization(decisionState, { ...options, completed: false });
341
+ }
342
+ if (currentWorkUnit === SERVICE_INITIALIZATION_WORK_UNIT && nextRoute === REPOSITORY_PREPARATION_WORK_UNIT) {
343
+ return validateServiceProjectInitialization(decisionState, { ...options, completed: true });
344
+ }
288
345
  if (nextRoute === REPOSITORY_PREPARATION_WORK_UNIT) {
289
346
  const analysis = validateTechnicalAnalysisCompletion(decisionState, options);
290
347
  if (analysis.result === "blocked") return analysis;
@@ -294,6 +351,10 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
294
351
  if (entry.result === 'blocked' || nextRoute === 'work-unit.spec-synthesis') return entry;
295
352
  }
296
353
  if (nextRoute === TICKET_DECOMPOSITION_WORK_UNIT) {
354
+ if (decisionState?.service_project_initialization) {
355
+ const service = validateServiceProjectInitialization(decisionState, { ...options, completed: true });
356
+ if (service.result === "blocked") return service;
357
+ }
297
358
  const readiness = validateImplementationRepositoriesReady(decisionState, options);
298
359
  if (readiness.result === "blocked") return readiness;
299
360
  }