create-yss-spec 3.4.7 → 3.4.9

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 (454) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +5 -5
  4. package/template/.agents/skills/alibaba-java-code-style/SKILL.md +2 -2
  5. package/template/.agents/skills/archify/SKILL.md +2 -19
  6. package/template/.agents/skills/archify/references/geometry-and-routing.md +20 -0
  7. package/template/.agents/skills/code-review/SKILL.md +3 -33
  8. package/template/.agents/skills/code-review/references/candidate-capture.md +33 -0
  9. package/template/.agents/skills/code-review/references/yss-review-standards.md +20 -0
  10. package/template/.agents/skills/codebase-design/SKILL.md +2 -2
  11. package/template/.agents/skills/competitive-intelligence/SKILL.md +1 -1
  12. package/template/.agents/skills/diagnosing-bugs/SKILL.md +6 -2
  13. package/template/.agents/skills/formily-foundation/SKILL.md +1 -1
  14. package/template/.agents/skills/formily-step-flow/SKILL.md +3 -2
  15. package/template/.agents/skills/frontend-commit/SKILL.md +6 -6
  16. package/template/.agents/skills/grilling/SKILL.md +2 -2
  17. package/template/.agents/skills/implement/SKILL.md +1 -1
  18. package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +3 -3
  19. package/template/.agents/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  20. package/template/.agents/skills/improve-codebase-architecture/SKILL.md +10 -6
  21. package/template/.agents/skills/java-backend-commit/SKILL.md +5 -5
  22. package/template/.agents/skills/llm-wiki/SKILL.md +1 -1
  23. package/template/.agents/skills/lombok/SKILL.md +1 -1
  24. package/template/.agents/skills/mapstruct/SKILL.md +3 -1
  25. package/template/.agents/skills/prototype/SKILL.md +1 -1
  26. package/template/.agents/skills/prototype-review/SKILL.md +1 -1
  27. package/template/.agents/skills/resolving-merge-conflicts/SKILL.md +2 -2
  28. package/template/.agents/skills/tdd/SKILL.md +1 -1
  29. package/template/.agents/skills/to-questionnaire/SKILL.md +4 -2
  30. package/template/.agents/skills/to-spec/SKILL.md +3 -3
  31. package/template/.agents/skills/to-tickets/SKILL.md +7 -7
  32. package/template/.agents/skills/using-git-worktrees/SKILL.md +13 -11
  33. package/template/.agents/skills/wait-what/SKILL.md +1 -1
  34. package/template/.agents/skills/wayfinder/SKILL.md +4 -2
  35. package/template/.agents/skills/writing-for-agents/SKILL.md +9 -73
  36. package/template/.agents/skills/writing-for-agents/references/writing-principles.md +76 -0
  37. package/template/.agents/skills/yss-api-integration/SKILL.md +2 -2
  38. package/template/.agents/skills/yss-application/SKILL.md +12 -0
  39. package/template/.agents/skills/yss-application/references/application-layer-guide.md +7 -0
  40. package/template/.agents/skills/yss-audit-log/SKILL.md +3 -1
  41. package/template/.agents/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  42. package/template/.agents/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  43. package/template/.agents/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  44. package/template/.agents/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  45. package/template/.agents/skills/yss-backend-spec-review/SKILL.md +44 -0
  46. package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  47. package/template/.agents/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  48. package/template/.agents/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  49. package/template/.agents/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  50. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
  51. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  52. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  53. package/template/.agents/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  54. package/template/.agents/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  55. package/template/.agents/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  56. package/template/.agents/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  57. package/template/.agents/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  58. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  59. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  60. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  61. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  62. package/template/.agents/skills/yss-design-system/SKILL.md +2 -2
  63. package/template/.agents/skills/yss-domain/SKILL.md +17 -5
  64. package/template/.agents/skills/yss-domain/references/domain-layer-guide.md +10 -3
  65. package/template/.agents/skills/yss-domain/references/existing-project.md +5 -0
  66. package/template/.agents/skills/yss-dto/SKILL.md +13 -10
  67. package/template/.agents/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  68. package/template/.agents/skills/yss-exception/SKILL.md +2 -2
  69. package/template/.agents/skills/yss-formily-schema-generator/SKILL.md +12 -12
  70. package/template/.agents/skills/yss-hook/SKILL.md +8 -44
  71. package/template/.agents/skills/yss-hook/references/use-request.md +42 -0
  72. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +1 -5
  73. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  74. package/template/.agents/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  75. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  76. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  77. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  78. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  79. package/template/.agents/skills/yss-mybatis/SKILL.md +14 -0
  80. package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +1 -1
  81. package/template/.agents/skills/yss-openapi-governance/SKILL.md +1 -32
  82. package/template/.agents/skills/yss-openapi-governance/references/governance-output.md +34 -0
  83. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +1 -1
  84. package/template/.agents/skills/yss-prototype-stage/SKILL.md +1 -5
  85. package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  86. package/template/.agents/skills/yss-repository/SKILL.md +13 -1
  87. package/template/.agents/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  88. package/template/.agents/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  89. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  90. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  91. package/template/.agents/skills/yss-stage-decision/SKILL.md +1 -1
  92. package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  93. package/template/.agents/skills/yss-tactical-design/SKILL.md +1 -3
  94. package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  95. package/template/.agents/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  96. package/template/.agents/skills/yss-validation/SKILL.md +1 -1
  97. package/template/.agents/skills/yss-web-controller/SKILL.md +16 -7
  98. package/template/.agents/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  99. package/template/.agents/skills/ytable-usage/SKILL.md +2 -2
  100. package/template/.codex/skills/alibaba-java-code-style/SKILL.md +2 -2
  101. package/template/.codex/skills/archify/SKILL.md +2 -19
  102. package/template/.codex/skills/archify/references/geometry-and-routing.md +20 -0
  103. package/template/.codex/skills/code-review/SKILL.md +3 -33
  104. package/template/.codex/skills/code-review/references/candidate-capture.md +33 -0
  105. package/template/.codex/skills/code-review/references/yss-review-standards.md +20 -0
  106. package/template/.codex/skills/codebase-design/SKILL.md +2 -2
  107. package/template/.codex/skills/competitive-intelligence/SKILL.md +1 -1
  108. package/template/.codex/skills/data-analytics/mcp/server.cjs +2 -1
  109. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +9 -32
  110. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +29 -0
  111. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +1 -1
  112. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +4 -4
  113. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +12 -22
  114. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +5 -10
  115. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +47 -49
  116. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +45 -0
  117. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +4 -5
  118. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +1 -1
  119. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +1 -1
  120. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +1 -1
  121. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +1 -1
  122. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +4 -4
  123. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +1 -1
  124. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +2 -2
  125. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +1 -1
  126. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +1 -1
  127. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +1 -1
  128. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +4 -4
  129. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +16 -14
  130. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +1 -1
  131. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +1 -1
  132. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +7 -7
  133. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +7 -7
  134. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +4 -2
  135. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +5 -5
  136. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +3 -3
  137. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +7 -71
  138. package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +70 -0
  139. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +4 -4
  140. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +1 -1
  141. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +1 -1
  142. package/template/.codex/skills/diagnosing-bugs/SKILL.md +6 -2
  143. package/template/.codex/skills/formily-foundation/SKILL.md +1 -1
  144. package/template/.codex/skills/formily-step-flow/SKILL.md +3 -2
  145. package/template/.codex/skills/frontend-commit/SKILL.md +6 -6
  146. package/template/.codex/skills/grilling/SKILL.md +2 -2
  147. package/template/.codex/skills/implement/SKILL.md +1 -1
  148. package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +3 -3
  149. package/template/.codex/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  150. package/template/.codex/skills/improve-codebase-architecture/SKILL.md +10 -6
  151. package/template/.codex/skills/java-backend-commit/SKILL.md +5 -5
  152. package/template/.codex/skills/llm-wiki/SKILL.md +1 -1
  153. package/template/.codex/skills/lombok/SKILL.md +1 -1
  154. package/template/.codex/skills/mapstruct/SKILL.md +3 -1
  155. package/template/.codex/skills/product-design/references/critical-overrides.md +3 -4
  156. package/template/.codex/skills/product-design/skills/audit/SKILL.md +1 -1
  157. package/template/.codex/skills/product-design/skills/design-qa/SKILL.md +1 -1
  158. package/template/.codex/skills/product-design/skills/get-context/SKILL.md +2 -1
  159. package/template/.codex/skills/product-design/skills/ideate/SKILL.md +2 -50
  160. package/template/.codex/skills/product-design/skills/ideate/references/image-prompt-patterns.md +51 -0
  161. package/template/.codex/skills/product-design/skills/image-to-code/SKILL.md +6 -6
  162. package/template/.codex/skills/product-design/skills/index/SKILL.md +2 -2
  163. package/template/.codex/skills/product-design/skills/prototype/SKILL.md +6 -6
  164. package/template/.codex/skills/product-design/skills/url-to-code/SKILL.md +1 -1
  165. package/template/.codex/skills/product-design/skills/user-context/SKILL.md +1 -1
  166. package/template/.codex/skills/prototype/SKILL.md +1 -1
  167. package/template/.codex/skills/prototype-review/SKILL.md +1 -1
  168. package/template/.codex/skills/resolving-merge-conflicts/SKILL.md +2 -2
  169. package/template/.codex/skills/tdd/SKILL.md +1 -1
  170. package/template/.codex/skills/to-questionnaire/SKILL.md +4 -2
  171. package/template/.codex/skills/to-spec/SKILL.md +3 -3
  172. package/template/.codex/skills/to-tickets/SKILL.md +7 -7
  173. package/template/.codex/skills/using-git-worktrees/SKILL.md +13 -11
  174. package/template/.codex/skills/wait-what/SKILL.md +1 -1
  175. package/template/.codex/skills/wayfinder/SKILL.md +4 -2
  176. package/template/.codex/skills/writing-for-agents/SKILL.md +9 -73
  177. package/template/.codex/skills/writing-for-agents/references/writing-principles.md +76 -0
  178. package/template/.codex/skills/yss-api-integration/SKILL.md +2 -2
  179. package/template/.codex/skills/yss-application/SKILL.md +12 -0
  180. package/template/.codex/skills/yss-application/references/application-layer-guide.md +7 -0
  181. package/template/.codex/skills/yss-audit-log/SKILL.md +3 -1
  182. package/template/.codex/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  183. package/template/.codex/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  184. package/template/.codex/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  185. package/template/.codex/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  186. package/template/.codex/skills/yss-backend-spec-review/SKILL.md +44 -0
  187. package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  188. package/template/.codex/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  189. package/template/.codex/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  190. package/template/.codex/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  191. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
  192. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  193. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  194. package/template/.codex/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  195. package/template/.codex/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  196. package/template/.codex/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  197. package/template/.codex/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  198. package/template/.codex/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  199. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  200. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  201. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  202. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  203. package/template/.codex/skills/yss-design-system/SKILL.md +2 -2
  204. package/template/.codex/skills/yss-domain/SKILL.md +17 -5
  205. package/template/.codex/skills/yss-domain/references/domain-layer-guide.md +10 -3
  206. package/template/.codex/skills/yss-domain/references/existing-project.md +5 -0
  207. package/template/.codex/skills/yss-dto/SKILL.md +13 -10
  208. package/template/.codex/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  209. package/template/.codex/skills/yss-exception/SKILL.md +2 -2
  210. package/template/.codex/skills/yss-formily-schema-generator/SKILL.md +12 -12
  211. package/template/.codex/skills/yss-hook/SKILL.md +8 -44
  212. package/template/.codex/skills/yss-hook/references/use-request.md +42 -0
  213. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +1 -5
  214. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  215. package/template/.codex/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  216. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  217. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  218. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  219. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  220. package/template/.codex/skills/yss-mybatis/SKILL.md +14 -0
  221. package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +1 -1
  222. package/template/.codex/skills/yss-openapi-governance/SKILL.md +1 -32
  223. package/template/.codex/skills/yss-openapi-governance/references/governance-output.md +34 -0
  224. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +1 -1
  225. package/template/.codex/skills/yss-prototype-stage/SKILL.md +1 -5
  226. package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  227. package/template/.codex/skills/yss-repository/SKILL.md +13 -1
  228. package/template/.codex/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  229. package/template/.codex/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  230. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  231. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  232. package/template/.codex/skills/yss-stage-decision/SKILL.md +1 -1
  233. package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  234. package/template/.codex/skills/yss-tactical-design/SKILL.md +1 -3
  235. package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  236. package/template/.codex/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  237. package/template/.codex/skills/yss-validation/SKILL.md +1 -1
  238. package/template/.codex/skills/yss-web-controller/SKILL.md +16 -7
  239. package/template/.codex/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  240. package/template/.codex/skills/ytable-usage/SKILL.md +2 -2
  241. package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +2 -2
  242. package/template/.cursor/skills/archify/SKILL.md +2 -19
  243. package/template/.cursor/skills/archify/references/geometry-and-routing.md +20 -0
  244. package/template/.cursor/skills/code-review/SKILL.md +3 -33
  245. package/template/.cursor/skills/code-review/references/candidate-capture.md +33 -0
  246. package/template/.cursor/skills/code-review/references/yss-review-standards.md +20 -0
  247. package/template/.cursor/skills/codebase-design/SKILL.md +2 -2
  248. package/template/.cursor/skills/competitive-intelligence/SKILL.md +1 -1
  249. package/template/.cursor/skills/diagnosing-bugs/SKILL.md +6 -2
  250. package/template/.cursor/skills/formily-foundation/SKILL.md +1 -1
  251. package/template/.cursor/skills/formily-step-flow/SKILL.md +3 -2
  252. package/template/.cursor/skills/frontend-commit/SKILL.md +6 -6
  253. package/template/.cursor/skills/grilling/SKILL.md +2 -2
  254. package/template/.cursor/skills/implement/SKILL.md +1 -1
  255. package/template/.cursor/skills/implementation-repo-onboarding/SKILL.md +3 -3
  256. package/template/.cursor/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  257. package/template/.cursor/skills/improve-codebase-architecture/SKILL.md +10 -6
  258. package/template/.cursor/skills/java-backend-commit/SKILL.md +5 -5
  259. package/template/.cursor/skills/llm-wiki/SKILL.md +1 -1
  260. package/template/.cursor/skills/lombok/SKILL.md +1 -1
  261. package/template/.cursor/skills/mapstruct/SKILL.md +3 -1
  262. package/template/.cursor/skills/prototype/SKILL.md +1 -1
  263. package/template/.cursor/skills/prototype-review/SKILL.md +1 -1
  264. package/template/.cursor/skills/resolving-merge-conflicts/SKILL.md +2 -2
  265. package/template/.cursor/skills/tdd/SKILL.md +1 -1
  266. package/template/.cursor/skills/to-questionnaire/SKILL.md +4 -2
  267. package/template/.cursor/skills/to-spec/SKILL.md +3 -3
  268. package/template/.cursor/skills/to-tickets/SKILL.md +7 -7
  269. package/template/.cursor/skills/using-git-worktrees/SKILL.md +13 -11
  270. package/template/.cursor/skills/wait-what/SKILL.md +1 -1
  271. package/template/.cursor/skills/wayfinder/SKILL.md +4 -2
  272. package/template/.cursor/skills/writing-for-agents/SKILL.md +9 -73
  273. package/template/.cursor/skills/writing-for-agents/references/writing-principles.md +76 -0
  274. package/template/.cursor/skills/yss-api-integration/SKILL.md +2 -2
  275. package/template/.cursor/skills/yss-application/SKILL.md +12 -0
  276. package/template/.cursor/skills/yss-application/references/application-layer-guide.md +7 -0
  277. package/template/.cursor/skills/yss-audit-log/SKILL.md +3 -1
  278. package/template/.cursor/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  279. package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  280. package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  281. package/template/.cursor/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  282. package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +44 -0
  283. package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  284. package/template/.cursor/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  285. package/template/.cursor/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  286. package/template/.cursor/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  287. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
  288. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  289. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  290. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  291. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  292. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  293. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  294. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  295. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  296. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  297. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  298. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  299. package/template/.cursor/skills/yss-design-system/SKILL.md +2 -2
  300. package/template/.cursor/skills/yss-domain/SKILL.md +17 -5
  301. package/template/.cursor/skills/yss-domain/references/domain-layer-guide.md +10 -3
  302. package/template/.cursor/skills/yss-domain/references/existing-project.md +5 -0
  303. package/template/.cursor/skills/yss-dto/SKILL.md +13 -10
  304. package/template/.cursor/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  305. package/template/.cursor/skills/yss-exception/SKILL.md +2 -2
  306. package/template/.cursor/skills/yss-formily-schema-generator/SKILL.md +12 -12
  307. package/template/.cursor/skills/yss-hook/SKILL.md +8 -44
  308. package/template/.cursor/skills/yss-hook/references/use-request.md +42 -0
  309. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +1 -5
  310. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  311. package/template/.cursor/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  312. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  313. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  314. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  315. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  316. package/template/.cursor/skills/yss-mybatis/SKILL.md +14 -0
  317. package/template/.cursor/skills/yss-openapi-draft-review/SKILL.md +1 -1
  318. package/template/.cursor/skills/yss-openapi-governance/SKILL.md +1 -32
  319. package/template/.cursor/skills/yss-openapi-governance/references/governance-output.md +34 -0
  320. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +1 -1
  321. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +1 -5
  322. package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  323. package/template/.cursor/skills/yss-repository/SKILL.md +13 -1
  324. package/template/.cursor/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  325. package/template/.cursor/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  326. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  327. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  328. package/template/.cursor/skills/yss-stage-decision/SKILL.md +1 -1
  329. package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  330. package/template/.cursor/skills/yss-tactical-design/SKILL.md +1 -3
  331. package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  332. package/template/.cursor/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  333. package/template/.cursor/skills/yss-validation/SKILL.md +1 -1
  334. package/template/.cursor/skills/yss-web-controller/SKILL.md +16 -7
  335. package/template/.cursor/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  336. package/template/.cursor/skills/ytable-usage/SKILL.md +2 -2
  337. package/template/.pi/skills/alibaba-java-code-style/SKILL.md +2 -2
  338. package/template/.pi/skills/archify/SKILL.md +2 -19
  339. package/template/.pi/skills/archify/references/geometry-and-routing.md +20 -0
  340. package/template/.pi/skills/code-review/SKILL.md +3 -33
  341. package/template/.pi/skills/code-review/references/candidate-capture.md +33 -0
  342. package/template/.pi/skills/code-review/references/yss-review-standards.md +20 -0
  343. package/template/.pi/skills/codebase-design/SKILL.md +2 -2
  344. package/template/.pi/skills/competitive-intelligence/SKILL.md +1 -1
  345. package/template/.pi/skills/diagnosing-bugs/SKILL.md +6 -2
  346. package/template/.pi/skills/formily-foundation/SKILL.md +1 -1
  347. package/template/.pi/skills/formily-step-flow/SKILL.md +3 -2
  348. package/template/.pi/skills/frontend-commit/SKILL.md +6 -6
  349. package/template/.pi/skills/grilling/SKILL.md +2 -2
  350. package/template/.pi/skills/implement/SKILL.md +1 -1
  351. package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +3 -3
  352. package/template/.pi/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  353. package/template/.pi/skills/improve-codebase-architecture/SKILL.md +10 -6
  354. package/template/.pi/skills/java-backend-commit/SKILL.md +5 -5
  355. package/template/.pi/skills/llm-wiki/SKILL.md +1 -1
  356. package/template/.pi/skills/lombok/SKILL.md +1 -1
  357. package/template/.pi/skills/mapstruct/SKILL.md +3 -1
  358. package/template/.pi/skills/prototype/SKILL.md +1 -1
  359. package/template/.pi/skills/prototype-review/SKILL.md +1 -1
  360. package/template/.pi/skills/resolving-merge-conflicts/SKILL.md +2 -2
  361. package/template/.pi/skills/tdd/SKILL.md +1 -1
  362. package/template/.pi/skills/to-questionnaire/SKILL.md +4 -2
  363. package/template/.pi/skills/to-spec/SKILL.md +3 -3
  364. package/template/.pi/skills/to-tickets/SKILL.md +7 -7
  365. package/template/.pi/skills/using-git-worktrees/SKILL.md +13 -11
  366. package/template/.pi/skills/wait-what/SKILL.md +1 -1
  367. package/template/.pi/skills/wayfinder/SKILL.md +4 -2
  368. package/template/.pi/skills/writing-for-agents/SKILL.md +9 -73
  369. package/template/.pi/skills/writing-for-agents/references/writing-principles.md +76 -0
  370. package/template/.pi/skills/yss-api-integration/SKILL.md +2 -2
  371. package/template/.pi/skills/yss-application/SKILL.md +12 -0
  372. package/template/.pi/skills/yss-application/references/application-layer-guide.md +7 -0
  373. package/template/.pi/skills/yss-audit-log/SKILL.md +3 -1
  374. package/template/.pi/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  375. package/template/.pi/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  376. package/template/.pi/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  377. package/template/.pi/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  378. package/template/.pi/skills/yss-backend-spec-review/SKILL.md +44 -0
  379. package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  380. package/template/.pi/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  381. package/template/.pi/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  382. package/template/.pi/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  383. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
  384. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  385. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  386. package/template/.pi/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  387. package/template/.pi/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  388. package/template/.pi/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  389. package/template/.pi/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  390. package/template/.pi/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  391. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  392. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  393. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  394. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  395. package/template/.pi/skills/yss-design-system/SKILL.md +2 -2
  396. package/template/.pi/skills/yss-domain/SKILL.md +17 -5
  397. package/template/.pi/skills/yss-domain/references/domain-layer-guide.md +10 -3
  398. package/template/.pi/skills/yss-domain/references/existing-project.md +5 -0
  399. package/template/.pi/skills/yss-dto/SKILL.md +13 -10
  400. package/template/.pi/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  401. package/template/.pi/skills/yss-exception/SKILL.md +2 -2
  402. package/template/.pi/skills/yss-formily-schema-generator/SKILL.md +12 -12
  403. package/template/.pi/skills/yss-hook/SKILL.md +8 -44
  404. package/template/.pi/skills/yss-hook/references/use-request.md +42 -0
  405. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +1 -5
  406. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  407. package/template/.pi/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  408. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  409. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  410. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  411. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  412. package/template/.pi/skills/yss-mybatis/SKILL.md +14 -0
  413. package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +1 -1
  414. package/template/.pi/skills/yss-openapi-governance/SKILL.md +1 -32
  415. package/template/.pi/skills/yss-openapi-governance/references/governance-output.md +34 -0
  416. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +1 -1
  417. package/template/.pi/skills/yss-prototype-stage/SKILL.md +1 -5
  418. package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  419. package/template/.pi/skills/yss-repository/SKILL.md +13 -1
  420. package/template/.pi/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  421. package/template/.pi/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  422. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  423. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  424. package/template/.pi/skills/yss-stage-decision/SKILL.md +1 -1
  425. package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  426. package/template/.pi/skills/yss-tactical-design/SKILL.md +1 -3
  427. package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  428. package/template/.pi/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  429. package/template/.pi/skills/yss-validation/SKILL.md +1 -1
  430. package/template/.pi/skills/yss-web-controller/SKILL.md +16 -7
  431. package/template/.pi/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  432. package/template/.pi/skills/ytable-usage/SKILL.md +2 -2
  433. package/template/docs/agents/yss-skill-registry.yaml +13 -0
  434. package/template/docs/engineering/backend-platforms.md +14 -0
  435. package/template/docs/process/schemas/digital-human-task-package.schema.json +713 -100
  436. package/template/docs/process/schemas/slice-implementation-contract-v3.schema.json +41 -0
  437. package/template/scripts/backend-standards-coverage +26 -0
  438. package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
  439. package/template/scripts/lib/backend-platform-verification.mjs +2 -2
  440. package/template/scripts/lib/backend-platform.mjs +62 -0
  441. package/template/scripts/lib/backend-review.mjs +140 -0
  442. package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
  443. package/template/scripts/lib/first-slice-artifacts.mjs +47 -0
  444. package/template/scripts/lib/first-slice-tests.mjs +24 -0
  445. package/template/scripts/lib/lifecycle-transition.mjs +9 -0
  446. package/template/scripts/lib/maintenance-candidate.mjs +160 -0
  447. package/template/scripts/lib/profile-skill-sync.mjs +46 -5
  448. package/template/scripts/lib/slice-execution-preflight.mjs +43 -0
  449. package/template/scripts/slice-contract +7 -3
  450. package/template/scripts/verify-backend-platform-matrix +8 -2
  451. package/template/skills-lock.json +77 -63
  452. package/template/yss-public-skills.json +4 -2
  453. package/template.manifest.json +0 -1
  454. package/template.snapshot.json +5 -5
