create-yss-spec 3.5.2 → 3.5.3

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 (438) hide show
  1. package/package.json +1 -1
  2. package/src/template/asset-runtime.js +3 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  4. package/template/.agents/skills/codebase-design/SKILL.md +4 -0
  5. package/template/{.codex/skills/improve-codebase-architecture/SKILL.md → .agents/skills/codebase-design/references/architecture-audit.md} +3 -9
  6. package/template/.agents/skills/frontend-commit/SKILL.md +4 -93
  7. package/template/.agents/skills/git-commit-core/SKILL.md +18 -0
  8. package/template/.agents/skills/java-backend-commit/SKILL.md +4 -96
  9. package/template/.agents/skills/llm-wiki/SKILL.md +12 -13
  10. package/template/.agents/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  11. package/template/.agents/skills/llm-wiki/references/compile.md +21 -114
  12. package/template/.agents/skills/llm-wiki/references/ingest.md +8 -33
  13. package/template/.agents/skills/llm-wiki/references/lint.md +9 -46
  14. package/template/.agents/skills/llm-wiki/references/query.md +9 -18
  15. package/template/.agents/skills/llm-wiki/references/schema.md +56 -29
  16. package/template/.agents/skills/llm-wiki/references/transactions.md +48 -0
  17. package/template/.agents/skills/llm-wiki/references/writing.md +4 -4
  18. package/template/.agents/skills/llm-wiki/scripts/advise.mjs +46 -58
  19. package/template/.agents/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  20. package/template/.agents/skills/llm-wiki/scripts/core.mjs +262 -0
  21. package/template/.agents/skills/llm-wiki/scripts/extract.mjs +35 -18
  22. package/template/.agents/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  23. package/template/.agents/skills/llm-wiki/scripts/feedback.mjs +51 -0
  24. package/template/.agents/skills/llm-wiki/scripts/inventory.mjs +43 -171
  25. package/template/.agents/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  26. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  27. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  28. package/template/.agents/skills/llm-wiki/scripts/migrate.mjs +51 -0
  29. package/template/.agents/skills/llm-wiki/scripts/query.mjs +149 -0
  30. package/template/.agents/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  31. package/template/.agents/skills/llm-wiki/scripts/sources.mjs +166 -0
  32. package/template/.agents/skills/llm-wiki/scripts/transaction.mjs +384 -0
  33. package/template/.agents/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  34. package/template/.agents/skills/prototype/LOGIC.md +1 -1
  35. package/template/.agents/skills/prototype/SKILL.md +5 -19
  36. package/template/.agents/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  37. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  38. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  39. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  40. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +8 -8
  41. package/template/.agents/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  42. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  43. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  44. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  45. package/template/.agents/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  46. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
  47. package/template/.agents/skills/yss-research/SKILL.md +4 -0
  48. package/template/.codex/skills/codebase-design/SKILL.md +4 -0
  49. package/template/{.pi/skills/improve-codebase-architecture/SKILL.md → .codex/skills/codebase-design/references/architecture-audit.md} +3 -9
  50. package/template/.codex/skills/frontend-commit/SKILL.md +4 -93
  51. package/template/.codex/skills/git-commit-core/SKILL.md +18 -0
  52. package/template/.codex/skills/java-backend-commit/SKILL.md +4 -96
  53. package/template/.codex/skills/llm-wiki/SKILL.md +12 -13
  54. package/template/.codex/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  55. package/template/.codex/skills/llm-wiki/references/compile.md +21 -114
  56. package/template/.codex/skills/llm-wiki/references/ingest.md +8 -33
  57. package/template/.codex/skills/llm-wiki/references/lint.md +9 -46
  58. package/template/.codex/skills/llm-wiki/references/query.md +9 -18
  59. package/template/.codex/skills/llm-wiki/references/schema.md +56 -29
  60. package/template/.codex/skills/llm-wiki/references/transactions.md +48 -0
  61. package/template/.codex/skills/llm-wiki/references/writing.md +4 -4
  62. package/template/.codex/skills/llm-wiki/scripts/advise.mjs +46 -58
  63. package/template/.codex/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  64. package/template/.codex/skills/llm-wiki/scripts/core.mjs +262 -0
  65. package/template/.codex/skills/llm-wiki/scripts/extract.mjs +35 -18
  66. package/template/.codex/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  67. package/template/.codex/skills/llm-wiki/scripts/feedback.mjs +51 -0
  68. package/template/.codex/skills/llm-wiki/scripts/inventory.mjs +43 -171
  69. package/template/.codex/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  70. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  71. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  72. package/template/.codex/skills/llm-wiki/scripts/migrate.mjs +51 -0
  73. package/template/.codex/skills/llm-wiki/scripts/query.mjs +149 -0
  74. package/template/.codex/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  75. package/template/.codex/skills/llm-wiki/scripts/sources.mjs +166 -0
  76. package/template/.codex/skills/llm-wiki/scripts/transaction.mjs +384 -0
  77. package/template/.codex/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  78. package/template/.codex/skills/prototype/LOGIC.md +1 -1
  79. package/template/.codex/skills/prototype/SKILL.md +5 -19
  80. package/template/.codex/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  81. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  82. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  83. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  84. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +8 -8
  85. package/template/.codex/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  86. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  87. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  88. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  89. package/template/.codex/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  90. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
  91. package/template/.codex/skills/yss-research/SKILL.md +4 -0
  92. package/template/.cursor/skills/codebase-design/SKILL.md +4 -0
  93. package/template/.cursor/skills/{improve-codebase-architecture/SKILL.md → codebase-design/references/architecture-audit.md} +3 -9
  94. package/template/.cursor/skills/frontend-commit/SKILL.md +4 -93
  95. package/template/.cursor/skills/git-commit-core/SKILL.md +18 -0
  96. package/template/.cursor/skills/java-backend-commit/SKILL.md +4 -96
  97. package/template/.cursor/skills/llm-wiki/SKILL.md +12 -13
  98. package/template/.cursor/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  99. package/template/.cursor/skills/llm-wiki/references/compile.md +21 -114
  100. package/template/.cursor/skills/llm-wiki/references/ingest.md +8 -33
  101. package/template/.cursor/skills/llm-wiki/references/lint.md +9 -46
  102. package/template/.cursor/skills/llm-wiki/references/query.md +9 -18
  103. package/template/.cursor/skills/llm-wiki/references/schema.md +56 -29
  104. package/template/.cursor/skills/llm-wiki/references/transactions.md +48 -0
  105. package/template/.cursor/skills/llm-wiki/references/writing.md +4 -4
  106. package/template/.cursor/skills/llm-wiki/scripts/advise.mjs +46 -58
  107. package/template/.cursor/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  108. package/template/.cursor/skills/llm-wiki/scripts/core.mjs +262 -0
  109. package/template/.cursor/skills/llm-wiki/scripts/extract.mjs +35 -18
  110. package/template/.cursor/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  111. package/template/.cursor/skills/llm-wiki/scripts/feedback.mjs +51 -0
  112. package/template/.cursor/skills/llm-wiki/scripts/inventory.mjs +43 -171
  113. package/template/.cursor/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  114. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  115. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  116. package/template/.cursor/skills/llm-wiki/scripts/migrate.mjs +51 -0
  117. package/template/.cursor/skills/llm-wiki/scripts/query.mjs +149 -0
  118. package/template/.cursor/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  119. package/template/.cursor/skills/llm-wiki/scripts/sources.mjs +166 -0
  120. package/template/.cursor/skills/llm-wiki/scripts/transaction.mjs +384 -0
  121. package/template/.cursor/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  122. package/template/.cursor/skills/prototype/LOGIC.md +1 -1
  123. package/template/.cursor/skills/prototype/SKILL.md +5 -19
  124. package/template/.cursor/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  125. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  126. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  127. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  128. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +8 -8
  129. package/template/.cursor/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  130. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  131. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  132. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  133. package/template/.cursor/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  134. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
  135. package/template/.cursor/skills/yss-research/SKILL.md +4 -0
  136. package/template/.pi/skills/codebase-design/SKILL.md +4 -0
  137. package/template/{.agents/skills/improve-codebase-architecture/SKILL.md → .pi/skills/codebase-design/references/architecture-audit.md} +3 -9
  138. package/template/.pi/skills/frontend-commit/SKILL.md +4 -93
  139. package/template/.pi/skills/git-commit-core/SKILL.md +18 -0
  140. package/template/.pi/skills/java-backend-commit/SKILL.md +4 -96
  141. package/template/.pi/skills/llm-wiki/SKILL.md +12 -13
  142. package/template/.pi/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  143. package/template/.pi/skills/llm-wiki/references/compile.md +21 -114
  144. package/template/.pi/skills/llm-wiki/references/ingest.md +8 -33
  145. package/template/.pi/skills/llm-wiki/references/lint.md +9 -46
  146. package/template/.pi/skills/llm-wiki/references/query.md +9 -18
  147. package/template/.pi/skills/llm-wiki/references/schema.md +56 -29
  148. package/template/.pi/skills/llm-wiki/references/transactions.md +48 -0
  149. package/template/.pi/skills/llm-wiki/references/writing.md +4 -4
  150. package/template/.pi/skills/llm-wiki/scripts/advise.mjs +46 -58
  151. package/template/.pi/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  152. package/template/.pi/skills/llm-wiki/scripts/core.mjs +262 -0
  153. package/template/.pi/skills/llm-wiki/scripts/extract.mjs +35 -18
  154. package/template/.pi/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  155. package/template/.pi/skills/llm-wiki/scripts/feedback.mjs +51 -0
  156. package/template/.pi/skills/llm-wiki/scripts/inventory.mjs +43 -171
  157. package/template/.pi/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  158. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  159. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  160. package/template/.pi/skills/llm-wiki/scripts/migrate.mjs +51 -0
  161. package/template/.pi/skills/llm-wiki/scripts/query.mjs +149 -0
  162. package/template/.pi/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  163. package/template/.pi/skills/llm-wiki/scripts/sources.mjs +166 -0
  164. package/template/.pi/skills/llm-wiki/scripts/transaction.mjs +384 -0
  165. package/template/.pi/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  166. package/template/.pi/skills/prototype/LOGIC.md +1 -1
  167. package/template/.pi/skills/prototype/SKILL.md +5 -19
  168. package/template/.pi/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  169. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  170. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  171. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  172. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +8 -8
  173. package/template/.pi/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  174. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  175. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  176. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  177. package/template/.pi/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  178. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
  179. package/template/.pi/skills/yss-research/SKILL.md +4 -0
  180. package/template/.template-spec/agents/README.md +1 -1
  181. package/template/.template-spec/agents/digital-human-roles.yaml +1 -1
  182. package/template/.template-spec/agents/skill-migrations.md +15 -0
  183. package/template/.template-spec/agents/yss-skill-registry.yaml +10 -29
  184. package/template/.template-spec/architecture/README.md +3 -34
  185. package/template/.template-spec/plan/templates/competitive-analysis-template.md +2 -2
  186. package/template/.template-spec/process/contract-reading.md +24 -0
  187. package/template/.template-spec/process/lifecycle-registry-baseline.json +3 -1
  188. package/template/.template-spec/process/lifecycle-registry.yaml +6 -0
  189. package/template/.template-spec/process/research-completion.md +23 -0
  190. package/template/.template-spec/process/schemas/digital-human-task-package.schema.json +202 -12
  191. package/template/.template-spec/process/schemas/frontend-implementation-evidence.schema.json +7 -15
  192. package/template/.template-spec/process/subagent-collaboration.md +8 -0
  193. package/template/.template-spec/process/templates/frontend-implementation-verification-template.yaml +15 -1
  194. package/template/AGENTS.md +1 -1
  195. package/template/CONTEXT.md +5 -1
  196. package/template/README.md +12 -24
  197. package/template/scripts/contract +5 -5
  198. package/template/scripts/lib/contract-views.mjs +57 -2
  199. package/template/scripts/lib/execution-evidence.mjs +51 -0
  200. package/template/scripts/lib/harness-execution-scope.mjs +1 -1
  201. package/template/scripts/lib/implementation-contract-compiler.mjs +2 -0
  202. package/template/scripts/lib/lifecycle-context-query.mjs +15 -3
  203. package/template/scripts/lib/lifecycle-status.mjs +32 -6
  204. package/template/scripts/lib/lifecycle-transition.mjs +19 -1
  205. package/template/scripts/lib/maintenance-research.mjs +63 -0
  206. package/template/scripts/lib/read-only-intake.mjs +132 -0
  207. package/template/scripts/lib/skill-registry.mjs +2 -1
  208. package/template/scripts/lib/skill-supply-chain.mjs +4 -0
  209. package/template/scripts/lib/slice-task-package.mjs +1 -1
  210. package/template/scripts/lib/task-package.mjs +9 -2
  211. package/template/scripts/lifecycle-status +2 -2
  212. package/template/scripts/prepare-read-only-intake +16 -0
  213. package/template/scripts/run-read-only-intake +14 -0
  214. package/template/scripts/verify-digital-human-task-package +2 -2
  215. package/template/scripts/verify-frontend-implementation-evidence +24 -1
  216. package/template/scripts/verify-maintenance-research +13 -0
  217. package/template/skills-lock.json +19 -76
  218. package/template.manifest.json +118 -29
  219. package/template.snapshot.json +5 -6
  220. package/template/.agents/skills/grill-with-docs/SKILL.md +0 -20
  221. package/template/.agents/skills/grill-with-docs/agents/openai.yaml +0 -5
  222. package/template/.agents/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  223. package/template/.agents/skills/prototype/UI.md +0 -112
  224. package/template/.agents/skills/setup-matt-pocock-skills/domain.md +0 -37
  225. package/template/.agents/skills/to-questionnaire/SKILL.md +0 -55
  226. package/template/.agents/skills/to-questionnaire/agents/openai.yaml +0 -5
  227. package/template/.agents/skills/wait-what/SKILL.md +0 -7
  228. package/template/.agents/skills/wait-what/agents/openai.yaml +0 -5
  229. package/template/.codex/skills/data-analytics/.app.json +0 -84
  230. package/template/.codex/skills/data-analytics/.codex-plugin/plugin.json +0 -66
  231. package/template/.codex/skills/data-analytics/.mcp.json +0 -30
  232. package/template/.codex/skills/data-analytics/AGENTS.md +0 -20
  233. package/template/.codex/skills/data-analytics/DEPENDENCIES.MD +0 -27
  234. package/template/.codex/skills/data-analytics/README.md +0 -60
  235. package/template/.codex/skills/data-analytics/__yss_dotfile__.gitignore +0 -2
  236. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html +0 -16
  237. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part001 +0 -1
  238. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part002 +0 -1
  239. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part003 +0 -1
  240. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part004 +0 -1
  241. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part005 +0 -1
  242. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part006 +0 -1
  243. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html +0 -16
  244. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part001 +0 -1
  245. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part002 +0 -1
  246. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part003 +0 -1
  247. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part004 +0 -1
  248. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part005 +0 -1
  249. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part006 +0 -1
  250. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part007 +0 -1
  251. package/template/.codex/skills/data-analytics/assets/datascience-small.svg +0 -5
  252. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html +0 -16
  253. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part001 +0 -1
  254. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part002 +0 -1
  255. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part003 +0 -1
  256. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part004 +0 -1
  257. package/template/.codex/skills/data-analytics/assets/datascience.png +0 -0
  258. package/template/.codex/skills/data-analytics/assets/datascience.svg +0 -10
  259. package/template/.codex/skills/data-analytics/mcp/server.cjs +0 -2964
  260. package/template/.codex/skills/data-analytics/package-lock.json +0 -3048
  261. package/template/.codex/skills/data-analytics/package.json +0 -43
  262. package/template/.codex/skills/data-analytics/scripts/normalize-widget-assets.mjs +0 -75
  263. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +0 -137
  264. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/agents/openai.yaml +0 -6
  265. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +0 -29
  266. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +0 -148
  267. package/template/.codex/skills/data-analytics/skills/build-dashboard/agents/openai.yaml +0 -6
  268. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/bi-platform-dashboard.md +0 -18
  269. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/html-dashboard.md +0 -24
  270. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/mcp-artifact-dashboard.md +0 -71
  271. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/streamlit-dashboard.md +0 -85
  272. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +0 -207
  273. package/template/.codex/skills/data-analytics/skills/build-report/agents/openai.yaml +0 -6
  274. package/template/.codex/skills/data-analytics/skills/build-report/assets/executive-report-shell.html +0 -70
  275. package/template/.codex/skills/data-analytics/skills/build-report/assets/technical-report-shell.html +0 -66
  276. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +0 -108
  277. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/agents/openai.yaml +0 -6
  278. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/__init__.py +0 -1
  279. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +0 -52
  280. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/constants.py +0 -61
  281. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/docx_writer.py +0 -362
  282. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/html_parser.py +0 -829
  283. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/model.py +0 -30
  284. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +0 -127
  285. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/quality.py +0 -374
  286. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/rendering.py +0 -613
  287. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/table_utils.py +0 -54
  288. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/utils.py +0 -16
  289. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc_plan.py +0 -9
  290. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +0 -45
  291. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +0 -77
  292. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/agents/openai.yaml +0 -6
  293. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/scripts/report_to_google_slides.py +0 -2379
  294. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +0 -88
  295. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/agents/openai.yaml +0 -6
  296. package/template/.codex/skills/data-analytics/skills/build-report/specifications/executive-report.md +0 -97
  297. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +0 -59
  298. package/template/.codex/skills/data-analytics/skills/build-report/specifications/technical-report.md +0 -75
  299. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +0 -103
  300. package/template/.codex/skills/data-analytics/skills/design-kpis/agents/openai.yaml +0 -6
  301. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +0 -68
  302. package/template/.codex/skills/data-analytics/skills/gather-business-context/agents/openai.yaml +0 -6
  303. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +0 -251
  304. package/template/.codex/skills/data-analytics/skills/index/agents/openai.yaml +0 -6
  305. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +0 -131
  306. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/agents/openai.yaml +0 -6
  307. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +0 -141
  308. package/template/.codex/skills/data-analytics/skills/kpi-reporting/agents/openai.yaml +0 -6
  309. package/template/.codex/skills/data-analytics/skills/kpi-reporting/references/report-templates.md +0 -32
  310. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +0 -106
  311. package/template/.codex/skills/data-analytics/skills/market-sizing/agents/openai.yaml +0 -6
  312. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +0 -130
  313. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/agents/openai.yaml +0 -6
  314. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +0 -141
  315. package/template/.codex/skills/data-analytics/skills/product-business-analysis/agents/openai.yaml +0 -6
  316. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +0 -178
  317. package/template/.codex/skills/data-analytics/skills/spreadsheets/agents/openai.yaml +0 -9
  318. package/template/.codex/skills/data-analytics/skills/spreadsheets/assets/file-spreadsheet.png +0 -0
  319. package/template/.codex/skills/data-analytics/skills/spreadsheets/charts.md +0 -31
  320. package/template/.codex/skills/data-analytics/skills/spreadsheets/references/artifact_tool_api.md +0 -466
  321. package/template/.codex/skills/data-analytics/skills/spreadsheets/style_guidelines.md +0 -99
  322. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +0 -197
  323. package/template/.codex/skills/data-analytics/skills/user-context/agents/openai.yaml +0 -6
  324. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +0 -26
  325. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/source-category-config.json +0 -51
  326. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/user-context-config.md +0 -66
  327. package/template/.codex/skills/data-analytics/skills/user-context/references/automation.md +0 -69
  328. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +0 -204
  329. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-state-template.json +0 -87
  330. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +0 -497
  331. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/connector-playbook.md +0 -74
  332. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/setup.md +0 -65
  333. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/skill-template.md +0 -160
  334. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/source-intake.md +0 -75
  335. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/weekly-polling-automation.md +0 -96
  336. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +0 -263
  337. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +0 -1462
  338. package/template/.codex/skills/data-analytics/skills/user-context/scripts/init_user_context_state.py +0 -128
  339. package/template/.codex/skills/data-analytics/skills/user-context/scripts/reset_user_context_state.py +0 -101
  340. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +0 -499
  341. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +0 -978
  342. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +0 -126
  343. package/template/.codex/skills/data-analytics/skills/validate-data/agents/openai.yaml +0 -6
  344. package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +0 -70
  345. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +0 -157
  346. package/template/.codex/skills/data-analytics/skills/visualize-data/agents/openai.yaml +0 -6
  347. package/template/.codex/skills/data-analytics/skills/visualize-data/references/seaborn-templates.md +0 -774
  348. package/template/.codex/skills/data-analytics/src/DESIGN.md +0 -222
  349. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +0 -3666
  350. package/template/.codex/skills/data-analytics/src/analytics-app/analytics-layout.test.mjs +0 -136
  351. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartFrame.tsx +0 -54
  352. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartLegend.tsx +0 -96
  353. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartRenderer.tsx +0 -1647
  354. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartTooltip.tsx +0 -245
  355. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-app-helpers.tsx +0 -462
  356. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-capabilities.ts +0 -107
  357. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-compatibility.ts +0 -164
  358. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-contract.ts +0 -192
  359. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-theme.ts +0 -203
  360. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-tokens.css +0 -619
  361. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-transforms.ts +0 -402
  362. package/template/.codex/skills/data-analytics/src/analytics-app/fonts/SystemSansVariableVF.woff2 +0 -0
  363. package/template/.codex/skills/data-analytics/src/analytics-app/imageExport.ts +0 -370
  364. package/template/.codex/skills/data-analytics/src/analytics-app/layout/AnalyticsLayoutCanvas.tsx +0 -536
  365. package/template/.codex/skills/data-analytics/src/analytics-app/layout/RichMarkdown.tsx +0 -681
  366. package/template/.codex/skills/data-analytics/src/analytics-app/layout/analyticsLayoutCore.ts +0 -164
  367. package/template/.codex/skills/data-analytics/src/analytics-app/main.tsx +0 -21
  368. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/chart_contract.py +0 -472
  369. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/check_analytics_app_runtime_links.py +0 -75
  370. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/design_contract.py +0 -142
  371. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/package_utils.py +0 -142
  372. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/tests/test_package_utils.py +0 -377
  373. package/template/.codex/skills/data-analytics/src/analytics-app/styles.css +0 -3468
  374. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.d.ts +0 -44
  375. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.jsx +0 -639
  376. package/template/.codex/skills/data-analytics/src/analytics-app/tables/data-table.css +0 -327
  377. package/template/.codex/skills/data-analytics/src/analytics-app/tokens.css +0 -225
  378. package/template/.codex/skills/data-analytics/src/analytics-app/types.ts +0 -204
  379. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +0 -85
  380. package/template/.codex/skills/data-analytics/src/codex-style-contract.md +0 -30
  381. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.html +0 -12
  382. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.jsx +0 -1008
  383. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.css +0 -2117
  384. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.html +0 -122
  385. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.js +0 -3588
  386. package/template/.codex/skills/data-analytics/src/datascience-table-widget.css +0 -483
  387. package/template/.codex/skills/data-analytics/src/datascience-table-widget.html +0 -32
  388. package/template/.codex/skills/data-analytics/src/datascience-table-widget.js +0 -333
  389. package/template/.codex/skills/data-analytics/src/mcp-host.js +0 -153
  390. package/template/.codex/skills/data-analytics/src/recharts-config.js +0 -315
  391. package/template/.codex/skills/data-analytics/src/recharts-renderer.jsx +0 -294
  392. package/template/.codex/skills/data-analytics/src/sql-source-view.css +0 -33
  393. package/template/.codex/skills/data-analytics/src/sql-source-view.js +0 -157
  394. package/template/.codex/skills/data-analytics/src/styles/codex-theme.css +0 -121
  395. package/template/.codex/skills/data-analytics/src/table-renderer.jsx +0 -28
  396. package/template/.codex/skills/data-analytics/tests/chart-transforms.test.mjs +0 -87
  397. package/template/.codex/skills/data-analytics/tests/funnel-smoke.html +0 -105
  398. package/template/.codex/skills/data-analytics/tests/inline-widget-compare.html +0 -233
  399. package/template/.codex/skills/data-analytics/tests/mcp-server.test.mjs +0 -1500
  400. package/template/.codex/skills/data-analytics/tests/native-style-contract.test.mjs +0 -219
  401. package/template/.codex/skills/data-analytics/tests/recharts-config.test.mjs +0 -144
  402. package/template/.codex/skills/data-analytics/tests/recharts-renderer.test.mjs +0 -11
  403. package/template/.codex/skills/data-analytics/tests/rich-markdown.test.mjs +0 -54
  404. package/template/.codex/skills/data-analytics/tests/widget-render-harness.html +0 -321
  405. package/template/.codex/skills/data-analytics/tsconfig.json +0 -19
  406. package/template/.codex/skills/data-analytics/vite.config.ts +0 -46
  407. package/template/.codex/skills/grill-with-docs/SKILL.md +0 -20
  408. package/template/.codex/skills/grill-with-docs/agents/openai.yaml +0 -5
  409. package/template/.codex/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  410. package/template/.codex/skills/prototype/UI.md +0 -112
  411. package/template/.codex/skills/setup-matt-pocock-skills/domain.md +0 -37
  412. package/template/.codex/skills/to-questionnaire/SKILL.md +0 -55
  413. package/template/.codex/skills/to-questionnaire/agents/openai.yaml +0 -5
  414. package/template/.codex/skills/wait-what/SKILL.md +0 -7
  415. package/template/.codex/skills/wait-what/agents/openai.yaml +0 -5
  416. package/template/.cursor/skills/grill-with-docs/SKILL.md +0 -20
  417. package/template/.cursor/skills/grill-with-docs/agents/openai.yaml +0 -5
  418. package/template/.cursor/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  419. package/template/.cursor/skills/prototype/UI.md +0 -112
  420. package/template/.cursor/skills/setup-matt-pocock-skills/domain.md +0 -37
  421. package/template/.cursor/skills/to-questionnaire/SKILL.md +0 -55
  422. package/template/.cursor/skills/to-questionnaire/agents/openai.yaml +0 -5
  423. package/template/.cursor/skills/wait-what/SKILL.md +0 -7
  424. package/template/.cursor/skills/wait-what/agents/openai.yaml +0 -5
  425. package/template/.pi/skills/grill-with-docs/SKILL.md +0 -20
  426. package/template/.pi/skills/grill-with-docs/agents/openai.yaml +0 -5
  427. package/template/.pi/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  428. package/template/.pi/skills/prototype/UI.md +0 -112
  429. package/template/.pi/skills/setup-matt-pocock-skills/domain.md +0 -37
  430. package/template/.pi/skills/to-questionnaire/SKILL.md +0 -55
  431. package/template/.pi/skills/to-questionnaire/agents/openai.yaml +0 -5
  432. package/template/.pi/skills/wait-what/SKILL.md +0 -7
  433. package/template/.pi/skills/wait-what/agents/openai.yaml +0 -5
  434. package/template/.template-spec/agents/domain.md +0 -31
  435. /package/template/.agents/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  436. /package/template/.codex/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  437. /package/template/.cursor/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  438. /package/template/.pi/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
