create-yss-spec 3.4.8 → 3.4.10

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 (459) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/template/attach-planner.js +5 -0
  4. package/src/template/sync-planner.js +5 -0
  5. package/template/.agents/skills/.strategic-design-skills-manifest.json +5 -5
  6. package/template/.agents/skills/alibaba-java-code-style/SKILL.md +2 -2
  7. package/template/.agents/skills/archify/SKILL.md +2 -19
  8. package/template/.agents/skills/archify/references/geometry-and-routing.md +20 -0
  9. package/template/.agents/skills/code-review/SKILL.md +3 -33
  10. package/template/.agents/skills/code-review/references/candidate-capture.md +33 -0
  11. package/template/.agents/skills/code-review/references/yss-review-standards.md +3 -5
  12. package/template/.agents/skills/codebase-design/SKILL.md +2 -2
  13. package/template/.agents/skills/competitive-intelligence/SKILL.md +1 -1
  14. package/template/.agents/skills/diagnosing-bugs/SKILL.md +6 -2
  15. package/template/.agents/skills/formily-foundation/SKILL.md +1 -1
  16. package/template/.agents/skills/formily-step-flow/SKILL.md +3 -2
  17. package/template/.agents/skills/frontend-commit/SKILL.md +6 -6
  18. package/template/.agents/skills/grilling/SKILL.md +2 -2
  19. package/template/.agents/skills/implement/SKILL.md +1 -1
  20. package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +3 -3
  21. package/template/.agents/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  22. package/template/.agents/skills/improve-codebase-architecture/SKILL.md +10 -6
  23. package/template/.agents/skills/java-backend-commit/SKILL.md +5 -5
  24. package/template/.agents/skills/llm-wiki/SKILL.md +1 -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-audit-log/SKILL.md +3 -1
  40. package/template/.agents/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  41. package/template/.agents/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  42. package/template/.agents/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  43. package/template/.agents/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  44. package/template/.agents/skills/yss-backend-spec-review/SKILL.md +6 -0
  45. package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
  46. package/template/.agents/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  47. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
  48. package/template/.agents/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  49. package/template/.agents/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  50. package/template/.agents/skills/yss-design-system/SKILL.md +2 -2
  51. package/template/.agents/skills/yss-domain/SKILL.md +17 -5
  52. package/template/.agents/skills/yss-domain/references/domain-layer-guide.md +2 -2
  53. package/template/.agents/skills/yss-domain/references/existing-project.md +5 -0
  54. package/template/.agents/skills/yss-dto/SKILL.md +13 -10
  55. package/template/.agents/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  56. package/template/.agents/skills/yss-exception/SKILL.md +2 -2
  57. package/template/.agents/skills/yss-formily-schema-generator/SKILL.md +12 -12
  58. package/template/.agents/skills/yss-hook/SKILL.md +8 -44
  59. package/template/.agents/skills/yss-hook/references/use-request.md +42 -0
  60. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
  61. package/template/.agents/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  62. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  63. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  64. package/template/.agents/skills/yss-mybatis/SKILL.md +10 -0
  65. package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +3 -1
  66. package/template/.agents/skills/yss-openapi-governance/SKILL.md +5 -32
  67. package/template/.agents/skills/yss-openapi-governance/references/governance-output.md +34 -0
  68. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +12 -6
  69. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
  70. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  71. package/template/.agents/skills/yss-prototype-stage/SKILL.md +3 -5
  72. package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  73. package/template/.agents/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
  74. package/template/.agents/skills/yss-repository/SKILL.md +13 -1
  75. package/template/.agents/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  76. package/template/.agents/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  77. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  78. package/template/.agents/skills/yss-stage-decision/SKILL.md +3 -1
  79. package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  80. package/template/.agents/skills/yss-tactical-design/SKILL.md +3 -3
  81. package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  82. package/template/.agents/skills/yss-technical-design/SKILL.md +2 -0
  83. package/template/.agents/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
  84. package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
  85. package/template/.agents/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  86. package/template/.agents/skills/yss-validation/SKILL.md +1 -1
  87. package/template/.agents/skills/yss-web-controller/SKILL.md +16 -7
  88. package/template/.agents/skills/ytable-usage/SKILL.md +2 -2
  89. package/template/.codex/skills/alibaba-java-code-style/SKILL.md +2 -2
  90. package/template/.codex/skills/archify/SKILL.md +2 -19
  91. package/template/.codex/skills/archify/references/geometry-and-routing.md +20 -0
  92. package/template/.codex/skills/code-review/SKILL.md +3 -33
  93. package/template/.codex/skills/code-review/references/candidate-capture.md +33 -0
  94. package/template/.codex/skills/code-review/references/yss-review-standards.md +3 -5
  95. package/template/.codex/skills/codebase-design/SKILL.md +2 -2
  96. package/template/.codex/skills/competitive-intelligence/SKILL.md +1 -1
  97. package/template/.codex/skills/data-analytics/mcp/server.cjs +2 -1
  98. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +9 -32
  99. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +29 -0
  100. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +1 -1
  101. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +4 -4
  102. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +12 -22
  103. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +5 -10
  104. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +47 -49
  105. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +45 -0
  106. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +4 -5
  107. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +1 -1
  108. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +1 -1
  109. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +1 -1
  110. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +1 -1
  111. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +4 -4
  112. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +1 -1
  113. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +2 -2
  114. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +1 -1
  115. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +1 -1
  116. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +1 -1
  117. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +4 -4
  118. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +16 -14
  119. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +1 -1
  120. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +1 -1
  121. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +7 -7
  122. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +7 -7
  123. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +4 -2
  124. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +5 -5
  125. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +3 -3
  126. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +7 -71
  127. package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +70 -0
  128. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +4 -4
  129. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +1 -1
  130. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +1 -1
  131. package/template/.codex/skills/diagnosing-bugs/SKILL.md +6 -2
  132. package/template/.codex/skills/formily-foundation/SKILL.md +1 -1
  133. package/template/.codex/skills/formily-step-flow/SKILL.md +3 -2
  134. package/template/.codex/skills/frontend-commit/SKILL.md +6 -6
  135. package/template/.codex/skills/grilling/SKILL.md +2 -2
  136. package/template/.codex/skills/implement/SKILL.md +1 -1
  137. package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +3 -3
  138. package/template/.codex/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  139. package/template/.codex/skills/improve-codebase-architecture/SKILL.md +10 -6
  140. package/template/.codex/skills/java-backend-commit/SKILL.md +5 -5
  141. package/template/.codex/skills/llm-wiki/SKILL.md +1 -1
  142. package/template/.codex/skills/product-design/references/critical-overrides.md +3 -4
  143. package/template/.codex/skills/product-design/skills/audit/SKILL.md +1 -1
  144. package/template/.codex/skills/product-design/skills/design-qa/SKILL.md +1 -1
  145. package/template/.codex/skills/product-design/skills/get-context/SKILL.md +2 -1
  146. package/template/.codex/skills/product-design/skills/ideate/SKILL.md +2 -50
  147. package/template/.codex/skills/product-design/skills/ideate/references/image-prompt-patterns.md +51 -0
  148. package/template/.codex/skills/product-design/skills/image-to-code/SKILL.md +6 -6
  149. package/template/.codex/skills/product-design/skills/index/SKILL.md +2 -2
  150. package/template/.codex/skills/product-design/skills/prototype/SKILL.md +6 -6
  151. package/template/.codex/skills/product-design/skills/url-to-code/SKILL.md +1 -1
  152. package/template/.codex/skills/product-design/skills/user-context/SKILL.md +1 -1
  153. package/template/.codex/skills/prototype/SKILL.md +1 -1
  154. package/template/.codex/skills/prototype-review/SKILL.md +1 -1
  155. package/template/.codex/skills/resolving-merge-conflicts/SKILL.md +2 -2
  156. package/template/.codex/skills/tdd/SKILL.md +1 -1
  157. package/template/.codex/skills/to-questionnaire/SKILL.md +4 -2
  158. package/template/.codex/skills/to-spec/SKILL.md +3 -3
  159. package/template/.codex/skills/to-tickets/SKILL.md +7 -7
  160. package/template/.codex/skills/using-git-worktrees/SKILL.md +13 -11
  161. package/template/.codex/skills/wait-what/SKILL.md +1 -1
  162. package/template/.codex/skills/wayfinder/SKILL.md +4 -2
  163. package/template/.codex/skills/writing-for-agents/SKILL.md +9 -73
  164. package/template/.codex/skills/writing-for-agents/references/writing-principles.md +76 -0
  165. package/template/.codex/skills/yss-api-integration/SKILL.md +2 -2
  166. package/template/.codex/skills/yss-application/SKILL.md +12 -0
  167. package/template/.codex/skills/yss-audit-log/SKILL.md +3 -1
  168. package/template/.codex/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  169. package/template/.codex/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  170. package/template/.codex/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  171. package/template/.codex/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  172. package/template/.codex/skills/yss-backend-spec-review/SKILL.md +6 -0
  173. package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
  174. package/template/.codex/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  175. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
  176. package/template/.codex/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  177. package/template/.codex/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  178. package/template/.codex/skills/yss-design-system/SKILL.md +2 -2
  179. package/template/.codex/skills/yss-domain/SKILL.md +17 -5
  180. package/template/.codex/skills/yss-domain/references/domain-layer-guide.md +2 -2
  181. package/template/.codex/skills/yss-domain/references/existing-project.md +5 -0
  182. package/template/.codex/skills/yss-dto/SKILL.md +13 -10
  183. package/template/.codex/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  184. package/template/.codex/skills/yss-exception/SKILL.md +2 -2
  185. package/template/.codex/skills/yss-formily-schema-generator/SKILL.md +12 -12
  186. package/template/.codex/skills/yss-hook/SKILL.md +8 -44
  187. package/template/.codex/skills/yss-hook/references/use-request.md +42 -0
  188. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
  189. package/template/.codex/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  190. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  191. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  192. package/template/.codex/skills/yss-mybatis/SKILL.md +10 -0
  193. package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +3 -1
  194. package/template/.codex/skills/yss-openapi-governance/SKILL.md +5 -32
  195. package/template/.codex/skills/yss-openapi-governance/references/governance-output.md +34 -0
  196. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +12 -6
  197. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
  198. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  199. package/template/.codex/skills/yss-prototype-stage/SKILL.md +3 -5
  200. package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  201. package/template/.codex/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
  202. package/template/.codex/skills/yss-repository/SKILL.md +13 -1
  203. package/template/.codex/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  204. package/template/.codex/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  205. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  206. package/template/.codex/skills/yss-stage-decision/SKILL.md +3 -1
  207. package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  208. package/template/.codex/skills/yss-tactical-design/SKILL.md +3 -3
  209. package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  210. package/template/.codex/skills/yss-technical-design/SKILL.md +2 -0
  211. package/template/.codex/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
  212. package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
  213. package/template/.codex/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  214. package/template/.codex/skills/yss-validation/SKILL.md +1 -1
  215. package/template/.codex/skills/yss-web-controller/SKILL.md +16 -7
  216. package/template/.codex/skills/ytable-usage/SKILL.md +2 -2
  217. package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +2 -2
  218. package/template/.cursor/skills/archify/SKILL.md +2 -19
  219. package/template/.cursor/skills/archify/references/geometry-and-routing.md +20 -0
  220. package/template/.cursor/skills/code-review/SKILL.md +3 -33
  221. package/template/.cursor/skills/code-review/references/candidate-capture.md +33 -0
  222. package/template/.cursor/skills/code-review/references/yss-review-standards.md +3 -5
  223. package/template/.cursor/skills/codebase-design/SKILL.md +2 -2
  224. package/template/.cursor/skills/competitive-intelligence/SKILL.md +1 -1
  225. package/template/.cursor/skills/diagnosing-bugs/SKILL.md +6 -2
  226. package/template/.cursor/skills/formily-foundation/SKILL.md +1 -1
  227. package/template/.cursor/skills/formily-step-flow/SKILL.md +3 -2
  228. package/template/.cursor/skills/frontend-commit/SKILL.md +6 -6
  229. package/template/.cursor/skills/grilling/SKILL.md +2 -2
  230. package/template/.cursor/skills/implement/SKILL.md +1 -1
  231. package/template/.cursor/skills/implementation-repo-onboarding/SKILL.md +3 -3
  232. package/template/.cursor/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  233. package/template/.cursor/skills/improve-codebase-architecture/SKILL.md +10 -6
  234. package/template/.cursor/skills/java-backend-commit/SKILL.md +5 -5
  235. package/template/.cursor/skills/llm-wiki/SKILL.md +1 -1
  236. package/template/.cursor/skills/prototype/SKILL.md +1 -1
  237. package/template/.cursor/skills/prototype-review/SKILL.md +1 -1
  238. package/template/.cursor/skills/resolving-merge-conflicts/SKILL.md +2 -2
  239. package/template/.cursor/skills/tdd/SKILL.md +1 -1
  240. package/template/.cursor/skills/to-questionnaire/SKILL.md +4 -2
  241. package/template/.cursor/skills/to-spec/SKILL.md +3 -3
  242. package/template/.cursor/skills/to-tickets/SKILL.md +7 -7
  243. package/template/.cursor/skills/using-git-worktrees/SKILL.md +13 -11
  244. package/template/.cursor/skills/wait-what/SKILL.md +1 -1
  245. package/template/.cursor/skills/wayfinder/SKILL.md +4 -2
  246. package/template/.cursor/skills/writing-for-agents/SKILL.md +9 -73
  247. package/template/.cursor/skills/writing-for-agents/references/writing-principles.md +76 -0
  248. package/template/.cursor/skills/yss-api-integration/SKILL.md +2 -2
  249. package/template/.cursor/skills/yss-application/SKILL.md +12 -0
  250. package/template/.cursor/skills/yss-audit-log/SKILL.md +3 -1
  251. package/template/.cursor/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  252. package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  253. package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  254. package/template/.cursor/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  255. package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +6 -0
  256. package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
  257. package/template/.cursor/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  258. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
  259. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  260. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  261. package/template/.cursor/skills/yss-design-system/SKILL.md +2 -2
  262. package/template/.cursor/skills/yss-domain/SKILL.md +17 -5
  263. package/template/.cursor/skills/yss-domain/references/domain-layer-guide.md +2 -2
  264. package/template/.cursor/skills/yss-domain/references/existing-project.md +5 -0
  265. package/template/.cursor/skills/yss-dto/SKILL.md +13 -10
  266. package/template/.cursor/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  267. package/template/.cursor/skills/yss-exception/SKILL.md +2 -2
  268. package/template/.cursor/skills/yss-formily-schema-generator/SKILL.md +12 -12
  269. package/template/.cursor/skills/yss-hook/SKILL.md +8 -44
  270. package/template/.cursor/skills/yss-hook/references/use-request.md +42 -0
  271. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
  272. package/template/.cursor/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  273. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  274. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  275. package/template/.cursor/skills/yss-mybatis/SKILL.md +10 -0
  276. package/template/.cursor/skills/yss-openapi-draft-review/SKILL.md +3 -1
  277. package/template/.cursor/skills/yss-openapi-governance/SKILL.md +5 -32
  278. package/template/.cursor/skills/yss-openapi-governance/references/governance-output.md +34 -0
  279. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +12 -6
  280. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
  281. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  282. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +3 -5
  283. package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  284. package/template/.cursor/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
  285. package/template/.cursor/skills/yss-repository/SKILL.md +13 -1
  286. package/template/.cursor/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  287. package/template/.cursor/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  288. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  289. package/template/.cursor/skills/yss-stage-decision/SKILL.md +3 -1
  290. package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  291. package/template/.cursor/skills/yss-tactical-design/SKILL.md +3 -3
  292. package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  293. package/template/.cursor/skills/yss-technical-design/SKILL.md +2 -0
  294. package/template/.cursor/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
  295. package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
  296. package/template/.cursor/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  297. package/template/.cursor/skills/yss-validation/SKILL.md +1 -1
  298. package/template/.cursor/skills/yss-web-controller/SKILL.md +16 -7
  299. package/template/.cursor/skills/ytable-usage/SKILL.md +2 -2
  300. package/template/.pi/skills/alibaba-java-code-style/SKILL.md +2 -2
  301. package/template/.pi/skills/archify/SKILL.md +2 -19
  302. package/template/.pi/skills/archify/references/geometry-and-routing.md +20 -0
  303. package/template/.pi/skills/code-review/SKILL.md +3 -33
  304. package/template/.pi/skills/code-review/references/candidate-capture.md +33 -0
  305. package/template/.pi/skills/code-review/references/yss-review-standards.md +3 -5
  306. package/template/.pi/skills/codebase-design/SKILL.md +2 -2
  307. package/template/.pi/skills/competitive-intelligence/SKILL.md +1 -1
  308. package/template/.pi/skills/diagnosing-bugs/SKILL.md +6 -2
  309. package/template/.pi/skills/formily-foundation/SKILL.md +1 -1
  310. package/template/.pi/skills/formily-step-flow/SKILL.md +3 -2
  311. package/template/.pi/skills/frontend-commit/SKILL.md +6 -6
  312. package/template/.pi/skills/grilling/SKILL.md +2 -2
  313. package/template/.pi/skills/implement/SKILL.md +1 -1
  314. package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +3 -3
  315. package/template/.pi/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
  316. package/template/.pi/skills/improve-codebase-architecture/SKILL.md +10 -6
  317. package/template/.pi/skills/java-backend-commit/SKILL.md +5 -5
  318. package/template/.pi/skills/llm-wiki/SKILL.md +1 -1
  319. package/template/.pi/skills/prototype/SKILL.md +1 -1
  320. package/template/.pi/skills/prototype-review/SKILL.md +1 -1
  321. package/template/.pi/skills/resolving-merge-conflicts/SKILL.md +2 -2
  322. package/template/.pi/skills/tdd/SKILL.md +1 -1
  323. package/template/.pi/skills/to-questionnaire/SKILL.md +4 -2
  324. package/template/.pi/skills/to-spec/SKILL.md +3 -3
  325. package/template/.pi/skills/to-tickets/SKILL.md +7 -7
  326. package/template/.pi/skills/using-git-worktrees/SKILL.md +13 -11
  327. package/template/.pi/skills/wait-what/SKILL.md +1 -1
  328. package/template/.pi/skills/wayfinder/SKILL.md +4 -2
  329. package/template/.pi/skills/writing-for-agents/SKILL.md +9 -73
  330. package/template/.pi/skills/writing-for-agents/references/writing-principles.md +76 -0
  331. package/template/.pi/skills/yss-api-integration/SKILL.md +2 -2
  332. package/template/.pi/skills/yss-application/SKILL.md +12 -0
  333. package/template/.pi/skills/yss-audit-log/SKILL.md +3 -1
  334. package/template/.pi/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
  335. package/template/.pi/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
  336. package/template/.pi/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
  337. package/template/.pi/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
  338. package/template/.pi/skills/yss-backend-spec-review/SKILL.md +6 -0
  339. package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
  340. package/template/.pi/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
  341. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
  342. package/template/.pi/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
  343. package/template/.pi/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
  344. package/template/.pi/skills/yss-design-system/SKILL.md +2 -2
  345. package/template/.pi/skills/yss-domain/SKILL.md +17 -5
  346. package/template/.pi/skills/yss-domain/references/domain-layer-guide.md +2 -2
  347. package/template/.pi/skills/yss-domain/references/existing-project.md +5 -0
  348. package/template/.pi/skills/yss-dto/SKILL.md +13 -10
  349. package/template/.pi/skills/yss-dto/references/wire-validation-checklist.md +14 -0
  350. package/template/.pi/skills/yss-exception/SKILL.md +2 -2
  351. package/template/.pi/skills/yss-formily-schema-generator/SKILL.md +12 -12
  352. package/template/.pi/skills/yss-hook/SKILL.md +8 -44
  353. package/template/.pi/skills/yss-hook/references/use-request.md +42 -0
  354. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
  355. package/template/.pi/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
  356. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
  357. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  358. package/template/.pi/skills/yss-mybatis/SKILL.md +10 -0
  359. package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +3 -1
  360. package/template/.pi/skills/yss-openapi-governance/SKILL.md +5 -32
  361. package/template/.pi/skills/yss-openapi-governance/references/governance-output.md +34 -0
  362. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +12 -6
  363. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
  364. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  365. package/template/.pi/skills/yss-prototype-stage/SKILL.md +3 -5
  366. package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
  367. package/template/.pi/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
  368. package/template/.pi/skills/yss-repository/SKILL.md +13 -1
  369. package/template/.pi/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
  370. package/template/.pi/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
  371. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
  372. package/template/.pi/skills/yss-stage-decision/SKILL.md +3 -1
  373. package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
  374. package/template/.pi/skills/yss-tactical-design/SKILL.md +3 -3
  375. package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
  376. package/template/.pi/skills/yss-technical-design/SKILL.md +2 -0
  377. package/template/.pi/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
  378. package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
  379. package/template/.pi/skills/yss-ui-business-page-generation/SKILL.md +5 -3
  380. package/template/.pi/skills/yss-validation/SKILL.md +1 -1
  381. package/template/.pi/skills/yss-web-controller/SKILL.md +16 -7
  382. package/template/.pi/skills/ytable-usage/SKILL.md +2 -2
  383. package/template/AGENTS.md +2 -0
  384. package/template/CONTEXT.md +2 -1
  385. package/template/README.md +1 -0
  386. package/template/docs/agents/issue-tracker.md +7 -0
  387. package/template/docs/process/contract-reading.md +46 -0
  388. package/template/docs/process/lifecycle-artifact-map.md +2 -2
  389. package/template/docs/process/lifecycle-registry-baseline.json +2 -1
  390. package/template/docs/process/lifecycle-registry.yaml +10 -4
  391. package/template/docs/process/schemas/api-contract-decision-v2.schema.json +198 -0
  392. package/template/docs/process/schemas/digital-human-task-package.schema.json +68 -4
  393. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +259 -0
  394. package/template/docs/process/schemas/stage-tracking.schema.json +259 -0
  395. package/template/docs/process/stage-tracking.md +62 -0
  396. package/template/docs/process/strategic-handoff-package.md +8 -0
  397. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +2 -0
  398. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +1 -0
  399. package/template/docs/user-guide//351/230/266/346/256/265/346/216/245/345/205/245/344/270/216/344/272/247/347/211/251/345/244/215/347/224/250/344/275/277/347/224/250/346/211/213/345/206/214.md +243 -0
  400. package/template/scripts/api-contract-decision +16 -0
  401. package/template/scripts/backend-standards-coverage +26 -0
  402. package/template/scripts/complete-backend-delivery +17 -0
  403. package/template/scripts/contract +13 -0
  404. package/template/scripts/dispatch-slice-task +13 -0
  405. package/template/scripts/lib/api-contract-decision.mjs +45 -4
  406. package/template/scripts/lib/approval-record.mjs +1 -1
  407. package/template/scripts/lib/approved-execution-context.mjs +35 -7
  408. package/template/scripts/lib/backend-architecture.mjs +2 -2
  409. package/template/scripts/lib/backend-delivery-terminal.mjs +51 -0
  410. package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
  411. package/template/scripts/lib/backend-platform.mjs +1 -1
  412. package/template/scripts/lib/backend-review.mjs +58 -20
  413. package/template/scripts/lib/backend-scaffold-prerequisites.mjs +1 -1
  414. package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
  415. package/template/scripts/lib/context-contract.mjs +1 -1
  416. package/template/scripts/lib/context-reconciliation.mjs +1 -1
  417. package/template/scripts/lib/contract-source.mjs +22 -0
  418. package/template/scripts/lib/contract-views.mjs +109 -0
  419. package/template/scripts/lib/delivery-preflight.mjs +3 -2
  420. package/template/scripts/lib/digital-human-roles.mjs +1 -1
  421. package/template/scripts/lib/existing-backend-architecture.mjs +4 -3
  422. package/template/scripts/lib/existing-ui-baseline.mjs +4 -2
  423. package/template/scripts/lib/first-slice-artifacts.mjs +1 -1
  424. package/template/scripts/lib/frontend-delivery-boundary.mjs +1 -1
  425. package/template/scripts/lib/frontend-delivery.mjs +1 -1
  426. package/template/scripts/lib/harness-execution-scope.mjs +15 -1
  427. package/template/scripts/lib/implementation-contract-compiler.mjs +4 -4
  428. package/template/scripts/lib/json-schema.mjs +19 -4
  429. package/template/scripts/lib/lifecycle-context-query.mjs +5 -1
  430. package/template/scripts/lib/lifecycle-controls.mjs +1 -1
  431. package/template/scripts/lib/lifecycle-execution-scope.mjs +92 -0
  432. package/template/scripts/lib/lifecycle-registry.mjs +2 -1
  433. package/template/scripts/lib/lifecycle-transition.mjs +25 -4
  434. package/template/scripts/lib/openapi-draft-validation.mjs +2 -1
  435. package/template/scripts/lib/profile-skill-sync.mjs +46 -5
  436. package/template/scripts/lib/skill-registry.mjs +1 -1
  437. package/template/scripts/lib/slice-contract-preparation.mjs +16 -14
  438. package/template/scripts/lib/slice-contract-views.mjs +1 -1
  439. package/template/scripts/lib/slice-contract.mjs +18 -3
  440. package/template/scripts/lib/slice-execution-preflight.mjs +7 -3
  441. package/template/scripts/lib/slice-repositories.mjs +1 -1
  442. package/template/scripts/lib/slice-task-package.mjs +3 -2
  443. package/template/scripts/lib/stage-tracking-migration.mjs +176 -0
  444. package/template/scripts/lib/stage-tracking.mjs +184 -0
  445. package/template/scripts/lib/strategic-handoff-consumption.mjs +5 -4
  446. package/template/scripts/lib/strategic-handoff-io.mjs +5 -2
  447. package/template/scripts/lib/strategic-handoff-routing.mjs +31 -0
  448. package/template/scripts/lib/strategic-handoff.mjs +4 -2
  449. package/template/scripts/lib/task-package.mjs +2 -0
  450. package/template/scripts/lib/technical-design-boundary.mjs +4 -2
  451. package/template/scripts/lib/ui-baseline.mjs +1 -1
  452. package/template/scripts/lib/user-decision.mjs +1 -1
  453. package/template/scripts/lib/validation-phase.mjs +72 -0
  454. package/template/scripts/stage-tracking +25 -0
  455. package/template/scripts/strategic-consumer-entry +47 -0
  456. package/template/scripts/verify-context-reconciliation +4 -3
  457. package/template/scripts/verify-lifecycle-checkpoint +10 -0
  458. package/template/skills-lock.json +65 -63
  459. package/template.snapshot.json +4 -4
