create-yss-spec 3.1.3 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/README.md +5 -1
  2. package/package.json +1 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  4. package/template/.agents/skills/code-review/SKILL.md +4 -0
  5. package/template/.agents/skills/code-review/agents/openai.yaml +1 -1
  6. package/template/.agents/skills/code-review/references/yss-review-standards.md +9 -2
  7. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  8. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  9. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  10. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  11. package/template/.agents/skills/yss-domain/SKILL.md +3 -3
  12. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  13. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  14. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  15. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  16. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  17. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  18. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  19. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  20. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  21. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  22. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  23. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  24. package/template/.agents/skills/yss-mvc-design/SKILL.md +16 -0
  25. package/template/.agents/skills/yss-mvc-design/agents/openai.yaml +4 -0
  26. package/template/.agents/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  27. package/template/.agents/skills/yss-mybatis/SKILL.md +34 -58
  28. package/template/.agents/skills/yss-mybatis/agents/openai.yaml +2 -2
  29. package/template/.agents/skills/yss-mybatis/references/source-index.md +88 -68
  30. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +48 -43
  31. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  32. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  33. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  34. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +6 -3
  35. package/template/.agents/skills/yss-repository/SKILL.md +28 -70
  36. package/template/.agents/skills/yss-repository/agents/openai.yaml +2 -2
  37. package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  38. package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  39. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  40. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  41. package/template/.agents/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  42. package/template/.agents/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  43. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  44. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  45. package/template/.agents/skills/yss-tactical-design/SKILL.md +2 -2
  46. package/template/.agents/skills/yss-tactical-design/references/output-template.md +2 -0
  47. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  48. package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  49. package/template/.agents/skills/yss-technical-design/SKILL.md +31 -0
  50. package/template/.agents/skills/yss-technical-design/agents/openai.yaml +4 -0
  51. package/template/.agents/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  52. package/template/.agents/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  53. package/template/.agents/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  54. package/template/.agents/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  55. package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  56. package/template/.agents/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  57. package/template/.agents/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  58. package/template/.claude/skills/code-review/SKILL.md +4 -0
  59. package/template/.claude/skills/code-review/agents/openai.yaml +1 -1
  60. package/template/.claude/skills/code-review/references/yss-review-standards.md +9 -2
  61. package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  62. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  63. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  64. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  65. package/template/.claude/skills/yss-domain/SKILL.md +3 -3
  66. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  67. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  68. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  69. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  70. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  71. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  72. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  73. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  74. package/template/.claude/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  75. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  76. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  77. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  78. package/template/.claude/skills/yss-mvc-design/SKILL.md +16 -0
  79. package/template/.claude/skills/yss-mvc-design/agents/openai.yaml +4 -0
  80. package/template/.claude/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  81. package/template/.claude/skills/yss-mybatis/SKILL.md +34 -58
  82. package/template/.claude/skills/yss-mybatis/agents/openai.yaml +2 -2
  83. package/template/.claude/skills/yss-mybatis/references/source-index.md +88 -68
  84. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +48 -43
  85. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  86. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  87. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  88. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +6 -3
  89. package/template/.claude/skills/yss-repository/SKILL.md +28 -70
  90. package/template/.claude/skills/yss-repository/agents/openai.yaml +2 -2
  91. package/template/.claude/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  92. package/template/.claude/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  93. package/template/.claude/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  94. package/template/.claude/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  95. package/template/.claude/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  96. package/template/.claude/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  97. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  98. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  99. package/template/.claude/skills/yss-tactical-design/SKILL.md +2 -2
  100. package/template/.claude/skills/yss-tactical-design/references/output-template.md +2 -0
  101. package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  102. package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  103. package/template/.claude/skills/yss-technical-design/SKILL.md +31 -0
  104. package/template/.claude/skills/yss-technical-design/agents/openai.yaml +4 -0
  105. package/template/.claude/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  106. package/template/.claude/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  107. package/template/.claude/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  108. package/template/.claude/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  109. package/template/.claude/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  110. package/template/.claude/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  111. package/template/.claude/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  112. package/template/.codex/skills/code-review/SKILL.md +4 -0
  113. package/template/.codex/skills/code-review/agents/openai.yaml +1 -1
  114. package/template/.codex/skills/code-review/references/yss-review-standards.md +9 -2
  115. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  116. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  117. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  118. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  119. package/template/.codex/skills/yss-domain/SKILL.md +3 -3
  120. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  121. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  122. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  123. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  124. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  125. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  126. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  127. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  128. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  129. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  130. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  131. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  132. package/template/.codex/skills/yss-mvc-design/SKILL.md +16 -0
  133. package/template/.codex/skills/yss-mvc-design/agents/openai.yaml +4 -0
  134. package/template/.codex/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  135. package/template/.codex/skills/yss-mybatis/SKILL.md +34 -58
  136. package/template/.codex/skills/yss-mybatis/agents/openai.yaml +2 -2
  137. package/template/.codex/skills/yss-mybatis/references/source-index.md +88 -68
  138. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +48 -43
  139. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  140. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  141. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  142. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +6 -3
  143. package/template/.codex/skills/yss-repository/SKILL.md +28 -70
  144. package/template/.codex/skills/yss-repository/agents/openai.yaml +2 -2
  145. package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  146. package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  147. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  148. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  149. package/template/.codex/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  150. package/template/.codex/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  151. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  152. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  153. package/template/.codex/skills/yss-tactical-design/SKILL.md +2 -2
  154. package/template/.codex/skills/yss-tactical-design/references/output-template.md +2 -0
  155. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  156. package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  157. package/template/.codex/skills/yss-technical-design/SKILL.md +31 -0
  158. package/template/.codex/skills/yss-technical-design/agents/openai.yaml +4 -0
  159. package/template/.codex/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  160. package/template/.codex/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  161. package/template/.codex/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  162. package/template/.codex/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  163. package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  164. package/template/.codex/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  165. package/template/.codex/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  166. package/template/.cursor/skills/code-review/SKILL.md +4 -0
  167. package/template/.cursor/skills/code-review/agents/openai.yaml +1 -1
  168. package/template/.cursor/skills/code-review/references/yss-review-standards.md +9 -2
  169. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  170. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  171. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  172. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  173. package/template/.cursor/skills/yss-domain/SKILL.md +3 -3
  174. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  175. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  176. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  177. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  178. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  179. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  180. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  181. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  182. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  183. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  184. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  185. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  186. package/template/.cursor/skills/yss-mvc-design/SKILL.md +16 -0
  187. package/template/.cursor/skills/yss-mvc-design/agents/openai.yaml +4 -0
  188. package/template/.cursor/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  189. package/template/.cursor/skills/yss-mybatis/SKILL.md +34 -58
  190. package/template/.cursor/skills/yss-mybatis/agents/openai.yaml +2 -2
  191. package/template/.cursor/skills/yss-mybatis/references/source-index.md +88 -68
  192. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +48 -43
  193. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  194. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  195. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  196. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +6 -3
  197. package/template/.cursor/skills/yss-repository/SKILL.md +28 -70
  198. package/template/.cursor/skills/yss-repository/agents/openai.yaml +2 -2
  199. package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  200. package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  201. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  202. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  203. package/template/.cursor/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  204. package/template/.cursor/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  205. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  206. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  207. package/template/.cursor/skills/yss-tactical-design/SKILL.md +2 -2
  208. package/template/.cursor/skills/yss-tactical-design/references/output-template.md +2 -0
  209. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  210. package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  211. package/template/.cursor/skills/yss-technical-design/SKILL.md +31 -0
  212. package/template/.cursor/skills/yss-technical-design/agents/openai.yaml +4 -0
  213. package/template/.cursor/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  214. package/template/.cursor/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  215. package/template/.cursor/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  216. package/template/.cursor/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  217. package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  218. package/template/.cursor/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  219. package/template/.cursor/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  220. package/template/.pi/skills/code-review/SKILL.md +4 -0
  221. package/template/.pi/skills/code-review/agents/openai.yaml +1 -1
  222. package/template/.pi/skills/code-review/references/yss-review-standards.md +9 -2
  223. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  224. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  225. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  226. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  227. package/template/.pi/skills/yss-domain/SKILL.md +3 -3
  228. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  229. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  230. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  231. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  232. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  233. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  234. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  235. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  236. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  237. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  238. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  239. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  240. package/template/.pi/skills/yss-mvc-design/SKILL.md +16 -0
  241. package/template/.pi/skills/yss-mvc-design/agents/openai.yaml +4 -0
  242. package/template/.pi/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  243. package/template/.pi/skills/yss-mybatis/SKILL.md +34 -58
  244. package/template/.pi/skills/yss-mybatis/agents/openai.yaml +2 -2
  245. package/template/.pi/skills/yss-mybatis/references/source-index.md +88 -68
  246. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +48 -43
  247. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  248. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  249. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  250. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +6 -3
  251. package/template/.pi/skills/yss-repository/SKILL.md +28 -70
  252. package/template/.pi/skills/yss-repository/agents/openai.yaml +2 -2
  253. package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  254. package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  255. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  256. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  257. package/template/.pi/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  258. package/template/.pi/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  259. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  260. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  261. package/template/.pi/skills/yss-tactical-design/SKILL.md +2 -2
  262. package/template/.pi/skills/yss-tactical-design/references/output-template.md +2 -0
  263. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  264. package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  265. package/template/.pi/skills/yss-technical-design/SKILL.md +31 -0
  266. package/template/.pi/skills/yss-technical-design/agents/openai.yaml +4 -0
  267. package/template/.pi/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  268. package/template/.pi/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  269. package/template/.pi/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  270. package/template/.pi/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  271. package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  272. package/template/.pi/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  273. package/template/.pi/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  274. package/template/.qoder/skills/code-review/SKILL.md +4 -0
  275. package/template/.qoder/skills/code-review/agents/openai.yaml +1 -1
  276. package/template/.qoder/skills/code-review/references/yss-review-standards.md +9 -2
  277. package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  278. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  279. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  280. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  281. package/template/.qoder/skills/yss-domain/SKILL.md +3 -3
  282. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  283. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  284. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  285. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  286. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  287. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  288. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  289. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  290. package/template/.qoder/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  291. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  292. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  293. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  294. package/template/.qoder/skills/yss-mvc-design/SKILL.md +16 -0
  295. package/template/.qoder/skills/yss-mvc-design/agents/openai.yaml +4 -0
  296. package/template/.qoder/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  297. package/template/.qoder/skills/yss-mybatis/SKILL.md +34 -58
  298. package/template/.qoder/skills/yss-mybatis/agents/openai.yaml +2 -2
  299. package/template/.qoder/skills/yss-mybatis/references/source-index.md +88 -68
  300. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +48 -43
  301. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  302. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  303. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  304. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +6 -3
  305. package/template/.qoder/skills/yss-repository/SKILL.md +28 -70
  306. package/template/.qoder/skills/yss-repository/agents/openai.yaml +2 -2
  307. package/template/.qoder/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  308. package/template/.qoder/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  309. package/template/.qoder/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  310. package/template/.qoder/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  311. package/template/.qoder/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  312. package/template/.qoder/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  313. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  314. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  315. package/template/.qoder/skills/yss-tactical-design/SKILL.md +2 -2
  316. package/template/.qoder/skills/yss-tactical-design/references/output-template.md +2 -0
  317. package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  318. package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  319. package/template/.qoder/skills/yss-technical-design/SKILL.md +31 -0
  320. package/template/.qoder/skills/yss-technical-design/agents/openai.yaml +4 -0
  321. package/template/.qoder/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  322. package/template/.qoder/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  323. package/template/.qoder/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  324. package/template/.qoder/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  325. package/template/.qoder/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  326. package/template/.qoder/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  327. package/template/.qoder/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  328. package/template/.trae/skills/code-review/SKILL.md +4 -0
  329. package/template/.trae/skills/code-review/agents/openai.yaml +1 -1
  330. package/template/.trae/skills/code-review/references/yss-review-standards.md +9 -2
  331. package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  332. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  333. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +1 -1
  334. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  335. package/template/.trae/skills/yss-domain/SKILL.md +3 -3
  336. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  337. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  338. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +107 -0
  339. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
  340. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -0
  341. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +3 -3
  342. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +9 -0
  343. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +35 -2
  344. package/template/.trae/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  345. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  346. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  347. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  348. package/template/.trae/skills/yss-mvc-design/SKILL.md +16 -0
  349. package/template/.trae/skills/yss-mvc-design/agents/openai.yaml +4 -0
  350. package/template/.trae/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  351. package/template/.trae/skills/yss-mybatis/SKILL.md +34 -58
  352. package/template/.trae/skills/yss-mybatis/agents/openai.yaml +2 -2
  353. package/template/.trae/skills/yss-mybatis/references/source-index.md +88 -68
  354. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +48 -43
  355. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  356. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +81 -19
  357. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +6 -2
  358. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +6 -3
  359. package/template/.trae/skills/yss-repository/SKILL.md +28 -70
  360. package/template/.trae/skills/yss-repository/agents/openai.yaml +2 -2
  361. package/template/.trae/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  362. package/template/.trae/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  363. package/template/.trae/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  364. package/template/.trae/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  365. package/template/.trae/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  366. package/template/.trae/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  367. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  368. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  369. package/template/.trae/skills/yss-tactical-design/SKILL.md +2 -2
  370. package/template/.trae/skills/yss-tactical-design/references/output-template.md +2 -0
  371. package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  372. package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  373. package/template/.trae/skills/yss-technical-design/SKILL.md +31 -0
  374. package/template/.trae/skills/yss-technical-design/agents/openai.yaml +4 -0
  375. package/template/.trae/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  376. package/template/.trae/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  377. package/template/.trae/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  378. package/template/.trae/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  379. package/template/.trae/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  380. package/template/.trae/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  381. package/template/.trae/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  382. package/template/CONTEXT.md +2 -1
  383. package/template/docs/agents/digital-human-roles.yaml +4 -2
  384. package/template/docs/agents/yss-skill-registry.yaml +25 -1
  385. package/template/docs/architecture/templates/architecture-review-checklist.md +1 -1
  386. package/template/docs/architecture/templates/system-overview-design-template.md +15 -4
  387. package/template/docs/process/lifecycle-artifact-map.md +6 -0
  388. package/template/docs/process/lifecycle-registry-baseline.json +8 -1
  389. package/template/docs/process/lifecycle-registry.yaml +32 -2
  390. package/template/docs/process/schemas/implementation-repository-preparation-result.schema.json +38 -0
  391. package/template/docs/process/schemas/project-scaffold-contract.schema.json +113 -0
  392. package/template/docs/process/schemas/strategic-design-handoff.schema.json +77 -4
  393. package/template/docs/process/strategic-handoff-package.md +4 -2
  394. package/template/docs/process/template-verification-profiles.yaml +37 -0
  395. package/template/docs/templates/implementation-repo-registry-template.md +8 -0
  396. package/template/docs/templates/review-report-template.md +7 -3
  397. package/template/docs/user-guide//346/210/230/346/234/257/350/256/276/350/256/241/345/255/220/351/241/271/347/233/256/347/224/250/346/210/267/346/211/213/345/206/214.md +7 -6
  398. package/template/scripts/fixtures/strategic-handoff/fixture.mjs +3 -2
  399. package/template/scripts/lib/implementation-contract-compiler.mjs +8 -1
  400. package/template/scripts/lib/lifecycle-context-query.mjs +137 -0
  401. package/template/scripts/lib/lifecycle-transition.mjs +109 -3
  402. package/template/scripts/lib/scenario-checks.mjs +29 -26
  403. package/template/scripts/lib/skill-registry.mjs +9 -0
  404. package/template/scripts/lib/strategic-handoff-consumption.mjs +4 -4
  405. package/template/scripts/lib/strategic-handoff-design-targets.mjs +15 -0
  406. package/template/scripts/lib/technical-design-boundary.mjs +23 -0
  407. package/template/scripts/query-lifecycle-context +25 -0
  408. package/template/scripts/sync-strategic-handoff-tools +3 -2
  409. package/template/scripts/verify-business-language-scenarios +0 -7
  410. package/template/scripts/verify-frontend-scaffold-generator-scenarios +2 -0
  411. package/template/scripts/verify-lifecycle-context-query-scenarios +68 -0
  412. package/template/scripts/verify-lifecycle-transition-scenarios +44 -4
  413. package/template/scripts/verify-strategic-handoff-package-scenarios +7 -1
  414. package/template/skills-lock.json +48 -18
  415. package/template.snapshot.json +4 -4
  416. package/template/.agents/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  417. package/template/.agents/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  418. package/template/.agents/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  419. package/template/.agents/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  420. package/template/.agents/skills/yss-mybatis/references/README.md +0 -57
  421. package/template/.agents/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  422. package/template/.claude/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  423. package/template/.claude/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  424. package/template/.claude/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  425. package/template/.claude/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  426. package/template/.claude/skills/yss-mybatis/references/README.md +0 -57
  427. package/template/.claude/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  428. package/template/.codex/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  429. package/template/.codex/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  430. package/template/.codex/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  431. package/template/.codex/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  432. package/template/.codex/skills/yss-mybatis/references/README.md +0 -57
  433. package/template/.codex/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  434. package/template/.cursor/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  435. package/template/.cursor/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  436. package/template/.cursor/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  437. package/template/.cursor/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  438. package/template/.cursor/skills/yss-mybatis/references/README.md +0 -57
  439. package/template/.cursor/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  440. package/template/.pi/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  441. package/template/.pi/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  442. package/template/.pi/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  443. package/template/.pi/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  444. package/template/.pi/skills/yss-mybatis/references/README.md +0 -57
  445. package/template/.pi/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  446. package/template/.qoder/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  447. package/template/.qoder/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  448. package/template/.qoder/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  449. package/template/.qoder/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  450. package/template/.qoder/skills/yss-mybatis/references/README.md +0 -57
  451. package/template/.qoder/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  452. package/template/.trae/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  453. package/template/.trae/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  454. package/template/.trae/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  455. package/template/.trae/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  456. package/template/.trae/skills/yss-mybatis/references/README.md +0 -57
  457. package/template/.trae/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ const load = ref => JSON.parse(readFileSync(new URL(ref, import.meta.url), 'utf8'));