@@ -0,0 +1,51 @@
1
+ import {readFileSync,existsSync} from './validation-phase.mjs';
2
+ import {safe, hash} from './strategic-handoff-io.mjs';
3
+
4
+ /** Checks binding, not the truth of arbitrary prose. Owner tests/review remain mandatory. */
5
+ export function executionEvidenceBlockers(result, contract, current) {
6
+ const blockers=[];
7
+ if(result.evidence_binding_version!==1)return ['legacy-evidence-binding-missing'];
8
+ const unit=contract.work_units.find(u=>u.id===result.work_unit_id);
9
+ if(!unit)return ['work-unit-mismatch'];
10
+ try {
11
+ const approved=current.approved_slice;
12
+ if(!approved || result.consumed_contract?.contract_digest!==approved.digest || hash(readFileSync(safe(current.root,approved.ref)))!==approved.digest)blockers.push('evidence-contract-digest-mismatch');
13
+ const evidence=result.evidence_files||[];
14
+ const checks=unit.work_unit.verification;
15
+ const evidenceRoot=contract.repositories?unit.project_root:current.root;
16
+ for(const check of checks) {
17
+ const rows=(result.verification_results||[]).filter(r=>r.verification_id===check.id);
18
+ if(rows.length!==1){blockers.push('verification-id-missing-or-duplicate');continue;}
19
+ const row=rows[0];
20
+ if(row.command!==check.command||row.cwd!==check.cwd||row.exit_code!==0||!Number.isFinite(Date.parse(row.executed_at)))blockers.push('verification-binding-mismatch');
21
+ if(!Array.isArray(row.acceptance_refs)||row.acceptance_refs.length!==new Set(row.acceptance_refs).size||JSON.stringify([...row.acceptance_refs].sort())!==JSON.stringify([...check.acceptance_refs].sort()))blockers.push('acceptance-evidence-coverage-missing');
22
+ if(!Array.isArray(row.evidence_refs)||!check.expected_evidence.every(ref=>row.evidence_refs.includes(ref)))blockers.push('verification-evidence-link-missing');
23
+ const covered=new Set();
24
+ for(const ref of row.evidence_refs||[]) {
25
+ const matches=evidence.filter(e=>typeof e==='object'&&e.path===ref&&(!contract.repositories||e.project_root===unit.project_root));
26
+ if(!matches.length)blockers.push('verification-evidence-link-missing');
27
+ for(const entry of matches) {
28
+ if(!check.acceptance_refs.includes(entry.behavior_ref))blockers.push('evidence-behavior-unrelated');
29
+ else covered.add(entry.behavior_ref);
30
+ if(hash(readFileSync(safe(evidenceRoot,ref)))!==entry.digest)blockers.push('evidence-digest-mismatch');
31
+ }
32
+ }
33
+ if(check.acceptance_refs.some(id=>!covered.has(id)))blockers.push('acceptance-evidence-coverage-missing');
34
+ }
35
+ // Bind declared execution inputs too: changed source bytes cannot reuse an earlier result.
36
+ if(!Array.isArray(result.source_bindings)||!result.source_bindings.length)blockers.push('execution-source-bindings-missing');
37
+ for(const entry of result.source_bindings||[]) {
38
+ const root=entry.project_root||unit.project_root;
39
+ const allowedRoots=new Set([unit.project_root,...checks.flatMap(check=>check.dependency_roots||[])]);
40
+ if(!allowedRoots.has(root)||(contract.repositories&&!contract.repositories[root])){blockers.push('execution-source-repository-mismatch');continue;}
41
+ if(entry.deleted===true) {
42
+ if(existsSync(safe(root,entry.path,{missing:true})) || entry.digest!==null)blockers.push('execution-source-drift');
43
+ } else if(hash(readFileSync(safe(root,entry.path)))!==entry.digest)blockers.push('execution-source-drift');
44
+ }
45
+ for(const changed of result.changed_files||[]) {
46
+ const ref=typeof changed==='string'?changed:changed.path;
47
+ if(!result.source_bindings?.some(b=>b.path===ref&&(b.project_root||unit.project_root)===(typeof changed==='object'&&changed.project_root||unit.project_root)))blockers.push('changed-source-binding-missing');
48
+ }
49
+ } catch(error) {blockers.push(`execution-evidence-unreadable: ${error.message}`);}
50
+ return [...new Set(blockers)];
51
+ }
@@ -33,7 +33,7 @@ function activeProfile(root) {
33
33
  export function enforceHarnessTaskScope(task,{root=ROOT}={}) {
34
34
  const scope=loadExecutionScope(root);
35
35
  if(scope) {
36
- assertScopeWorkUnit(task.contract?.kind==='slice-implementation'?'work-unit.slice-implementation':task.work_unit_id,{root});
36
+ assertScopeWorkUnit(task.contract?.kind==='slice-implementation'?'work-unit.slice-implementation':task.work_unit_id,{root,readOnly:task.contract?.kind==='read-only-intake'});
37
37
  ensure(task.role_id!=='role.frontend-engineer','后端职责不允许派发前端实现');
38
38
  ensure(task.allowed_write_paths.every(ref=>!/^apps\/frontend(?:\/|$)/.test(ref)),'禁止写入前端工程');
39
39
  }
@@ -1,4 +1,5 @@
1
1
  import { resolveBackendPlatform, resolveComponentCapabilities } from "./backend-platform.mjs";
2
+ import { executionEvidenceBlockers } from './execution-evidence.mjs';
2
3
  import { safe } from './strategic-handoff-io.mjs';
3
4
  import { selectSliceWorkUnit, normalizeSliceContract, withinSlicePath } from './slice-contract.mjs';
4
5
  import { createApprovedExecutionContext, createApprovedRecompilationContext, assertApprovedExecutionContext } from './approved-execution-context.mjs';
@@ -349,6 +350,7 @@ export function validateExecutionResult(result, contract, current) {
349
350
  else if (item.exit_code !== 0) blockers.push("verification-failed");
350
351
  }
351
352
  if(contract.schema_version===3) {
353
+ blockers.push(...executionEvidenceBlockers(result, contract, {...current, root: current.root || ROOT}));
352
354
  const unit=contract.work_units.find(item=>item.id===result.work_unit_id);
353
355
  if(!unit)blockers.push('work-unit-mismatch');
354
356
  else {
@@ -1,6 +1,6 @@
1
1
  import { loadExecutionScope, assertScopeWorkUnit, scopedNextRoutes } from './lifecycle-execution-scope.mjs';
2
2
  import { createHash } from "node:crypto";
3
- import { readFileSync } from "node:fs";
3
+ import { readFileSync, withValidationPhase, validationDependencies } from "./validation-phase.mjs";
4
4
  import path from "node:path";
5
5
  import { parseDocument } from "../vendor/yaml.mjs";
6
6
  import { ROOT, loadRegistry, semanticDigest, validateRegistry } from "./lifecycle-registry.mjs";
@@ -63,11 +63,19 @@ function selectedSkills(route, skillRegistry) {
63
63
  return skillRegistry.skills.filter((skill) => ids.has(skill.id));
64
64
  }
65
65
 
66
- export function queryLifecycleContext({ mode, stageId, workUnitId, include = [] } = {}) {
66
+ export function queryLifecycleContext(options = {}) {
67
+ return withValidationPhase({ root: ROOT, purpose: "lifecycle-context-query", readOnly: true }, () => querySnapshot(options));
68
+ }
69
+
70
+ function querySnapshot({ mode, stageId, workUnitId, include = [] } = {}) {
67
71
  if (!mode && !stageId && !workUnitId && include.length === 0) {
68
72
  throw new TypeError("至少提供 --mode、--stage、--work-unit 或 --include 之一");
69
73
  }
70
74
 
75
+ const identity = loadYaml("yss-project.yaml", "仓库身份");
76
+ if (identity.schema_version !== 1 || !["template-source", "project-instance"].includes(identity.repository_mode)) {
77
+ throw new TypeError("仓库身份或版本无效");
78
+ }
71
79
  const scope = loadExecutionScope();
72
80
  if (workUnitId) assertScopeWorkUnit(workUnitId, { readOnly: true });
73
81
  const lifecycle = validateRegistry(loadRegistry());
@@ -114,9 +122,11 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
114
122
  work_unit: workUnitId ?? null,
115
123
  },
116
124
  sources: {
125
+ repository_identity: { ref: "yss-project.yaml", sha256: sha256(read("yss-project.yaml")) },
117
126
  lifecycle_registry: {
118
127
  ref: LIFECYCLE_REGISTRY_REF,
119
128
  semantic_sha256: semanticDigest(lifecycle),
129
+ sha256: sha256(read(LIFECYCLE_REGISTRY_REF)),
120
130
  status: lifecycle.status,
121
131
  },
122
132
  orchestration_contract: {
@@ -152,5 +162,7 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
152
162
  result.references = [...collectPathReferences(result), LIFECYCLE_REGISTRY_REF, ORCHESTRATION_CONTRACT_REF, SKILL_REGISTRY_REF]
153
163
  .filter((value, index, all) => all.indexOf(value) === index)
154
164
  .sort();
155
- return canonicalize(result);
165
+ result.sources.read_set = validationDependencies().files.map(row=>({ref:path.relative(ROOT,row.file).split(path.sep).join("/"),sha256:row.digest})).sort((a,b)=>a.ref.localeCompare(b.ref,"en"));
166
+ const canonical = canonicalize(result);
167
+ return { ...canonical, context_sha256: sha256(JSON.stringify(canonical)) };
156
168
  }
@@ -16,7 +16,7 @@ function source(root, ref) {
16
16
  }
17
17
 
18
18
  /** Read-only projection; checkpoint, registry and orchestration remain authoritative. */
19
- export function lifecycleStatus({ root, checkpointRef }) {
19
+ export function lifecycleStatus({ root, checkpointRef, taskPackageRef }) {
20
20
  if (!root || !checkpointRef) throw new TypeError('root and checkpoint are required');
21
21
  root = path.resolve(root);
22
22
  const identity = source(root, 'yss-project.yaml').value;
@@ -76,10 +76,36 @@ export function lifecycleStatus({ root, checkpointRef }) {
76
76
  check('stage-tracking', 'not-checked', [checkpointRef], '未登记追踪;按实例既有兼容或显式迁移入口处理,不自动补建');
77
77
  }
78
78
  if (value.status === 'blocked' && !diagnostics.some(x => x.severity === 'error')) issue('reason-missing', 'checkpoint 已标 blocked,原因未登记', checkpointRef, '补齐真实阻塞原因');
79
+ let taskSource, task, contractSource;
80
+ const recovery = {sequence: ['read-status', 'inspect-actual-result', 'verify-current-inputs', 'continue-or-reroute'], task_package_ref: taskPackageRef ?? null, contract_view: null, result_refs: [], prechecks: [], verification_items: [], checks: 'read-only; execution and approval not evaluated'};
81
+ if(taskPackageRef) {
82
+ try {
83
+ taskSource=source(root,taskPackageRef);task=taskSource.value;
84
+ if(task.work_unit_id!==value.next_work_unit && task.convergence?.parent_work_unit!==value.next_work_unit)throw Error('任务包与 checkpoint 工作单元不一致');
85
+ if(!['not-started','active','paused','resolved','failed'].includes(task.workflow_status))throw Error('任务运行状态未知');
86
+ recovery.prechecks.push({status:'not-checked',cwd:root,command:['node','scripts/verify-digital-human-task-package',taskPackageRef]});
87
+ if(task.contract?.kind==='slice-implementation') {
88
+ contractSource=source(root,task.contract.slice_contract_ref);
89
+ const c=contractSource.value.slice_contract||contractSource.value;
90
+ if(c.contract_id!==task.contract.contract_id||c.contract_version!==task.contract.contract_version)throw Error('任务与当前合同版本不一致');
91
+ recovery.contract_view={cwd:root,command:['node','scripts/contract','view',task.contract.slice_contract_ref,'--kind','slice','--profile','task','--unit',task.work_unit_id]};
92
+ const approval=task.contract.gate_refs?.[0];
93
+ recovery.prechecks.push({status:'not-checked',cwd:root,command:['node','scripts/slice-contract','verify',task.contract.slice_contract_ref,'--unit',task.work_unit_id,...(approval?['--approval-ref',approval]:[])],approval_scope:approval?'current-approval-required':'not-checked: approval reference missing'});
94
+ if(c.schema_version===3){
95
+ const unit=c.work_units?.find(x=>x.id===task.work_unit_id);
96
+ if(!unit)throw Error('当前合同不存在该工作单元');
97
+ recovery.verification_items=Object.entries(c.verification||{}).filter(([id,check])=>unit.verification_refs?.includes(id)||check.required_for_all===true).map(([id,check])=>({id,...check,status:'not-checked'}));
98
+ }
99
+ }
100
+ recovery.result_refs=[...new Set([...(task.result?.evidence_refs||[]),...(task.verification_results||[]).map(x=>x.evidence_ref)].filter(Boolean))];
101
+ for(const ref of recovery.result_refs)readFileSync(safeTrackingPath(root,ref));
102
+ check('task-recovery','passed',[taskPackageRef,...recovery.result_refs],'仅读取任务身份、状态和结果引用;继续前仍须正式验收');
103
+ } catch(error) {issue('task-recovery-invalid',error.message,taskPackageRef,'核对任务身份与实际结果,再执行适用预检');}
104
+ }
79
105
  const blockers = [...new Set(diagnostics.filter(x => x.severity === 'error').map(x => x.message))];
80
106
  const next_step = {
81
107
  action_type: 'verify', work_unit: value.next_work_unit ?? null, cwd: root,
82
- command: null, input_refs: [checkpointRef],
108
+ command: null, input_refs: [checkpointRef,...(taskPackageRef?[taskPackageRef]:[])],
83
109
  prerequisites: ['核验当前来源、Context、适用门禁与决定或延续', '核对当前范围、任务结果和允许写路径;输入变化时重验'],
84
110
  };
85
111
  let next_action;
@@ -89,10 +115,10 @@ export function lifecycleStatus({ root, checkpointRef }) {
89
115
  } else if (value.status === 'paused-human-gate') {
90
116
  next_step.action_type = 'wait';
91
117
  next_action = '核对当前会签责任方、资产与决定范围;满足已登记恢复条件后复验';
92
- } else if (activeItems.some(item => item.progress === 'running')) {
118
+ } else if (activeItems.some(item => item.progress === 'running') || task?.workflow_status === 'active') {
93
119
  next_step.action_type = 'inspect';
94
120
  next_action = '核对运行中任务身份与实际结果;状态未知时不得重复派发';
95
- } else if (activeItems.length && activeItems.every(item => item.progress === 'completed')) {
121
+ } else if ((activeItems.length && activeItems.every(item => item.progress === 'completed')) || task?.workflow_status === 'resolved') {
96
122
  next_step.action_type = 'inspect';
97
123
  next_action = '核验已有完成证据并重算下一工作单元,不直接重做';
98
124
  } else {
@@ -105,7 +131,7 @@ export function lifecycleStatus({ root, checkpointRef }) {
105
131
  return {
106
132
  schema_version: 1, read_only: true, stage: value.stage, checkpoint_status: value.status,
107
133
  work_unit: value.next_work_unit ?? null, owner, blockers, next_action,
108
- execution_authorization: 'not-evaluated', verification_scope, diagnostics, next_step,
109
- source_digests: { checkpoint: { ref: checkpointRef, digest: checkpoint.digest }, registry: { ref: registryRef, digest: registry.digest }, orchestration: { ref: contractRef, digest: contract.digest } },
134
+ execution_authorization: 'not-evaluated', verification_scope, diagnostics, next_step, recovery,
135
+ source_digests: { checkpoint: { ref: checkpointRef, digest: checkpoint.digest }, registry: { ref: registryRef, digest: registry.digest }, orchestration: { ref: contractRef, digest: contract.digest }, ...(taskSource?{task:{ref:taskPackageRef,digest:taskSource.digest}}:{}), ...(contractSource?{slice_contract:{ref:task.contract.slice_contract_ref,digest:contractSource.digest}}:{}) },
110
136
  };
111
137
  }
@@ -14,6 +14,8 @@ import { loadApprovalRecord, validateApprovalRecord } from "./approval-record.mj
14
14
  import { validateBackendReview } from "./backend-review.mjs";
15
15
  import { validateJsonSchema } from "./json-schema.mjs";
16
16
  import { ROOT } from "./lifecycle-registry.mjs";
17
+ import { readRepositoryMode } from './repository-mode.mjs';
18
+ import { validateResearchCompletion } from './maintenance-research.mjs';
17
19
 
18
20
  const IMPLEMENTATION_WORK_UNIT = "work-unit.slice-implementation";
19
21
  const TICKET_DECOMPOSITION_WORK_UNIT = "work-unit.ticket-decomposition";
@@ -28,6 +30,7 @@ function deepFreeze(value) {
28
30
  }
29
31
 
30
32
  const NEXT_ROUTES = deepFreeze({
33
+ "work-unit.maintenance-research": ["work-unit.ssot-update"],
31
34
  "work-unit.entry-triage": ["work-unit.plan-opportunity", "work-unit.plan-requirements"],
32
35
  "work-unit.ssot-update": ["work-unit.skill-projection-sync", "work-unit.intensity-aware-verification-v2"],
33
36
  "work-unit.skill-projection-sync": ["work-unit.template-snapshot-build", "work-unit.intensity-aware-verification-v2"],
@@ -303,6 +306,21 @@ function validateTicketReference(ref, trackerKind) {
303
306
  * by `validateWorkflowExecutionResult` before this function is called.
304
307
  */
305
308
  export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, options = {}) {
309
+ let entryRoutes;
310
+ if (currentWorkUnit === 'work-unit.entry-triage' || currentWorkUnit === 'work-unit.maintenance-research' || nextRoute === 'work-unit.maintenance-research') {
311
+ try {
312
+ const mode = readRepositoryMode(options.root || ROOT);
313
+ if (currentWorkUnit === 'work-unit.entry-triage') entryRoutes = mode === 'template-source'
314
+ ? ['work-unit.maintenance-research', 'work-unit.ssot-update'] : NEXT_ROUTES[currentWorkUnit];
315
+ if ((currentWorkUnit === 'work-unit.maintenance-research' || nextRoute === 'work-unit.maintenance-research') && mode !== 'template-source') throw Error('template-research-requires-template-source');
316
+ if (currentWorkUnit === 'work-unit.maintenance-research') {
317
+ assertScopeTransition(currentWorkUnit, nextRoute, decisionState, options);
318
+ if (nextRoute !== null && nextRoute !== 'work-unit.ssot-update') return blockedResult([BLOCKING_SIGNALS.invalidRoute]);
319
+ validateResearchCompletion(decisionState, {root: options.root || ROOT, continuing: nextRoute !== null});
320
+ return allowedResult(decisionState.evidence_refs);
321
+ }
322
+ } catch (error) { return blockedResult(['maintenance-research-boundary'], [error.message]); }
323
+ }
306
324
  try { assertTrackingTransition(currentWorkUnit, nextRoute, decisionState, { root: options.root || ROOT }); }
307
325
  catch (error) { return blockedResult(['stage-tracking-blocked'], [error.message]); }
308
326
  try { assertScopeTransition(currentWorkUnit, nextRoute, decisionState, options); }
@@ -320,7 +338,7 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
320
338
  try { enforceFrontendDelivery(decisionState, { root: options.root, phase: nextRoute === IMPLEMENTATION_WORK_UNIT ? "implementation" : "inputs" }); }
321
339
  catch (error) { return blockedResult(["frontend-delivery-blocked"], [error.message]); }
322
340
  }
323
- const routes = NEXT_ROUTES[currentWorkUnit] && scopedNextRoutes(currentWorkUnit, NEXT_ROUTES[currentWorkUnit], options);
341
+ const routes = NEXT_ROUTES[currentWorkUnit] && scopedNextRoutes(currentWorkUnit, entryRoutes || NEXT_ROUTES[currentWorkUnit], options);
324
342
  if (!routes) return blockedResult([BLOCKING_SIGNALS.invalidRoute], ["known_current_work_unit"]);
325
343
  if (nextRoute === REPOSITORY_PREPARATION_WORK_UNIT && !["work-unit.technical-analysis", SERVICE_INITIALIZATION_WORK_UNIT].includes(currentWorkUnit)) {
326
344
  return blockedResult([BLOCKING_SIGNALS.technicalAnalysisRequired], ["work-unit.technical-analysis predecessor"]);
@@ -0,0 +1,63 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import {spawnSync} from 'node:child_process';
4
+ import {safe, hash, parse, ensure} from './strategic-handoff-io.mjs';
5
+ import {assertUserDecisionRequirement} from './user-decision.mjs';
6
+
7
+ export const RESEARCH_VALIDATOR = '.agents/skills/yss-research/scripts/validate-research-package.mjs';
8
+ const binding = (root, ref) => ({ref, digest: hash(fs.readFileSync(safe(root, ref)))});
9
+ function readBound(root, bound) {
10
+ ensure(bound && binding(root, bound.ref).digest === bound.digest, 'research-evidence-stale');
11
+ return fs.readFileSync(safe(root, bound.ref));
12
+ }
13
+ function execute(root, brief, evidence) {
14
+ return spawnSync(process.execPath, [safe(root, RESEARCH_VALIDATOR), safe(root, brief), safe(root, evidence)], {
15
+ cwd: root, encoding: 'utf8', timeout: 30000, maxBuffer: 2 * 1024 * 1024,
16
+ env: {...process.env, NODE_OPTIONS: '', NODE_PATH: ''},
17
+ });
18
+ }
19
+
20
+ /** Capture actual validator output; never overwrite a historical run. */
21
+ export function recordResearchVerification(root, brief, evidence, output) {
22
+ const inputs = {brief: binding(root, brief), evidence: binding(root, evidence), validator: binding(root, RESEARCH_VALIDATOR)};
23
+ const dir = safe(root, output, {missing: true});
24
+ ensure(!fs.existsSync(dir), '研究验证输出目录必须不存在');
25
+ const started_at = new Date().toISOString(), result = execute(root, brief, evidence);
26
+ fs.mkdirSync(dir, {recursive: true});
27
+ fs.writeFileSync(path.join(dir, 'stdout.log'), result.stdout || '');
28
+ fs.writeFileSync(path.join(dir, 'stderr.log'), result.stderr || result.error?.message || '');
29
+ const record = {schema_version: 1, kind: 'maintenance-research-verification', inputs,
30
+ command: ['node', RESEARCH_VALIDATOR, brief, evidence], started_at, completed_at: new Date().toISOString(),
31
+ exit_code: result.status, stdout: binding(root, `${output}/stdout.log`), stderr: binding(root, `${output}/stderr.log`)};
32
+ for (const value of Object.values(inputs)) readBound(root, value);
33
+ fs.writeFileSync(path.join(dir, 'verification.json'), JSON.stringify(record, null, 2) + '\n');
34
+ return {binding: binding(root, `${output}/verification.json`), exit_code: result.status};
35
+ }
36
+
37
+ export function validateResearchCompletion(state, {root, continuing = false}) {
38
+ ensure(state?.context_reconciliation?.status === 'not-applicable' && state.context_reconciliation.reason?.trim(), 'research-context-reason-missing');
39
+ fs.readFileSync(safe(root, state.context_reconciliation.ref));
40
+ for (const key of ['blocking_signals', 'drift', 'violation', 'new_impacts', 'stale_candidates']) {
41
+ ensure(Array.isArray(state[key]) && state[key].length === 0, `research-${key}-unresolved`);
42
+ }
43
+ const record = parse(readBound(root, state.research_verification));
44
+ ensure(record.schema_version === 1 && record.kind === 'maintenance-research-verification', 'research-verification-invalid');
45
+ for (const key of ['brief', 'evidence', 'validator']) readBound(root, record.inputs?.[key]);
46
+ ensure(record.inputs.validator.ref === RESEARCH_VALIDATOR, 'research-validator-mismatch');
47
+ ensure(record.exit_code === 0 && Number.isFinite(Date.parse(record.started_at)) && Date.parse(record.completed_at) >= Date.parse(record.started_at), 'research-verification-not-passed');
48
+ ensure(JSON.stringify(record.command) === JSON.stringify(['node', RESEARCH_VALIDATOR, record.inputs.brief.ref, record.inputs.evidence.ref]), 'research-command-mismatch');
49
+ readBound(root, record.stdout); readBound(root, record.stderr);
50
+ for (const ref of [state.context_reconciliation.ref, state.research_verification.ref, record.inputs.brief.ref, record.inputs.evidence.ref]) {
51
+ ensure(state.evidence_refs?.includes(ref), `research-evidence-unreferenced: ${ref}`);
52
+ }
53
+ const current = execute(root, record.inputs.brief.ref, record.inputs.evidence.ref);
54
+ ensure(!current.error && current.status === 0, 'research-current-validation-failed');
55
+ readBound(root, state.research_verification);
56
+ for(const value of Object.values(record.inputs))readBound(root,value);
57
+ if (continuing) {
58
+ const authorization = parse(readBound(root, state.maintenance_authorization));
59
+ ensure(authorization.boundary === 'template-maintenance-scope' && authorization.scope?.includes('work-unit.ssot-update'), 'maintenance-authorization-required');
60
+ assertUserDecisionRequirement(authorization, {root});
61
+ }
62
+ return record;
63
+ }
@@ -0,0 +1,132 @@
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 { parse } from '../vendor/yaml.mjs';
6
+ import { runCommand } from './command-runner.mjs';
7
+
8
+ const ensure = (ok, message) => { if (!ok) throw new TypeError(`read-only-intake: ${message}`); };
9
+ export const digest = value => `sha256:${createHash('sha256').update(value).digest('hex')}`;
10
+ const inside = (root, file) => { const rel = path.relative(root, file); return rel !== '..' && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel); };
11
+ export function intakeEvidencePath(ref, { root, runDir }) {
12
+ const runtime = ref.startsWith('run:');
13
+ const base = runtime ? runDir : root;
14
+ ensure(base && path.isAbsolute(base), '运行证据必须显式提供绝对 run-dir');
15
+ const relative = runtime ? ref.slice(4) : ref;
16
+ ensure(relative && !path.isAbsolute(relative) && !relative.split(/[\\/]/).includes('..'), '证据路径越界');
17
+ const resolvedBase = fs.realpathSync(base), file = path.resolve(base, relative);
18
+ ensure(inside(path.resolve(base), file) && inside(resolvedBase, fs.realpathSync(file)), '证据符号链接越界');
19
+ ensure(fs.statSync(file).isFile(), '证据必须为文件');
20
+ return file;
21
+ }
22
+ // Stream large preserved evidence archives instead of allocating the whole file.
23
+ export function fileDigest(file) {
24
+ const hash = createHash('sha256'), buffer = Buffer.allocUnsafe(1024 * 1024);
25
+ const fd = fs.openSync(file, 'r');
26
+ try {
27
+ let size;
28
+ while ((size = fs.readSync(fd, buffer, 0, buffer.length, null)) !== 0) hash.update(buffer.subarray(0, size));
29
+ return `sha256:${hash.digest('hex')}`;
30
+ } finally { fs.closeSync(fd); }
31
+ }
32
+ /** Final observable repository files, including ignored and untracked files; never follow links. */
33
+ export function intakeSnapshot(root) {
34
+ const result = spawnSync('git', ['ls-files', '-z', '--cached', '--others'], { cwd: root, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
35
+ ensure(result.status === 0, result.stderr || '无法观察仓库');
36
+ const rows = {};
37
+ for (const ref of [...new Set(result.stdout.split('\0').filter(Boolean))].sort()) {
38
+ const file = path.join(root, ref);
39
+ try {
40
+ const stat = fs.lstatSync(file);
41
+ if (stat.isDirectory()) {
42
+ const nested = spawnSync('git', ['rev-parse', '--show-toplevel'], { cwd: file, encoding: 'utf8' });
43
+ ensure(nested.status === 0 && fs.realpathSync(nested.stdout.trim()) === fs.realpathSync(file), `子仓未初始化: ${ref}`);
44
+ const head = spawnSync('git', ['rev-parse', 'HEAD'], { cwd: file, encoding: 'utf8' });
45
+ ensure(nested.status === 0 && head.status === 0, `子仓不可观测: ${ref}`);
46
+ rows[ref] = { kind: 'gitlink', head: head.stdout.trim(), files: intakeSnapshot(file) };
47
+ } else rows[ref] = { kind: stat.isSymbolicLink() ? 'link' : 'file', mode: stat.mode, digest: stat.isSymbolicLink() ? digest(fs.readlinkSync(file)) : fileDigest(file) };
48
+ } catch (error) { if (error.code === 'ENOENT') rows[ref] = null; else throw error; }
49
+ }
50
+ const head=spawnSync('git',['rev-parse','--verify','HEAD'],{cwd:root,encoding:'utf8'});
51
+ const index=spawnSync('git',['ls-files','--stage','-z'],{cwd:root,encoding:'utf8',maxBuffer:16*1024*1024});
52
+ ensure(index.status===0,'无法观察 Git index');
53
+ return {git:{head:head.status===0?head.stdout.trim():null,index_digest:digest(index.stdout)},files:rows};
54
+ }
55
+ export function validateReadOnlyIntake(value, { root, runDir, roles, lifecycle }) {
56
+ const identity = parse(fs.readFileSync(path.join(root, 'yss-project.yaml'), 'utf8'));
57
+ ensure(identity.schema_version === 1 && ['template-source', 'project-instance'].includes(identity.repository_mode), '仓库身份无效');
58
+ ensure(value.contract.kind === 'read-only-intake' && value.schema_version === 2 && value.execution_state === 'Explorer' && value.allowed_write_paths.length === 0, '只读合同不授予写权限');
59
+ ensure(lifecycle.work_units.some(x => x.id === value.work_unit_id) && ['work-unit.entry-triage', 'work-unit.harness-entry'].includes(value.work_unit_id), '只允许已登记分诊入口');
60
+ ensure(roles.runtimes.some(x => x.id === value.runtime_id), '未知运行时');
61
+ ensure(value.contract.status === 'issued' || value.workflow_status === 'paused', '过期合同必须暂停');
62
+ for (const ref of [value.contract.contract_ref, ...value.inputs, ...value.expected_evidence_files]) intakeEvidencePath(ref, { root, runDir });
63
+ if (value.result) {
64
+ ensure(value.result.work_unit===value.work_unit_id && value.result.workflow_reference===value.contract.contract_ref,'结果必须绑定原分诊工作单元和合同来源');
65
+ ensure(!value.result.changed_files?.length && !value.result.changed_artifacts?.length, '只读结果包含变更');
66
+ ensure(value.result.next_route == null && !value.result.checkpoint_ref, '只读结果不得流转或修改 checkpoint');
67
+ for (const ref of value.result.evidence_refs || []) intakeEvidencePath(ref, { root, runDir });
68
+ }
69
+ const commands = new Set(value.verification_commands);
70
+ ensure((value.verification_status === 'not-executed') === (value.verification_results.length === 0), '执行状态与实际结果不一致');
71
+ for (const row of value.verification_results) {
72
+ ensure(commands.has(row.command) && row.evidence_ref.startsWith('run:'), '运行结果必须绑定声明的命令及真实运行日志');
73
+ const evidence = fs.readFileSync(intakeEvidencePath(row.evidence_ref, { root, runDir }));
74
+ ensure(row.evidence_digest === digest(evidence), '运行证据摘要不一致');
75
+ const record = JSON.parse(evidence);
76
+ for (const key of ['command','exit_code','duration_ms','executed_at']) ensure(record[key] === row[key], `运行记录 ${key} 不一致`);
77
+ for (const stream of ['stdout','stderr']) {
78
+ const ref = row[`${stream}_ref`];
79
+ ensure(ref?.startsWith('run:'), '运行日志无效');
80
+ ensure(record[`${stream}_digest`] === digest(fs.readFileSync(intakeEvidencePath(ref, { root, runDir }))), '运行日志摘要不一致');
81
+ }
82
+ }
83
+ if (value.workflow_status === 'resolved' || value.result?.result === 'completed') {
84
+ ensure(value.workflow_status === 'resolved' && value.result?.result === 'completed', '完成状态不一致');
85
+ ensure(value.result.evidence_refs?.length && value.result.context_reconciliation?.status === 'not-applicable' && value.result.context_reconciliation?.reason, '只读结论缺少来源或不流转说明');
86
+ for (const key of ['drift','violation','new_impacts','stale_candidates','blocking_signals','deferred_seams']) ensure(Array.isArray(value.result[key]) && !value.result[key].length, `完成结果 ${key} 必须为空`);
87
+ ensure(value.verification_results.every(x => x.exit_code === 0) && [...commands].every(c => value.verification_results.some(x => x.command === c)), '实际验证缺失或失败');
88
+ ensure(value.observation_ref?.startsWith('run:'), '完成结果缺少执行器仓库观测');
89
+ const observation = JSON.parse(fs.readFileSync(intakeEvidencePath(value.observation_ref, { root, runDir }), 'utf8'));
90
+ const dispatchedBytes=fs.readFileSync(intakeEvidencePath(observation.task_ref,{root,runDir}));
91
+ ensure(observation.task_digest===digest(dispatchedBytes),'原派发任务摘要不一致');
92
+ const dispatched=JSON.parse(dispatchedBytes);
93
+ for(const key of ['task_id','work_unit_id','actor_id','role_id','runtime_id','contract','inputs','allowed_write_paths','objective','forbidden_actions','expected_outputs','expected_evidence_files','skill_source','downstream_consumers','convergence'])ensure(JSON.stringify(dispatched[key])===JSON.stringify(value[key]),`结果替换原任务 ${key}`);
94
+ ensure(!dispatched.verification_commands.length || JSON.stringify(dispatched.verification_commands)===JSON.stringify(value.verification_commands),'结果替换验证要求');
95
+ ensure(observation.kind === 'read-only-intake-observation' && observation.task_id === value.task_id && observation.root === fs.realpathSync(root), '观测身份不匹配');
96
+ ensure(JSON.stringify(observation.before) === JSON.stringify(observation.after) && JSON.stringify(observation.after) === JSON.stringify(intakeSnapshot(root)), '仓库实际差异与只读声明冲突');
97
+ }
98
+ return value;
99
+ }
100
+ /** Runner-owned evidence is outside the repository; the child receives no new repository permissions. */
101
+ export async function observeReadOnlyIntake(task, { root, runDir, command, args = [], timeoutMs = 0 }) {
102
+ const label = command ? JSON.stringify([command,...args]) : null;
103
+ ensure(!command || !task.verification_commands.length || task.verification_commands.length===1 && task.verification_commands[0]===label,'执行命令与声明不一致,不得替换要求的验证');
104
+ root = fs.realpathSync(root);
105
+ ensure(path.isAbsolute(runDir) && !inside(root, path.resolve(runDir)), '运行目录必须位于仓库外');
106
+ ensure(!inside(root, fs.realpathSync(path.dirname(runDir))), '运行目录父路径符号链接进入仓库');
107
+ fs.mkdirSync(runDir, { recursive: false });
108
+ runDir = fs.realpathSync(runDir);
109
+ fs.writeFileSync(path.join(runDir,'task.json'),JSON.stringify(task,null,2)+'\n',{flag:'wx'});
110
+ const before = intakeSnapshot(root), started = new Date().toISOString();
111
+ const result = command ? await runCommand(command, args, { cwd: root, timeoutMs, stdoutFile: path.join(runDir, 'stdout.log'), stderrFile: path.join(runDir, 'stderr.log') }) : null;
112
+ const after = intakeSnapshot(root);
113
+ const observation = { schema_version: 1, kind: 'read-only-intake-observation', task_id: task.task_id, task_ref:'run:task.json', task_digest:digest(fs.readFileSync(path.join(runDir,'task.json'))), root, started_at: started, before, after };
114
+ fs.writeFileSync(path.join(runDir, 'observation.json'), JSON.stringify(observation, null, 2)+'\n');
115
+ const changed = JSON.stringify(before) !== JSON.stringify(after);
116
+ const completed = !changed && (!result || result.status === 0);
117
+ const output = structuredClone(task);
118
+ output.observation_ref = 'run:observation.json';
119
+ output.verification_status = result ? 'executed' : 'not-executed';
120
+ output.verification_results = [];
121
+ if (result) {
122
+ const label = JSON.stringify([command, ...args]);
123
+ const record = { command: label, exit_code: result.status ?? 1, duration_ms: Math.round(result.duration_ms), executed_at: started, termination: result.termination ?? null, stdout_digest: digest(fs.readFileSync(path.join(runDir,'stdout.log'))), stderr_digest: digest(fs.readFileSync(path.join(runDir,'stderr.log'))) };
124
+ const bytes = JSON.stringify(record, null, 2)+'\n'; fs.writeFileSync(path.join(runDir, 'execution.json'), bytes);
125
+ output.verification_commands = [label];
126
+ output.verification_results = [{command:label,exit_code:record.exit_code,duration_ms:record.duration_ms,executed_at:started,evidence_ref:'run:execution.json',evidence_digest:digest(bytes),stdout_ref:'run:stdout.log',stderr_ref:'run:stderr.log'}];
127
+ }
128
+ output.workflow_status = completed ? 'resolved' : 'failed';
129
+ output.result = { result_schema: 'workflow-execution-result-v1', work_unit: task.work_unit_id, workflow_reference: task.contract.contract_ref, result: completed ? 'completed' : 'failed', skill: 'yss-research', changed_files: [], changed_artifacts: [], evidence_refs: [...task.inputs, 'run:observation.json'], context_reconciliation: {status:'not-applicable',ref:'CONTEXT.md',reason:'只读分诊,不批准资产或流转阶段'}, deferred_seams: [], drift: [], violation: changed ? ['repository-changed'] : [], new_impacts: [], stale_candidates: [], next_route: null, blocking_signals: completed ? [] : ['read-only-intake-failed'] };
130
+ fs.writeFileSync(path.join(runDir, 'task-result.json'), JSON.stringify(output, null, 2)+'\n');
131
+ return output;
132
+ }
@@ -65,7 +65,8 @@ export function loadSkillRegistry(filePath = DEFAULT_REGISTRY) {
65
65
  export function resolveSkillForNewUse(registry, requestedId) {
66
66
  requireString(requestedId, "requested skill id");
67
67
  if (OBSOLETE.has(requestedId)) {
68
- const replacementSkill = requestedId === "grill-me" ? "grilling" : null;
68
+ const lifecycleOwner = ["harness-orchestrator", "yss-strategic-design", "yss-product-lifecycle"].find(id => registry.skills?.some(skill => skill.id === id));
69
+ const replacementSkill = ({ "grill-me": "grilling", "wait-what": "i-have-adhd", "grill-with-docs": lifecycleOwner, "to-questionnaire": lifecycleOwner, "improve-codebase-architecture": "codebase-design" })[requestedId] ?? null;
69
70
  throw new SkillLifecycleError(
70
71
  SKILL_LIFECYCLE_FAILURE_CODES.retired,
71
72
  replacementSkill
@@ -12,6 +12,10 @@ const STRATEGIC_DESIGN_MANIFEST_PATH = path.join(SOURCE_ROOT, ".strategic-design
12
12
  export const PROJECTION_ROOTS = [".codex/skills", ".cursor/skills", ".pi/skills"];
13
13
  export const OBSOLETE = new Set(["yss-antd-design", "yss-antdv-next-design", "to-" + "prd", "to-" + "issues", "design-an-interface", "qa", "request-refactor-plan", "ubiquitous-language", "edit-article", "obsidian-vault", "writing-great-skills", "code-review-process", "yss-domain-modeling", "yss-dir", "yss-duckdb", "yss-file", "yss-filerunner", "yss-db2mybatis", "yss-mail", "yss-mapper-dynamic", "yss-quality", "yss-sql-condition", "yss-sql-tpl", "yss-valuation", "yss-variable", "yss-openapi", "web-design-engineer", "web-video-presentation", "wireframe-prototype", "wizard", "git-guardrails-claude-code", "claude-handoff", "batch-grill-me", "grill-me", "product-design-prototype", "research", "ask-matt", "dispatching-parallel-agents", "loop-me", "migrate-to-shoehorn", "prototype-page-acceptance", "scaffold-exercises", "setup-pre-commit", "setup-ts-deep-modules", "teach", "writing-beats", "writing-fragments", "writing-shape", "yss-microapp-commit", "yss-page-module-development", "yss-dictionary", "yss-jdbc", "yss-log", "yss-taskflow", "yss-backend-scaffold-application", "yss-backend-scaffold-domain", "yss-backend-scaffold-infrastructure", "yss-backend-scaffold-web", "yss-router", "yss-source-index"]);
14
14
  for (const id of ["component-selection-imports", "page-form-module", "page-list-module", "page-skeleton", "vue3-best-practices", "yss-use-table-height", "yss-use-tree-height", "yss-components", "yss-mvc-scaffold-generator", "yss-mvc-design", "yss-mvc-data-analysis-project-initializer", "yss-backend-scaffold-parent", "yss-backend-scaffold-adapter", "yss-application-layer-reference", "yss-domain-layer-reference", "yss-infrastructure-layer-reference", "yss-web-layer-reference"]) OBSOLETE.add(id);
15
+ OBSOLETE.add("grill-with-docs");
16
+ OBSOLETE.add("to-questionnaire");
17
+ OBSOLETE.add("improve-codebase-architecture");
18
+ OBSOLETE.add("wait-what");
15
19
  export function obsoleteCanonicalResidues(names, obsolete = OBSOLETE) {
16
20
  return names.filter((name) => obsolete.has(name)).sort();
17
21
  }
@@ -31,7 +31,7 @@ function compile(binding,{root=ROOT,work_unit_id,task_id,actor_id,runtime_id,exe
31
31
  task_id,work_unit_id,actor_id,runtime_id,execution_state,workflow_status:'not-started',stage_id:'stage.vertical-slice-implementation',
32
32
  contract:{kind:'slice-implementation',contract_id:contract.contract_id,contract_version:contract.contract_version,status:'issued',contract_ref:binding.ref,slice_contract_ref:binding.ref,gate_refs:[binding.approval_ref]},
33
33
  inputs:[binding.ref,...new Set(Object.values(contract.lifecycle_refs))],
34
- objective:`${unit.behavior}(执行目录:${unit.project_root};完整约束读取 ${binding.ref})`,
34
+ objective:`${unit.behavior}(执行目录:${unit.project_root};默认消费 ${binding.ref} 的 task 视图并指定 ${work_unit_id},追溯时展开 full)`,
35
35
  allowed_write_paths:unit.allowed_write_paths,forbidden_actions:[...unit.work_unit.forbidden_patterns,'来源过期、越界、缺证据、验证失败或新增影响时停止并回交'],
36
36
  expected_outputs:[unit.behavior],expected_evidence_files:unit.work_unit.expected_evidence,verification_commands:unit.work_unit.verification_commands,verification_results:[],
37
37
  downstream_consumers:unit.downstream_consumers||['role.lifecycle-orchestrator'],convergence:{parent_work_unit:'work-unit.slice-implementation',convergence_ref:unit.convergence_ref||binding.approval_ref,conflict_escalation:'返回生命周期主控'},user_decisions:decisions
@@ -1,3 +1,4 @@
1
+ import { validateReadOnlyIntake } from './read-only-intake.mjs';
1
2
  import { assertTrackingEntry } from './stage-tracking.mjs';
2
3
  import { normalizeSliceContract } from './slice-contract.mjs';
3
4
  import { assertSliceV3TaskPackage } from './slice-task-package.mjs';
@@ -17,7 +18,7 @@ import { LEGACY_TASK_PACKAGE_SCHEMA, TASK_PACKAGE_SCHEMA, validateTaskPackageSch
17
18
 
18
19
  export { LEGACY_TASK_PACKAGE_SCHEMA, TASK_PACKAGE_SCHEMA, validateTaskPackageSchema };
19
20
  export const TASK_PACKAGE_REGISTRY_REF = ".template-spec/agents/digital-human-roles.yaml";
20
- export const CONTRACT_KINDS = new Set(["lifecycle-work-unit", "slice-implementation", "template-maintenance"]);
21
+ export const CONTRACT_KINDS = new Set(["lifecycle-work-unit", "slice-implementation", "template-maintenance", "read-only-intake"]);
21
22
  export const EXECUTION_STATES = new Set(["Explorer", "Drafter", "Worker", "Reviewer", "Verifier"]);
22
23
  export const WORKFLOW_STATUSES = new Set(["not-started", "active", "paused", "resolved", "failed"]);
23
24
 
@@ -203,8 +204,14 @@ function validateContract(value, registry, lifecycle) {
203
204
  if (value.execution_state === "Worker") assertImplementationDecision({ slice_contract_ref: contract.slice_contract_ref, vertical_slice_ticket_ref: slice.lifecycle_refs.ticket, user_decisions: value.user_decisions });
204
205
  }
205
206
 
206
- export function validateTaskPackage(value, { rolesDoc, lifecycleDoc } = {}) {
207
+ export function validateTaskPackage(value, { rolesDoc, lifecycleDoc, root = ROOT, runDir } = {}) {
207
208
  validateTaskPackageSchema(value);
209
+ if (value.schema_version === 2) {
210
+ enforceHarnessTaskScope(value, { root });
211
+ const registry = rolesDoc || loadDigitalHumanRoles();
212
+ validateSkillSource(value, registry);
213
+ return validateReadOnlyIntake(value, { root, runDir, roles: registry, lifecycle: lifecycleDoc || loadRegistry() });
214
+ }
208
215
  enforceHarnessTaskScope(value);
209
216
  const intake = value.execution_state === "Explorer" && value.allowed_write_paths.length === 0 && ["work-unit.entry-triage", "work-unit.harness-entry"].includes(value.work_unit_id);
210
217
  if (!intake) {
@@ -4,8 +4,8 @@ import path from 'node:path';
4
4
  import { lifecycleStatus } from './lib/lifecycle-status.mjs';
5
5
 
6
6
  try {
7
- const { values } = parseArgs({ strict: true, options: { root: { type: 'string' }, checkpoint: { type: 'string' } } });
8
- const result = lifecycleStatus({ root: path.resolve(values.root ?? '.'), checkpointRef: values.checkpoint });
7
+ const { values } = parseArgs({ strict: true, options: { root: { type: 'string' }, checkpoint: { type: 'string' }, task: {type: 'string'} } });
8
+ const result = lifecycleStatus({ root: path.resolve(values.root ?? '.'), checkpointRef: values.checkpoint, taskPackageRef: values.task });
9
9
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
10
10
  if (result.blockers.length) process.exitCode = 1;
11
11
  } catch (error) {
@@ -0,0 +1,16 @@
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 {ROOT} from './lib/lifecycle-registry.mjs';
6
+ import {loadTaskPackage,generateTaskPackageDefaults,validateTaskPackage} from './lib/task-package.mjs';
7
+ try {
8
+ const {values}=parseArgs({options:{input:{type:'string'},output:{type:'string'}}});
9
+ if(!values.input||!values.output)throw Error('用法: prepare-read-only-intake --input <来源选择.json|yaml> --output <仓库外/task.json>');
10
+ const {value:input}=loadTaskPackage(values.input);
11
+ const output=path.resolve(values.output),parent=fs.realpathSync(path.dirname(output)),root=fs.realpathSync(ROOT);
12
+ if(parent===root||parent.startsWith(root+path.sep))throw Error('任务包必须保存于仓库外运行目录');
13
+ const task=generateTaskPackageDefaults(input.role_id,{...input,schema_version:2,execution_state:'Explorer',workflow_status:'active',allowed_write_paths:[],expected_evidence_files:[],verification_commands:input.verification_commands||[],verification_results:[],verification_status:'not-executed',contract:{...input.contract,kind:'read-only-intake',status:'issued'}});
14
+ validateTaskPackage(task);
15
+ fs.writeFileSync(output,JSON.stringify(task,null,2)+'\n',{flag:'wx'});process.stdout.write(output+'\n');
16
+ }catch(error){process.stderr.write(error.message+'\n');process.exitCode=1;}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'node:util';
3
+ import { ROOT } from './lib/lifecycle-registry.mjs';
4
+ import { loadTaskPackage, validateTaskPackage } from './lib/task-package.mjs';
5
+ import { observeReadOnlyIntake } from './lib/read-only-intake.mjs';
6
+ try {
7
+ const {values,positionals} = parseArgs({options:{task:{type:'string'},'run-dir':{type:'string'},'timeout-ms':{type:'string',default:'0'}},allowPositionals:true});
8
+ if(!values.task||!values['run-dir'])throw Error('需要 --task 和仓库外新目录 --run-dir;命令放在 -- 之后');
9
+ const {value}=loadTaskPackage(values.task);validateTaskPackage(value);
10
+ if(value.schema_version!==2||value.workflow_status!=='active')throw Error('只接受 active 的只读 v2 任务');
11
+ const result=await observeReadOnlyIntake(value,{root:ROOT,runDir:values['run-dir'],command:positionals[0],args:positionals.slice(1),timeoutMs:Number(values['timeout-ms'])});
12
+ validateTaskPackage(result,{runDir:values['run-dir']});
13
+ process.stdout.write(JSON.stringify(result,null,2)+'\n');if(result.workflow_status!=='resolved')process.exitCode=1;
14
+ }catch(error){process.stderr.write(error.message+'\n');process.exitCode=1;}
@@ -3,10 +3,10 @@ import { parseArgs } from "node:util";
3
3
  import { loadTaskPackage, validateTaskPackage } from "./lib/task-package.mjs";
4
4
 
5
5
  try {
6
- const { positionals } = parseArgs({ allowPositionals: true, strict: true });
6
+ const { positionals, values } = parseArgs({ options: { "run-dir": { type: "string" } }, allowPositionals: true, strict: true });
7
7
  if (positionals.length !== 1) throw new TypeError("用法: scripts/verify-digital-human-task-package <task-package.yaml|task-package.json>");
8
8
  const { value } = loadTaskPackage(positionals[0]);
9
- validateTaskPackage(value);
9
+ validateTaskPackage(value, { runDir: values["run-dir"] });
10
10
  process.stdout.write("数字人任务包验证通过\n");
11
11
  } catch (error) {
12
12
  process.stderr.write(`数字人任务包验证失败: ${error.message}\n`);