@@ -0,0 +1,47 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ /** Declarations bind responsibilities to compiled types, not naming conventions. */
5
+ export function inspectFirstSliceArtifacts(contract, projectRoot) {
6
+ const declaration = contract.backend?.first_slice;
7
+ const failures = [], properties = { 'yss.firstSlice': 'true' };
8
+ if (!declaration || !Array.isArray(declaration.artifacts) || !declaration.artifacts.length) {
9
+ return { failures: ['backend.first_slice.artifacts-required'], properties };
10
+ }
11
+ const roles = new Map(), types = [], seen = new Set();
12
+ const root = fs.realpathSync(projectRoot);
13
+ for (const item of declaration.artifacts) {
14
+ const label = item?.type || item?.path || 'unknown';
15
+ try {
16
+ if (!['domain','application','infrastructure','web','test'].includes(item.role)) throw Error('invalid-role');
17
+ if (!/^[a-zA-Z_$][\w$]*(\.[a-zA-Z_$][\w$]*)+$/.test(item.type || '')) throw Error('qualified-type-required');
18
+ if (seen.has(item.type)) throw Error('duplicate-type');
19
+ seen.add(item.type);
20
+ if (!item.path || path.isAbsolute(item.path) || item.path.split(/[\\/]/).includes('..')) throw Error('relative-path-required');
21
+ const file = fs.realpathSync(path.resolve(root, item.path));
22
+ if (!file.startsWith(`${root}${path.sep}`)) throw Error('path-escape');
23
+ const source = fs.readFileSync(file, 'utf8');
24
+ const pkg = source.match(/^\s*package\s+([\w.]+)\s*;/m)?.[1];
25
+ const name = item.type.slice(item.type.lastIndexOf('.') + 1);
26
+ if (`${pkg}.${name}` !== item.type || !new RegExp(`\\b(class|interface|enum|record)\\s+${name}\\b`).test(source)) throw Error('declared-type-mismatch');
27
+ if (item.role === 'test') {
28
+ if (!item.path.includes('/src/test/java/')) throw Error('test-source-required');
29
+ } else {
30
+ if (!item.path.includes('/src/main/java/')) throw Error('main-source-required');
31
+ types.push(item.type);
32
+ const packages = roles.get(item.role) || new Set(); packages.add(pkg); roles.set(item.role, packages);
33
+ }
34
+ } catch (error) { failures.push(`${label}:${error.message}`); }
35
+ }
36
+ const aliases = { service: 'application', core: 'application', repository: 'infrastructure', server: 'web' };
37
+ for (const layer of contract.backend.affected_layers || []) {
38
+ const role = aliases[layer] || layer;
39
+ if (['domain','application','infrastructure','web'].includes(role) && !roles.has(role)) failures.push(`affected-role-empty:${role}`);
40
+ }
41
+ if (!declaration.artifacts.some(item => item.role === 'test')) failures.push('behavior-test-binding-required');
42
+ if ((contract.backend.affected_layers || []).some(layer => ['web','server'].includes(layer))) properties['yss.arch.requireController'] = 'true';
43
+ if (!types.length) failures.push('business-type-required');
44
+ properties['yss.arch.requiredTypes'] = types.join(',');
45
+ for (const [role, packages] of roles) properties[`yss.arch.${role}`] = [...packages].join(',');
46
+ return { failures, properties };
47
+ }
@@ -0,0 +1,24 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { parseXmlDocument } from '../vendor/xml.mjs';
5
+ const array = value => value === undefined ? [] : Array.isArray(value) ? value : [value];
6
+
7
+ export function verifyFirstSliceTests(contract, projectRoot, startedAt, architectureType) {
8
+ const declarations = contract.backend.first_slice.artifacts.filter(item => item.role === 'test');
9
+ const required = [...declarations.map(item => ({ type: item.type, module: item.path.split('/src/test/java/')[0] })), architectureType];
10
+ const evidence = [], failures = [];
11
+ for (const item of required) {
12
+ try {
13
+ const candidates = ['surefire-reports','failsafe-reports'].map(folder => path.join(projectRoot,item.module,'target',folder,`TEST-${item.type}.xml`));
14
+ const ref = candidates.find(file => fs.existsSync(file) && fs.statSync(file).mtimeMs >= startedAt);
15
+ if (!ref) throw Error('fresh execution report missing');
16
+ const bytes = fs.readFileSync(ref), suite = parseXmlDocument(bytes.toString()).testsuite;
17
+ const cases = array(suite?.testcase);
18
+ if (!cases.length || cases.some(c => ['failure','error','skipped'].some(key => Object.hasOwn(c,key)))) throw Error('test not executed successfully');
19
+ if (cases.some(c => c['@_classname'] !== item.type)) throw Error('test class does not match contract');
20
+ evidence.push({type:item.type,ref,sha256:createHash('sha256').update(bytes).digest('hex'),test_count:cases.length});
21
+ } catch(error) { failures.push(`${item.type}:${error.message}`); }
22
+ }
23
+ return { status: failures.length ? 'failed' : 'passed', evidence, failures };
24
+ }
@@ -9,6 +9,7 @@ import { validatePlanSpecEntry } from "./plan-spec-entry.mjs";
9
9
  import path from "node:path";