5
+ const schema = load('../references/technical-design-common.schema.json');
6
+ const branches = [
7
+ ['domain-driven', '../../yss-tactical-design/references/tactical-design.schema.json'],
8
+ ['layered-mvc', '../../yss-mvc-design/references/mvc-design.schema.json']
9
+ ];
10
+ schema.$comment = 'Generated by scripts/generate-schema.mjs from common and specialist schemas. Do not hand-edit.';
11
+ schema.allOf = branches.map(([family, ref]) => {
12
+ const branch = load(ref); delete branch.$id; delete branch.$schema;
13
+ return { if: { properties: { architecture: { properties: { family: { const: family } } } } }, then: { properties: { design: branch } } };
14
+ });
15
+ const output = fileURLToPath(new URL('../references/technical-design.schema.json', import.meta.url));
16
+ const bytes = `${JSON.stringify(schema, null, 2)}\n`;
17
+ if (process.argv.includes('--check')) {
18
+ if (readFileSync(output, 'utf8') !== bytes) throw new Error('技术设计 Schema 投影漂移,请运行 generate-schema.mjs');
19
+ } else writeFileSync(output, bytes);
20
+ process.stdout.write('技术设计分支 Schema 已同步\n');
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
+ import { parseArgs } from 'node:util';
6
+ import { assertScaffoldUserDecision } from '../../../../scripts/lib/user-decision.mjs';
7
+ import { validateJsonSchema } from '../../../../scripts/lib/json-schema.mjs';
8
+ import { read, safe, hash, digest, ensure } from '../../../../scripts/lib/strategic-handoff-io.mjs';
9
+ import { validate as validateDdd } from '../../yss-tactical-design/scripts/validate-tactical-design.mjs';
10
+ import { designTargets } from '../../../../scripts/lib/strategic-handoff-design-targets.mjs';
11
+ import { verifyConsumption } from '../../../../scripts/lib/strategic-handoff-consumption.mjs';
12
+
13
+ const schema = fileURLToPath(new URL('../references/technical-design.schema.json', import.meta.url));
14
+ const text = x => typeof x === 'string' && x.trim().length > 0;
15
+ const nonempty = xs => Array.isArray(xs) && xs.length > 0 && xs.every(text);
16
+ export const technicalDigest = data => digest(Object.fromEntries(Object.entries(data).filter(([key]) => key !== 'digest')));
17
+
18
+
19
+ function validateMvc(design) {
20
+ const modules = new Map(design.module_catalog.map(item => [item.module_id, item]));
21
+ const cases = new Map(design.use_case_catalog.map(item => [item.use_case_id, item]));
22
+ const rules = new Set(design.rule_catalog.map(item => item.rule_id));
23
+ const permitted = {
24
+ server: ['service','core','client'], service: ['repository','adapter'], core: ['repository','adapter'],
25
+ repository: [], adapter: ['client','feign-client'], client: [], 'feign-client': ['client']
26
+ };
27
+ for (const module of modules.values()) for (const ref of module.depends_on) {
28
+ ensure(modules.has(ref) && permitted[module.layer].includes(modules.get(ref).layer), `模块依赖越界: ${module.module_id} -> ${ref}`);
29
+ }
30
+ for (const item of cases.values()) {
31
+ ensure(['service','core'].includes(modules.get(item.module_ref)?.layer), `用例必须属于 service/core: ${item.use_case_id}`);
32
+ ensure(item.rule_refs.every(ref => rules.has(ref)), `用例引用未声明规则: ${item.use_case_id}`);
33
+ }
34
+ for (const rule of design.rule_catalog) ensure(rule.use_case_refs.every(ref => cases.has(ref) && cases.get(ref).rule_refs.includes(rule.rule_id)), `规则与用例未双向关联: ${rule.rule_id}`);
35
+ for (const item of design.state_transition_catalog) ensure(cases.has(item.use_case_ref), '状态转换引用未声明用例');
36
+ if (!design.state_transition_catalog.length) ensure(text(design.state_not_applicable_reason), '无状态转换必须说明原因');
37
+ for (const item of design.persistence_mapping) ensure(cases.has(item.use_case_ref) && modules.get(item.repository_ref)?.layer === 'repository', '持久化映射的用例或 Repository 引用无效');
38
+ for (const item of design.integration_catalog) ensure(modules.get(item.adapter_ref)?.layer === 'adapter', '外部集成必须关联 Adapter');
39
+ if (!design.integration_catalog.length) ensure(text(design.integration_not_applicable_reason), '无外部集成必须说明原因');
40
+ }
41
+
42
+ export function verifyArchitecture(data, root) {
43
+ const binding = data.architecture;
44
+ const file = safe(root, binding.decision_ref);
45
+ ensure(hash(readFileSync(file)) === binding.decision_digest, '架构来源摘要漂移');
46
+ const record = read(file);
47
+ if (binding.source_kind === 'scaffold-decision') {
48
+ const decision = record.decisions?.find(item => item.project_id === binding.project_id);
49
+ ensure(record.status === 'current' && record.template === false, '架构选择记录必须为当前正式记录');
50
+ ensure(decision && ['user-confirmed','lifecycle-approved','consumed'].includes(decision.status), '分支设计前必须确认项目架构');
51
+ ensure(decision.confirmed_architecture === binding.family, '技术设计与确认架构不匹配');
52
+ ensure(text(decision.user_confirmation?.confirmation_ref) && text(decision.user_confirmation?.confirmed_by), '缺少真实架构确认引用');
53
+ assertScaffoldUserDecision(decision, { root });
54
+ } else {
55
+ // Registration formats differ by repository; bind the actual registered identity,
56
+ // never infer architecture from a directory or a design's self-declaration.
57
+ const entry = record.repositories?.find(item => item.project_id === binding.project_id) ?? record;
58
+ ensure(entry.project_id === binding.project_id && entry.architecture_identity?.architecture_family === binding.family, '技术设计与既有工程登记架构不匹配');
59
+ ensure(!['stale','blocked'].includes(record.status) && !['stale','blocked'].includes(entry.status), '工程登记已失效');
60
+ }
61
+ }
62
+
63
+ function validateLocalTraceability(data, root, sliceRef) {
64
+ const { ids, seams } = designTargets(data);
65
+ const sources = new Map(data.source_items.map(item => [item.source_id, item]));
66
+ ensure(sources.size === data.source_items.length, '源规则或场景 ID 重复');
67
+ const rows = new Map(data.traceability.map(item => [item.source_id, item]));
68
+ ensure(rows.size === data.traceability.length, '承接记录重复');
69
+ ensure(data.strategic_handoff || sources.size > 0, '无战略包时必须列出需求规则与场景');
70
+ for (const source of sources.values()) ensure(data.inputs.some(item => item.ref === source.source_ref), '源规则或场景未绑定当前输入');
71
+ for (const id of rows.keys()) ensure(sources.has(id), `未知承接来源: ${id}`);
72
+ for (const [id, source] of sources) {
73
+ const row = rows.get(id);
74
+ ensure(row, `缺少规则或场景承接: ${id}`);
75
+ if (row.disposition === 'implemented') {
76
+ ensure(nonempty(row.tactical_refs) && row.tactical_refs.every(ref => ids.has(ref)), `设计落点悬空: ${id}`);
77
+ ensure(nonempty(row.test_seam_refs) && row.test_seam_refs.every(ref => seams.has(ref) && row.tactical_refs.includes(seams.get(ref).subject_ref)), `测试 seam 未关联设计落点: ${id}`);
78
+ if (source.kind === 'scenario' && source.critical) ensure(['success','failure'].every(outcome => row.scenario_tests?.some(test => test.outcome === outcome && row.test_seam_refs.includes(test.seam_ref))), `关键场景缺少成功/失败测试: ${id}`);
79
+ ensure(nonempty(row.evidence_refs), `缺少承接证据: ${id}`);
80
+ } else if (row.disposition === 'not-applicable') {
81
+ ensure(text(row.reason) && nonempty(row.evidence_refs), `不适用缺少依据: ${id}`);
82
+ } else {
83
+ if (row.disposition === 'deferred') for (const key of ['reason','risk','owner','followup_ticket_ref','verification_plan','target_version']) ensure(text(row[key]), `延期缺少 ${key}: ${id}`);
84
+ ensure(sliceRef && row.dependency_status === 'known' && nonempty(row.dependent_slice_refs) && !row.dependent_slice_refs.includes(sliceRef), `未闭合承接阻断当前范围: ${id}`);
85
+ }
86
+ for (const ref of row.evidence_refs || []) safe(root, ref);
87
+ }
88
+ }
89
+
90
+ export async function validateTechnicalDesign(data, { root = process.cwd(), sliceRef, legacyDdd = false } = {}) {
91
+ if (data?.schema_version === 1) {
92
+ ensure(legacyDdd, '旧 v1 合同需要显式 --legacy-ddd,仅按 DDD 兼容读取');
93
+ const errors = validateDdd(data);
94
+ ensure(!errors.length, errors.join('; '));
95
+ if (sliceRef) ensure(data.status === 'approved', '切片只能消费 approved 设计');
96
+ if (data.strategic_handoff || data.strategic_context_import_ref || data.upstream_impact?.source_kind === 'strategic-handoff') {
97
+ const result = await verifyConsumption(data, { root, sliceRef });
98
+ ensure(result.result === 'verified', JSON.stringify(result));
99
+ }
100
+ return { result: 'legacy-ddd-read-only', architecture_family: 'domain-driven', status: data.status };
101
+ }
102
+ validateJsonSchema(data, schema, { label: '技术设计合同' });
103
+ ensure(data.digest === technicalDigest(data), '技术设计合同摘要不匹配');
104
+ ensure(!['stale','blocked','drift','new_impacts'].includes(data.status), '设计状态不可消费');
105
+ if (sliceRef) ensure(data.status === 'approved', '切片只能消费 approved 设计');
106
+ verifyArchitecture(data, root);
107
+ ensure(data.inputs.some(item => item.kind === 'context' && item.ref === 'CONTEXT.md') && data.inputs.some(item => item.kind === 'spec'), '共同输入缺少根 CONTEXT.md 或 Spec');
108
+ for (const input of data.inputs) ensure(hash(readFileSync(safe(root, input.ref))) === input.digest, `输入摘要漂移: ${input.ref}`);
109
+ for (const ref of data.evidence_refs) safe(root, ref);
110
+ if (data.status === 'approved') ensure(data.evidence_refs.length > 0, '已批准设计缺少评审证据');
111
+ if (data.architecture.family === 'domain-driven') {
112
+ const errors = validateDdd(data.design);
113
+ ensure(!errors.length, errors.join('; '));
114
+ ensure(data.design.status === data.status, 'DDD 分支状态与共同合同不一致');
115
+ ensure(data.inputs.some(item => item.kind === 'strategic'), 'DDD 分支缺少战略领域输入');
116
+ ensure(!data.design.strategic_handoff && !data.design.strategic_context_import_ref, '战略绑定只允许在共同合同中维护');
117
+ } else validateMvc(data.design);
118
+ const { ids, seams } = designTargets(data);
119
+ for (const seam of seams.values()) ensure(ids.has(seam.subject_ref), `测试 seam 设计对象悬空: ${seam.seam_id}`);
120
+ validateLocalTraceability(data, root, sliceRef);
121
+ if (data.strategic_handoff) {
122
+ const result = await verifyConsumption(data, { root, sliceRef });
123
+ ensure(result.result === 'verified', JSON.stringify(result));
124
+ }
125
+ return { result: 'ready-for-lifecycle-review', technical_design_id: data.technical_design_id, architecture_family: data.architecture.family, status: data.status, digest: data.digest };
126
+ }
127
+
128
+ async function main() {
129
+ const { values, positionals } = parseArgs({ allowPositionals: true, options: { root: { type: 'string', default: process.cwd() }, slice: { type: 'string' }, 'legacy-ddd': { type: 'boolean', default: false } } });
130
+ ensure(positionals.length === 1, '用法: validate-technical-design.mjs <合同> --root <项目根> [--slice <ID>] [--legacy-ddd]');
131
+ const result = await validateTechnicalDesign(read(path.resolve(positionals[0])), { root: values.root, sliceRef: values.slice, legacyDdd: values['legacy-ddd'] });
132
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
133
+ }
134
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main().catch(error => { process.stderr.write(`${JSON.stringify({ result: 'blocked', errors: [error.message] })}\n`); process.exitCode = 1; });
@@ -0,0 +1,32 @@
1
+ import { writeFileSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { hash } from '../../../../scripts/lib/strategic-handoff-io.mjs';
4
+ import { technicalDigest } from '../scripts/validate-technical-design.mjs';
5
+ export function mvcFixture(root) {
6
+ const files = {
7
+ 'CONTEXT.md': '# 业务上下文\n',
8
+ 'spec.md': '# 需求\nrule.valid: 必填材料完整。scenario.submit: 提交成功或校验失败。\n',
9
+ 'registration.json': JSON.stringify({ project_id: 'example', status: 'current', architecture_identity: { architecture_family: 'layered-mvc' } }),
10
+ 'review.md': '设计评审测试证据;不构成真实批准。\n'
11
+ };
12
+ for (const [ref, bytes] of Object.entries(files)) writeFileSync(path.join(root, ref), bytes);
13
+ const data = {
14
+ schema_version: 2, technical_design_id: 'technical-design.example', version: 'v1', status: 'ready-for-human', context_ref: 'CONTEXT.md',
15
+ architecture: { family: 'layered-mvc', project_id: 'example', source_kind: 'existing-registration', decision_ref: 'registration.json', decision_digest: hash(readFileSync(path.join(root, 'registration.json'))) },
16
+ inputs: ['CONTEXT.md','spec.md'].map((ref,index) => ({ kind: index ? 'spec' : 'context', ref, version: 'v1', digest: hash(readFileSync(path.join(root,ref))) })),
17
+ source_items: [{ source_id: 'rule.valid', kind: 'rule', critical: false, source_ref: 'spec.md' }, { source_id: 'scenario.submit', kind: 'scenario', critical: true, source_ref: 'spec.md' }],
18
+ traceability: ['rule.valid','scenario.submit'].map(source_id => ({ source_id, disposition: 'implemented', tactical_refs: ['use-case.submit'], test_seam_refs: ['test-seam.success','test-seam.failure'], evidence_refs: ['spec.md'], dependency_status: 'known', dependent_slice_refs: ['slice.submit'], scenario_tests: [{ outcome: 'success', seam_ref: 'test-seam.success' }, { outcome: 'failure', seam_ref: 'test-seam.failure' }] })),
19
+ design: {
20
+ module_catalog: [{ module_id: 'module.server', layer: 'server', responsibility: 'HTTP 适配', depends_on: ['module.service'] }, { module_id: 'module.service', layer: 'service', responsibility: '提交用例和事务', depends_on: ['module.repository'] }, { module_id: 'module.repository', layer: 'repository', responsibility: '数据持久化', depends_on: [] }],
21
+ use_case_catalog: [{ use_case_id: 'use-case.submit', module_ref: 'module.service', flow: ['校验材料','保存申请'], rule_refs: ['rule.valid'], failure_handling: '材料不完整拒绝提交,写入失败回滚' }],
22
+ rule_catalog: [{ rule_id: 'rule.valid', statement: '材料必须完整', use_case_refs: ['use-case.submit'] }],
23
+ state_transition_catalog: [], state_not_applicable_reason: '本范围只登记申请,无状态流转',
24
+ consistency_policy: { transaction_boundary: '一次提交同一事务', rollback: '写入失败整体回滚', concurrency: '唯一约束拒绝竞争提交', idempotency: '请求键唯一' },
25
+ persistence_mapping: [{ mapping_id: 'mapping.application', use_case_ref: 'use-case.submit', repository_ref: 'module.repository', storage_model: 'application', notes: '请求键唯一' }],
26
+ integration_catalog: [], integration_not_applicable_reason: '无外部集成',
27
+ test_seams: [{ seam_id: 'test-seam.success', kind: 'service', subject_ref: 'use-case.submit', assertion: '完整材料保存成功' }, { seam_id: 'test-seam.failure', kind: 'service', subject_ref: 'use-case.submit', assertion: '缺材料时不写入' }]
28
+ }, evidence_refs: ['review.md']
29
+ };
30
+ data.digest = technicalDigest(data);
31
+ return data;
32
+ }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { attachScaffoldDecisionFixture } from '../../../../scripts/fixtures/user-decision/build-fixture.mjs';
8
+ import { mvcFixture } from './fixtures.mjs';
9
+ import { technicalDigest, validateTechnicalDesign } from '../scripts/validate-technical-design.mjs';
10
+ import { hash, read } from '../../../../scripts/lib/strategic-handoff-io.mjs';
11
+ import { enforceTechnicalDesign } from '../../../../scripts/lib/technical-design-boundary.mjs';
12
+ import { compileDefaultImplementationContract, evaluateContractFreshness, loadCompilerContract } from '../../../../scripts/lib/implementation-contract-compiler.mjs';
13
+ import { loadSkillRegistry } from '../../../../scripts/lib/skill-registry.mjs';
14
+ const root = mkdtempSync(path.join(tmpdir(), 'yss-technical-design-'));
15
+ let checks = 0;
16
+ try {
17
+ const mvc = mvcFixture(root);
18
+ const validate = data => validateTechnicalDesign(data, { root });
19
+ assert.equal((await validate(mvc)).architecture_family, 'layered-mvc'); checks++;
20
+ async function rejected(change, pattern) {
21
+ const data = structuredClone(mvc); change(data); data.digest = technicalDigest(data);
22
+ await assert.rejects(() => validate(data), pattern); checks++;
23
+ }
24
+ await rejected(d => { d.architecture.family = 'mixed'; }, /not one of/);
25
+ await rejected(d => { d.architecture.project_id = 'wrong'; }, /登记架构不匹配/);
26
+ await rejected(d => { d.architecture.decision_digest = `sha256:${'0'.repeat(64)}`; }, /来源摘要漂移/);
27
+ await rejected(d => { d.traceability.pop(); }, /缺少规则或场景承接/);
28
+ await rejected(d => { d.traceability[1].scenario_tests.pop(); }, /成功\/失败测试/);
29
+ await rejected(d => { d.traceability[0].tactical_refs = ['aggregate.fake']; }, /设计落点悬空/);
30
+ await rejected(d => { d.design.module_catalog[0].depends_on = ['module.repository']; }, /模块依赖越界/);
31
+ await rejected(d => { d.design.consistency_policy.transaction_boundary = ''; }, /non-empty/);
32
+ await rejected(d => { d.design.aggregate_catalog = []; }, /Additional properties/);
33
+ await rejected(d => { d.design.test_seams[0].subject_ref = 'missing'; }, /设计对象悬空/);
34
+ await rejected(d => { d.status = 'stale'; }, /状态不可消费/);
35
+ await rejected(d => { d.traceability[0].disposition = 'conflict'; }, /未闭合承接/);
36
+ const deferred = structuredClone(mvc); deferred.status = 'approved';
37
+ Object.assign(deferred.traceability[0], { disposition: 'deferred', reason: '下一版', risk: '提交不可用', owner: '维护者', followup_ticket_ref: 'ticket.next', verification_plan: '回归提交', target_version: 'v2' });
38
+ deferred.digest = technicalDigest(deferred);
39
+ await assert.rejects(() => validateTechnicalDesign(deferred, { root, sliceRef: 'slice.submit' }), /未闭合承接/); checks++;
40
+ assert.equal((await validateTechnicalDesign(deferred, { root, sliceRef: 'slice.other' })).architecture_family, 'layered-mvc'); checks++;
41
+ deferred.traceability[0].dependency_status = 'unknown'; deferred.digest = technicalDigest(deferred);
42
+ await assert.rejects(() => validateTechnicalDesign(deferred, { root, sliceRef: 'slice.other' }), /未闭合承接/); checks++;
43
+ writeFileSync(path.join(root, 'spec.md'), 'changed');
44
+ await assert.rejects(() => validate(mvc), /输入摘要漂移/); checks++;
45
+ mvcFixture(root);
46
+ const old = read(fileURLToPath(new URL('../../yss-tactical-design/tests/fixtures/valid-tactical-design.yaml', import.meta.url)));
47
+ await assert.rejects(() => validate(old), /显式 --legacy-ddd/); checks++;
48
+ assert.equal((await validateTechnicalDesign(old, { root, legacyDdd: true })).result, 'legacy-ddd-read-only'); checks++;
49
+ const ddd = structuredClone(mvc); ddd.architecture.family = 'domain-driven';
50
+ writeFileSync(path.join(root, 'registration.json'), JSON.stringify({ project_id: 'example', status: 'current', architecture_identity: { architecture_family: 'domain-driven' } }));
51
+ ddd.architecture.decision_digest = hash(readFileSync(path.join(root, 'registration.json'))); ddd.design = old;
52
+ ddd.inputs.push({ kind: 'strategic', ref: 'spec.md', version: 'v1', digest: hash(readFileSync(path.join(root, 'spec.md'))) });
53
+ for (const row of ddd.traceability) Object.assign(row, { tactical_refs: [old.test_seams[0].subject_ref], test_seam_refs: [old.test_seams[0].seam_id], scenario_tests: ['success','failure'].map(outcome => ({ outcome, seam_ref: old.test_seams[0].seam_id })) });
54
+ ddd.digest = technicalDigest(ddd);
55
+ assert.equal((await validate(ddd)).architecture_family, 'domain-driven'); checks++;
56
+ ddd.design.aggregate_catalog[0].api_exposure = 'public'; ddd.digest = technicalDigest(ddd);
57
+ await assert.rejects(() => validate(ddd), /internal-only/); checks++;
58
+ const scaffold = mvcFixture(root);
59
+ const decision = attachScaffoldDecisionFixture(path.join(root, 'decision-evidence'), { project_id: 'example', status: 'user-confirmed', confirmed_architecture: 'layered-mvc', decision_inputs_digest: `sha256:${'1'.repeat(64)}`, user_confirmation: { confirmation_ref: 'user-message', confirmed_by: 'user' } });
60
+ const record = { status: 'current', template: false, decisions: [decision] };
61
+ const recordFile = path.join(root, 'decision.json');
62
+ writeFileSync(recordFile, JSON.stringify(record));
63
+ scaffold.architecture = { ...scaffold.architecture, source_kind: 'scaffold-decision', decision_ref: 'decision.json', decision_digest: hash(readFileSync(recordFile)) }; scaffold.digest = technicalDigest(scaffold);
64
+ assert.equal((await validate(scaffold)).architecture_family, 'layered-mvc'); checks++;
65
+ record.decisions[0].status = 'awaiting-user-decision'; writeFileSync(recordFile, JSON.stringify(record)); scaffold.architecture.decision_digest = hash(readFileSync(recordFile)); scaffold.digest = technicalDigest(scaffold);
66
+ await assert.rejects(() => validate(scaffold), /分支设计前必须确认/); checks++;
67
+ record.decisions[0].status = 'user-confirmed'; record.decisions[0].user_confirmation.user_decision_ref = 'missing-user-decision.json'; writeFileSync(recordFile, JSON.stringify(record)); scaffold.architecture.decision_digest = hash(readFileSync(recordFile)); scaffold.digest = technicalDigest(scaffold);
68
+ await assert.rejects(() => validate(scaffold), /user-decision/); checks++;
69
+ const current = mvcFixture(root); current.status = 'approved'; current.digest = technicalDigest(current);
70
+ const file = path.join(root, 'design.json'); writeFileSync(file, JSON.stringify(current));
71
+ const technical_design = { ref: 'design.json', version: 'v1', digest: hash(readFileSync(file)) };
72
+ const identity = { architecture_family: 'layered-mvc', architecture_profile: 'layered-mvc-service', generator_skill: 'yss-layered-mvc-scaffold-generator', requested_capabilities: [], resolved_modules: ['server','service','repository'], verification_database: 'h2', production_database: 'not-bound', contract_digest: 'a'.repeat(64) };
73
+ const state = { technical_design, slice_id: 'slice.submit', architecture_identity: identity, conditions: ['backend-technical-design-impact'] };
74
+ enforceTechnicalDesign(state, { root }); checks++;
75
+ assert.throws(() => enforceTechnicalDesign({ ...state, technical_design: undefined }, { root }), /缺少已批准技术设计/); checks++;
76
+ assert.throws(() => enforceTechnicalDesign({ ...state, architecture_identity: { architecture_family: 'domain-driven' } }, { root }), /架构不匹配/); checks++;
77
+ const resolution = compileDefaultImplementationContract({ ...state, root, requiredCapabilities: ['contract.request-validation'], architecture_evidence: { engineering_baseline: identity, repository_registration: identity, manifest: identity } });
78
+ assert.deepEqual(resolution.technical_design, technical_design); assert(!resolution.required_skills.includes('yss-domain')); checks++;
79
+ writeFileSync(path.join(root, 'spec.md'), 'changed again');
80
+ assert.equal(evaluateContractFreshness({ schema_version: 2, resolution }, { registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), root }).freshness, 'stale'); checks++;
81
+ } finally { rmSync(root, { recursive: true, force: true }); }
82
+ process.stdout.write(`技术设计场景通过:${checks} 项(MVC、DDD、兼容、架构、承接、切片与漂移)\n`);
@@ -62,6 +62,10 @@ Look for the originating spec, in this order:
62
62
 