@@ -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
+ }
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
2
+ import { existsSync, lstatSync, readFileSync, readdirSync } from './validation-phase.mjs';
3
3
  import path from "node:path";
4
4
 
5
5
  const CONTEXT_FILE = "CONTEXT.md";
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { existsSync, readFileSync } from './validation-phase.mjs';
2
2
  import path from "node:path";
3
3
  import { parseDocument } from "../vendor/yaml.mjs";
4
4
  import { resolveContextTermRefs, verifyContextSnapshot } from "./context-contract.mjs";
@@ -0,0 +1,22 @@
1
+ import {readFileSync} from './validation-phase.mjs';
2
+ import {safe,hash} from './strategic-handoff-io.mjs';
3
+ import {parseSliceYaml} from './slice-contract.mjs';
4
+ export function contractSourceMetadata(bytes){
5
+ const text=String(bytes),front=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
6
+ if(front)return parseSliceYaml(front[1]);
7
+ return /^\s*[{[]/.test(text)||/^[A-Za-z_][\w-]*:\s/m.test(text)&&!/^#/m.test(text)?parseSliceYaml(text):{};
8
+ }
9
+ /** Reads original bytes; returns derivable facts only. It never selects or approves a source. */
10
+ export function readContractSource(selection,{root=process.cwd(),read=ref=>readFileSync(safe(root,ref))}={}){
11
+ const selected=typeof selection==='string'?{ref:selection}:selection;
12
+ if(!selected?.ref)throw new TypeError('来源选择缺少 ref');
13
+ const bytes=read(selected.ref),digest=hash(bytes),data=contractSourceMetadata(bytes);
14
+ const observed=data.requirement_version??data.version??data.contract_version??data.decision_version;
15
+ const conflicts=[];
16
+ const conflict=(field,before,after)=>conflicts.push({field,source_ref:selected.ref,before,after});
17
+ if(selected.digest&&selected.digest!==digest)conflict('digest',selected.digest,digest);
18
+ if(selected.version!==undefined&&observed!==undefined&&String(selected.version)!==String(observed))conflict('version',selected.version,observed);
19
+ if(conflicts.length){const error=new TypeError(conflicts.map(({field,before,after})=>`${field==='version'?'来源版本冲突':'来源冲突'} ${selected.ref}.${field}: supplied=${before}; observed=${after}; 恢复: 核对双方来源并显式选择当前版本`).join('\n'));Object.assign(error,{code:'SLICE_SOURCE_CONFLICT',...conflicts[0],conflicts});throw error;}
20
+ const version=selected.version??observed;
21
+ return {bytes,data,binding:{ref:selected.ref,digest,...(version!==undefined?{version:String(version)}:{}),...(selected.approval_ref?{approval_ref:selected.approval_ref}:{})}};
22
+ }
@@ -0,0 +1,109 @@
1
+ import {readFileSync,withValidationPhase} from './validation-phase.mjs';
2
+ import {safe,hash,schema} from './strategic-handoff-io.mjs';
3
+ import {parseSliceYaml,readSliceContract} from './slice-contract.mjs';
4
+ import {renderSliceContractView,diffSliceContracts} from './slice-contract-views.mjs';
5
+
6
+ // This is a presentation adapter table, never a lifecycle or approval registry.
7
+ export const contractKinds=Object.freeze({
8
+ slice:null,plan:null,spec:null,'product-design':null,'prototype-confirmation':null,'visual-baseline':null,
9
+ 'technical-design':'.agents/skills/yss-technical-design/references/technical-design.schema.json',
10
+ 'api-decision':'docs/process/schemas/api-contract-decision.schema.json',
11
+ 'data-decision':'docs/process/schemas/data-architecture-decision.schema.json',
12
+ scaffold:'docs/process/schemas/project-scaffold-contract.schema.json',
13
+ 'scaffold-decision':'docs/process/schemas/scaffold-architecture-decisions.schema.json',
14
+ handoff:null,'backend-delivery':'docs/process/schemas/backend-delivery.schema.json',
15
+ 'frontend-acceptance':'docs/process/schemas/frontend-delivery-acceptance.schema.json',approval:null,'user-decision':'docs/process/schemas/user-decision.schema.json',
16
+ 'context-reconciliation':'docs/process/schemas/context-reconciliation.schema.json'
17
+ });
18
+ const object=v=>v&&typeof v==='object'&&!Array.isArray(v);
19
+ const stringify=v=>typeof v==='string'?v:JSON.stringify(v,null,2);
20
+ const metadata=/^(schema_version|kind|digest|sha256|subject_digest|.*_digest|.*_sha256|resolution|basis|inputs|sources|artifact_bindings|current_version)$/;
21
+ function display(value){
22
+ if(Array.isArray(value))return value.map(display);
23
+ if(!object(value))return value;
24
+ return Object.fromEntries(Object.entries(value).filter(([key])=>!metadata.test(key)).map(([k,v])=>[k,display(v)]));
25
+ }
26
+ function validateKind(kind){if(!Object.hasOwn(contractKinds,kind))throw new TypeError(`未知合同类型 ${kind};可用:${Object.keys(contractKinds).join(', ')}`);}
27
+ function load(ref,root){
28
+ const bytes=readFileSync(safe(root,ref));
29
+ if(/\.md$/i.test(ref)){
30
+ const text=bytes.toString('utf8'),front=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
31
+ return{bytes,raw:{...(front?parseSliceYaml(front[1]):{}),正文:front?text.slice(front[0].length):text}};
32
+ }
33
+ const raw=parseSliceYaml(bytes);if(!object(raw))throw new TypeError('合同必须是结构化对象或 Markdown 文档');return{bytes,raw};
34
+ }
35
+ function references(value,root,rows=[],seen=new Set()){
36
+ if(!value||typeof value!=='object')return rows;
37
+ if(object(value)&&typeof value.ref==='string'&&typeof value.digest==='string'){
38
+ const key=`${value.ref}\0${value.digest}`;
39
+ if(!seen.has(key)){seen.add(key);try{rows.push({ref:value.ref,current:hash(readFileSync(safe(root,value.ref)))===value.digest});}catch(error){rows.push({ref:value.ref,current:false,error:error.message});}}
40
+ }
41
+ if(object(value))for(const [key,ref]of Object.entries(value))if(key.endsWith('_ref')&&typeof ref==='string'&&typeof value[key.replace(/_ref$/,'_digest')]==='string')references({ref,digest:value[key.replace(/_ref$/,'_digest')]},root,rows,seen);
42
+ for(const child of Object.values(value))references(child,root,rows,seen);
43
+ return rows;
44
+ }
45
+ function declaredBlockers(value,prefix=''){
46
+ if(!value||typeof value!=='object')return[];
47
+ const rows=[];
48
+ for(const [key,child]of Object.entries(value)){
49
+ const field=prefix?`${prefix}.${key}`:key;
50
+ if(['blockers','blocking_findings','stale_inputs','readiness_blockers'].includes(key)&&Array.isArray(child))for(const item of child)rows.push(`${field}: ${stringify(item)}`);
51
+ else rows.push(...declaredBlockers(child,field));
52
+ }
53
+ return rows;
54
+ }
55
+ function markdown(view){
56
+ const lines=[`# ${view.kind} · ${view.binding.id||view.binding.ref}`,`版本:${view.binding.version||'源资产未声明'};权威文件:${view.binding.ref}`,`摘要:${view.binding.digest}`,`检查:${view.checks.join(';')}。批准有效性未核验;本视图不授予执行权限。`];
57
+ for(const [name,value]of Object.entries(view.content))if(value!==undefined)lines.push(`## ${name}`,stringify(value));
58
+ if(view.blockers.length)lines.push('## 阻断与未决检查',...view.blockers.map(x=>`- ${x}`));
59
+ return lines.join('\n\n')+'\n';
60
+ }
61
+ export function viewContract(ref,options={}){return withValidationPhase({root:options.root,purpose:'contract-view',slice_id:ref,work_unit_id:options.unit_id,readOnly:true},()=>view(ref,options));}
62
+ function view(ref,{root=process.cwd(),kind,profile='review',unit_id}={}){
63
+ validateKind(kind);if(!['review','task','full'].includes(profile))throw new TypeError(`未知阅读档位 ${profile}`);
64
+ let binding,content,checks=['可读取'],blockers=[],sourceChecks=[];
65
+ if(kind==='slice'){
66
+ const loaded=readSliceContract(ref,{root,diagnostic:true});binding=loaded.binding;blockers.push(...declaredBlockers(loaded.raw));
67
+ const legacy=renderSliceContractView(ref,{root,unit_id:profile==='task'?unit_id:undefined});
68
+ checks.push('Slice 结构及绑定来源');
69
+ if(legacy.diagnostic_only){content={诊断:legacy.blockers};blockers=legacy.blockers.map(b=>b.reason);}
70
+ else if(profile==='full')content={权威合同:loaded.raw,完整视图:legacy};
71
+ else if(profile==='review'){
72
+ content={...legacy.summary,验收:legacy.acceptance,实施范围:{工程:loaded.raw.scope?.project_roots||legacy.constraints.project_roots,允许写入:loaded.raw.scope?.allowed_write_paths||legacy.constraints.allowed_write_paths},关键约束:loaded.raw.scope?.forbidden_patterns||legacy.constraints.forbidden_patterns,停止条件:'来源或批准过期、越界、缺证据、验证失败、drift / violation / new_impacts 时停止并回交。'};
73
+ for(const key of ['risks','risk_acceptance','blockers','pending_decisions','constraints'])if(loaded.raw[key])content[key]=loaded.raw[key];
74
+ for(const [label,pattern]of [['风险',/风险/],['关键取舍',/取舍/],['待决定事项',/待|决定/],['变化',/变化|变更/]])if(!Object.keys(content).some(k=>pattern.test(k)))content[label]='来源未说明,审阅时核实。';
75
+ const extensions=loaded.raw.extensions||{};
76
+ for(const [name,extension]of Object.entries(extensions))for(const [key,value]of Object.entries(extension))if(/risk|constraint|decision|block|exception|unknown/.test(key))content[`${name}.${key}`]=value;
77
+ }else{
78
+ if(!unit_id)throw new TypeError('task 视图必须指定 --unit');
79
+ const units=loaded.contract.work_units.filter(u=>u.id===unit_id);if(units.length!==1)throw new TypeError(`工作单元缺失或不唯一: ${unit_id}`);
80
+ content={当前任务:units[0].work_unit||units[0],全局约束:legacy.constraints,专项约束:legacy.extensions,编译约束:loaded.raw.resolution,适用性:loaded.raw.applicability,验收:legacy.acceptance,上游引用:Object.fromEntries(Object.entries(loaded.sources).map(([k,v])=>[k,{ref:v.ref,version:v.version}])),停止条件:'来源或批准过期、越界、缺证据、验证失败、drift / violation / new_impacts 时停止并回交。'};
81
+ const known=new Set(['schema_version','contract_id','contract_version','slice_id','status','basis','scope','applicability','resolution','acceptance','verification','work_units','extensions','ticket_policy']);
82
+ content.其他约束=Object.fromEntries(Object.entries(loaded.raw).filter(([k])=>!known.has(k)));
83
+ }
84
+ }else{
85
+ const {bytes,raw}=load(ref,root);binding={ref,id:raw.contract_id||raw.technical_design_id||raw.decision_id||raw.request?.request_id||raw.handoff_id||raw.baseline_id||raw.spec_id||raw.plan_id||raw.id||null,version:raw.contract_version||raw.decision_version||raw.handoff_version||raw.version||null,digest:hash(bytes)};
86
+ blockers.push(...declaredBlockers(raw));
87
+ let schemaRef=contractKinds[kind];if(kind==='api-decision'&&raw.schema_version===2)schemaRef='docs/process/schemas/api-contract-decision-v2.schema.json';
88
+ if(kind==='frontend-acceptance'&&[1,3].includes(raw.schema_version))schemaRef=`docs/process/schemas/frontend-delivery-acceptance${raw.schema_version===1?'-v1':'-v3'}.schema.json`;
89
+ if(schemaRef)try{schema(raw,schemaRef);checks.push('结构校验');}catch(error){blockers.push(error.message);}
90
+ else checks.push('结构与批准未核验,按资产所有者规则继续');
91
+ sourceChecks=references(raw,root);if(sourceChecks.length)checks.push(`核对 ${sourceChecks.length} 项可识别来源摘要;其余语义由资产所有者核验`);for(const source of sourceChecks)if(!source.current)blockers.push(`来源不可读或过期:${source.ref}`);
92
+ // Unknown business fields remain visible. Only well-known machine metadata is hidden.
93
+ content=profile==='full'?{权威合同:raw,来源核对:sourceChecks}:display(raw);
94
+ if(kind==='api-decision'&&raw.schema_version===2&&raw.draft_review){try{const review=load(raw.draft_review.ref,root).raw;content.实际审查记录=profile==='full'?review:display(review);if(review.result!=='approved'||!Array.isArray(review.blocking_findings)||review.blocking_findings.length)blockers.push('OpenAPI Draft Review 实际记录未批准或有阻断');if(review.draft_ref!==raw.openapi?.ref||review.draft_digest!==raw.openapi?.digest)blockers.push('Draft Review 未绑定当前 OpenAPI');}catch(error){blockers.push(error.message);}}
95
+ if(profile==='task'){
96
+ if(raw.work_units){if(!unit_id)throw new TypeError('含工作单元的合同必须指定 --unit');const matches=raw.work_units.filter(x=>x.id===unit_id);if(matches.length!==1)throw new TypeError(`工作单元缺失或不唯一: ${unit_id}`);content.work_units=matches;}
97
+ content.机器绑定中的约束=Object.fromEntries(['resolution','basis','inputs','sources','artifact_bindings'].filter(k=>raw[k]!==undefined).map(k=>[k,raw[k]]));
98
+ content.约束分类='保留未分类字段;本视图只允许阅读,执行影响由资产所有者核验。';
99
+ }
100
+ }
101
+ const view={read_only:true,execution_allowed:false,kind,profile,binding,checks,approval_validity:'not-checked',content,blockers};view.markdown=markdown(view);return view;
102
+ }
103
+ export function diffContract(beforeRef,afterRef,{root=process.cwd(),beforeRoot=root,kind}={}){
104
+ validateKind(kind);if(kind==='slice')return diffSliceContracts(beforeRef,afterRef,{root,beforeRoot});
105
+ const before=load(beforeRef,beforeRoot),after=load(afterRef,root),changes=[];
106
+ const walk=(a,b,p)=>{if(JSON.stringify(a)===JSON.stringify(b))return;if(object(a)&&object(b)){for(const key of new Set([...Object.keys(a),...Object.keys(b)]))walk(a[key],b[key],p?`${p}.${key}`:key);}else changes.push({path:p,before:a??null,after:b??null,category:metadata.test(p.split('.').at(-1))?'binding-change':'requires-review'});};
107
+ walk(before.raw,after.raw,'');const source_checks=[...references(before.raw,beforeRoot).map(x=>({...x,side:'before'})),...references(after.raw,root).map(x=>({...x,side:'after'}))];
108
+ return{read_only:true,approval_reusable:false,execution_allowed:false,before:{ref:beforeRef,digest:hash(before.bytes)},after:{ref:afterRef,digest:hash(after.bytes)},bytes_changed:!before.bytes.equals(after.bytes),changes,source_checks,decision_impact:'必须按当前差异和授权延续协议核验;无法读取旧来源时影响未知。'};
109
+ }
@@ -1,7 +1,7 @@
1
1
  import { normalizeSliceContract, sourceSliceContract, parseSliceYaml } from './slice-contract.mjs';
2
2
  import { assertExistingSliceStructure, createApprovedExecutionContext, verifySliceContractApproval } from './approved-execution-context.mjs';
3
3
  import path from 'node:path';
4
- import { readFileSync, existsSync } from 'node:fs';
4
+ import { readFileSync, existsSync, withValidationPhase } from './validation-phase.mjs';
5
5
  import { ROOT, read, parse, safe, hash, digest, ensure, schema, sourceApprovalPolicy } from './strategic-handoff-io.mjs';
6
6
  import { parseContextContract } from './context-contract.mjs';
7
7
  import { validateApprovalRecord } from './approval-record.mjs';
@@ -47,7 +47,8 @@ function requireBackendCapability(key) {
47
47
  }
48
48
 
49
49
  /** Read-only: never executes input commands, starts services, unpacks archives or writes receipts. */
50
- export async function preflightDelivery(input,{stage,root=process.cwd(),work_unit_id}={}) {
50
+ export async function preflightDelivery(input,options={}) {return withValidationPhase({root:path.resolve(options.root||process.cwd(),typeof input?.governance_root==='string'?input.governance_root:'.'),purpose:`delivery-${options.stage}`,slice_id:input?.scope?.slice_id,work_unit_id:options.work_unit_id,readOnly:true,signal:options.signal},()=>preflight(input,options));}
51
+ async function preflight(input,{stage,root=process.cwd(),work_unit_id}={}) {
51
52
  try { ensure(STAGES.includes(stage),'未知阶段;必须是 prepare|build|export|accept');schema(input,'docs/process/schemas/delivery-preflight-input.schema.json'); }
52
53
  catch(error) { return invalidPreflightInput(error.message); }
53
54
  root=path.resolve(root,input.governance_root||'.');
@@ -1,4 +1,4 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFileSync } from './validation-phase.mjs';
2
2
  import path from "node:path";
3
3
  import { parseDocument } from "../vendor/yaml.mjs";
4
4
  import { loadRegistry, ROOT } from "./lifecycle-registry.mjs";
@@ -1,6 +1,7 @@
1
1
  import {assertApprovedExecutionContext} from './approved-execution-context.mjs';
2
2
  import {createHash} from 'node:crypto';
3
- import {readFileSync,realpathSync,lstatSync,readdirSync} from 'node:fs';
3
+ import { realpathSync } from 'node:fs';
4
+ import { readFileSync, lstatSync, readdirSync } from './validation-phase.mjs';
4
5
  import path from 'node:path';
5
6
  import {execFileSync} from 'node:child_process';
6
7
  import {parseDocument} from '../vendor/yaml.mjs';
@@ -35,7 +36,7 @@ function inspectMaven(root,units){
35
36
  const script=`import json,sys,xml.etree.ElementTree as ET\nout=[]\nfor p in json.load(sys.stdin):\n r=ET.parse(p).getroot(); ns={'m':'http://maven.apache.org/POM/4.0.0'}; q=lambda s:r.find(s,ns)\n aid=q('m:artifactId'); aid=aid if aid is not None else q('artifactId')\n deps=[e.text.strip() for e in r.findall('m:dependencies/m:dependency/m:artifactId',ns)+r.findall('m:profiles/m:profile/m:dependencies/m:dependency/m:artifactId',ns)+r.findall('dependencies/dependency/artifactId') if e.text]\n modules=[e.text.strip() for e in r.findall('.//m:modules/m:module',ns)+r.findall('.//modules/module') if e.text]\n out.append({'artifact_id':aid.text.strip() if aid is not None else '', 'dependencies':deps, 'modules':modules})\nprint(json.dumps(out))`;
36
37
  try{return JSON.parse(execFileSync('python3',['-c',script],{input:JSON.stringify(units.map(u=>file(root,u.pom_ref))),encoding:'utf8',timeout:15000,maxBuffer:2*1024*1024}));}catch(error){requireThat(false,'ARCH_BUILD_INVALID',`无法读取实际 Maven 构建单元: ${error.message}`);}
37
38
  }
38
- export function verifyExistingArchitecture(identity,bindings,{root,registry,execution}={}){
39
+ export function verifyExistingArchitecture(identity,bindings,{root,registry,execution,readOnly=false}={}){
39
40
  const profile=validateExistingArchitecture(identity,registry);
40
41
  requireThat(text(root),'ARCH_EVIDENCE_REF','需要治理 root');
41
42
  const baseline=bound(root,bindings?.engineering_baseline),registration=bound(root,bindings?.repository_registration),manifest=bound(root,bindings?.manifest);
@@ -132,7 +133,7 @@ export function verifyExistingArchitecture(identity,bindings,{root,registry,exec
132
133
  }
133
134
  if(changes.length){
134
135
  requireThat(execution,'ARCH_SOURCE_STALE',`固定源码改变: ${changes.join(', ')}`);
135
- const permission=assertApprovedExecutionContext(execution,{root,architectureIdentity:identity,architectureEvidence:bindings});
136
+ const permission=assertApprovedExecutionContext(execution,{root,architectureIdentity:identity,architectureEvidence:bindings,readOnly});
136
137
  const allowed=permission.allowed_write_paths.map(x=>{if(path.isAbsolute(x)){const rel=path.relative(projectRoot,x).split(path.sep).join('/');return rel==='.'||rel===''?'.':relative(rel);}return x==='.'?'.':relative(x);});
137
138
  requireThat(changes.every(ref=>allowed.some(scope=>beneath(ref,scope))&&registration.allowed_write_paths.some(scope=>beneath(ref,scope))),'ARCH_SOURCE_OUT_OF_SCOPE','输出增量超出批准写范围');
138
139
  }
@@ -1,8 +1,10 @@
1
- import { readFileSync, statSync } from 'node:fs';
1
+ import { statSync } from 'node:fs';
2
+ import { readFileSync, withValidationPhase, inValidationPhase } from './validation-phase.mjs';
2
3
  import { ensure, hash, digest, read, safe, files, schema, treeDigest } from './strategic-handoff-io.mjs';
3
4
 
4
5
  // This is an observation bundle, not a prototype or an approval generator.
5
- export function validateExistingUiBaseline(data, { bundleRoot } = {}) {
6
+ export function validateExistingUiBaseline(data,options={}) {return inValidationPhase()?validate(data,options):withValidationPhase({root:options.bundleRoot,purpose:'existing-ui-baseline',readOnly:true},()=>validate(data,options));}
7
+ function validate(data, { bundleRoot } = {}) {
6
8
  const errors=[];
7
9
  try {
8
10
  schema(data,'docs/process/schemas/existing-ui-baseline.schema.json');
@@ -33,7 +33,7 @@ export function inspectFirstSliceArtifacts(contract, projectRoot) {
33
33
  }
34
34
  } catch (error) { failures.push(`${label}:${error.message}`); }
35
35
  }
36
- const aliases = { service: 'application', core: 'domain', repository: 'infrastructure', server: 'web' };
36
+ const aliases = { service: 'application', core: 'application', repository: 'infrastructure', server: 'web' };
37
37
  for (const layer of contract.backend.affected_layers || []) {
38
38
  const role = aliases[layer] || layer;
39
39
  if (['domain','application','infrastructure','web'].includes(role) && !roles.has(role)) failures.push(`affected-role-empty:${role}`);
@@ -1,6 +1,6 @@
1
1
  import { normalizeSliceContract, sourceSliceContract, parseSliceYaml } from './slice-contract.mjs';
2
2
  import { loadDeliveryProfile } from './harness-execution-scope.mjs';
3
- import { existsSync } from 'node:fs';
3
+ import { existsSync } from './validation-phase.mjs';
4
4
  import path from 'node:path';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { ROOT, read, safe, ensure, digest } from './strategic-handoff-io.mjs';
@@ -1,5 +1,5 @@
1
1
  import { uiBaselineRef, uiBaselineCaseIds, uiBaselineKind, hasConsumerRoutes } from './ui-baseline.mjs';
2
- import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { existsSync, readdirSync, readFileSync } from './validation-phase.mjs';
3
3
  import path from 'node:path';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import { openBackendDelivery } from './backend-delivery.mjs';
@@ -1,4 +1,5 @@
1
- import { existsSync } from 'node:fs';
1
+ import { loadExecutionScope, assertScopeWorkUnit } from './lifecycle-execution-scope.mjs';
2
+ import { existsSync } from './validation-phase.mjs';
2
3
  import path from 'node:path';
3
4
  import { ROOT, read, safe, ensure } from './strategic-handoff-io.mjs';
4
5
 
@@ -30,6 +31,12 @@ function activeProfile(root) {
30
31
  }
31
32
 
32
33
  export function enforceHarnessTaskScope(task,{root=ROOT}={}) {
34
+ const scope=loadExecutionScope(root);
35
+ if(scope) {
36
+ assertScopeWorkUnit(task.contract?.kind==='slice-implementation'?'work-unit.slice-implementation':task.work_unit_id,{root});
37
+ ensure(task.role_id!=='role.frontend-engineer','后端职责不允许派发前端实现');
38
+ ensure(task.allowed_write_paths.every(ref=>!/^apps\/frontend(?:\/|$)/.test(ref)),'禁止写入前端工程');
39
+ }
33
40
  const profile=activeProfile(root);
34
41
  if (!profile) return;
35
42
  ensure(task.contract?.kind!=='template-maintenance','专职产品项目不得派发模板维护任务');
@@ -41,6 +48,13 @@ export function enforceHarnessTaskScope(task,{root=ROOT}={}) {
41
48
  }
42
49
 
43
50
  export function enforceHarnessSkillScope(skills,registry,{root=ROOT}={}) {
51
+ if(loadExecutionScope(root)) {
52
+ assertScopeWorkUnit('work-unit.slice-implementation',{root});
53
+ for(const id of skills) {
54
+ const impacts=registry.skills.find(skill=>skill.id===id)?.impacts||[];
55
+ ensure(!impacts.includes('frontend')||impacts.includes('backend')||impacts.includes('lifecycle'),`后端职责禁止编译生产前端技能: ${id}`);
56
+ }
57
+ }
44
58
  const profile=activeProfile(root);
45
59
  if (!profile) return;
46
60
  const side=profile.profile_id==='harness.frontend-delivery'?'frontend':'backend';
@@ -5,7 +5,7 @@ import { createApprovedExecutionContext, createApprovedRecompilationContext, ass
5
5
  import { enforceTechnicalDesign } from './technical-design-boundary.mjs';
6
6
  import { enforceHarnessSkillScope } from "./harness-execution-scope.mjs";
7
7
  import { createHash } from "node:crypto";
8
- import { readFileSync } from "node:fs";
8
+ import { readFileSync } from './validation-phase.mjs';
9
9
  import path from "node:path";
10
10
  import { parseDocument } from "../vendor/yaml.mjs";
11
11
  import { DEFAULT_REGISTRY, loadSkillRegistry, resolveSkillForNewUse } from "./skill-registry.mjs";
@@ -276,8 +276,8 @@ export function evaluateContractFreshness(contract, { registry, compilerContract
276
276
  const reasons = [];
277
277
  let trustedExecution;
278
278
  try {
279
- trustedExecution=approved_slice?createApprovedExecutionContext(approved_slice,{root,contract:all,work_unit_id}):execution;
280
- if(trustedExecution)assertApprovedExecutionContext(trustedExecution,{root,contract});
279
+ trustedExecution=approved_slice?createApprovedExecutionContext(approved_slice,{root,contract:all,work_unit_id,readOnly}):execution;
280
+ if(trustedExecution)assertApprovedExecutionContext(trustedExecution,{root,contract,readOnly});
281
281
  } catch(error) { reasons.push(error.code||'EXECUTION_APPROVAL_INVALID');trustedExecution=undefined; }
282
282
  try { enforceTechnicalDesign({ ...resolution, slice_id: contract.slice_id ?? resolution.slice_id }, { root,execution:trustedExecution,readOnly }); }
283
283
  catch { reasons.push("technical-design-stale-or-unavailable"); }
@@ -289,7 +289,7 @@ export function evaluateContractFreshness(contract, { registry, compilerContract
289
289
  try { validateArchitectureIdentity(resolution.architecture_identity, registry); }
290
290
  catch { reasons.push("architecture-identity-invalid"); }
291
291
  if (resolution.architecture_identity.schema_version === 2) {
292
- try { verifyArchitectureEvidence(resolution.architecture_identity, resolution.architecture_evidence, { root, registry, execution:trustedExecution }); }
292
+ try { verifyArchitectureEvidence(resolution.architecture_identity, resolution.architecture_evidence, { root, registry, execution:trustedExecution, readOnly }); }
293
293
  catch (error) { reasons.push(error.code ?? "architecture-evidence-stale-or-unavailable"); }
294
294
  }
295
295
  if (resolution.architecture_identity_digest !== architectureDigest(resolution.architecture_identity)) reasons.push("architecture-identity-digest-changed");