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
@@ -902,6 +902,47 @@
902
902
  ]
903
903
  }
904
904
  }
905
+ },
906
+ "first_slice": {
907
+ "type": "object",
908
+ "additionalProperties": false,
909
+ "required": [
910
+ "artifacts"
911
+ ],
912
+ "properties": {
913
+ "artifacts": {
914
+ "type": "array",
915
+ "minItems": 1,
916
+ "items": {
917
+ "type": "object",
918
+ "additionalProperties": false,
919
+ "required": [
920
+ "role",
921
+ "path",
922
+ "type"
923
+ ],
924
+ "properties": {
925
+ "role": {
926
+ "enum": [
927
+ "domain",
928
+ "application",
929
+ "infrastructure",
930
+ "web",
931
+ "test"
932
+ ]
933
+ },
934
+ "path": {
935
+ "type": "string",
936
+ "minLength": 1
937
+ },
938
+ "type": {
939
+ "type": "string",
940
+ "minLength": 1
941
+ }
942
+ }
943
+ }
944
+ }
945
+ }
905
946
  }
906
947
  },
907
948
  "required": [
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { parseArgs } from 'node:util';
5
+ import { parseSliceYaml, selectSliceWorkUnit } from './lib/slice-contract.mjs';
6
+ import { inspectSliceContract } from './lib/slice-execution-preflight.mjs';
7
+ import { inspectMaintenanceCandidate } from './lib/maintenance-candidate.mjs';
8
+ import { compileStandardsCoverage, coverageFile } from './lib/backend-standards-coverage.mjs';
9
+ import { validateBackendReview } from './lib/backend-review.mjs';
10
+ try {
11
+ const {values}=parseArgs({options:{input:{type:'string'},root:{type:'string'},verify:{type:'boolean'}},strict:true});
12
+ if(!values.input)throw Error('usage: scripts/backend-standards-coverage --input <review-state.json|yaml> [--root <governance-root>] [--verify]');
13
+ const root=path.resolve(values.root||'.'),state=parseSliceYaml(fs.readFileSync(path.resolve(values.input),'utf8'));
14
+ if(values.verify)console.log(JSON.stringify(validateBackendReview(state,{root}),null,2));
15
+ else {
16
+ const input=state.review_input;if(!input)throw Error('review_input required');
17
+ const projectRoot=path.resolve(root,input.project_root||'.');let contract=null,comparison_ref=null;
18
+ if(input.scope_kind==='change') {
19
+ const loaded=inspectSliceContract(input.slice_contract_ref,{root,approval_ref:input.approval_ref,work_unit_id:input.work_unit_id});
20
+ if(!loaded.report.execution_allowed)throw Error(loaded.report.blockers.join('; '));
21
+ contract=selectSliceWorkUnit(loaded.contract,input.work_unit_id);
22
+ comparison_ref=input.review_mode==='worktree'?inspectMaintenanceCandidate({manifestPath:coverageFile(projectRoot,input.candidate_snapshot_ref)}).manifest.merge_base:input.review_base_ref;
23
+ }
24
+ console.log(JSON.stringify(compileStandardsCoverage({root,projectRoot,contract,scope_kind:input.scope_kind,baseline_binding:input.baseline_binding,comparison_ref,actual_skills:input.actual_skill_impacts||[],responsibility_evidence:input.responsibility_evidence||[]}),null,2));
25
+ }
26
+ } catch(error){console.error(error.message);process.exitCode=1;}
@@ -21,7 +21,7 @@ export function platformSourceFingerprint(family, root = ROOT) {
21
21
  const skill = family === 'domain-driven' ? 'yss-ddd-scaffold-generator' : family === 'layered-mvc' ? 'yss-layered-mvc-scaffold-generator' : null;
22
22
  if (!skill) fail('unknown architecture');
23
23
  const base = `.agents/skills/${skill}`;
24
- const generator = fileMap(root, [`${base}/scripts/generate_scaffold.mjs`, ...(family === 'domain-driven' ? [`${base}/assets`] : ['.agents/skills/yss-ddd-scaffold-generator/assets/wrapper']), 'scripts/lib/backend-platform.mjs', 'scripts/lib/scaffold-local-database.mjs']);
24
+ const generator = fileMap(root, [`${base}/scripts/generate_scaffold.mjs`, ...(family === 'domain-driven' ? [`${base}/assets`] : [`${base}/assets`, '.agents/skills/yss-ddd-scaffold-generator/assets/wrapper']), 'scripts/lib/backend-platform.mjs', 'scripts/lib/scaffold-local-database.mjs']);
25
25
  const verifier = fileMap(root, ['scripts/lib/backend-platform-provenance.mjs', 'scripts/lib/backend-platform-verification.mjs', 'scripts/lib/command-runner.mjs', 'scripts/vendor/xml.mjs', '.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs']);
26
26
  return { schema_version: 1, generator_digest: digest(JSON.stringify(generator)), verifier_digest: digest(JSON.stringify(verifier)) };
27
27
  }
@@ -21,9 +21,9 @@ export async function platformEvidenceArtifacts(evidenceDir) {
21
21
  export function checkPlatformTests(source, capabilities = []) {
22
22
  const suite = parseXmlDocument(source).testsuite;
23
23
  const cases = array(suite?.testcase);
24
- const required = ['httpJsonRoundTrip', 'httpValidationRejectsBlank', 'validationAndJsonAutoConfiguration', 'mybatisCanMapVerificationQuery', ...(capabilities.includes('feign-client') ? ['feignCanDecodeJson'] : [])];
24
+ const required = ['httpJsonRoundTrip', 'httpValidationRejectsBlank', 'validationAndJsonAutoConfiguration', 'mybatisCanMapVerificationQuery', 'mappingPersistenceAndPaginationRoundTrip', 'transactionRollsBackOnUseCaseFailure', ...(capabilities.includes('feign-client') ? ['feignCanDecodeJson'] : [])];
25
25
  if (!suite || required.some(name => !cases.some(item => item['@_name'] === name && !['failure', 'error', 'skipped'].some(key => Object.hasOwn(item, key))))) fail('integration tests missing, failed or skipped');
26
- return { status: 'passed', test_count: cases.length };
26
+ return { status: 'passed', test_count: cases.length, scope: 'test-scope mapping, MyBatis RowBounds, TransactionTemplate, HTTP status and JSON; not component error envelope, pagination interceptor, use-case proxy or production dialect certification' };
27
27
  }
28
28
  export async function verifyPlatformTests(projectRoot, evidenceDir, manifest, startedAt) {
29
29
  try {
@@ -367,6 +367,13 @@ class PlatformIntegrationTest {
367
367
  try {
368
368
  try (java.io.OutputStream stream = connection.getOutputStream()) { stream.write(mapper.writeValueAsBytes(request)); }
369
369
  assertEquals(expectedStatus, connection.getResponseCode());
370
+ if (expectedStatus == 400) {
371
+ try (java.io.InputStream stream = connection.getErrorStream()) {
372
+ assertNotNull(stream);
373
+ java.util.Map<?, ?> error = mapper.readValue(stream, java.util.Map.class);
374
+ assertFalse(error.isEmpty()); // Exact YSS error envelope requires the component capability contract.
375
+ }
376
+ }
370
377
  if (expectedStatus == 200) {
371
378
  assertTrue(connection.getContentType().startsWith("application/json"));
372
379
  try (java.io.InputStream stream = connection.getInputStream()) { assertEquals(value, mapper.readValue(stream, ProbePayload.class).getValue()); }
@@ -375,6 +382,54 @@ class PlatformIntegrationTest {
375
382
  }
376
383
  @Autowired ${mapper.split(".").at(-1)} mapper;
377
384
  @Autowired SqlSessionFactory sqlSessionFactory;
385
+ @Autowired org.springframework.jdbc.core.JdbcTemplate jdbc;
386
+ @Autowired org.springframework.transaction.PlatformTransactionManager transactions;
387
+ @Autowired org.mybatis.spring.SqlSessionTemplate sessions;
388
+ @Autowired PlatformProbeMapping probeMapping;
389
+
390
+ @lombok.Getter
391
+ @lombok.Setter
392
+ public static class ProbeRow {
393
+ private Long id;
394
+ private String value;
395
+ }
396
+ interface RoundTripMapper {
397
+ @org.apache.ibatis.annotations.Insert("INSERT INTO scaffold_roundtrip(id, probe_value) VALUES(#{id}, #{value})")
398
+ int insert(ProbeRow row);
399
+ @org.apache.ibatis.annotations.Results(@org.apache.ibatis.annotations.Result(column = "probe_value", property = "value"))
400
+ @Select("SELECT id, probe_value FROM scaffold_roundtrip ORDER BY id")
401
+ java.util.List<ProbeRow> page(org.apache.ibatis.session.RowBounds bounds);
402
+ @Select("SELECT COUNT(*) FROM scaffold_roundtrip") int count();
403
+ }
404
+ private RoundTripMapper roundTripMapper() {
405
+ jdbc.execute("CREATE TABLE IF NOT EXISTS scaffold_roundtrip(id BIGINT PRIMARY KEY, probe_value VARCHAR(100) NOT NULL)");
406
+ jdbc.update("DELETE FROM scaffold_roundtrip");
407
+ if (!sqlSessionFactory.getConfiguration().hasMapper(RoundTripMapper.class)) sqlSessionFactory.getConfiguration().addMapper(RoundTripMapper.class);
408
+ return sessions.getMapper(RoundTripMapper.class);
409
+ }
410
+ @Test void mappingPersistenceAndPaginationRoundTrip() {
411
+ RoundTripMapper persistence = roundTripMapper();
412
+ for (long id = 1; id <= 3; id++) {
413
+ ProbeRow original = new ProbeRow(); original.setId(id); original.setValue("probe-" + id);
414
+ ProbeRow copy = probeMapping.copy(original);
415
+ assertNotSame(original, copy); assertEquals(original.getId(), copy.getId());
416
+ persistence.insert(copy);
417
+ }
418
+ assertEquals(3, persistence.count());
419
+ java.util.List<ProbeRow> page = persistence.page(new org.apache.ibatis.session.RowBounds(1, 1));
420
+ assertEquals(1, page.size()); assertEquals(Long.valueOf(2), page.get(0).getId());
421
+ assertEquals("probe-2", page.get(0).getValue());
422
+ assertNull(probeMapping.copy(null));
423
+ }
424
+ @Test void transactionRollsBackOnUseCaseFailure() {
425
+ final RoundTripMapper persistence = roundTripMapper();
426
+ org.springframework.transaction.support.TransactionTemplate transaction = new org.springframework.transaction.support.TransactionTemplate(transactions);
427
+ assertThrows(IllegalStateException.class, () -> transaction.execute(status -> {
428
+ ProbeRow row = new ProbeRow(); row.setId(9L); row.setValue("must-rollback"); persistence.insert(row);
429
+ throw new IllegalStateException("synthetic use-case failure");
430
+ }));
431
+ assertEquals(0, persistence.count());
432
+ }
378
433
  static final class ValidationProbe { @NotBlank String value = ""; }
379
434
  @Test void validationAndJsonAutoConfiguration() throws Exception {
380
435
  assertFalse(validator.validate(new ValidationProbe()).isEmpty());
@@ -398,5 +453,12 @@ ${capabilities.includes("feign-client") ? ` @Autowired org.springframework.cl
398
453
  assertTrue(decoder.decode(response, java.util.Map.class) instanceof java.util.Map);
399
454
  }
400
455
  ` : ""}}
456
+
457
+ @org.mapstruct.Mapper(componentModel = "spring", unmappedTargetPolicy = org.mapstruct.ReportingPolicy.ERROR)
458
+ interface PlatformProbeMapping {
459
+ @org.mapstruct.Mapping(target = "id", source = "id")
460
+ @org.mapstruct.Mapping(target = "value", source = "value")
461
+ PlatformIntegrationTest.ProbeRow copy(PlatformIntegrationTest.ProbeRow row);
462
+ }
401
463
  `;
402
464
  }
@@ -0,0 +1,140 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { createHash } from 'node:crypto';
5
+ import { parseSliceYaml, selectSliceWorkUnit } from './slice-contract.mjs';
6
+ import { validateApprovalRecord } from './approval-record.mjs';
7
+ import { inspectSliceContract } from './slice-execution-preflight.mjs';
8
+ import { inspectMaintenanceCandidate } from './maintenance-candidate.mjs';
9
+ import { compileStandardsCoverage, coverageDigest, coverageFile, verifyCoverageRows } from './backend-standards-coverage.mjs';
10
+
11
+ const ensure = (condition, message) => { if (!condition) throw new Error(`backend-review: ${message}`); };
12
+ const text = value => typeof value === 'string' && value.trim();
13
+ const digest = value => createHash('sha256').update(value).digest('hex');
14
+ function git(root, args) {
15
+ const result = spawnSync('git', args, { cwd: root, maxBuffer: 64 * 1024 * 1024 });
16
+ ensure(result.status === 0, `git ${args[0]} failed`); return result.stdout;
17
+ }
18
+ function file(root, ref) {
19
+ ensure(text(ref) && !path.isAbsolute(ref), 'relative evidence reference required');
20
+ const resolved = fs.realpathSync(path.resolve(root, ref));
21
+ ensure(resolved.startsWith(`${fs.realpathSync(root)}${path.sep}`), 'evidence path escape');
22
+ return resolved;
23
+ }
24
+
25
+ export function backendReviewSkills(contract, actualSkills = []) {
26
+ return [...new Set([...(contract.resolution?.required_skills || []), ...(contract.common?.required_skills || []),
27
+ ...(contract.backend?.required_skills || []), ...actualSkills, 'alibaba-java-code-style'])].sort();
28
+ }
29
+
30
+ /** Validate existing code-review result and constraint_results; this is not an approval authority. */
31
+ export function validateBackendReview(state, { root = process.cwd() } = {}) {
32
+ const input = state?.review_input;
33
+ ensure(['baseline','change'].includes(input?.scope_kind), 'scope_kind required; historical records are read-only');
34
+ if (input.scope_kind === 'baseline') return validateBaselineReview(state, {root});
35
+ ensure(input?.slice_contract_ref, 'review input must bind Slice contract');
36
+ const loaded = inspectSliceContract(input.slice_contract_ref, { root, approval_ref: input.approval_ref, work_unit_id: input.work_unit_id });
37
+ ensure(loaded.report.execution_allowed, `approved current contract required: ${loaded.report.blockers.join('; ')}`);
38
+ const contract = selectSliceWorkUnit(loaded.contract, input.work_unit_id);
39
+ if (contract.backend?.status !== 'required') return { status: 'not-applicable', reason: 'contract has no backend impact' };
40
+ ensure(Array.isArray(input.actual_skill_impacts), 'actual_skill_impacts must be explicit (may be empty)');
41
+ const result = parseSliceYaml(fs.readFileSync(file(root, state.review_result_ref), 'utf8'));
42
+ ensure(result.skill === 'code-review' && result.result === 'completed', 'only completed code-review can proceed');
43
+ ensure(result.contract_digest === loaded.binding.digest, 'review contract digest stale');
44
+ for (const identity of ['reviewer','implementer']) {
45
+ const actor = result[identity];
46
+ for (const field of ['actor_id','runtime_id','instance_id']) ensure(text(actor?.[field]), `${identity}.${field} required`);
47
+ }
48
+ ensure(result.reviewer.actor_id !== result.implementer.actor_id && result.reviewer.instance_id !== result.implementer.instance_id, 'independent Reviewer required');
49
+ ensure(result.implementer.actor_id === input.implementation_actor_id && result.implementer.instance_id === input.implementation_instance_id, 'implementation identity mismatch');
50
+ ensure(result.candidate_digest === input.candidate_digest, 'candidate digest mismatch');
51
+ const projectRoot = fs.realpathSync(path.resolve(root, input.project_root || '.'));
52
+ ensure(contract.common.project_roots.some(ref => fs.realpathSync(path.resolve(root, ref)) === projectRoot), 'candidate project is outside approved contract');
53
+ // Reuse the packed worktree candidate protocol. Its exclusions are restricted to review evidence.
54
+ if (input.review_mode === 'worktree') {
55
+ const { manifest, trackedDiff, entries } = inspectMaintenanceCandidate({ manifestPath: file(projectRoot, input.candidate_snapshot_ref) });
56
+ ensure(manifest.candidate_digest === input.candidate_digest, 'snapshot digest mismatch');
57
+ ensure(trackedDiff.equals(git(projectRoot, ['diff','--no-ext-diff','--binary','--full-index',manifest.merge_base])), 'tracked candidate stale');
58
+ const excluded = manifest.excluded_paths || [];
59
+ ensure(excluded.every(p => p.startsWith('.template-source/evidence/maintenance/') && !p.split('/').includes('..')), 'candidate exclusions must be evidence only');
60
+ const actual = git(projectRoot, ['ls-files','-z','--others','--exclude-standard']).toString().split('\0').filter(Boolean)
61
+ .filter(p => !excluded.some(ex => p === ex || p.startsWith(`${ex}/`))).sort();
62
+ ensure(JSON.stringify(actual) === JSON.stringify(entries.map(e => e.path).sort()), 'untracked candidate inventory stale');
63
+ for (const entry of entries) {
64
+ const info = fs.lstatSync(path.resolve(projectRoot, entry.path));
65
+ ensure(info.mode === entry.mode && (entry.kind === 'symlink' ? info.isSymbolicLink() : info.isFile()), `untracked candidate mode/kind stale: ${entry.path}`);
66
+ const current = entry.kind === 'symlink' ? Buffer.from(fs.readlinkSync(path.resolve(projectRoot, entry.path))) : fs.readFileSync(file(projectRoot, entry.path));
67
+ ensure(current.equals(entry.content), `untracked candidate stale: ${entry.path}`);
68
+ }
69
+ } else {
70
+ ensure(input.review_mode === 'committed', 'unsupported candidate mode');
71
+ const tree = git(projectRoot, ['rev-parse',`${input.implementation_candidate_ref}^{tree}`]).toString().trim();
72
+ ensure(tree === input.candidate_digest, 'committed candidate mismatch');
73
+ ensure(git(projectRoot, ['rev-parse','HEAD^{tree}']).toString().trim() === tree && !git(projectRoot, ['status','--porcelain']).length, 'committed candidate is not current clean checkout');
74
+ }
75
+ const coverage = currentStandardsCoverage(input, {root, projectRoot, contract});
76
+ verifyCoverageRows(coverage, result.constraint_results, {root, projectRoot});
77
+ const required = coverage.skills.map(row => row.skill);
78
+ ensure(Array.isArray(result.verification_results) && result.verification_results.length > 0, 'machine verification required');
79
+ for (const check of result.verification_results) {
80
+ ensure(text(check.command) && Number.isFinite(Date.parse(check.executed_at)) && check.exit_code === 0 && check.candidate_digest === result.candidate_digest, 'machine check failed, absent or stale');
81
+ ensure(digest(fs.readFileSync(file(root, check.evidence_ref))) === check.evidence_digest, 'machine evidence stale');
82
+ }
83
+ ensure(result.axes?.Standards === 'passed' && result.axes?.Spec === 'passed', 'Standards and Spec must pass separately');
84
+ ensure(Array.isArray(result.findings), 'findings required');
85
+ for (const finding of result.findings) {
86
+ ensure(!['violation','drift','new_impacts','missing_evidence'].includes(finding.disposition) || finding.status === 'resolved', 'blocking finding remains open');
87
+ if (finding.disposition === 'suggestion' && finding.status !== 'resolved') ensure(text(finding.follow_up_ref), 'suggestion needs backlog reference');
88
+ }
89
+ return { status: 'passed', candidate_digest: input.candidate_digest, reviewed_skills: required };
90
+ }
91
+
92
+ /** Recompute derived coverage, do not trust a submitted expected-rule list. */
93
+ export function currentStandardsCoverage(input, {root, projectRoot, contract=null}={}) {
94
+ ensure(input.standards_coverage_ref && input.standards_coverage_digest, 'standards coverage binding required');
95
+ const bytes=fs.readFileSync(file(root,input.standards_coverage_ref));
96
+ ensure(digest(bytes)===input.standards_coverage_digest, 'standards coverage digest stale');
97
+ const recorded=parseSliceYaml(bytes.toString());
98
+ let comparison_ref=null;
99
+ if(input.scope_kind==='change') {
100
+ comparison_ref=input.review_mode==='worktree'
101
+ ? inspectMaintenanceCandidate({manifestPath:file(projectRoot,input.candidate_snapshot_ref)}).manifest.merge_base
102
+ : input.review_base_ref;
103
+ }
104
+ const current=compileStandardsCoverage({root,projectRoot,contract,scope_kind:input.scope_kind,
105
+ baseline_binding:input.baseline_binding,comparison_ref,actual_skills:input.actual_skill_impacts||[],responsibility_evidence:input.responsibility_evidence||[]});
106
+ ensure(coverageDigest(current)===coverageDigest(recorded),'standards coverage stale or incomplete');
107
+ return current;
108
+ }
109
+
110
+ function validateBaselineReview(state,{root}) {
111
+ const input=state.review_input,projectRoot=fs.realpathSync(path.resolve(root,input.project_root||'.'));
112
+ const coverage=currentStandardsCoverage(input,{root,projectRoot});
113
+ const result=parseSliceYaml(fs.readFileSync(file(root,state.review_result_ref),'utf8'));
114
+ ensure(result.skill==='code-review' && result.result==='completed','independent code-review baseline report required');
115
+ ensure(result.candidate_digest===coverageDigest(coverage.inventory) && input.candidate_digest===result.candidate_digest,'baseline candidate stale');
116
+ for(const key of ['actor_id','runtime_id','instance_id'])ensure(text(result.reviewer?.[key])&&text(result.implementer?.[key]),'baseline actor identity required');
117
+ ensure(result.reviewer.actor_id!==result.implementer.actor_id && result.reviewer.instance_id!==result.implementer.instance_id,'independent Reviewer required');
118
+ ensure(result.implementer.actor_id===input.implementation_actor_id && result.implementer.instance_id===input.implementation_instance_id,'baseline actor mismatch');
119
+ verifyCoverageRows(coverage,result.constraint_results,{root,projectRoot});
120
+ ensure(result.axes?.Standards==='passed','Standards must pass');
121
+ ensure(['passed','missing_evidence'].includes(result.axes?.Spec),'baseline Spec must be explicit');
122
+ if(result.axes.Spec==='passed') {
123
+ ensure(input.spec_binding?.ref && input.spec_binding?.digest,'approved Spec evidence binding required');
124
+ ensure(digest(fs.readFileSync(file(root,input.spec_binding.ref)))===input.spec_binding.digest.replace(/^sha256:/,''),'Spec evidence stale');
125
+ ensure(text(input.spec_binding.approval_ref),'Spec approval record required');
126
+ const approval=parseSliceYaml(fs.readFileSync(file(root,input.spec_binding.approval_ref),'utf8'));
127
+ validateApprovalRecord(approval,{root,requireApproved:true,rolesDoc:parseSliceYaml(fs.readFileSync(file(root,'docs/agents/digital-human-roles.yaml'),'utf8'))});
128
+ ensure(approval.gate_id==='gate.spec-baseline-approved' && approval.artifact_bindings?.some(b=>b.digest.replace(/^sha256:/,'')===input.spec_binding.digest.replace(/^sha256:/,'')),'Spec approval does not bind current baseline');
129
+ ensure(Array.isArray(result.constraint_results)&&result.constraint_results.some(r=>r.axis==='Spec'&&r.status==='passed'&&text(r.evidence_ref)),'Spec acceptance evidence required');
130
+ for(const row of result.constraint_results.filter(r=>r.axis==='Spec')) {
131
+ ensure(row.status==='passed'&&text(row.constraint)&&text(row.code_ref)&&text(row.evidence_ref),'Spec acceptance unresolved');
132
+ coverageFile(projectRoot,row.code_ref.split(':')[0]);
133
+ ensure(digest(fs.readFileSync(file(root,row.evidence_ref)))===row.evidence_digest,'Spec acceptance evidence stale');
134
+ }
135
+ }
136
+ ensure(Array.isArray(result.findings)&&result.findings.every(f=>f.disposition==='suggestion'||f.status==='resolved'||(f.disposition==='missing_evidence'&&f.axis==='Spec'&&result.axes.Spec==='missing_evidence')),'baseline blocking findings remain');
137
+ ensure(Array.isArray(result.verification_results)&&result.verification_results.length,'baseline verification required');
138
+ for(const check of result.verification_results)ensure(text(check.command)&&check.exit_code===0&&Number.isFinite(Date.parse(check.executed_at))&&check.candidate_digest===result.candidate_digest&&digest(fs.readFileSync(file(root,check.evidence_ref)))===check.evidence_digest,'baseline machine evidence missing or stale');
139
+ return {status:'audited',axes:result.axes,execution_allowed:false,scope_kind:'baseline',candidate_digest:result.candidate_digest,reviewed_skills:coverage.skills.map(s=>s.skill)};
140
+ }
@@ -0,0 +1,237 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { parseSliceYaml } from './slice-contract.mjs';
6
+ import { treeHash } from './skill-supply-chain.mjs';
7
+
8
+ export const coverageDigest = value => createHash('sha256').update(typeof value === 'string' || Buffer.isBuffer(value) ? value : JSON.stringify(value)).digest('hex');
9
+ const ensure = (ok, message) => { if (!ok) throw Error(`backend-review: ${message}`); };
10
+ const beneath = (file, scope) => scope === '.' || file === scope || file.startsWith(`${scope}/`);
11
+ export const CORE_SKILLS = ['yss-web-controller','yss-dto','yss-domain','yss-application','yss-repository','yss-mybatis'];
12
+ const roleSkills = {web:'yss-web-controller',server:'yss-web-controller',domain:'yss-domain',application:'yss-application',service:'yss-application',core:'yss-application',infrastructure:'yss-repository',persistence:'yss-repository',repository:'yss-repository'};
13
+ export function coverageFile(root, ref) {
14
+ ensure(typeof ref === 'string' && ref && !path.isAbsolute(ref) && !ref.split(/[\\/]/).includes('..'), 'safe relative coverage reference required');
15
+ const resolved = fs.realpathSync(path.resolve(root, ref));
16
+ ensure(resolved.startsWith(`${fs.realpathSync(root)}${path.sep}`), 'coverage reference escapes root');
17
+ return resolved;
18
+ }
19
+ function binding(root, item) {
20
+ ensure(item?.ref && item?.digest, 'coverage basis ref/digest required');
21
+ const bytes = fs.readFileSync(coverageFile(root,item.ref));
22
+ ensure(coverageDigest(bytes) === item.digest.replace(/^sha256:/,''), `coverage basis stale: ${item.ref}`);
23
+ return parseSliceYaml(bytes.toString());
24
+ }
25
+ function files(root, prefix = '') {
26
+ return fs.readdirSync(path.join(root,prefix),{withFileTypes:true}).sort((a,b)=>a.name.localeCompare(b.name,'en')).flatMap(entry => {
27
+ if (['.git','target','node_modules'].includes(entry.name) || (prefix==='.template-source' && entry.name==='evidence')) return [];
28
+ const ref = prefix ? `${prefix}/${entry.name}` : entry.name;
29
+ ensure(!entry.isSymbolicLink(), `unresolved source symlink: ${ref}`);
30
+ return entry.isDirectory() ? files(root,ref) : [ref];
31
+ });
32
+ }
33
+ function git(root,args) {
34
+ const r=spawnSync('git',args,{cwd:root,encoding:'utf8',maxBuffer:32*1024*1024});
35
+ ensure(r.status===0,`coverage git ${args[0]} failed`); return r.stdout;
36
+ }
37
+ function stripComments(source) {
38
+ // Exclude literals too: a diagnostic string containing "FooRepository" is not a dependency.
39
+ return source.replace(/"""[\s\S]*?"""|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\/\*[\s\S]*?\*\/|\/\/[^\n]*/g, value => value.replace(/[^\n]/g,' '));
40
+ }
41
+ function uses(from,to) {
42
+ return to.declared.some(name => from.tokens.has(name) && (from.pkg===to.pkg || from.code.includes(`${to.pkg}.${name}`) || from.code.includes(`import ${to.pkg}.*`)));
43
+ }
44
+ function javaType(ref,source) {
45
+ const code=stripComments(source), pkg=code.match(/\bpackage\s+([\w.]+)\s*;/)?.[1];
46
+ const declared=[...code.matchAll(/(?:@\s*interface|\bclass|\binterface|\benum|\brecord)\s+(\w+)/g)].map(m=>m[1]);
47
+ const annotations=[...code.matchAll(/@([\w.]+)/g)].map(m=>m[1].split('.').at(-1));
48
+ const parents=[...code.matchAll(/\b(?:extends|implements)\s+([\w.,<>\s]+?)(?=\{|\bpermits\b)/g)].flatMap(m=>m[1].match(/\b[A-Z]\w*/g)||[]);
49
+ const tokens=new Set(code.match(/\b[A-Z]\w*/g)||[]);
50
+ return {ref,code,pkg,declared,annotations,parents,tokens,http:false,roles:new Set()};
51
+ }
52
+ function readRules(root,skill) {
53
+ ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid skill identifier');
54
+ const folder=`.agents/skills/${skill}`;
55
+ ensure(fs.existsSync(path.join(root,folder,'SKILL.md')), `missing applicable skill: ${skill}`);
56
+ const sources=files(path.join(root,folder)).filter(p=>p.endsWith('.md') && !p.includes('source-index'));
57
+ const rules=[],sourceDigests=[];
58
+ for (const name of sources) {
59
+ const ref=`${folder}/${name}`, source=fs.readFileSync(coverageFile(root,ref),'utf8');
60
+ sourceDigests.push({ref,digest:coverageDigest(source)});
61
+ for (const m of source.matchAll(/^<!-- yss-rule (\{[^\n]+\}) -->$/gm)) {
62
+ const rule=JSON.parse(m[1]);
63
+ ensure(/^[a-z][a-z0-9.-]+$/.test(rule.id) && rule.level==='mandatory' && ['always','change','web','wire','domain','application','persistence','mybatis','pagination','batch'].includes(rule.when), `invalid rule declaration: ${ref}`);
64
+ ensure(source.includes(`<a id="${rule.id}"></a>`),`rule anchor missing: ${rule.id}`);
65
+ rules.push({...rule,skill,rule_ref:`${ref}#${rule.id}`,rule_digest:coverageDigest(source)});
66
+ }
67
+ }
68
+ // Whole-text semantic review is always required, including unstructured auxiliary rules.
69
+ const ref=`${folder}/SKILL.md`;
70
+ rules.push({id:`${skill}.full-text`,when:'always',level:'mandatory',evidence:'semantic-review',skill,rule_ref:ref,rule_digest:coverageDigest(fs.readFileSync(coverageFile(root,ref)))});
71
+ return {rules,sourceDigests};
72
+ }
73
+
74
+ /** Read-only derivation: never approves a contract or executes project build commands. */
75
+ export function compileStandardsCoverage({root,projectRoot,contract=null,scope_kind='baseline',baseline_binding=null,comparison_ref=null,actual_skills=[],responsibility_evidence=[]}={}) {
76
+ ensure(['baseline','change'].includes(scope_kind),'scope_kind required');
77
+ root=fs.realpathSync(root);projectRoot=fs.realpathSync(projectRoot);
78
+ const basis=contract?.resolution?.architecture_evidence?.engineering_baseline || baseline_binding;
79
+ const baseline=basis?binding(root,basis):null;
80
+ const identity=contract?.resolution?.architecture_identity || baseline?.architecture_identity;
81
+ const family=identity?.architecture_family;
82
+ const issues=[];
83
+ if (baseline && (baseline.kind!=='existing-engineering-baseline' || baseline.status!=='current') && identity?.source_kind==='existing-registration') issues.push({id:'baseline-not-current',reason:'既有工程基线未标记为当前观测,须先核对登记'});
84
+ if (!['domain-driven','layered-mvc'].includes(family)) issues.push({id:'architecture-unknown',reason:'需要登记架构;只读盘点不能猜测 DDD/MVC'});
85
+ const all=files(projectRoot);
86
+ const roots=baseline?.source?.roots || ['.'];
87
+ ensure(roots.every(r=>r==='.' || (!path.isAbsolute(r)&&!r.split('/').includes('..'))),'invalid registered source roots');
88
+ const selected=all.filter(ref=>roots.some(r=>beneath(ref,r)));
89
+ const outside=all.filter(ref=>!selected.includes(ref)&&ref.endsWith('.java'));
90
+ if (outside.length) issues.push({id:'unregistered-source',reason:outside.join(', ')});
91
+ const inventory=selected.map(ref=>({path:ref,mode:fs.statSync(coverageFile(projectRoot,ref)).mode,digest:coverageDigest(fs.readFileSync(coverageFile(projectRoot,ref)))}));
92
+ const types=selected.filter(ref=>ref.endsWith('.java')).map(ref=>javaType(ref,fs.readFileSync(coverageFile(projectRoot,ref),'utf8')));
93
+ for(const t of types) if(!t.declared.length || /\\u[0-9a-fA-F]{4}/.test(t.code)) issues.push({id:`unparsed:${t.ref}`,reason:'源码类型解析不足,须人工核实或编译态证据'});
94
+ if(!types.some(t=>!t.ref.includes('/test/'))) issues.push({id:'zero-business-types',reason:'未发现业务类型,不能证明存量工程合规'});
95
+ const httpNames=new Set(['RestController','Controller','RequestMapping','GetMapping','PostMapping','PutMapping','DeleteMapping','PatchMapping']);
96
+ let changed=true;
97
+ while(changed){changed=false;for(const t of types) if(!t.http&&(t.annotations.some(a=>httpNames.has(a))||t.parents.some(p=>httpNames.has(p)))){t.http=true;for(const name of t.declared)httpNames.add(name);changed=true;}}
98
+ const localNames=new Set(types.flatMap(t=>t.declared));
99
+ const familiar=new Set([...httpNames,'interface','Override','Deprecated','SuppressWarnings','FunctionalInterface','Serializable','Comparable','Exception','RuntimeException','Service','Repository','Mapper','Entity','TableName','Id','TableId','Autowired','Component','Configuration','Bean','Valid','Validated','NotNull','NotBlank','Size','Min','Max','Pattern','RequestBody','RequestParam','PathVariable','RequestHeader','CookieValue','ResponseBody','ResponseStatus','ExceptionHandler','ControllerAdvice','RestControllerAdvice','Transactional','Data','Getter','Setter','Builder','NoArgsConstructor','AllArgsConstructor','RequiredArgsConstructor','Slf4j','EqualsAndHashCode','ToString','JsonProperty','JsonIgnore','JsonCreator','Test']);
100
+ const resolutions=responsibility_evidence.map(item=>({...binding(root,item),binding:item}));
101
+ const units=baseline?.build_units || [];
102
+ for(const t of types) {
103
+ for(const u of units) for(const [role,refs] of Object.entries(u.role_paths||{})) if(refs.some(ref=>beneath(t.ref,ref))) t.roles.add(role);
104
+ for(const a of contract?.backend?.first_slice?.artifacts||[]) if(a.path===t.ref)t.roles.add(a.role);
105
+ if(t.http)t.roles.add('web');
106
+ if(t.annotations.includes('Service'))t.roles.add('application');
107
+ if(t.annotations.some(a=>['Repository','Entity','TableName'].includes(a))||(t.annotations.includes('Mapper')&&!/org\.mapstruct/.test(t.code))||/\b(?:JdbcTemplate|SqlSession|EntityManager|BaseMapper)\b/.test(t.code))t.roles.add('persistence');
108
+ const unresolved=[...t.annotations,...t.parents].filter(n=>!localNames.has(n)&&!familiar.has(n));
109
+ if((unresolved.length || (!t.roles.size && !/@\s*interface\b/.test(t.code))) && !t.ref.includes('/test/')) {
110
+ const resolution=resolutions.find(r=>r.source_ref===t.ref);
111
+ if(!resolution)t.uncertainty={id:`unresolved-responsibility:${t.ref}`,reason:unresolved.join(', ')||'type has no registered or observed responsibility'};
112
+ else {
113
+ ensure(resolution.source_digest===coverageDigest(fs.readFileSync(coverageFile(projectRoot,t.ref))) && typeof resolution.reason==='string' && resolution.reason.trim() && Array.isArray(resolution.roles) && resolution.roles.length && resolution.roles.every(r=>roleSkills[r]||r==='data'),'responsibility evidence stale or invalid');
114
+ ensure(resolution.evidence_ref && resolution.evidence_digest && coverageDigest(fs.readFileSync(coverageFile(root,resolution.evidence_ref)))===resolution.evidence_digest,'responsibility verification evidence stale');
115
+ resolution.roles.forEach(r=>t.roles.add(r));
116
+ if(resolution.roles.some(r=>['web','server'].includes(r)))t.http=true;
117
+ }
118
+ }
119
+
120
+ }
121
+ let active=types, changedPaths=[];
122
+ if(scope_kind==='change') {
123
+ ensure(contract && comparison_ref,'change coverage needs approved contract and comparison_ref');
124
+ ensure(/^[a-f0-9]{40}$/.test(comparison_ref),'comparison_ref must be an immutable commit');
125
+ changedPaths=[...new Set([...git(projectRoot,['diff','--name-only',comparison_ref]).trim().split('\n'),...git(projectRoot,['ls-files','--others','--exclude-standard']).trim().split('\n')].filter(Boolean))];
126
+ const affected=new Set(types.filter(t=>changedPaths.includes(t.ref)));
127
+ // Source inventory is broad; semantic work is restricted to changed types and bidirectional dependency closure.
128
+ let expanding=true;
129
+ while(expanding){expanding=false;for(const t of types)if(!affected.has(t)&&[...affected].some(a=>uses(t,a)||uses(a,t))){affected.add(t);expanding=true;}}
130
+ active=[...affected];
131
+ if(changedPaths.some(p=>selected.includes(p)&&!p.endsWith('.java')&&!p.startsWith('.template-source/'))) active=types; // config/build changes can affect all types
132
+ }
133
+ issues.push(...active.flatMap(t=>t.uncertainty?[t.uncertainty]:[]));
134
+ const tags=new Set(['always',...(scope_kind==='change'?['change']:[])]), reasons=new Map();
135
+ const add=(skill,reason)=>{if(!reasons.has(skill))reasons.set(skill,new Set());reasons.get(skill).add(reason);};
136
+ const declaredSkills=[...(contract?.resolution?.required_skills||[]),...(contract?.common?.required_skills||[]),...(contract?.backend?.required_skills||[])];
137
+ for(const s of [...declaredSkills,...actual_skills])add(s,'contract-or-declared-impact');
138
+ add('alibaba-java-code-style','backend-scope');
139
+ for(const t of active.filter(t=>!t.ref.includes('/test/'))) {
140
+ for(const role of t.roles)if(roleSkills[role])add(roleSkills[role],t.ref);
141
+ if(t.http){tags.add('web');tags.add('wire');add('yss-dto',t.ref);}
142
+ if(/\b(?:PageResult|PageQuery|CommandDTO|QueryDTO|SingleResult|MultiResult)\b/.test(t.code)){tags.add('wire');add('yss-dto',t.ref);}
143
+ if(t.roles.has('domain')&&family==='domain-driven')tags.add('domain');
144
+ if([...t.roles].some(r=>['application','service','core'].includes(r)))tags.add('application');
145
+ if([...t.roles].some(r=>['repository','persistence','infrastructure'].includes(r)))tags.add('persistence');
146
+ if(/\b(?:PageQuery|PageRequest|PageResult|IPage|PageHelper|pageIndex|pageSize)\b/.test(t.code))tags.add('pagination');
147
+ if(/\b(?:insertBatch|saveBatch|updateBatch|executeBatch)\b/.test(t.code))tags.add('batch');
148
+ for(const [regex,skill] of [[/\b(?:Valid|Validated|NotNull|NotBlank|Size)\b/,'yss-validation'],[/\b(?:ExceptionHandler|ControllerAdvice|RestControllerAdvice)\b/,'yss-exception'],[/\borg\.mapstruct\b/,'mapstruct'],[/\blombok\b/,'lombok']])if(regex.test(t.code))add(skill,t.ref);
149
+ }
150
+ for(const layer of contract?.backend?.affected_layers||[]) if(roleSkills[layer])add(roleSkills[layer],`affected-layer:${layer}`);
151
+ const configPaths=(scope_kind==='baseline'?selected:selected.filter(p=>changedPaths.includes(p))).filter(p=>/\.(?:xml|ya?ml|properties|sql|json)$/.test(p));
152
+ const runtimeText=[...active.map(t=>t.code),...configPaths.filter(p=>!p.endsWith('.java')).map(p=>fs.readFileSync(coverageFile(projectRoot,p),'utf8'))].join('\n');
153
+ // Derive component ownership from the existing registry and the locked platform index.
154
+ // These are discovery signals only; they never certify component compatibility.
155
+ const discovery_sources=[];
156
+ const registryRef='docs/agents/yss-skill-registry.yaml';
157
+ if(fs.existsSync(path.join(root,registryRef))) {
158
+ const registryBytes=fs.readFileSync(coverageFile(root,registryRef));
159
+ discovery_sources.push({ref:registryRef,digest:coverageDigest(registryBytes)});
160
+ const registry=parseSliceYaml(registryBytes.toString());
161
+ const line=identity?.platform_configuration?.component_platform_line;
162
+ if(!['boot2-java8','boot3-java17'].includes(line))issues.push({id:'component-discovery-platform-unknown',reason:'组件发现需要已登记的平台源码索引,不跨平台借证据'});
163
+ else for(const skill of [...new Set((registry.capabilities||[]).filter(c=>c.provider?.kind==='yss-component').map(c=>c.primary_skill))].sort()) {
164
+ ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid registered component skill');
165
+ const ref=`.agents/skills/${skill}/references/source-index.${line}.md`;
166
+ if(!fs.existsSync(path.join(root,ref))){issues.push({id:`component-index-missing:${skill}`,reason:ref});continue;}
167
+ const source=fs.readFileSync(coverageFile(root,ref),'utf8');
168
+ discovery_sources.push({ref,digest:coverageDigest(source)});
169
+ const symbols=[...source.matchAll(/src\/main\/java\/([\w/$]+)\.java/g)].map(m=>m[1].replaceAll('/','.'));
170
+ const gavs=[...source.matchAll(/GAV `([^:`]+):([^:`]+):[^`]+`/g)];
171
+ const symbolHit=symbols.some(symbol=>runtimeText.includes(symbol) || runtimeText.includes(`import ${symbol.slice(0,symbol.lastIndexOf('.'))}.*`));
172
+ const artifactHit=gavs.some(([,group,artifact])=>runtimeText.includes(`<groupId>${group}</groupId>`) && runtimeText.includes(`<artifactId>${artifact}</artifactId>`));
173
+ if(symbolHit||artifactHit)add(skill,`registered-component-index:${ref}`);
174
+ }
175
+ }
176
+ if(/org\.apache\.ibatis|com\.baomidou|mybatis|<mapper\b/i.test(runtimeText)){tags.add('mybatis');tags.add('persistence');add('yss-mybatis','source-or-build-binding');add('yss-repository','source-or-build-binding');}
177
+ if(/\b(?:JdbcTemplate|EntityManager)\b|spring-boot-starter-data-jpa|<mapper\b/.test(runtimeText)){tags.add('persistence');add('yss-repository','source-or-build-binding');}
178
+ for(const [skill,tag] of [['yss-web-controller','web'],['yss-dto','wire'],['yss-domain','domain'],['yss-application','application'],['yss-repository','persistence'],['yss-mybatis','mybatis']])if(reasons.has(skill))tags.add(tag);
179
+ if(family==='layered-mvc'){tags.delete('domain');if(reasons.has('yss-domain'))issues.push({id:'mvc-domain-conflict',reason:'MVC 不应加载 DDD 专属技能,须回合同核对'});reasons.delete('yss-domain');}
180
+ const observedSkills=[...reasons.keys()].sort();
181
+ if(scope_kind==='change')for(const skill of observedSkills)if(skill!=='alibaba-java-code-style'&&!declaredSkills.includes(skill))issues.push({id:`undeclared-skill:${skill}`,reason:'actual impact exceeds contract; recompile before execution'});
182
+ const constraints=[],rulesSources=[];
183
+ const lock=path.join(root,'skills-lock.json');
184
+ const skillLock=fs.existsSync(lock)?JSON.parse(fs.readFileSync(lock,'utf8')):null;
185
+ if(!skillLock)issues.push({id:'skill-lock-missing',reason:'缺少锁定的 canonical Skill 来源;只读盘点不能声明规范已锁定'});
186
+ const skillTrees={};
187
+ for(const skill of observedSkills) {
188
+ ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid skill identifier');
189
+ const skillRoot=path.join(root,'.agents/skills',skill);
190
+ if(fs.existsSync(skillRoot)) {
191
+ skillTrees[skill]=treeHash(skillRoot);
192
+ if(skillLock?.skills?.shared?.[skill]?.effectiveHash!==skillTrees[skill])issues.push({id:`skill-lock-drift:${skill}`,reason:'技能正文、引用或源码索引与锁不一致'});
193
+ }
194
+ }
195
+ for(const skill of observedSkills){const {rules,sourceDigests}=readRules(root,skill);rulesSources.push(...sourceDigests);for(const rule of rules){const applicability=tags.has(rule.when)?'required':(['pagination','batch'].includes(rule.when)?'conditional':'not-applicable');constraints.push({...rule,constraint_id:rule.id,applicability,applicability_basis:applicability==='required'?[...reasons.get(skill)].sort():[`no-observed-${rule.when}; reviewer must reconcile actual behavior`]});}}
196
+ ensure(new Set(constraints.map(r=>r.constraint_id)).size===constraints.length,'duplicate canonical constraint_id');
197
+ const platform=identity?.platform_configuration;
198
+ const catalogRef='docs/engineering/backend-platforms.json';
199
+ const catalogPath=path.join(root,catalogRef);
200
+ let platform_catalog_digest=null;
201
+ if(platform?.profile_id && fs.existsSync(catalogPath)) {
202
+ const bytes=fs.readFileSync(catalogPath);platform_catalog_digest=coverageDigest(bytes);
203
+ const profile=JSON.parse(bytes).profiles.find(p=>p.id===platform.profile_id);
204
+ if(!profile || profile.java_version!==platform.java_version || profile.spring_boot_version!==platform.spring_boot_version || profile.component_platform_line!==platform.component_platform_line)issues.push({id:'platform-identity-mismatch',reason:'登记精确平台与事实源不一致'});
205
+ else if(types.some(t=>new RegExp(`\\bimport\\s+${profile.validation_namespace==='javax'?'jakarta':'javax'}\\.(?:validation|servlet)\\.`).test(t.code)))issues.push({id:'platform-namespace-mismatch',reason:'源码使用了目标平台之外的 Validation/Servlet 命名空间'});
206
+ }
207
+ const findings=[];
208
+ for(const t of active) {
209
+ const dependencies=types.filter(other=>other!==t&&uses(t,other));
210
+ if([...t.roles].some(r=>['infrastructure','repository','persistence'].includes(r)) && dependencies.some(o=>[...o.roles].some(r=>['web','server'].includes(r))))findings.push({constraint_id:'repository.ownership',code_ref:t.ref,disposition:'violation',reason:'持久化层引用 Web 类型'});
211
+ if(t.http && !t.annotations.some(a=>['ControllerAdvice','RestControllerAdvice'].includes(a)) && (dependencies.some(o=>[...o.roles].some(r=>['domain','repository','infrastructure','persistence'].includes(r)))||/\b(?:[A-Z]\w*(?:Gateway|Repository|Mapper)|JdbcTemplate|EntityManager)\b/.test(t.code)))findings.push({constraint_id:'web.use-case',code_ref:t.ref,disposition:'violation',reason:'HTTP 入口直接引用领域/持久化能力'});
212
+ if(t.roles.has('domain')&&family==='domain-driven'&&/\bimport\s+(?:org\.springframework|org\.apache\.ibatis|com\.baomidou|jakarta\.persistence|javax\.persistence)\./.test(t.code))findings.push({constraint_id:'domain.dependencies',code_ref:t.ref,disposition:'violation',reason:'Domain 技术依赖泄漏'});
213
+ }
214
+ return {schema_version:1,scope_kind,architecture_identity:identity||null,basis: basis||null,comparison_ref,source_roots:roots,source_head:git(projectRoot,['rev-parse','HEAD']).trim(),changed_paths:changedPaths.sort(),inventory,reviewed_paths:active.map(t=>t.ref).sort(),skills:observedSkills.map(skill=>({skill,tree_digest:skillTrees[skill],reasons:[...reasons.get(skill)].sort()})),skill_assessments:CORE_SKILLS.map(skill=>({skill,status:observedSkills.includes(skill)?'applicable':'not-applicable',reason:observedSkills.includes(skill)?'observed-or-declared':'no matching registered responsibility or source signal'})),constraints:constraints.sort((a,b)=>a.constraint_id.localeCompare(b.constraint_id)),responsibility_evidence,discovery_sources,platform_catalog_digest,rule_sources:rulesSources.sort((a,b)=>a.ref.localeCompare(b.ref)),skill_lock_digest:fs.existsSync(lock)?coverageDigest(fs.readFileSync(lock)):null,issues,findings,limitations:['源码检查用于发现职责与明确反例,不替代编译态 ArchUnit、HTTP fixture 或 Reviewer 全文语义审查。']};
215
+ }
216
+
217
+ export function verifyCoverageRows(coverage, rows, {root,projectRoot}={}) {
218
+ ensure(!coverage.issues.length,`coverage unresolved: ${coverage.issues.map(i=>i.id).join(', ')}`);
219
+ ensure(!coverage.findings.length,`Standards violation: ${coverage.findings.map(i=>i.constraint_id).join(', ')}`);
220
+ ensure(Array.isArray(rows),'constraint_results required');
221
+ const standards=rows.filter(r=>r.axis==='Standards');
222
+ ensure(new Set(standards.map(r=>r.constraint_id)).size===standards.length,'duplicate constraint result');
223
+ for(const expected of coverage.constraints) {
224
+ const row=standards.find(r=>r.constraint_id===expected.constraint_id);
225
+ ensure(row,`constraint not reviewed: ${expected.constraint_id}`);
226
+ ensure(row.skill===expected.skill && row.rule_ref===expected.rule_ref && row.rule_digest===expected.rule_digest,'constraint owner/rule mismatch');
227
+ ensure(typeof row.constraint==='string'&&row.constraint.trim()&&Array.isArray(row.applicability_basis)&&coverageDigest(row.applicability_basis)===coverageDigest(expected.applicability_basis),'constraint applicability evidence required');
228
+ ensure(['passed','not-applicable'].includes(row.status),`${expected.constraint_id}: unresolved violation`);
229
+ if(row.status==='not-applicable')ensure(expected.applicability!=='required' && typeof row.reason==='string' && row.reason.trim(),`${expected.constraint_id}: applicable rule cannot be waived`);
230
+ ensure(row.code_ref && row.evidence_ref && row.evidence_digest,'rule/code/evidence required');
231
+ coverageFile(projectRoot,row.code_ref.split(':')[0]);
232
+ ensure(coverageDigest(fs.readFileSync(coverageFile(root,row.evidence_ref)))===row.evidence_digest,'verification evidence stale');
233
+ if(expected.evidence==='semantic-review')ensure(typeof row.review_notes==='string'&&row.review_notes.trim().length>=20,'full-text semantic review needs concrete reasoning');
234
+ }
235
+ const ids=new Set(coverage.constraints.map(r=>r.constraint_id));
236
+ ensure(standards.every(r=>ids.has(r.constraint_id)),'unknown constraint result; update canonical declaration before asserting coverage');
237
+ }