63
63
  Compile sources **before** spawning reviewers. For YSS implementation candidates follow [yss-review-standards.md](references/yss-review-standards.md): run machine checks that exist in the implementation repo; then collect repo docs (`CODING_STANDARDS.md` / `CONTRIBUTING.md` if present), every Slice `required_skills` skill file, the impact-conditioned specialist inputs (`alibaba-java-code-style`, `yss-ui`, `yss-domain`, …), and `docs/templates/review-report-template.md`. Missing applicable coverage is `missing_evidence`, not a pass.
64
64
 
65
+ For YSS backend review, derive the review roots from the candidate project root, implementation-repository registry, Slice `project_roots` and `allowed_write_paths`. Review only the project itself and registered backend development projects; exclude frontend roots, unrelated submodules/vendor trees and unregistered directories. Never replace this resolution with a fixed `apps/backend` assumption.
66
+
67
+ Every backend candidate must explicitly assess `yss-repository` and `yss-mybatis`. When the candidate changes persistence structure, Mapper/XML, SQL, pagination, batch operations, scanning/configuration or data-source behavior, read both skills and the selected Repository Profile; exact component claims also require a current `yss-mybatis` source index. When no persistence impact exists, record a concrete `not-applicable` reason for both instead of silently skipping them.
68
+
65
69
  Anything in the repo that documents how code should be written, such as `CODING_STANDARDS.md` or `CONTRIBUTING.md`, remains a source. It does **not** replace YSS or Alibaba specialist inputs.