10
10
  import { validateApiContractDecision } from "./api-contract-decision.mjs";
11
11
  import { loadApprovalRecord, validateApprovalRecord } from "./approval-record.mjs";
12
+ import { validateBackendReview } from "./backend-review.mjs";
12
13
  import { ROOT } from "./lifecycle-registry.mjs";
13
14
 
14
15
  const IMPLEMENTATION_WORK_UNIT = "work-unit.slice-implementation";
@@ -248,6 +249,14 @@ function validateTicketReference(ref, trackerKind) {
248
249
  * by `validateWorkflowExecutionResult` before this function is called.
249
250
  */
250
251
  export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, options = {}) {
252
+ if (currentWorkUnit === "work-unit.code-review" && nextRoute === "work-unit.release-and-retrospective") {
253
+ try {
254
+ if (decisionState?.review_input?.scope_kind !== "change") throw new Error("只读基线审计不能关闭实现审查");
255
+ validateBackendReview(decisionState, { root: options.root || ROOT });
256
+ }
257
+ catch (error) { return blockedResult(["backend-review-incomplete"], [error.message]); }
258
+ }
259
+
251
260
 
252
261
  if (["work-unit.technical-analysis", TICKET_DECOMPOSITION_WORK_UNIT, IMPLEMENTATION_WORK_UNIT, "work-unit.frontend-implementation-verification"].includes(nextRoute)) {
253
262
  try { enforceFrontendDelivery(decisionState, { root: options.root, phase: nextRoute === IMPLEMENTATION_WORK_UNIT ? "implementation" : "inputs" }); }
@@ -0,0 +1,160 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
+ import path from "node:path";
5
+ import { parseDocument, stringify } from "../vendor/yaml.mjs";
6
+
7
+ const MAGIC = Buffer.from("YSS-WORKTREE-CANDIDATE-V1\0", "ascii");
8
+ const MAX_BUFFER = 512 * 1024 * 1024;
9
+ const MAINTENANCE_EVIDENCE_ROOT = ".template-source/evidence/maintenance";
10
+ const CANDIDATE_FILES = ["candidate-manifest.yaml", "candidate.bin", "tracked.diff"];
11
+
12
+ function fail(message) { throw new TypeError(message); }
13
+ function ensure(condition, message) { if (!condition) fail(message); }
14
+ function git(args, root, encoding = "utf8") {
15
+ const result = spawnSync("git", args, { cwd: root, encoding, maxBuffer: MAX_BUFFER });
16
+ if (result.status !== 0) fail((typeof result.stderr === "string" ? result.stderr : result.stderr?.toString()).trim() || `git ${args.join(" ")} 执行失败`);
17
+ return result.stdout;
18
+ }
19
+ function uint64(value) { const buffer = Buffer.alloc(8); buffer.writeBigUInt64BE(BigInt(value)); return buffer; }
20
+ function uint32(value) { const buffer = Buffer.alloc(4); buffer.writeUInt32BE(value >>> 0); return buffer; }
21
+ function splitNull(buffer) {
22
+ const result = [];
23
+ let start = 0;
24
+ for (let index = 0; index < buffer.length; index += 1) if (buffer[index] === 0) { if (index > start) result.push(buffer.subarray(start, index)); start = index + 1; }
25
+ if (start < buffer.length) result.push(buffer.subarray(start));
26
+ return result;
27
+ }
28
+ function normalizeRelative(value, label) {
29
+ ensure(typeof value === "string" && value.trim(), `${label} 不能为空`);
30
+ const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
31
+ ensure(normalized && !path.posix.isAbsolute(normalized) && path.posix.normalize(normalized) === normalized && normalized !== ".." && !normalized.startsWith("../"), `${label} 必须是规范的仓库内相对路径`);
32
+ return normalized;
33
+ }
34
+ function isMaintenanceEvidencePath(value) {
35
+ return value === MAINTENANCE_EVIDENCE_ROOT || value.startsWith(`${MAINTENANCE_EVIDENCE_ROOT}/`);
36
+ }
37
+ function readLength(buffer, offset, bytes, label) {
38
+ ensure(offset + bytes <= buffer.length, `packed candidate 缺少 ${label}`);
39
+ const value = bytes === 8 ? buffer.readBigUInt64BE(offset) : BigInt(buffer.readUInt32BE(offset));
40
+ ensure(value <= BigInt(Number.MAX_SAFE_INTEGER), `packed candidate ${label} 过大`);
41
+ return { value: Number(value), offset: offset + bytes };
42
+ }
43
+
44
+ export function captureMaintenanceCandidate({ root, outputDir, baseRef = "HEAD", excludePaths = [] }) {
45
+ const repositoryRoot = path.resolve(root);
46
+ const outputPath = path.resolve(repositoryRoot, outputDir);
47
+ const outputRelative = normalizeRelative(path.relative(repositoryRoot, outputPath).replaceAll(path.sep, "/"), "outputDir");
48
+ ensure(isMaintenanceEvidencePath(outputRelative), `outputDir 必须位于 ${MAINTENANCE_EVIDENCE_ROOT}`);
49
+ ensure(!existsSync(outputPath), "outputDir 必须不存在,禁止复用可能含残留文件的候选目录");
50
+ ensure(Array.isArray(excludePaths), "excludePaths 必须是数组");
51
+ const explicitExclusions = excludePaths.map((value) => normalizeRelative(value, "excludePaths"));
52
+ for (const exclusion of explicitExclusions) ensure(isMaintenanceEvidencePath(exclusion), `excludePaths 只允许 ${MAINTENANCE_EVIDENCE_ROOT} 下的维护证据`);
53
+ const exclusions = [...new Set([outputRelative, ...explicitExclusions])];
54
+ const mergeBase = git(["merge-base", baseRef, "HEAD"], repositoryRoot).trim();
55
+ const trackedDiff = git(["diff", "--no-ext-diff", "--binary", "--full-index", mergeBase], repositoryRoot, null);
56
+ const rawPaths = splitNull(git(["ls-files", "-z", "--others", "--exclude-standard"], repositoryRoot, null))
57
+ .filter((rawPath) => {
58
+ const value = rawPath.toString();
59
+ return !exclusions.some((exclusion) => value === exclusion || value.startsWith(`${exclusion}/`));
60
+ })
61
+ .sort(Buffer.compare);
62
+ ensure(trackedDiff.length > 0 || rawPaths.length > 0, "维护候选不能为空");
63
+
64
+ const parts = [MAGIC, Buffer.from([0x54]), uint64(trackedDiff.length), trackedDiff];
65
+ const untrackedFiles = [];
66
+ const untrackedPathBytes = [];
67
+ for (const rawPath of rawPaths) {
68
+ ensure(!rawPath.includes(0) && rawPath.length > 0, "untracked path 无效");
69
+ const relative = rawPath.toString();
70
+ const absolute = path.resolve(repositoryRoot, relative);
71
+ ensure(!path.relative(repositoryRoot, absolute).startsWith(".."), `untracked path 越界: ${relative}`);
72
+ const stat = lstatSync(absolute);
73
+ let kind;
74
+ let content;
75
+ if (stat.isFile()) { kind = 0x52; content = readFileSync(absolute); }
76
+ else if (stat.isSymbolicLink()) { kind = 0x4c; content = readlinkSync(absolute, { encoding: "buffer" }); }
77
+ else fail(`候选包含不支持的 untracked 类型: ${relative}`);
78
+ parts.push(Buffer.from([0x55]), uint64(rawPath.length), rawPath, uint32(stat.mode), Buffer.from([kind]), uint64(content.length), content);
79
+ untrackedFiles.push(relative);
80
+ untrackedPathBytes.push(rawPath.toString("base64"));
81
+ }
82
+ const stream = Buffer.concat(parts);
83
+ const digest = createHash("sha256").update(stream).digest("hex");
84
+ const streamRef = `${outputRelative}/candidate.bin`;
85
+ const diffRef = `${outputRelative}/tracked.diff`;
86
+ const manifestRef = `${outputRelative}/candidate-manifest.yaml`;
87
+ const manifest = {
88
+ schema_version: 1,
89
+ candidate_kind: "yss-worktree-candidate-v1",
90
+ storage: "packed-stream",
91
+ review_mode: "worktree",
92
+ review_base_ref: baseRef,
93
+ merge_base: mergeBase,
94
+ implementation_candidate_ref: "working-tree",
95
+ candidate_snapshot_ref: manifestRef,
96
+ candidate_digest: digest,
97
+ tracked_diff_command: `git diff --no-ext-diff --binary --full-index ${mergeBase}`,
98
+ untracked_inventory_command: "git ls-files -z --others --exclude-standard",
99
+ untracked_diff_command: "packed in candidate.bin",
100
+ untracked_files: untrackedFiles,
101
+ untracked_path_bytes: untrackedPathBytes,
102
+ excluded_paths: exclusions,
103
+ snapshot_stream_ref: streamRef,
104
+ tracked_diff_ref: diffRef,
105
+ commit_list_command: `git log ${baseRef}..HEAD --oneline`
106
+ };
107
+ const outputParent = path.dirname(outputPath);
108
+ mkdirSync(outputParent, { recursive: true });
109
+ const stagingPath = mkdtempSync(path.join(outputParent, ".candidate-staging-"));
110
+ try {
111
+ writeFileSync(path.join(stagingPath, "candidate.bin"), stream);
112
+ writeFileSync(path.join(stagingPath, "tracked.diff"), trackedDiff);
113
+ writeFileSync(path.join(stagingPath, "candidate-manifest.yaml"), stringify(manifest, { lineWidth: 0 }));
114
+ renameSync(stagingPath, outputPath);
115
+ } finally {
116
+ if (existsSync(stagingPath)) rmSync(stagingPath, { recursive: true, force: true });
117
+ }
118
+ return { candidate_digest: digest, manifest, manifest_ref: manifestRef, files: [manifestRef, streamRef, diffRef] };
119
+ }
120
+
121
+ export function inspectMaintenanceCandidate({ manifestPath }) {
122
+ const absoluteManifest = path.resolve(manifestPath);
123
+ const document = parseDocument(readFileSync(absoluteManifest, "utf8"), { uniqueKeys: true });
124
+ ensure(document.errors.length === 0, document.errors[0]?.message || "candidate manifest 无法解析");
125
+ const manifest = document.toJS({ maxAliasCount: 0 });
126
+ ensure(manifest.storage === "packed-stream", "只支持 packed-stream candidate");
127
+ const candidateDir = path.dirname(absoluteManifest);
128
+ ensure(JSON.stringify(readdirSync(candidateDir).sort()) === JSON.stringify([...CANDIDATE_FILES].sort()), `packed candidate 目录必须恰好包含 ${CANDIDATE_FILES.join("、")}`);
129
+ const root = path.resolve(path.dirname(absoluteManifest), ...Array(manifest.candidate_snapshot_ref.split("/").length - 1).fill(".."));
130
+ ensure(path.resolve(root, manifest.candidate_snapshot_ref) === absoluteManifest, "candidate_snapshot_ref 未绑定当前 manifest");
131
+ const streamPath = path.resolve(root, manifest.snapshot_stream_ref);
132
+ const diffPath = path.resolve(root, manifest.tracked_diff_ref);
133
+ ensure(streamPath === path.join(candidateDir, "candidate.bin") && diffPath === path.join(candidateDir, "tracked.diff"), "packed candidate 引用必须绑定同目录规范文件");
134
+ const stream = readFileSync(streamPath);
135
+ ensure(createHash("sha256").update(stream).digest("hex") === manifest.candidate_digest.replace(/^sha256:/, ""), "candidate_digest 与 packed stream 不一致");
136
+ ensure(stream.subarray(0, MAGIC.length).equals(MAGIC), "packed stream magic 无效");
137
+ let offset = MAGIC.length;
138
+ ensure(stream[offset] === 0x54, "packed stream 缺少 tracked record");
139
+ offset += 1;
140
+ let length = readLength(stream, offset, 8, "tracked length");
141
+ offset = length.offset;
142
+ const trackedDiff = stream.subarray(offset, offset + length.value);
143
+ offset += length.value;
144
+ ensure(readFileSync(diffPath).equals(trackedDiff), "tracked.diff 与 packed stream 不一致");
145
+ const entries = [];
146
+ while (offset < stream.length) {
147
+ ensure(stream[offset] === 0x55, "packed stream record kind 无效");
148
+ offset += 1;
149
+ length = readLength(stream, offset, 8, "path length"); offset = length.offset;
150
+ const rawPath = stream.subarray(offset, offset + length.value); offset += length.value;
151
+ length = readLength(stream, offset, 4, "mode"); offset = length.offset;
152
+ const mode = length.value;
153
+ const kind = stream[offset]; offset += 1;
154
+ length = readLength(stream, offset, 8, "content length"); offset = length.offset;
155
+ const content = stream.subarray(offset, offset + length.value); offset += length.value;
156
+ entries.push({ path: rawPath.toString(), path_bytes: rawPath.toString("base64"), mode, kind: kind === 0x52 ? "regular" : "symlink", content });
157
+ }
158
+ ensure(JSON.stringify(entries.map((entry) => entry.path_bytes)) === JSON.stringify(manifest.untracked_path_bytes), "manifest inventory 与 packed stream 不一致");
159
+ return { manifest, trackedDiff, entries };
160
+ }
@@ -31,6 +31,8 @@ function files(directory, prefix = "") {
31
31
  if (!info.isDirectory()) fail(`技能源必须是目录: ${directory}`);
32
32
  const result = new Map();
33
33
  for (const entry of readdirSync(directory, { withFileTypes: true })) {
34
+ // Match the skill supply-chain inventory: interpreter caches are not source.
35
+ if (entry.name === "__pycache__" || entry.name === ".DS_Store" || /\.(iml|pyc|pyo)$/.test(entry.name)) continue;
34
36
  if (entry.isSymbolicLink()) fail(`跨仓同步不接受符号链接: ${path.join(directory, entry.name)}`);
35
37
  const absolute = path.join(directory, entry.name);
36
38
  const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
@@ -103,6 +105,29 @@ function dirtyMatch(dirty, relative) {
103
105
  return [...dirty].some((entry) => entry === relative || entry.startsWith(`${relative}/`) || relative.startsWith(`${entry}/`));
104
106
  }
105
107
 
108
+ function checkEntryReferences(profile, profileRoot, definition, changes, issues) {
109
+ const overlay = new Map(changes.filter((item) => item.profile === profile).map((item) => [path.resolve(profileRoot, item.path), item.content]));
110
+ const entries = new Set();
111
+ for (const relative of [".agents/skills", ...(definition.reference_roots ?? [])]) {
112
+ const directory = safe(profileRoot, relative, "reference root");
113
+ for (const name of files(directory).keys()) if (name.endsWith("/SKILL.md")) entries.add(path.join(directory, name));
114
+ }
115
+ for (const [file, content] of overlay) if (content !== null && file.endsWith("/SKILL.md")) entries.add(file);
116
+ for (const file of entries) {
117
+ const content = overlay.has(file) ? overlay.get(file) : readFileSync(file);
118
+ if (content === null) continue;
119
+ const prose = content.toString("utf8").replace(/```[\s\S]*?```/g, "").replace(/`[^`]*`/g, "");
120
+ for (const match of prose.matchAll(/\]\(([^\s)]+)\)/g)) {
121
+ const link = match[1].split("#")[0];
122
+ if (!link || /^[a-z][a-z\d+.-]*:/i.test(link) || link.includes("<")) continue;
123
+ const target = path.resolve(path.dirname(file), link);
124
+ const inside = target.startsWith(`${path.resolve(profileRoot)}${path.sep}`);
125
+ const present = inside && (overlay.has(target) ? overlay.get(target) !== null : existsSync(target));
126
+ if (!present) issues.push({ profile, status: "missing_reference", path: `${definition.target}/${path.relative(profileRoot, file)}`, message: `Skill 引用无法解析: ${link}` });
127
+ }
128
+ }
129
+ }
130
+
106
131
  function transformedSource(root, profile, item) {
107
132
  const source = safe(root, item.source ?? `.agents/skills/${item.id}`, "source");
108
133
  const sourceFiles = files(source);
@@ -262,22 +287,38 @@ export function planProfileSkillSync({ root, config, selectedProfiles, dirtyProv
262
287
  const targetSkillRoot = safe(profileRoot, ".agents/skills", "profile skill root");
263
288
  if (existsSync(targetSkillRoot)) {
264
289
  for (const entry of readdirSync(targetSkillRoot, { withFileTypes: true })) {
265
- if (!entry.isDirectory() || classified.has(entry.name)) continue;
266
- const sourceSkill = path.join(canonicalRoot, entry.name);
267
- if (!existsSync(sourceSkill) || !lstatSync(sourceSkill).isDirectory()) continue;
268
- if (!sameTree(files(sourceSkill), files(path.join(targetSkillRoot, entry.name)))) {
290
+ if (!entry.isDirectory() || !existsSync(path.join(targetSkillRoot, entry.name, "SKILL.md"))) continue;
291
+ const classification = classified.get(entry.name);
292
+ if (classification === "excluded") {
293
+ issues.push({ profile, skill: entry.name, status: "active_excluded", path: `${definition.target}/.agents/skills/${entry.name}`, message: "活跃 Skill 不能用 excluded 跳过维护;登记 exact、adapted、local_only 或 upstream" });
294
+ } else if (!classification) {
269
295
  issues.push({
270
296
  profile,
271
297
  skill: entry.name,
272
298
  status: "unregistered_difference",
273
299
  path: `${definition.target}/.agents/skills/${entry.name}`,
274
- message: "同名 Skill 内容不同但未登记同步分类",
300
+ message: "实际 Skill 入口未登记同步分类(包括内容相同及 profile 独有入口)",
275
301
  });
276
302
  }
277
303
  }
278
304
  }
279
305
 
306
+ // Platform packages are source directories, unlike generated shared projections.
307
+ // Register them using exact/adapted source and target paths; keep schema v1 readable.
308
+ for (const platformRoot of config.platform_roots ?? []) {
309
+ const directory = safe(profileRoot, platformRoot, "platform root");
310
+ if (!existsSync(directory)) continue;
311
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
312
+ if (!entry.isDirectory() || existsSync(path.join(targetSkillRoot, entry.name, "SKILL.md"))) continue;
313
+ const relative = `${platformRoot}/${entry.name}`;
314
+ if (![...files(path.join(directory, entry.name)).keys()].some((name) => name === "SKILL.md" || name.endsWith("/SKILL.md"))) continue;
315
+ const owners = [...(definition.exact ?? []), ...(definition.adapted ?? [])].filter((item) => item.target === relative);
316
+ if (owners.length !== 1) issues.push({ profile, skill: entry.name, status: "unregistered_platform_package", path: `${definition.target}/${relative}`, message: "平台技能包必须按完整包路径登记唯一来源" });
317
+ }
318
+ }
319
+
280
320
  const changedPaths = [...new Set(changes.filter((item) => item.profile === profile).map((item) => item.path))];
321
+ if (config.verify_entry_references) checkEntryReferences(profile, profileRoot, definition, changes, issues);
281
322
  const dirty = dirtyProvider(profileRoot, changedPaths);
282
323
  for (const change of changes.filter((item) => item.profile === profile && dirtyMatch(dirty, item.path))) {
283
324
  issues.push({ profile, skill: change.skill, status: "adaptation_conflict", path: `${definition.target}/${change.path}`, message: "目标含未提交改动" });
@@ -0,0 +1,43 @@
1
+ import { readSliceContract } from './slice-contract.mjs';
2
+ import { createApprovedExecutionContext } from './approved-execution-context.mjs';
3
+ import { evaluateContractFreshness, loadCompilerContract } from './implementation-contract-compiler.mjs';
4
+ import { loadSkillRegistry } from './skill-registry.mjs';
5
+
6
+ /** Readability, structure and execution approval are different levels of evidence. */
7
+ export function inspectSliceContract(ref, { root = process.cwd(), approval_ref, work_unit_id } = {}) {
8
+ const loaded = readSliceContract(ref, { root });
9
+ const { contract, binding } = loaded;
10
+ const checks = { readable: 'passed', structure: 'passed', approval: 'not-checked', freshness: 'not-checked' };
11
+ const blockers = [];
12
+ if (loaded.raw.schema_version === 2) {
13
+ for (const [section, fields] of Object.entries(loadCompilerContract().slice_contract_required)) {
14
+ const target = section === 'root' ? contract : contract[section];
15
+ for (const field of fields) if (!target || !Object.hasOwn(target, field)) blockers.push(`missing:${section}.${field}`);
16
+ }
17
+ for (const section of ['common', 'resolution', 'backend']) {
18
+ if (!Array.isArray(contract[section]?.required_skills)) blockers.push(`invalid:${section}.required_skills`);
19
+ }
20
+ if (!Array.isArray(contract.work_units) || !contract.work_units.length) blockers.push('slice-contract-work-units-missing');
21
+ for (const unit of contract.work_units || []) {
22
+ if (unit.contract_id !== contract.contract_id) blockers.push(`work-unit-contract-id-mismatch:${unit.id}`);
23
+ if (unit.contract_version !== contract.contract_version) blockers.push(`work-unit-contract-version-mismatch:${unit.id}`);
24
+ if (!unit.work_unit?.primary_skill) blockers.push(`work-unit-primary-skill-missing:${unit.id}`);
25
+ }
26
+ if (blockers.length) checks.structure = 'failed';
27
+ }
28
+ if (approval_ref && !blockers.length) {
29
+ try {
30
+ const approved_slice = { ...binding, approval_ref };
31
+ const context = createApprovedExecutionContext(approved_slice, { root, contract, work_unit_id });
32
+ checks.approval = 'passed';
33
+ const current = evaluateContractFreshness(contract, { root, registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), approved_slice, work_unit_id }, context);
34
+ checks.freshness = current.freshness === 'current' ? 'passed' : 'failed';
35
+ blockers.push(...current.reasons);
36
+ } catch (error) {
37
+ checks.approval = 'failed';
38
+ blockers.push(error.code || error.message);
39
+ }
40
+ }
41
+ return { ...loaded, report: { read_only: true, ...binding, checks, approval_validity: checks.approval,
42
+ execution_allowed: !!approval_ref && !blockers.length && checks.freshness === 'passed', blockers } };
43
+ }
@@ -4,13 +4,14 @@ import path from 'node:path';
4
4
  import { prepareSliceImplementationContract, migrateSliceContractV2, persistSliceDraft } from './lib/slice-contract-preparation.mjs';
5
5
  import { renderSliceContractView, diffSliceContracts } from './lib/slice-contract-views.mjs';
6
6
  import { parseSliceYaml, readSliceContract } from './lib/slice-contract.mjs';
7
+ import { inspectSliceContract } from './lib/slice-execution-preflight.mjs';
7
8
 
8
9
  try {
9
10
  const args=process.argv.slice(2),mode=args.shift(),options={},positional=[];
10
11
  for(let i=0;i<args.length;i++) {
11
12
  if(args[i]==='--json'){options.json=true;continue;}
12
13
  if(args[i].startsWith('--')) {
13
- const key=args[i].slice(2);if(!['root','input','output','unit','before-root'].includes(key)||!args[i+1])throw new Error(`未知或缺值参数 ${args[i]}`);
14
+ const key=args[i].slice(2);if(!['root','input','output','unit','before-root','approval-ref'].includes(key)||!args[i+1])throw new Error(`未知或缺值参数 ${args[i]}`);
14
15
  options[key]=args[++i];
15
16
  }else positional.push(args[i]);
16
17
  }
@@ -24,7 +25,10 @@ try {
24
25
  if(result.report.blockers.length)process.exitCode=1;
25
26
  }else if(mode==='view')result=renderSliceContractView(positional[0],{root,unit_id:options.unit});
26
27
  else if(mode==='diff')result=diffSliceContracts(positional[0],positional[1],{root,beforeRoot:options['before-root']?path.resolve(options['before-root']):root});
27
- else if(mode==='verify')result={read_only:true,approval_validity:'not-checked',...readSliceContract(positional[0],{root}).binding};
28
- else throw new Error('用法: scripts/slice-contract prepare <ticket> --input <补充.yaml> --output <新合同.yaml> | migrate <v2.yaml> --input <补充.yaml> --output <新合同.yaml> | view <合同.yaml> [--unit <id>] | diff <旧合同> <新合同> | verify <合同> [--root <项目根>]');
28
+ else if(mode==='verify') {
29
+ result=inspectSliceContract(positional[0],{root,approval_ref:options['approval-ref'],work_unit_id:options.unit}).report;
30
+ if(result.blockers.length)process.exitCode=1;
31
+ }
32
+ else throw new Error('用法: scripts/slice-contract prepare <ticket> --input <补充.yaml> --output <新合同.yaml> | migrate <v2.yaml> --input <补充.yaml> --output <新合同.yaml> | view <合同.yaml> [--unit <id>] | diff <旧合同> <新合同> | verify <合同> [--root <项目根>] [--approval-ref <批准记录>] [--unit <工作单元>]');
29
33
  process.stdout.write(options.json||!result.markdown?`${JSON.stringify(result,null,2)}\n`:`${result.markdown}\n`);
30
34
  }catch(error){process.stderr.write(`${error.message}\n`);process.exitCode=1;}
@@ -10,7 +10,7 @@ import { ScaffoldGenerator, parseArgs as dddArgs } from "../.agents/skills/yss-d
10
10
  import { generate, validateContract as validateMvcContract, parseArgs as mvcArgs } from "../.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs";
11
11
  import { run } from "../.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs";
12
12
 
13
- const { values } = parseArgs({ options: { "evidence-dir": { type: "string" }, inputs: { type: "string" }, resume: { type: "boolean", default: false } }, strict: true });
13
+ const { values } = parseArgs({ options: { "evidence-dir": { type: "string" }, inputs: { type: "string" }, resume: { type: "boolean", default: false }, "require-combination": { type: "string", multiple: true } }, strict: true });
14
14
  if (!values["evidence-dir"]) throw new Error("--evidence-dir is required; optional --inputs points to real approved contracts and candidate catalog");
15
15
  const evidence = path.resolve(values["evidence-dir"]);
16
16
  await mkdir(evidence, { recursive: true });
@@ -24,9 +24,15 @@ for (const item of input.combinations ?? []) {
24
24
  if (keys.has(key) || !catalog.profiles.some(p => p.id === item.profile_id && p.spring_boot_version === item.spring_boot_version) || !["domain-driven", "layered-mvc"].includes(item.architecture_family)) throw new Error("duplicate or unknown exact matrix combination");
25
25
  keys.add(key);
26
26
  }
27
+ const allKeys = loadBackendPlatforms().profiles.flatMap(profile => ["domain-driven", "layered-mvc"].map(family => `${profile.id}:${profile.spring_boot_version}:${family}`));
28
+ const requested = values["require-combination"] || input.required_combinations || allKeys;
29
+ if (!Array.isArray(requested) || !requested.length || new Set(requested).size !== requested.length || requested.some(key => !allKeys.includes(key))) throw new Error("required combinations must be unique exact profile_id:spring_boot_version:architecture_family keys");
30
+ const required = new Set(requested);
27
31
  const rows = [];
28
32
  for (const profile of loadBackendPlatforms().profiles) for (const family of ["domain-driven", "layered-mvc"]) {
29
33
  const row = { profile_id: profile.id, spring_boot_version: profile.spring_boot_version, java_version: profile.java_version, architecture_family: family, status: "blocked", blockers: [], commands: [], executed_at: new Date().toISOString() };
34
+ row.required = required.has(`${profile.id}:${profile.spring_boot_version}:${family}`);
35
+ if (!row.required) { row.status = "not-executed"; row.reason = "outside explicitly requested matrix"; rows.push(row); continue; }
30
36
  const configuration = input.combinations?.find(item => item.profile_id === profile.id && item.spring_boot_version === profile.spring_boot_version && item.architecture_family === family);
31
37
  for (const key of ["YSS_MAVEN_REPOSITORY_URL", "MAVEN_REPO_USERNAME", "MAVEN_REPO_PASSWORD"]) if (!process.env[key]) row.blockers.push(`missing environment: ${key}`);
32
38
  if (!configuration?.contract_ref) row.blockers.push("missing real approved scaffold contract/YSS compatibility coordinates");
@@ -63,7 +69,7 @@ for (const profile of loadBackendPlatforms().profiles) for (const family of ["do
63
69
  }
64
70
  rows.push(row);
65
71
  }
66
- const report = { schema_version: 1, kind: "backend-platform-matrix", generated_at: new Date().toISOString(), status: rows.every(row => row.status === "passed") ? "passed" : "blocked", combinations: rows };
72
+ const report = { schema_version: 1, kind: "backend-platform-matrix", generated_at: new Date().toISOString(), scope: requested.length === allKeys.length ? "full-matrix" : "required-combinations", required_combinations: requested, certification_policy: "each platform and architecture still requires complete independently validated compatibility evidence", status: rows.filter(row => row.required).every(row => row.status === "passed") ? "passed" : "blocked", combinations: rows };
67
73
  await writeFile(path.join(evidence, "platform-matrix.json"), JSON.stringify(report, null, 2));
68
74
  process.stdout.write(`${report.status}: ${path.join(evidence, "platform-matrix.json")}\n`);
69
75
  if (report.status !== "passed") process.exitCode = 1;