66
70
 
67
71
  On top of whatever the repo documents, the Standards axis always carries the **smell baseline** below — a fixed set of Fowler code smells (_Refactoring_, ch.3) that applies even when a repo documents nothing. Two rules bind it:
@@ -1,3 +1,3 @@
1
1
  interface:
2
2
  display_name: "Code Review"
3
- short_description: "Review a diff on standards, spec, and YSS/Alibaba specialist inputs"
3
+ short_description: "Review standards/spec plus YSS backend Repository/MyBatis and UI inputs"
@@ -11,7 +11,7 @@
11
11
  1. 仓库文档:`CODING_STANDARDS.md`、`CONTRIBUTING.md` 或实现仓等价文件(若存在)。
12
12
  2. Slice Implementation Contract 的 `required_skills`:对每个技能读取 `.agents/skills/<id>/SKILL.md` 及该 skill 指明的 references。
13
13
  3. 影响面专项检查输入(与合同并集,不得互相替代):
14
- - 后端:`alibaba-java-code-style`、`yss-domain`、`yss-application`、`yss-repository`、`yss-web-controller`、`yss-dto`、`mapstruct`、`lombok`
14
+ - 后端:`alibaba-java-code-style`、`yss-domain`、`yss-application`、`yss-repository`、`yss-mybatis`、`yss-web-controller`、`yss-dto`、`mapstruct`、`lombok`
15
15
  - UI:`yss-ui`、`yss-design-system`、`yss-ui-business-page-generation`
16
16
  4. 报告模板中的后端 / 前端门禁表。空着的适用行视为 `missing_evidence`。
17
17
 
@@ -19,11 +19,18 @@ YSS 页面模块约定(YTable、YFormily、页面骨架等)走 Standards,
19
19
 
20
20
  审查者只读这些 skill,不得用它们写实现路径。`role.test-engineer` 任务包禁止 `implement` 与脚手架生成器。
21
21
 
22
+ ### 后端范围与持久化适用性
23
+
24
+ - Review roots 从候选本体项目、实现仓登记、Slice `project_roots` 和 `allowed_write_paths` 解析;只包含本体项目和已登记后端研发项目,不固定为 `apps/backend`,不扫描前端、无关 submodule/vendor 或未登记目录。
25
+ - 每个后端候选都必须分别评估 `yss-repository` 与 `yss-mybatis`。命中 PO、Repository、Mapper/XML、SQL、分页、批量、扫描/配置或数据源行为时,两者均为 applicable,并加载所选 Repository Profile 与当前 MyBatis source index。
26
+ - 精确组件 API/配置结论要求 source index 的组件 tree 与当前源码一致且组件子树 clean;不满足时为 `missing_evidence` / `stale`,不能判 pass。
27
+ - 无持久化影响时,两项 Skill 分别记录具体 `not-applicable` 原因;仅写“未命中”或留空不构成证据。
28
+
22
29
  ## 2. 机器检查
23
30
 
24
31
  在派发 Standards / Spec 子审查之前,对实现仓**已登记且当前可执行**的命令实际跑一遍:
25
32
 
26
- - 后端优先:切片合同里的 `./mvnw` 验证;若工程已配置 Checkstyle / P3C / Spotless / `validate`,一并执行。
33
+ - 后端优先:对本体项目和每个已登记后端研发项目分别执行其切片合同里的 `./mvnw` 验证;若工程已配置 Checkstyle / P3C / Spotless / `validate`,一并执行。
27
34
  - 前端优先:切片合同里的 `pnpm` 验证;若存在 `pnpm lint` / `pnpm type-check`,一并执行。
28
35
 
29
36
  记录命令、退出码、时间和证据引用。退出码非 0 记为 Standards **hard violation**。
@@ -88,7 +88,7 @@ node scripts/run_first_slice_verification.mjs \
88
88
  - 生成后的后端工程必须使用项目根目录 `./mvnw ...` 执行构建、测试、运行和 CI 验证;不得在 README、实施记录、Ticket、Review 或 Release 中默认写裸 `mvn ...`。既有仓库确实无法使用 wrapper 时,必须记录受控例外。
89
89
  - 原型确认后,`scaffold_status=required` 才能进入本 skill;本 skill 的生成边界是工程结构、POM、配置、Wrapper 和机械模板,不是业务实现。
90
90
  - 脚手架合同必须携带 `contract_id`、`contract_version`、实现合同编译器 draft 引用、生命周期批准引用、持久化引用、当前版本、允许写路径、预期证据文件和验证命令;字段缺失或版本过期时阻断。
91
- - 新脚手架合同只接受 schema v3,必须携带 `architecture_family=domain-driven`、`generator_skill`、`decision_ref/id/digest`、固定模块闭包,并分别携带 `project_name`、`base_package` 和 `maven_coordinates`;后者包含项目 `group_id` / `project_version`、父 POM GAV 与 `yss_components_version`,并由 CLI 原样传入。历史 schema v2 仅只读兼容,不用于新生成;schema v1/v2 均不自动升级。
91
+ - 新脚手架优先接受统一 Project Scaffold Contract schema v4;已批准且当前的后端 schema v3 可完成兼容生成。两者都必须携带 `architecture_family=domain-driven`、`generator_skill`、`decision_ref/id/digest`、固定模块闭包,以及 `project_name`、`base_package` 和 `maven_coordinates`。历史 schema v2 仅只读兼容,不用于新生成;schema v1/v2 均不自动升级。
92
92
  - 合同 `profiles` 只支持 `target-domain-model`、`mybatis-plus`、`mysql`、`spring-boot-2.7-jdk8`、`javax`、`web`、`yss-internal`。普通 MyBatis、Boot 3、独立 client module、client-in-domain 和其他旧架构均为 `unsupported`,不提供回退分支。
93
93
  - 运行生成器必须传入 `--contract-file`;生成器会校验合同 `status=approved`、`current_version`、`primary_skill`、`controlled-generation`、实际输出路径和固定三条验证命令,不接受仅凭任意字符串引用的放行。
94
94
  - 生成项目必须写入 Manifest v3 `.yss/scaffold-generation.json`,记录架构选择及 digest、生成器、合同 digest、Target Profile、模块闭包、模板 digest、下游完整 skill tree digest、脚手架父合同与 实现合同编译器 合同 digest、generator-owned 文件 hash、严格 `generation_policy` 和完成等级;清单缺失或不一致时不得交给后续 实现合同编译器。
@@ -9,6 +9,7 @@ import { fileURLToPath } from "node:url";
9
9
  import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
10
10
  import { assertLocalDatabaseProfile, localDatabaseConfiguration, scaffoldArchitectureIdentity } from "../../../../scripts/lib/scaffold-local-database.mjs";
11
11
  import { validateArchitectureIdentity } from "../../../../scripts/lib/backend-architecture.mjs";
12
+ import { validateJsonSchema } from "../../../../scripts/lib/json-schema.mjs";
12
13
 
13
14
  import {
14
15
  findGitRoot,
@@ -204,7 +205,9 @@ class ScaffoldGenerator {
204
205
  const contractText = await readFile(this.contractFile, "utf8");
205
206
  let contract; try { contract = JSON.parse(contractText); } catch { fail(`脚手架合同文件无法读取或不是合法 JSON: ${this.contractFile}`); }
206
207
  if (!contract || Array.isArray(contract) || typeof contract !== "object") fail("脚手架合同必须是 JSON 对象");
207
- if (contract.schema_version !== 3) fail(`unsupported: scaffold contract schema_version=${contract.schema_version};新生成只接受 schema v3,不提供自动升级`);
208
+ if (![3, 4].includes(contract.schema_version)) fail(`unsupported: scaffold contract schema_version=${contract.schema_version};只接受兼容 v3 或统一 v4`);
209
+ if (contract.schema_version === 4 && (contract.kind !== "project-scaffold-contract" || contract.delivery_role !== "backend" || contract.scaffold_kind !== "backend-ddd")) fail("schema v4 合同必须绑定 backend/backend-ddd");
210
+ if (contract.schema_version === 4) validateJsonSchema(contract, path.join(REPOSITORY_ROOT, "docs/process/schemas/project-scaffold-contract.schema.json"), { label: "Project Scaffold Contract v4" });
208
211
  const requiredMetadata = [["--contract-id", this.options.contractId], ["--contract-version", this.options.contractVersion], ["--approval-ref", this.options.approvalRef], ["--compiler-draft-ref", this.options.compilerDraftRef], ["--persisted-ref", this.options.persistedRef]];
209
212
  const missing = requiredMetadata.filter(([, value]) => !isPresent(value)).map(([flag]) => flag);
210
213
  if (missing.length) fail(`生成项目必须提供当前已批准脚手架合同的完整元数据: ${missing.join(", ")}`);
@@ -214,7 +217,7 @@ class ScaffoldGenerator {
214
217
  if (contract.status !== "approved") fail("脚手架合同必须已由生命周期批准");
215
218
  if (contract.contract_id !== this.options.contractId) fail("--contract-id 与脚手架合同不一致");
216
219
  if (contract.contract_version !== this.options.contractVersion) fail("--contract-version 与脚手架合同不一致");
217
- if (contract.current_version !== contract.contract_version) fail("脚手架合同版本不是当前版本");
220
+ if (contract.current_version !== contract.contract_version && !(contract.schema_version === 4 && contract.current_version === true)) fail("脚手架合同版本不是当前版本");
218
221
  if (contract.compiler_draft_ref !== this.options.compilerDraftRef) fail("--compiler-draft-ref 与脚手架合同不一致");
219
222
  if (contract.persisted_ref !== this.options.persistedRef) fail("--persisted-ref 与脚手架合同不一致");
220
223
  if (contract.lifecycle_approval_ref !== this.options.approvalRef) fail("--approval-ref 与脚手架合同不一致");
@@ -364,6 +367,7 @@ class ScaffoldGenerator {
364
367
  const scaffoldParent = path.join(SKILL_ROOT, "references", "yss-backend-scaffold-parent", "SKILL.md");
365
368
  const compilerContract = path.join(REPOSITORY_ROOT, ".agents", "skills", "yss-implementation-contract-compiler", "references", "compiler-contract.yaml");
366
369
  const manifest = { schema_version: 3, kind: "backend-scaffold", architecture_profile: contract.architecture_profile, architecture_identity: scaffoldArchitectureIdentity(contract, this.contractDigest), contract_id: this.options.contractId, contract_version: this.options.contractVersion, scaffold_request_id: contract.scaffold_request_id, architecture_family: contract.architecture_family, generator_skill: contract.generator_skill, decision_id: contract.decision_id, decision_digest: contract.decision_digest, module_profile: contract.module_profile, approval_ref: this.options.approvalRef, compiler_draft_ref: this.options.compilerDraftRef, persisted_ref: this.options.persistedRef, contract_file_ref: this.contractFile, contract_digest: this.contractDigest, lifecycle_approval_ref: contract.lifecycle_approval_ref, current_version: contract.current_version, approver: contract.approval.approver, allowed_write_paths: contract.allowed_write_paths, expected_evidence_files: contract.expected_evidence_files, project_name: this.projectName, base_package: this.basePackage, bootstrap_main_class: `${this.basePackage}.${this.applicationClassName}`, bootstrap_main_source: this.bootstrapMainSource, maven_coordinates: this.mavenCoordinates, maven_coordinates_source: this.mavenCoordinatesSource, profiles: this.profiles, generation_mode: "controlled-generation", completion_level: "generated", generator: { id: "yss-ddd-scaffold-generator", template_digest: await treeDigest(path.join(SKILL_ROOT, "assets")) }, ownership: { generated_files: generatedFiles, user_owned_globs: ["**/src/main/java/**", "**/src/test/java/**", "db/**"] }, readiness: { downstream_skills: downstream, contracts: { scaffold_parent: sha256(await readFile(scaffoldParent)), compiler_contract: sha256(await readFile(compilerContract)) }, architecture_ruleset: sha256(await readFile(path.join(this.javaTemplateDir, "architecture-rules-test.java.template"))) }, generation_policy: { mode: "initialize-only", existing_target: "unsupported", old_project_migration: "unsupported", template_upgrade: "unsupported" }, verification_commands: COMMANDS, generated_at: isoNow() };
370
+ manifest.schema_version = contract.schema_version;
367
371
  await writeText(path.join(this.projectRoot, ".yss", "scaffold-generation.json"), `${JSON.stringify(manifest, null, 2)}\n`); console.log(" ✓ .yss/scaffold-generation.json");
368
372
  }
369
373
  async copyWrapperFiles() {
@@ -375,7 +379,7 @@ class ScaffoldGenerator {
375
379
  const required = [path.join(this.projectRoot, "pom.xml"), path.join(this.projectRoot, `${this.projectName}-bootstrap`, "pom.xml"), path.join(this.projectRoot, this.bootstrapMainSource), path.join(this.projectRoot, "mvnw"), path.join(this.projectRoot, ".yss", "scaffold-generation.json")];
376
380
  const missing = []; for (const target of required) if (!await isFile(target)) missing.push(target); if (missing.length) fail(`生成产物缺失: ${missing.join(", ")}`);
377
381
  const manifest = await readJson(required[4], "脚手架生成元数据清单无法读取");
378
- if (manifest.schema_version !== 3 || manifest.contract_id !== this.options.contractId || manifest.contract_version !== this.options.contractVersion || manifest.current_version !== this.options.contractVersion || manifest.generation_mode !== "controlled-generation" || manifest.architecture_family !== "domain-driven" || manifest.generator_skill !== "yss-ddd-scaffold-generator" || manifest.decision_id !== this.scaffoldContract.decision_id || manifest.decision_digest !== this.scaffoldContract.decision_digest || JSON.stringify(manifest.module_profile) !== JSON.stringify(this.scaffoldContract.module_profile) || manifest.bootstrap_main_class !== `${this.basePackage}.${this.applicationClassName}` || manifest.bootstrap_main_source !== this.bootstrapMainSource || manifest.profiles.architecture !== SUPPORTED_PROFILES.architecture || manifest.generation_policy.mode !== "initialize-only" || manifest.generation_policy.existing_target !== "unsupported" || JSON.stringify(manifest.verification_commands) !== JSON.stringify(COMMANDS)) fail("脚手架生成元数据清单与当前批准架构决策、合同、Target Profile、initialize-only 边界、机械启动入口或固定验证命令不一致");
382
+ if (![3, 4].includes(manifest.schema_version) || manifest.contract_id !== this.options.contractId || manifest.contract_version !== this.options.contractVersion || (manifest.current_version !== this.options.contractVersion && manifest.current_version !== true) || manifest.generation_mode !== "controlled-generation" || manifest.architecture_family !== "domain-driven" || manifest.generator_skill !== "yss-ddd-scaffold-generator" || manifest.decision_id !== this.scaffoldContract.decision_id || manifest.decision_digest !== this.scaffoldContract.decision_digest || JSON.stringify(manifest.module_profile) !== JSON.stringify(this.scaffoldContract.module_profile) || manifest.bootstrap_main_class !== `${this.basePackage}.${this.applicationClassName}` || manifest.bootstrap_main_source !== this.bootstrapMainSource || manifest.profiles.architecture !== SUPPORTED_PROFILES.architecture || manifest.generation_policy.mode !== "initialize-only" || manifest.generation_policy.existing_target !== "unsupported" || JSON.stringify(manifest.verification_commands) !== JSON.stringify(COMMANDS)) fail("脚手架生成元数据清单与当前批准架构决策、合同、Target Profile、initialize-only 边界、机械启动入口或固定验证命令不一致");
379
383
  const stack = [this.projectRoot], binary = new Set([".class", ".db", ".jar", ".png", ".jpg", ".jpeg", ".gif"]);
380
384
  while (stack.length) { const dir = stack.pop(); for (const entry of await readdir(dir, { withFileTypes: true })) { const target = path.join(dir, entry.name); if (entry.isDirectory()) { stack.push(target); continue; } if (!entry.isFile() || binary.has(path.extname(entry.name))) continue; const content = await readFile(target, "utf8"); if (content.includes("{{") || content.includes("root/root")) fail(`生成文件包含未替换占位符或明文凭据: ${target}`); } }
381
385
  }
@@ -39,7 +39,7 @@ function classifyFailure(phase, outcome) {
39
39
  }
40
40
  function parseArgs(argv) { const result = {}; for (let index = 0; index < argv.length; index += 1) { let token = argv[index]; if (token === "--help" || token === "-h") { result.help = true; continue; } const equals = token.indexOf("="); let value; if (equals !== -1) { value = token.slice(equals + 1); token = token.slice(0, equals); } if (!["--project-root", "--evidence-dir"].includes(token)) throw new Error(`不支持的参数: ${token}`); if (value === undefined) value = argv[++index]; if (!value || value.startsWith("--")) throw new Error(`参数 ${token} 缺少值`); result[token === "--project-root" ? "projectRoot" : "evidenceDir"] = path.resolve(value); } if (result.help) return result; if (!result.projectRoot || !result.evidenceDir) throw new Error("必须提供 --project-root 和 --evidence-dir"); return result; }
41
41
  function validateManifest(manifest) {
42
- if (![2, 3].includes(manifest.schema_version)) throw new Error(`unsupported: scaffold Manifest schema_version=${manifest.schema_version};只读兼容 v2,并验证当前 v3`);
42
+ if (![2, 3, 4].includes(manifest.schema_version)) throw new Error(`unsupported: scaffold Manifest schema_version=${manifest.schema_version};只读兼容 v2,并验证当前 v3/v4`);
43
43
  const required = ["schema_version", "contract_id", "contract_version", "scaffold_request_id", "contract_digest", "profiles", "ownership", "readiness", "generation_policy", "completion_level", "approval_ref", "approver", "lifecycle_approval_ref", "compiler_draft_ref", "persisted_ref", "contract_file_ref", "current_version", "allowed_write_paths", "expected_evidence_files", "verification_commands", "generation_mode"];
44
44
  if (manifest.schema_version === 3) required.push("architecture_family", "generator_skill", "decision_id", "decision_digest", "module_profile");
45
45
  const missing = required.filter((field) => manifest[field] === undefined || manifest[field] === null || manifest[field] === "");
@@ -140,6 +140,15 @@ async function prepareVerifierProject(project, manifest = targetManifest()) {
140
140
 
141
141
  test("生成批准的服务级 target profile 骨架,并写入可追溯 Manifest v3", async (t) => { const data = await fixture(); t.after(() => rm(data.root, { recursive: true, force: true })); const result = await command(data.args); assert.equal(result.code, 0, result.stderr); const project = path.join(data.output, "demo-service"); const manifest = JSON.parse(await readFile(path.join(project, ".yss/scaffold-generation.json"), "utf8")); assert.equal(manifest.schema_version, 3); assert.equal(manifest.architecture_family, "domain-driven"); assert.equal(manifest.generator_skill, "yss-ddd-scaffold-generator"); assert.equal(manifest.decision_id, "scaffold-decision.demo-service"); assert.equal(manifest.scaffold_request_id, "scaffold-request-1"); assert.equal(manifest.slice_id, undefined); assert.equal(manifest.completion_level, "generated"); assert.equal(manifest.profiles.architecture, "target-domain-model"); assert.deepEqual(manifest.generation_policy, { mode: "initialize-only", existing_target: "unsupported", old_project_migration: "unsupported", template_upgrade: "unsupported" }); assert.match(manifest.generator.template_digest, /^[a-f0-9]{64}$/); assert.match(manifest.contract_digest, /^[a-f0-9]{64}$/); assert.ok(manifest.ownership.generated_files.length > 8); assert.ok(manifest.ownership.generated_files.every((item) => item.owner === "generator" && /^[a-f0-9]{64}$/.test(item.sha256))); assert.equal(manifest.generation_mode, "controlled-generation"); assert.deepEqual(manifest.verification_commands, ["./mvnw validate", "./mvnw test", "./mvnw package"]); assert.equal(manifest.bootstrap_main_class, "com.yss.demo.DemoServiceApplication"); assert.equal(manifest.bootstrap_main_source, "demo-service-bootstrap/src/main/java/com/yss/demo/DemoServiceApplication.java"); assert.match(await readFile(path.join(project, manifest.bootstrap_main_source), "utf8"), /class DemoServiceApplication/); assert.match(await readFile(path.join(project, "pom.xml"), "utf8"), /demo-service/); assert.equal(manifest.readiness.downstream_skills["yss-domain"], await treeDigest(path.resolve(scripts, "../../yss-domain"))); assert.match(manifest.readiness.contracts.scaffold_parent, /^[a-f0-9]{64}$/); assert.match(manifest.readiness.contracts.compiler_contract, /^[a-f0-9]{64}$/); });
142
142
 
143
+ test("统一 Project Scaffold Contract v4 可生成 DDD 后端并保留 v4 Manifest", async (t) => {
144
+ const data = await fixture({ schema_version: 4, kind: "project-scaffold-contract", delivery_role: "backend", scaffold_kind: "backend-ddd", repository_scope: "external-repository", init_git: false, current_version: true });
145
+ t.after(() => rm(data.root, { recursive: true, force: true }));
146
+ const result = await command(data.args);
147
+ assert.equal(result.code, 0, result.stderr);
148
+ const manifest = JSON.parse(await readFile(path.join(data.output, "demo-service", ".yss/scaffold-generation.json"), "utf8"));
149
+ assert.equal(manifest.schema_version, 4);
150
+ });
151
+
143
152
  test("schema v1 scaffold contract is unsupported and is never upgraded", async (t) => {
144
153
  const data = await fixture({ schema_version: 1 });
145
154
  t.after(() => rm(data.root, { recursive: true, force: true }));
@@ -5,7 +5,7 @@ description: 用于构建或重构 YSS 领域层代码。当用户要求设计
5
5
 
6
6
  # yss-domain
7
7
 
8
- 这是一个领域实现 skill。核心目标是消费已批准的战术模型,将领域行为落实为代码;战术模型的设计与批准由 `yss-tactical-design` 和 `yss-product-lifecycle` 负责。
8
+ 这是一个领域实现 skill。核心目标是消费已批准的战术模型,将领域行为落实为代码;`yss-technical-design` 组织 DDD 分支,由 `yss-tactical-design` 设计、`yss-product-lifecycle` 维护批准。
9
9
 
10
10
  本 skill 在新脚手架链路只支持 `domain-driven` / `target-domain-model`。`layered-mvc-service` 与 `mvc-data-analysis-v1` 是独立 MVC Profile,不是失败的 DDD 工程;它们不加载本 skill,也不生成 Domain Gateway。既有旧架构不在本链路内迁移。
11
11
 
@@ -23,7 +23,7 @@ description: 用于构建或重构 YSS 领域层代码。当用户要求设计
23
23
 
24
24
  ## 工作方式
25
25
 
26
- 1. 先读取批准且版本当前的 tactical-design contract 和 Slice Implementation Contract。
26
+ 1. 先读取批准且版本当前的 Technical Design Contract 的 DDD `design` 分支和 Slice Implementation Contract;旧 v1 tactical-design contract 只按 DDD 显式兼容读取。
27
27
  2. 数据库字段只做补充,不直接决定领域对象结构。
28
28
  3. 按合同实现领域行为、状态机、不变量和 Gateway 边界。
29
29
  4. 规则不清晰或模型需要扩展时,返回 `new_impacts` / `drift` 并停止,不要静默猜测。
@@ -64,7 +64,7 @@ description: 用于构建或重构 YSS 领域层代码。当用户要求设计
64
64
  ## 阶段 7 合同
65
65
 
66
66
  - 只消费生命周期已批准的 `Slice Implementation Contract` 和当前 `work_unit`;不得扩大 `allowed_write_paths`。
67
- - `Slice Implementation Contract` 必须引用批准且版本当前的 `tactical_design_ref`;不得在实现阶段重新批准或替换聚合、不变量和一致性策略。
67
+ - `Slice Implementation Contract` 必须引用批准且版本当前的 `technical_design` 绑定(旧 DDD 显式兼容 `tactical_design_ref`);不得在实现阶段重新批准或替换聚合、不变量和一致性策略。
68
68
  - 领域规则、状态机和不变量必须使用 `behavior-tdd`,先形成失败测试,再实现最小行为。
69
69
  - 完成后按 `yss-implementation-contract-compiler/references/yss-skill-execution-result.md` 返回统一 `YSS Skill Execution Result`:changed files、领域/测试证据、实际验证结果、偏离和新增影响。
70
70
  - 发现新 API、权限、状态机、数据模型或架构影响时填入 `new_impacts` 并暂停,不得静默扩张切片。
@@ -5,7 +5,7 @@ description: Use when creating a new YSS frontend micro-application from the sta
5
5
 
6
6
  # YSS Frontend Scaffold Generator
7
7
 
8
- 用于从标准 YSS 前端模板创建 0-1 前端微应用工程。当前 v1 只定义流程和证据要求;自动生成脚本后续补齐。
8
+ 用于从标准 YSS 前端模板创建 0-1 前端微应用工程。它只在阶段 5 的 `work-unit.implementation-repository-preparation` 中消费生命周期批准、持久化且当前的 Project Scaffold Contract schema v4,执行 `controlled-generation`;不生成业务页面。
9
9
 
10
10
  ## Template Source
11
11
 
@@ -21,7 +21,8 @@ branch: template
21
21
  - `app_name`:应用名。
22
22
  - `microapp_name`:微应用注册名。
23
23
  - `base_route`:基础路由。
24
- - OpenAPI Freeze 记录:已批准的冻结 YAML 版本和引用。
24
+ - Project Scaffold Contract schema v4:包含用户确认的仓库 scope、目标路径、`init_git`、模板 commit、应用参数、允许写路径和验证命令。
25
+ - OpenAPI Freeze 记录:有 API 影响时提供已批准的冻结 YAML 版本和引用;无 API 影响时提供带原因的 `not-applicable`。
25
26
  - OpenAPI JSON 派生记录:`docs/.scratch/<feature>/api/<feature>-json-export.md`,包含 YAML / JSON SHA-256、Redocly CLI 版本和 lockfile 引用。
26
27
  - 冻结 JSON 产物:`docs/.scratch/<feature>/api/<feature>.json`;这是唯一允许交给既有前端代码生成流程的上游产物。
27
28
  - `target_git_url` 或 `output_dir`:目标实现仓库或本地输出目录。
@@ -32,14 +33,14 @@ branch: template
32
33
 
33
34
  采用专职前端 profile 或显式 `frontend_delivery` 绑定时,先按 `docs/process/frontend-backend-delivery.md` 实际核验战略与后端联合交付。缺任一输入只能诊断和回交;输入通过后准备计划/合同,正式实现、生成和恢复仍须当前批准的 Slice Contract 冻结接收摘要。接口或部署版本漂移时重新接收,不复用旧成功输出。
34
35
 
35
- 1. 确认当前任务已经通过 Harness 入口分诊,且实现位置已记录在 proposal、design、build entry review、实施计划或实现路由记录中。
36
+ 1. 确认当前任务已经通过 Harness 入口分诊、逐项目脚手架决定已由真实用户确认,且 schema v4 合同已由生命周期批准、持久化并保持当前。
36
37
  2. 确认目标是外部实现仓库;只有用户明确选择时才输出到 Harness 仓库的 `apps/frontend/<project>/`。`apps/frontend/` 只能作为项目容器,`app/frontend/`、`app/backend/` 及其子路径禁止作为输出位置。`git-submodule` 只能在已初始化且附加分支的子仓工作树生成;空 gitlink、detached HEAD、`--force` 覆盖挂载点不得当成普通目录。
37
- 3. 只读检查模板分支是否可访问:`git ls-remote --heads <repo> template`。
38
- 4. 需要生成工程时,克隆或复制模板到用户确认的目标位置;不得默认写入 Harness 仓库。
38
+ 3. 只读检查模板分支和合同锁定的 40 位 commit 是否可访问;生成时使用精确 commit,不跟随浮动分支。
39
+ 4. 使用 `scripts/generate_and_verify_scaffold.mjs` 从已核验 checkout 复制工作树,排除模板 `.git`;目标必须不存在或为空。不得默认写入 Harness、不得 `--force`。仅合同 `init_git=true` 时初始化目标 Git。
39
40
  5. 替换应用名、微应用名、路由、`micro-config.json`、环境变量和 README 中的模板占位。
40
- 6. 核验 OpenAPI Freeze 记录和 OpenAPI JSON 派生记录;通过批准的 Cross-repo 子合同或项目脚本,将记录中的 JSON 原样物化到 `<frontend>/openapi/openapi.json`,并再次核对 SHA-256。
41
+ 6. 有 API 影响时核验 OpenAPI Freeze 记录和 JSON 派生记录,将摘要一致的 JSON 原样物化到 `<frontend>/openapi/openapi.json`;`openapi_impact=not-applicable` 时必须有原因并禁止生成 API client。
41
42
  7. 保持模板既有的前端代码生成配置不变;本 Harness 只将 SHA-256 一致的 JSON 原样交给既有前端代码生成流程,不修改该配置、不在此仓库执行生成,也不设置生成 CI 门禁。目标前端项目在需要时手动运行其既有命令。
42
- 8. 记录目标前端项目的 install / lint / type-check / build 命令,以及既有客户端生成命令(如有);生成命令仅作为目标项目的手动验证项。
43
+ 8. 实际执行并记录 `pnpm install --frozen-lockfile`、`pnpm lint`、`pnpm type-check`、`pnpm build` 的退出码和日志;缺失脚本只能由批准的工程基线提供替代命令。任何必需命令失败都阻断。
43
44
  9. 按 `docs/templates/implementation-repo-registry-template.md` 回写前端实现仓库登记。
44
45
 
45
46
  ## Expected Template Shape
@@ -59,6 +60,7 @@ packages/package.json
59
60
  ## Boundaries
60
61
 
61
62
  - 不直接创建远端 Git 项目,除非用户明确要求。
63
+ - 不保留模板 `.git` 或模板 remote;不在未获确认时执行 `git init`。
62
64
  - 不推送、不创建 MR / PR,除非用户明确要求。
63
65
  - 不绕过 OpenAPI Draft / Freeze;API client 只消费与 OpenAPI JSON 派生记录 SHA-256 一致的冻结 JSON。
64
66
  - 不接受任意 URL、未冻结 YAML、后端运行时输出或手工 JSON 作为既有前端代码生成流程的输入。
@@ -75,4 +77,5 @@ packages/package.json
75
77
  - install / lint / type-check / build 命令,以及目标前端项目既有的手动客户端生成命令(如有)。
76
78
  - OpenAPI Freeze 记录、OpenAPI JSON 派生记录、JSON SHA-256 和 `openapi/openapi.json` 物化证据。
77
79
  - Harness 实现仓库登记草案。
80
+ - `.yss/scaffold-generation.json` Manifest v4 与 `scaffold-verification.json`。
78
81
  - 未覆盖项和 `TODO-HUMAN-REVIEW`。
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { generate } from "./generate_scaffold.mjs";
3
+ import { verify } from "./run_scaffold_verification.mjs";
4
+ function argsOf(argv) { const args = {}; for (let i = 0; i < argv.length; i += 2) args[argv[i].replace(/^--/, "")] = argv[i + 1]; return args; }
5
+ try {
6
+ const args = argsOf(process.argv.slice(2));
7
+ generate({ contractFile: args["contract-file"], templateCheckout: args["template-checkout"], outputDir: args["output-dir"] });
8
+ const report = verify(args["output-dir"], args["evidence-dir"]);
9
+ if (report.status !== "passed") process.exitCode = 1;
10
+ } catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; }