@treeseed/sdk 0.10.28 → 0.12.4

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 (509) hide show
  1. package/README.md +213 -7
  2. package/dist/agent-capacity.d.ts +916 -0
  3. package/dist/agent-capacity.js +1600 -0
  4. package/dist/agent-tools.d.ts +37 -0
  5. package/dist/agent-tools.js +301 -0
  6. package/dist/api/app.d.ts +1 -1
  7. package/dist/api/auth/d1-database.d.ts +2 -2
  8. package/dist/api/auth/d1-provider.d.ts +4 -4
  9. package/dist/api/auth/d1-store.d.ts +2 -2
  10. package/dist/api/auth/memory-provider.d.ts +1 -1
  11. package/dist/api/auth/tokens.d.ts +1 -1
  12. package/dist/api/config.d.ts +3 -1
  13. package/dist/api/config.js +34 -10
  14. package/dist/api/http.d.ts +2 -2
  15. package/dist/api/index.d.ts +10 -10
  16. package/dist/api/index.js +4 -2
  17. package/dist/api/operations-routes.d.ts +3 -3
  18. package/dist/api/operations.d.ts +1 -1
  19. package/dist/api/providers.d.ts +1 -1
  20. package/dist/api/providers.js +21 -4
  21. package/dist/api/railway.d.ts +3 -2
  22. package/dist/api/sdk-dispatch.d.ts +4 -4
  23. package/dist/api/sdk-routes.d.ts +2 -2
  24. package/dist/api/templates.d.ts +2 -2
  25. package/dist/api/types.d.ts +3 -2
  26. package/dist/capacity-provider.d.ts +118 -59
  27. package/dist/capacity-provider.js +235 -43
  28. package/dist/capacity.d.ts +2 -2
  29. package/dist/cli-tools.d.ts +1 -1
  30. package/dist/content-operations.d.ts +97 -0
  31. package/dist/content-operations.js +250 -0
  32. package/dist/content-store.d.ts +4 -4
  33. package/dist/control-plane-client.d.ts +13 -18
  34. package/dist/control-plane-client.js +8 -86
  35. package/dist/control-plane.d.ts +3 -2
  36. package/dist/control-plane.js +38 -13
  37. package/dist/copilot.d.ts +3 -0
  38. package/dist/copilot.js +16 -1
  39. package/dist/d1-http.d.ts +1 -1
  40. package/dist/d1-store.d.ts +32 -57
  41. package/dist/d1-store.js +115 -318
  42. package/dist/db/d1.d.ts +1 -232
  43. package/dist/db/index.d.ts +3 -3
  44. package/dist/db/market-schema.d.ts +50900 -11018
  45. package/dist/db/market-schema.js +2313 -467
  46. package/dist/db/node-sqlite.d.ts +1 -232
  47. package/dist/db/node-sqlite.js +7 -2
  48. package/dist/db/schema.d.ts +0 -462
  49. package/dist/db/schema.js +2 -22
  50. package/dist/dispatch.d.ts +1 -1
  51. package/dist/dispatch.js +0 -11
  52. package/dist/fixture-support.js +52 -4
  53. package/dist/governance.d.ts +133 -0
  54. package/dist/governance.js +285 -0
  55. package/dist/graph/build.d.ts +2 -2
  56. package/dist/graph/context-query-contracts.d.ts +1 -1
  57. package/dist/graph/dsl.d.ts +1 -1
  58. package/dist/graph/query.d.ts +4 -4
  59. package/dist/graph/ranking.d.ts +1 -1
  60. package/dist/graph/schema.d.ts +1 -1
  61. package/dist/graph.d.ts +11 -11
  62. package/dist/guarantees/index.d.ts +425 -0
  63. package/dist/guarantees/index.js +1146 -0
  64. package/dist/hosting/apps.d.ts +12 -0
  65. package/dist/hosting/apps.js +107 -0
  66. package/dist/hosting/builtins.d.ts +25 -0
  67. package/dist/hosting/builtins.js +602 -0
  68. package/dist/hosting/contracts.d.ts +208 -0
  69. package/dist/hosting/contracts.js +0 -0
  70. package/dist/hosting/graph.d.ts +195 -0
  71. package/dist/hosting/graph.js +1092 -0
  72. package/dist/hosting/index.d.ts +4 -0
  73. package/dist/hosting/index.js +4 -0
  74. package/dist/index.d.ts +88 -67
  75. package/dist/index.js +142 -14
  76. package/dist/local-dev/managed-dev.d.ts +85 -0
  77. package/dist/local-dev/managed-dev.js +368 -0
  78. package/dist/managed-dependencies.d.ts +9 -0
  79. package/dist/managed-dependencies.js +10 -9
  80. package/dist/market-client.d.ts +327 -9
  81. package/dist/market-client.js +464 -20
  82. package/dist/model-registry.d.ts +1 -1
  83. package/dist/model-registry.js +19 -19
  84. package/dist/operations/agent-tools.d.ts +2 -11
  85. package/dist/operations/agent-tools.js +2 -14
  86. package/dist/operations/providers/default.d.ts +1 -1
  87. package/dist/operations/providers/default.js +20 -37
  88. package/dist/operations/repository-operations.d.ts +26 -2
  89. package/dist/operations/repository-operations.js +159 -1
  90. package/dist/operations/runtime.d.ts +3 -3
  91. package/dist/operations/services/bootstrap-runner.d.ts +4 -2
  92. package/dist/operations/services/bootstrap-runner.js +22 -2
  93. package/dist/operations/services/build-warning-policy.d.ts +34 -0
  94. package/dist/operations/services/build-warning-policy.js +81 -82
  95. package/dist/operations/services/commit-message-provider.js +4 -4
  96. package/dist/operations/services/config-runtime.d.ts +83 -24
  97. package/dist/operations/services/config-runtime.js +449 -130
  98. package/dist/operations/services/deploy.d.ts +106 -624
  99. package/dist/operations/services/deploy.js +746 -263
  100. package/dist/operations/services/deployment-readiness.d.ts +30 -0
  101. package/dist/operations/services/deployment-readiness.js +206 -0
  102. package/dist/operations/services/git-remote-policy.js +12 -4
  103. package/dist/operations/services/git-runner.d.ts +66 -0
  104. package/dist/operations/services/git-runner.js +479 -0
  105. package/dist/operations/services/git-workflow.d.ts +45 -6
  106. package/dist/operations/services/git-workflow.js +251 -23
  107. package/dist/operations/services/github-actions-verification.d.ts +4 -1
  108. package/dist/operations/services/github-actions-verification.js +12 -3
  109. package/dist/operations/services/github-api.js +22 -6
  110. package/dist/operations/services/github-automation.d.ts +4 -4
  111. package/dist/operations/services/github-automation.js +19 -21
  112. package/dist/operations/services/github-credentials.d.ts +13 -0
  113. package/dist/operations/services/github-credentials.js +59 -0
  114. package/dist/operations/services/hosted-service-checks.d.ts +81 -0
  115. package/dist/operations/services/hosted-service-checks.js +478 -0
  116. package/dist/operations/services/hosting-audit.d.ts +2 -2
  117. package/dist/operations/services/hosting-audit.js +7 -7
  118. package/dist/operations/services/hub-launch.d.ts +1 -1
  119. package/dist/operations/services/hub-provider-launch.d.ts +5 -5
  120. package/dist/operations/services/hub-provider-launch.js +22 -17
  121. package/dist/operations/services/live-hosted-service-checks.d.ts +26 -0
  122. package/dist/operations/services/live-hosted-service-checks.js +463 -0
  123. package/dist/operations/services/local-dev.js +0 -1
  124. package/dist/operations/services/managed-host-security.d.ts +1 -1
  125. package/dist/operations/services/managed-host-security.js +1 -1
  126. package/dist/operations/services/managed-repositories.d.ts +37 -0
  127. package/dist/operations/services/managed-repositories.js +177 -0
  128. package/dist/operations/services/operations-runner-smoke.d.ts +31 -0
  129. package/dist/operations/services/operations-runner-smoke.js +198 -0
  130. package/dist/operations/services/package-adapters.d.ts +170 -0
  131. package/dist/operations/services/package-adapters.js +859 -0
  132. package/dist/operations/services/package-reference-policy.d.ts +13 -88
  133. package/dist/operations/services/package-reference-policy.js +96 -215
  134. package/dist/operations/services/project-host-operations.d.ts +4 -4
  135. package/dist/operations/services/project-platform.d.ts +57 -173
  136. package/dist/operations/services/project-platform.js +80 -111
  137. package/dist/operations/services/project-web-monitor.d.ts +2 -2
  138. package/dist/operations/services/project-web-monitor.js +122 -5
  139. package/dist/operations/services/railway-api.d.ts +117 -5
  140. package/dist/operations/services/railway-api.js +915 -93
  141. package/dist/operations/services/railway-deploy.d.ts +30 -112
  142. package/dist/operations/services/railway-deploy.js +521 -961
  143. package/dist/operations/services/release-history.js +3 -4
  144. package/dist/operations/services/release-proof-ledger.d.ts +13 -0
  145. package/dist/operations/services/release-proof-ledger.js +81 -0
  146. package/dist/operations/services/release-proof-planner.d.ts +48 -0
  147. package/dist/operations/services/release-proof-planner.js +195 -0
  148. package/dist/operations/services/release-proof-runner.d.ts +16 -0
  149. package/dist/operations/services/release-proof-runner.js +169 -0
  150. package/dist/operations/services/release-proof.d.ts +81 -0
  151. package/dist/operations/services/release-proof.js +79 -0
  152. package/dist/operations/services/repository-save-orchestrator.d.ts +8 -7
  153. package/dist/operations/services/repository-save-orchestrator.js +604 -212
  154. package/dist/operations/services/runtime-paths.d.ts +1 -3
  155. package/dist/operations/services/runtime-paths.js +0 -4
  156. package/dist/operations/services/runtime-tools.d.ts +1 -191
  157. package/dist/operations/services/runtime-tools.js +4 -443
  158. package/dist/operations/services/save-deploy-preflight.js +9 -1
  159. package/dist/operations/services/template-host-bindings.d.ts +2 -2
  160. package/dist/operations/services/template-host-bindings.js +3 -2
  161. package/dist/operations/services/template-registry.d.ts +6 -6
  162. package/dist/operations/services/template-registry.js +33 -14
  163. package/dist/operations/services/template-secret-sync.d.ts +3 -3
  164. package/dist/operations/services/verification-cache.d.ts +25 -0
  165. package/dist/operations/services/verification-cache.js +71 -0
  166. package/dist/operations/services/workflow-timing.d.ts +25 -0
  167. package/dist/operations/services/workflow-timing.js +79 -0
  168. package/dist/operations/services/workspace-dependency-mode.js +50 -5
  169. package/dist/operations/services/workspace-preflight.js +8 -8
  170. package/dist/operations/services/workspace-save-script.d.ts +4 -4
  171. package/dist/operations/services/workspace-save.d.ts +1 -0
  172. package/dist/operations/services/workspace-save.js +42 -19
  173. package/dist/operations/services/workspace-tools.js +42 -7
  174. package/dist/operations-registry.d.ts +1 -1
  175. package/dist/operations-registry.js +5 -6
  176. package/dist/operations-types.d.ts +1 -1
  177. package/dist/operations.d.ts +17 -11
  178. package/dist/operations.js +57 -3
  179. package/dist/platform/book-export.js +2 -0
  180. package/dist/platform/books-data.d.ts +1 -1
  181. package/dist/platform/config.d.ts +27 -0
  182. package/dist/platform/config.js +100 -0
  183. package/dist/platform/content-runtime-source.d.ts +54 -0
  184. package/dist/platform/content-runtime-source.js +169 -0
  185. package/dist/platform/contracts.d.ts +38 -2
  186. package/dist/platform/deploy-config.d.ts +1 -1
  187. package/dist/platform/deploy-config.js +80 -9
  188. package/dist/platform/deploy-runtime.d.ts +1 -1
  189. package/dist/platform/desired-state.d.ts +63 -0
  190. package/dist/platform/desired-state.js +1021 -0
  191. package/dist/platform/env.yaml +568 -45
  192. package/dist/platform/environment.d.ts +3 -2
  193. package/dist/platform/environment.js +122 -21
  194. package/dist/platform/local-content-materialization.d.ts +9 -0
  195. package/dist/platform/local-content-materialization.js +212 -0
  196. package/dist/platform/plugin.d.ts +13 -4
  197. package/dist/platform/plugins/runtime.d.ts +3 -3
  198. package/dist/platform/plugins/runtime.js +62 -1
  199. package/dist/platform/plugins.d.ts +6 -6
  200. package/dist/platform/published-content-pipeline.d.ts +3 -3
  201. package/dist/platform/published-content-pipeline.js +5 -1
  202. package/dist/platform/published-content.d.ts +4 -3
  203. package/dist/platform/site-config-schema.d.ts +1 -0
  204. package/dist/platform/site-config-schema.js +4 -1
  205. package/dist/platform/tenant/runtime-config.d.ts +152 -2
  206. package/dist/platform/tenant-config.d.ts +1 -1
  207. package/dist/platform/utils/site-config-schema.d.ts +154 -0
  208. package/dist/platform/utils/site-config-schema.js +400 -461
  209. package/dist/platform-operation-store.d.ts +1 -1
  210. package/dist/platform-operation-store.js +2 -2
  211. package/dist/platform-operations.js +1 -1
  212. package/dist/plugin-default.d.ts +1 -1
  213. package/dist/plugin-default.js +27 -12
  214. package/dist/project-import.d.ts +91 -0
  215. package/dist/project-import.js +257 -0
  216. package/dist/project-workflow.d.ts +1 -1
  217. package/dist/reconcile/bootstrap-systems.d.ts +2 -2
  218. package/dist/reconcile/bootstrap-systems.js +5 -5
  219. package/dist/reconcile/builtin-adapters.d.ts +7 -1
  220. package/dist/reconcile/builtin-adapters.js +3190 -429
  221. package/dist/reconcile/contracts.d.ts +23 -6
  222. package/dist/reconcile/desired-state.d.ts +2 -192
  223. package/dist/reconcile/desired-state.js +29 -38
  224. package/dist/reconcile/engine.d.ts +61 -395
  225. package/dist/reconcile/engine.js +229 -44
  226. package/dist/reconcile/index.d.ts +10 -8
  227. package/dist/reconcile/index.js +2 -0
  228. package/dist/reconcile/live-acceptance.d.ts +100 -0
  229. package/dist/reconcile/live-acceptance.js +2027 -0
  230. package/dist/reconcile/platform.d.ts +104 -0
  231. package/dist/reconcile/platform.js +100 -0
  232. package/dist/reconcile/providers/docker-private.d.ts +54 -0
  233. package/dist/reconcile/providers/docker-private.js +101 -0
  234. package/dist/reconcile/providers/github-private.d.ts +65 -0
  235. package/dist/reconcile/providers/github-private.js +119 -0
  236. package/dist/reconcile/providers/local-private.d.ts +28 -0
  237. package/dist/reconcile/providers/local-private.js +75 -0
  238. package/dist/reconcile/providers/railway-iac.d.ts +66 -0
  239. package/dist/reconcile/providers/railway-iac.js +275 -0
  240. package/dist/reconcile/providers/release-private.d.ts +92 -0
  241. package/dist/reconcile/providers/release-private.js +152 -0
  242. package/dist/reconcile/registry.d.ts +2 -2
  243. package/dist/reconcile/registry.js +16 -1
  244. package/dist/reconcile/state.d.ts +1 -1
  245. package/dist/reconcile/state.js +7 -44
  246. package/dist/reconcile/units.d.ts +1 -1
  247. package/dist/reconcile/units.js +9 -3
  248. package/dist/remote.d.ts +6 -6
  249. package/dist/scenes/artifacts.d.ts +16 -0
  250. package/dist/scenes/artifacts.js +61 -0
  251. package/dist/scenes/auth.d.ts +2 -0
  252. package/dist/scenes/auth.js +28 -0
  253. package/dist/scenes/base-url.d.ts +12 -0
  254. package/dist/scenes/base-url.js +123 -0
  255. package/dist/scenes/builtin-plugins.d.ts +2 -0
  256. package/dist/scenes/builtin-plugins.js +447 -0
  257. package/dist/scenes/checkpoints.d.ts +14 -0
  258. package/dist/scenes/checkpoints.js +33 -0
  259. package/dist/scenes/device-matrix.d.ts +2 -0
  260. package/dist/scenes/device-matrix.js +97 -0
  261. package/dist/scenes/devices.d.ts +11 -0
  262. package/dist/scenes/devices.js +22 -0
  263. package/dist/scenes/diagnostics.d.ts +5 -0
  264. package/dist/scenes/diagnostics.js +22 -0
  265. package/dist/scenes/diagram-providers.d.ts +2 -0
  266. package/dist/scenes/diagram-providers.js +181 -0
  267. package/dist/scenes/diagram-validation.d.ts +22 -0
  268. package/dist/scenes/diagram-validation.js +74 -0
  269. package/dist/scenes/environment.d.ts +2 -0
  270. package/dist/scenes/environment.js +65 -0
  271. package/dist/scenes/evidence-bundle.d.ts +5 -0
  272. package/dist/scenes/evidence-bundle.js +42 -0
  273. package/dist/scenes/evidence-report.d.ts +10 -0
  274. package/dist/scenes/evidence-report.js +73 -0
  275. package/dist/scenes/evidence.d.ts +16 -0
  276. package/dist/scenes/evidence.js +277 -0
  277. package/dist/scenes/index.d.ts +48 -0
  278. package/dist/scenes/index.js +312 -0
  279. package/dist/scenes/inspect.d.ts +9 -0
  280. package/dist/scenes/inspect.js +64 -0
  281. package/dist/scenes/loader.d.ts +3 -0
  282. package/dist/scenes/loader.js +38 -0
  283. package/dist/scenes/logs.d.ts +2 -0
  284. package/dist/scenes/logs.js +47 -0
  285. package/dist/scenes/operations.d.ts +3 -0
  286. package/dist/scenes/operations.js +128 -0
  287. package/dist/scenes/phase0.d.ts +9 -0
  288. package/dist/scenes/phase0.js +637 -0
  289. package/dist/scenes/planner.d.ts +12 -0
  290. package/dist/scenes/planner.js +166 -0
  291. package/dist/scenes/playwright-adapter.d.ts +2 -0
  292. package/dist/scenes/playwright-adapter.js +63 -0
  293. package/dist/scenes/plugins.d.ts +5 -0
  294. package/dist/scenes/plugins.js +115 -0
  295. package/dist/scenes/progress.d.ts +17 -0
  296. package/dist/scenes/progress.js +24 -0
  297. package/dist/scenes/publish-destinations.d.ts +12 -0
  298. package/dist/scenes/publish-destinations.js +99 -0
  299. package/dist/scenes/publish-plan-report.d.ts +10 -0
  300. package/dist/scenes/publish-plan-report.js +70 -0
  301. package/dist/scenes/publish-plan.d.ts +15 -0
  302. package/dist/scenes/publish-plan.js +248 -0
  303. package/dist/scenes/publish-redaction.d.ts +16 -0
  304. package/dist/scenes/publish-redaction.js +148 -0
  305. package/dist/scenes/publish-release-record.d.ts +13 -0
  306. package/dist/scenes/publish-release-record.js +34 -0
  307. package/dist/scenes/publish-report.d.ts +10 -0
  308. package/dist/scenes/publish-report.js +67 -0
  309. package/dist/scenes/publish.d.ts +16 -0
  310. package/dist/scenes/publish.js +298 -0
  311. package/dist/scenes/registry.d.ts +12 -0
  312. package/dist/scenes/registry.js +65 -0
  313. package/dist/scenes/remotion-adapter.d.ts +3 -0
  314. package/dist/scenes/remotion-adapter.js +94 -0
  315. package/dist/scenes/remotion-composition-registry.d.ts +2 -0
  316. package/dist/scenes/remotion-composition-registry.js +12 -0
  317. package/dist/scenes/remotion-compositions.d.ts +15 -0
  318. package/dist/scenes/remotion-compositions.js +464 -0
  319. package/dist/scenes/remotion-diagrams.d.ts +9 -0
  320. package/dist/scenes/remotion-diagrams.js +188 -0
  321. package/dist/scenes/remotion-input.d.ts +13 -0
  322. package/dist/scenes/remotion-input.js +291 -0
  323. package/dist/scenes/remotion-visuals.d.ts +29 -0
  324. package/dist/scenes/remotion-visuals.js +198 -0
  325. package/dist/scenes/render-media-assets.d.ts +9 -0
  326. package/dist/scenes/render-media-assets.js +117 -0
  327. package/dist/scenes/render-report.d.ts +10 -0
  328. package/dist/scenes/render-report.js +27 -0
  329. package/dist/scenes/render.d.ts +2 -0
  330. package/dist/scenes/render.js +218 -0
  331. package/dist/scenes/reporter.d.ts +3 -0
  332. package/dist/scenes/reporter.js +101 -0
  333. package/dist/scenes/resume.d.ts +2 -0
  334. package/dist/scenes/resume.js +79 -0
  335. package/dist/scenes/runner.d.ts +2 -0
  336. package/dist/scenes/runner.js +674 -0
  337. package/dist/scenes/schema.d.ts +6 -0
  338. package/dist/scenes/schema.js +994 -0
  339. package/dist/scenes/seed.d.ts +2 -0
  340. package/dist/scenes/seed.js +83 -0
  341. package/dist/scenes/segments.d.ts +15 -0
  342. package/dist/scenes/segments.js +79 -0
  343. package/dist/scenes/selectors.d.ts +3 -0
  344. package/dist/scenes/selectors.js +21 -0
  345. package/dist/scenes/timeline.d.ts +11 -0
  346. package/dist/scenes/timeline.js +26 -0
  347. package/dist/scenes/timeouts.d.ts +6 -0
  348. package/dist/scenes/timeouts.js +17 -0
  349. package/dist/scenes/training-captions.d.ts +14 -0
  350. package/dist/scenes/training-captions.js +98 -0
  351. package/dist/scenes/training-report.d.ts +10 -0
  352. package/dist/scenes/training-report.js +78 -0
  353. package/dist/scenes/training-transcript.d.ts +24 -0
  354. package/dist/scenes/training-transcript.js +204 -0
  355. package/dist/scenes/training.d.ts +10 -0
  356. package/dist/scenes/training.js +134 -0
  357. package/dist/scenes/types.d.ts +1872 -0
  358. package/dist/scenes/types.js +8 -0
  359. package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
  360. package/dist/scenes/visual-audit-contact-sheets.js +119 -0
  361. package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
  362. package/dist/scenes/visual-audit-fixtures.js +210 -0
  363. package/dist/scenes/visual-audit-report.d.ts +11 -0
  364. package/dist/scenes/visual-audit-report.js +85 -0
  365. package/dist/scenes/visual-audit-review.d.ts +23 -0
  366. package/dist/scenes/visual-audit-review.js +829 -0
  367. package/dist/scenes/visual-audit-routes.d.ts +13 -0
  368. package/dist/scenes/visual-audit-routes.js +308 -0
  369. package/dist/scenes/visual-audit.d.ts +3 -0
  370. package/dist/scenes/visual-audit.js +596 -0
  371. package/dist/scripts/build-dist.js +154 -40
  372. package/dist/scripts/check-build-warnings.js +42 -53
  373. package/dist/scripts/cleanup-markdown.js +1 -1
  374. package/dist/scripts/cli-test-fixtures.js +24 -28
  375. package/dist/scripts/deployment-readiness.js +20 -0
  376. package/dist/scripts/generate-treedx-openapi-types.js +186 -0
  377. package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
  378. package/dist/scripts/operations-runner-smoke.js +16 -0
  379. package/dist/scripts/package-tools.js +12 -1
  380. package/dist/scripts/prepare.js +3 -7
  381. package/dist/scripts/release-verify.js +6 -6
  382. package/dist/scripts/run-fixture-astro-command.js +1 -1
  383. package/dist/scripts/template-catalog.test.js +68 -82
  384. package/dist/scripts/tenant-dev.js +0 -10
  385. package/dist/scripts/tenant-workflow-action.js +10 -1
  386. package/dist/scripts/test-cloudflare-local.js +1 -1
  387. package/dist/scripts/test-scaffold.js +0 -1
  388. package/dist/scripts/test-smoke.js +3 -3
  389. package/dist/scripts/treeseed-build-dist.js +4 -7
  390. package/dist/scripts/treeseed-release-verify.js +1 -1
  391. package/dist/scripts/verify-driver.js +30 -21
  392. package/dist/scripts/workflow-commands.test.js +18 -27
  393. package/dist/scripts/workspace-command-e2e.js +1 -1
  394. package/dist/scripts/workspace-lint.js +6 -0
  395. package/dist/scripts/workspace-release-test.js +90 -1
  396. package/dist/scripts/workspace-test.js +6 -0
  397. package/dist/sdk-dispatch.d.ts +1 -1
  398. package/dist/sdk-dispatch.js +0 -16
  399. package/dist/sdk-fields.d.ts +1 -1
  400. package/dist/sdk-filters.d.ts +1 -1
  401. package/dist/sdk-types.d.ts +1352 -116
  402. package/dist/sdk-types.js +413 -2
  403. package/dist/sdk.d.ts +106 -100
  404. package/dist/sdk.js +211 -51
  405. package/dist/secrets-capability.d.ts +421 -0
  406. package/dist/secrets-capability.js +530 -0
  407. package/dist/seeds/normalize.js +1 -0
  408. package/dist/seeds/planner.js +38 -0
  409. package/dist/seeds/schema.js +293 -4
  410. package/dist/seeds/types.d.ts +60 -0
  411. package/dist/seeds/types.js +9 -1
  412. package/dist/service-credentials.d.ts +54 -0
  413. package/dist/service-credentials.js +112 -0
  414. package/dist/stores/cursor-store.d.ts +2 -2
  415. package/dist/stores/envelopes.d.ts +1 -1
  416. package/dist/stores/helpers.d.ts +1 -1
  417. package/dist/stores/lease-store.d.ts +2 -2
  418. package/dist/stores/message-store.d.ts +2 -2
  419. package/dist/stores/operational-store.d.ts +3 -26
  420. package/dist/stores/operational-store.js +0 -225
  421. package/dist/stores/project-workflow-store.d.ts +2 -2
  422. package/dist/stores/run-store.d.ts +2 -3
  423. package/dist/stores/run-store.js +0 -98
  424. package/dist/stores/subscription-store.d.ts +2 -3
  425. package/dist/stores/subscription-store.js +0 -100
  426. package/dist/template-catalog.d.ts +1 -1
  427. package/dist/template-launch-requirements.d.ts +2 -2
  428. package/dist/template-launch-requirements.js +9 -0
  429. package/dist/template-launch-ui.d.ts +2 -2
  430. package/dist/treedx/adapters.d.ts +6 -0
  431. package/dist/treedx/adapters.js +36 -0
  432. package/dist/treedx/client.d.ts +222 -0
  433. package/dist/treedx/client.js +871 -0
  434. package/dist/treedx/errors.d.ts +13 -0
  435. package/dist/treedx/errors.js +17 -0
  436. package/dist/treedx/federated-client.d.ts +27 -0
  437. package/dist/treedx/federated-client.js +158 -0
  438. package/dist/treedx/generated/openapi-types.d.ts +3558 -0
  439. package/dist/treedx/generated/openapi-types.js +0 -0
  440. package/dist/treedx/graph-adapter.d.ts +33 -0
  441. package/dist/treedx/graph-adapter.js +156 -0
  442. package/dist/treedx/index.d.ts +14 -0
  443. package/dist/treedx/index.js +48 -0
  444. package/dist/treedx/market-integration.d.ts +27 -0
  445. package/dist/treedx/market-integration.js +131 -0
  446. package/dist/treedx/ports.d.ts +166 -0
  447. package/dist/treedx/ports.js +231 -0
  448. package/dist/treedx/query-adapter.d.ts +19 -0
  449. package/dist/treedx/query-adapter.js +62 -0
  450. package/dist/treedx/registry-client.d.ts +11 -0
  451. package/dist/treedx/registry-client.js +19 -0
  452. package/dist/treedx/repository-adapter.d.ts +45 -0
  453. package/dist/treedx/repository-adapter.js +319 -0
  454. package/dist/treedx/sdk-integration.d.ts +27 -0
  455. package/dist/treedx/sdk-integration.js +63 -0
  456. package/dist/treedx/types.d.ts +1084 -0
  457. package/dist/treedx/types.js +8 -0
  458. package/dist/treedx/workspace-adapter.d.ts +27 -0
  459. package/dist/treedx/workspace-adapter.js +65 -0
  460. package/dist/treedx-backends.d.ts +220 -0
  461. package/dist/treedx-backends.js +634 -0
  462. package/dist/treedx-client.d.ts +89 -0
  463. package/dist/treedx-client.js +184 -0
  464. package/dist/treeseed/services/compose.yml +2 -3
  465. package/dist/treeseed/template-catalog/catalog.fixture.json +27 -27
  466. package/dist/types/agents.d.ts +256 -0
  467. package/dist/types/agents.js +42 -1
  468. package/dist/verification.d.ts +1 -0
  469. package/dist/verification.js +143 -14
  470. package/dist/workflow/operations.d.ts +580 -523
  471. package/dist/workflow/operations.js +2084 -1279
  472. package/dist/workflow/policy.js +19 -7
  473. package/dist/workflow/runs.d.ts +9 -3
  474. package/dist/workflow/runs.js +66 -26
  475. package/dist/workflow/session.d.ts +4 -1
  476. package/dist/workflow/session.js +50 -10
  477. package/dist/workflow/worktrees.d.ts +6 -2
  478. package/dist/workflow/worktrees.js +98 -15
  479. package/dist/workflow-state.d.ts +17 -4
  480. package/dist/workflow-state.js +68 -41
  481. package/dist/workflow-support.d.ts +26 -17
  482. package/dist/workflow-support.js +84 -24
  483. package/dist/workflow.d.ts +51 -16
  484. package/dist/workflow.js +19 -7
  485. package/drizzle/d1/0000_treeseed_d1.sql +0 -18
  486. package/drizzle/market/0000_market_control_plane.sql +1793 -1499
  487. package/drizzle/market/0004_treedx_market_integration.sql +99 -0
  488. package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
  489. package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
  490. package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
  491. package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
  492. package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
  493. package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
  494. package/drizzle/market/0011_github_app_adapter.sql +47 -0
  495. package/drizzle/market/0012_workday_test_runs.sql +44 -0
  496. package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
  497. package/drizzle/market/0014_governance_pipeline.sql +189 -0
  498. package/package.json +106 -18
  499. package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
  500. package/templates/github/deploy-web.workflow.yml +49 -12
  501. package/dist/operations/services/mailpit-runtime.d.ts +0 -20
  502. package/dist/operations/services/mailpit-runtime.js +0 -67
  503. package/dist/operations/services/release-candidate.d.ts +0 -41
  504. package/dist/operations/services/release-candidate.js +0 -616
  505. package/dist/scripts/ensure-mailpit.js +0 -48
  506. package/dist/scripts/logs-mailpit.js +0 -2
  507. package/dist/scripts/run-ts.js +0 -45
  508. package/dist/scripts/stop-mailpit.js +0 -5
  509. package/dist/scripts/treeseed-run-ts.js +0 -45
@@ -0,0 +1,1146 @@
1
+ import { execFile } from "node:child_process";
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
3
+ import { dirname, relative, resolve, sep } from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { parse as parseYaml } from "yaml";
6
+ const TREESEED_GUARANTEE_SCHEMA_VERSION = "treeseed.guarantee/v1";
7
+ const TREESEED_GUARANTEE_VERIFIERS_SCHEMA_VERSION = "treeseed.guarantee-verifiers/v1";
8
+ const TAXONOMY_PATTERN = /^[a-z][a-z0-9-]*$/u;
9
+ const GUARANTEE_ID_PATTERN = /^guarantee\.[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*){2,}\.\d{3}$/u;
10
+ const KNOWN_GATES = /* @__PURE__ */ new Set(["smoke", "core", "release", "security", "migration", "demo", "backlog", "future"]);
11
+ const KNOWN_STATUSES = /* @__PURE__ */ new Set(["active", "planned", "blocked", "backlog", "deprecated"]);
12
+ const KNOWN_SURFACES = /* @__PURE__ */ new Set(["admin-ui", "agent-runtime", "api-control-plane", "market-ui", "cli", "scene", "content-runtime"]);
13
+ const KNOWN_DEVICES = /* @__PURE__ */ new Set(["desktop_chromium", "desktop_firefox", "desktop_webkit", "tablet_chromium", "mobile_chromium", "mobile_webkit"]);
14
+ const KNOWN_VERIFIER_KINDS = /* @__PURE__ */ new Set(["apiAcceptanceCase", "vitestCase", "nodeScript", "packageScript", "scene", "manualEvidence", "todo"]);
15
+ const EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", "build", ".treeseed", "coverage"]);
16
+ const execFileAsync = promisify(execFile);
17
+ function diagnostic(severity, code, message, path, sourcePath) {
18
+ return { severity, code, message, ...path ? { path } : {}, ...sourcePath ? { sourcePath } : {} };
19
+ }
20
+ function isRecord(value) {
21
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
22
+ }
23
+ function stringValue(value) {
24
+ return typeof value === "string" ? value.trim() : "";
25
+ }
26
+ function stringArray(value) {
27
+ if (!Array.isArray(value)) return [];
28
+ return value.map((entry) => stringValue(entry)).filter(Boolean);
29
+ }
30
+ function numberArray(value) {
31
+ if (!Array.isArray(value)) return [];
32
+ return value.map((entry) => Number(entry)).filter((entry) => Number.isInteger(entry));
33
+ }
34
+ function numberValue(value) {
35
+ const numeric = Number(value);
36
+ return Number.isFinite(numeric) ? numeric : void 0;
37
+ }
38
+ function sortedUnique(values) {
39
+ return [...new Set(values)].sort((a, b) => a.localeCompare(b));
40
+ }
41
+ function normalizeTreeseedGuaranteeTaxonomy(value) {
42
+ return value.trim().replace(/TreeDX/gu, "treedx").replace(/tree[\s_-]*dx/giu, "treedx").replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replace(/[_\s]+/gu, "-").toLowerCase().replace(/[^a-z0-9-]+/gu, "-").replace(/^-|-$/gu, "").replace(/-{2,}/gu, "-");
43
+ }
44
+ function slugifyTreeseedGuaranteeJourney(value) {
45
+ return normalizeTreeseedGuaranteeTaxonomy(value.replace(/&/gu, "and"));
46
+ }
47
+ function readYamlFile(filePath, diagnostics) {
48
+ try {
49
+ return parseYaml(readFileSync(filePath, "utf8"));
50
+ } catch (error) {
51
+ diagnostics.push(diagnostic("error", "guarantee.yaml_parse_error", error instanceof Error ? error.message : String(error), "manifest", filePath));
52
+ return null;
53
+ }
54
+ }
55
+ function walkFiles(root, predicate) {
56
+ if (!existsSync(root)) return [];
57
+ const results = [];
58
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
59
+ if (EXCLUDED_DIRS.has(entry.name)) continue;
60
+ const fullPath = resolve(root, entry.name);
61
+ if (entry.isDirectory()) {
62
+ if (fullPath.endsWith(`${sep}packages${sep}treedx${sep}guarantees`)) continue;
63
+ results.push(...walkFiles(fullPath, predicate));
64
+ continue;
65
+ }
66
+ if (entry.isFile() && predicate(fullPath)) results.push(fullPath);
67
+ }
68
+ return results.sort((a, b) => a.localeCompare(b));
69
+ }
70
+ function nearestPackageRoot(workspaceRoot, filePath) {
71
+ const packagesRoot = resolve(workspaceRoot, "packages");
72
+ if (filePath.startsWith(`${packagesRoot}${sep}`)) {
73
+ const [packageName] = relative(packagesRoot, filePath).split(sep);
74
+ if (packageName) return resolve(packagesRoot, packageName);
75
+ }
76
+ return workspaceRoot;
77
+ }
78
+ function ownerPackageFromRoot(packageRoot) {
79
+ const packageJson = resolve(packageRoot, "package.json");
80
+ if (existsSync(packageJson)) {
81
+ try {
82
+ const parsed = JSON.parse(readFileSync(packageJson, "utf8"));
83
+ if (typeof parsed.name === "string" && parsed.name.trim()) return parsed.name.trim();
84
+ } catch {
85
+ }
86
+ }
87
+ return "@treeseed/market";
88
+ }
89
+ function validateTaxonomyPath(input) {
90
+ const packageRoot = nearestPackageRoot(input.workspaceRoot, input.sourcePath);
91
+ const relativePath = relative(packageRoot, input.sourcePath).split(sep);
92
+ const guaranteeIndex = relativePath.indexOf("guarantees");
93
+ if (guaranteeIndex < 0 || relativePath.length < guaranteeIndex + 4) {
94
+ input.diagnostics.push(diagnostic("error", "guarantee.invalid_path", "Guarantee files must live under guarantees/<type>/<subtype>/*.guarantee.yaml.", "sourcePath", input.sourcePath));
95
+ return;
96
+ }
97
+ const pathType = relativePath[guaranteeIndex + 1];
98
+ const pathSubtype = relativePath[guaranteeIndex + 2];
99
+ if (pathType === "verifiers") return;
100
+ if (pathType !== input.manifest.type) {
101
+ input.diagnostics.push(diagnostic("error", "guarantee.type_path_mismatch", `Guarantee type "${input.manifest.type}" must match directory "${pathType}".`, "type", input.sourcePath));
102
+ }
103
+ if (pathSubtype !== input.manifest.subtype) {
104
+ input.diagnostics.push(diagnostic("error", "guarantee.subtype_path_mismatch", `Guarantee subtype "${input.manifest.subtype}" must match directory "${pathSubtype}".`, "subtype", input.sourcePath));
105
+ }
106
+ }
107
+ function parseContract(value) {
108
+ if (!isRecord(value)) return void 0;
109
+ return {
110
+ ...typeof value.required === "boolean" ? { required: value.required } : {},
111
+ verifierRefs: stringArray(value.verifierRefs)
112
+ };
113
+ }
114
+ function parseRunContract(value) {
115
+ if (!isRecord(value)) return void 0;
116
+ const timeoutSeconds = numberValue(value.timeoutSeconds);
117
+ return {
118
+ ...timeoutSeconds && timeoutSeconds > 0 ? { timeoutSeconds } : {},
119
+ ...typeof value.allowSkipped === "boolean" ? { allowSkipped: value.allowSkipped } : {},
120
+ ...typeof value.requiredForRelease === "boolean" ? { requiredForRelease: value.requiredForRelease } : {}
121
+ };
122
+ }
123
+ function parseScene(value) {
124
+ if (!isRecord(value)) return void 0;
125
+ const mode = isRecord(value.mode) ? value.mode : {};
126
+ return {
127
+ ...typeof value.required === "boolean" ? { required: value.required } : {},
128
+ ...typeof value.manifest === "string" ? { manifest: value.manifest } : {},
129
+ ...isRecord(value.mode) ? { mode: { acceptance: mode.acceptance === true, demo: mode.demo === true, training: mode.training === true } } : {},
130
+ ...typeof value.entryRoute === "string" ? { entryRoute: value.entryRoute } : {},
131
+ ...typeof value.componentContract === "string" ? { componentContract: value.componentContract } : {},
132
+ expectedEvidence: stringArray(value.expectedEvidence)
133
+ };
134
+ }
135
+ function parseGuaranteeManifest(value, diagnostics, sourcePath) {
136
+ if (!isRecord(value)) {
137
+ diagnostics.push(diagnostic("error", "guarantee.invalid_manifest", "Guarantee manifest must be an object.", "manifest", sourcePath));
138
+ return null;
139
+ }
140
+ const schemaVersion = stringValue(value.schemaVersion);
141
+ if (schemaVersion !== TREESEED_GUARANTEE_SCHEMA_VERSION) diagnostics.push(diagnostic("error", "guarantee.unsupported_schema_version", `Unsupported guarantee schema version "${schemaVersion}".`, "schemaVersion", sourcePath));
142
+ const id = stringValue(value.id);
143
+ const type = stringValue(value.type);
144
+ const subtype = stringValue(value.subtype);
145
+ const journey = stringValue(value.journey);
146
+ const ownerPackage = stringValue(value.ownerPackage);
147
+ const surface = stringValue(value.surface);
148
+ const summary = stringValue(value.summary);
149
+ const status = stringValue(value.status);
150
+ for (const [field, fieldValue] of Object.entries({ id, type, subtype, journey, ownerPackage, summary, status })) {
151
+ if (!fieldValue) diagnostics.push(diagnostic("error", "guarantee.missing_required_field", `Missing required field: ${field}.`, field, sourcePath));
152
+ }
153
+ if (id && !GUARANTEE_ID_PATTERN.test(id)) diagnostics.push(diagnostic("error", "guarantee.invalid_id", `Invalid guarantee id "${id}".`, "id", sourcePath));
154
+ if (type && !TAXONOMY_PATTERN.test(type)) diagnostics.push(diagnostic("error", "guarantee.invalid_type", `Guarantee type must be lowercase kebab-case: ${type}.`, "type", sourcePath));
155
+ if (subtype && !TAXONOMY_PATTERN.test(subtype)) diagnostics.push(diagnostic("error", "guarantee.invalid_subtype", `Guarantee subtype must be lowercase kebab-case: ${subtype}.`, "subtype", sourcePath));
156
+ if (status && !KNOWN_STATUSES.has(status)) diagnostics.push(diagnostic("error", "guarantee.invalid_status", `Unsupported guarantee status "${status}".`, "status", sourcePath));
157
+ if (surface && !KNOWN_SURFACES.has(surface)) diagnostics.push(diagnostic("error", "guarantee.invalid_surface", `Unsupported guarantee surface "${surface}".`, "surface", sourcePath));
158
+ const dependencies = isRecord(value.dependencies) ? value.dependencies : {};
159
+ const actors = isRecord(value.actors) ? value.actors : {};
160
+ const devices = isRecord(value.devices) ? value.devices : {};
161
+ const preconditions = isRecord(value.preconditions) ? value.preconditions : {};
162
+ const evidence = isRecord(value.evidence) ? value.evidence : {};
163
+ const gates = stringArray(value.gates);
164
+ for (const gate of gates) {
165
+ if (!KNOWN_GATES.has(gate)) diagnostics.push(diagnostic("error", "guarantee.invalid_gate", `Unsupported guarantee gate "${gate}".`, "gates", sourcePath));
166
+ }
167
+ const requiredDevices = stringArray(devices.required);
168
+ const optionalDevices = stringArray(devices.optional);
169
+ for (const device of [...requiredDevices, ...optionalDevices]) {
170
+ if (!KNOWN_DEVICES.has(device)) diagnostics.push(diagnostic("error", "guarantee.invalid_device", `Unsupported guarantee device "${device}".`, "devices", sourcePath));
171
+ }
172
+ const manifest = {
173
+ schemaVersion: TREESEED_GUARANTEE_SCHEMA_VERSION,
174
+ id,
175
+ ...Number.isInteger(Number(value.journeyIndex)) ? { journeyIndex: Number(value.journeyIndex) } : {},
176
+ type,
177
+ subtype,
178
+ journey,
179
+ ownerPackage,
180
+ ...surface ? { surface } : {},
181
+ summary,
182
+ status,
183
+ ...parseRunContract(value.run) ? { run: parseRunContract(value.run) } : {},
184
+ dependencies: {
185
+ journeys: numberArray(dependencies.journeys),
186
+ guarantees: stringArray(dependencies.guarantees)
187
+ },
188
+ actors: {
189
+ allowed: stringArray(actors.allowed),
190
+ forbidden: stringArray(actors.forbidden)
191
+ },
192
+ devices: {
193
+ required: requiredDevices,
194
+ ...optionalDevices.length > 0 ? { optional: optionalDevices } : {}
195
+ },
196
+ gates,
197
+ preconditions: {
198
+ fixtures: stringArray(preconditions.fixtures),
199
+ notes: stringArray(preconditions.notes)
200
+ },
201
+ ...parseScene(value.scene) ? { scene: parseScene(value.scene) } : {},
202
+ ...parseContract(value.api) ? { api: parseContract(value.api) } : {},
203
+ ...parseContract(value.content) ? { content: parseContract(value.content) } : {},
204
+ ...parseContract(value.audit) ? { audit: parseContract(value.audit) } : {},
205
+ negativeCases: Array.isArray(value.negativeCases) ? value.negativeCases.filter(isRecord).map((entry) => ({
206
+ id: stringValue(entry.id),
207
+ ...typeof entry.actor === "string" ? { actor: entry.actor } : {},
208
+ verifierRefs: stringArray(entry.verifierRefs),
209
+ notes: stringArray(entry.notes)
210
+ })) : [],
211
+ evidence: {
212
+ required: stringArray(evidence.required),
213
+ optional: stringArray(evidence.optional)
214
+ },
215
+ notes: stringArray(value.notes)
216
+ };
217
+ if (manifest.status === "active") {
218
+ const hasContract = Boolean(manifest.scene?.required || manifest.api?.required || manifest.content?.required || manifest.audit?.required);
219
+ if (!hasContract) diagnostics.push(diagnostic("error", "guarantee.active_missing_contract", "Active guarantees must require a scene, API, content, or audit contract.", "scene", sourcePath));
220
+ if ((manifest.gates.includes("release") || manifest.gates.includes("security")) && manifest.evidence.required.length === 0) {
221
+ diagnostics.push(diagnostic("error", "guarantee.release_missing_evidence", "Release/security guarantees must require evidence.", "evidence.required", sourcePath));
222
+ }
223
+ if ((manifest.gates.includes("release") || manifest.gates.includes("security")) && allVerifierRefs(manifest).some((ref) => ref.startsWith("todo."))) {
224
+ diagnostics.push(diagnostic("error", "guarantee.release_todo_verifier", "Release/security guarantees cannot use todo verifier refs.", "verifierRefs", sourcePath));
225
+ }
226
+ }
227
+ if (manifest.status === "active" && manifest.negativeCases?.length === 0) {
228
+ diagnostics.push(diagnostic("warning", "guarantee.no_negative_cases", "Active guarantees should define at least one negative case.", "negativeCases", sourcePath));
229
+ }
230
+ if (manifest.scene?.required && manifest.scene.manifest) {
231
+ const scenePath = resolve(dirname(sourcePath), manifest.scene.manifest);
232
+ if (!existsSync(scenePath) && manifest.status === "active") diagnostics.push(diagnostic("error", "guarantee.scene_missing", `Scene manifest does not exist: ${manifest.scene.manifest}.`, "scene.manifest", sourcePath));
233
+ if (!existsSync(scenePath) && manifest.status !== "active") diagnostics.push(diagnostic("warning", "guarantee.scene_missing_planned", `Planned guarantee scene does not exist yet: ${manifest.scene.manifest}.`, "scene.manifest", sourcePath));
234
+ }
235
+ return diagnostics.some((entry) => entry.severity === "error" && entry.sourcePath === sourcePath && entry.code !== "guarantee.scene_missing_planned") ? manifest : manifest;
236
+ }
237
+ function loadTreeseedGuaranteeManifest(input) {
238
+ const sourcePath = resolve(input.path);
239
+ const packageRoot = nearestPackageRoot(resolve(input.workspaceRoot), sourcePath);
240
+ const ownerPackage = ownerPackageFromRoot(packageRoot);
241
+ const diagnostics = [];
242
+ const value = readYamlFile(sourcePath, diagnostics);
243
+ const manifest = value ? parseGuaranteeManifest(value, diagnostics, sourcePath) : null;
244
+ if (manifest) {
245
+ if (manifest.ownerPackage !== ownerPackage) {
246
+ diagnostics.push(diagnostic("error", "guarantee.owner_package_mismatch", `Guarantee ownerPackage "${manifest.ownerPackage}" must match package "${ownerPackage}".`, "ownerPackage", sourcePath));
247
+ }
248
+ validateTaxonomyPath({ workspaceRoot: input.workspaceRoot, sourcePath, manifest, diagnostics });
249
+ if (sourcePath.includes(`${sep}packages${sep}treedx${sep}guarantees${sep}`)) {
250
+ diagnostics.push(diagnostic("error", "guarantee.treedx_product_semantics_forbidden", "TreeSeed guarantee manifests must not live in packages/treedx.", "sourcePath", sourcePath));
251
+ }
252
+ }
253
+ return {
254
+ sourcePath,
255
+ relativePath: relative(resolve(input.workspaceRoot), sourcePath),
256
+ packageRoot,
257
+ ownerPackage,
258
+ manifest,
259
+ diagnostics
260
+ };
261
+ }
262
+ function parseVerifierRegistry(value, diagnostics, sourcePath) {
263
+ if (!isRecord(value)) {
264
+ diagnostics.push(diagnostic("error", "guarantee_verifiers.invalid_manifest", "Verifier registry must be an object.", "manifest", sourcePath));
265
+ return null;
266
+ }
267
+ const schemaVersion = stringValue(value.schemaVersion);
268
+ const ownerPackage = stringValue(value.ownerPackage);
269
+ if (schemaVersion !== TREESEED_GUARANTEE_VERIFIERS_SCHEMA_VERSION) diagnostics.push(diagnostic("error", "guarantee_verifiers.unsupported_schema_version", `Unsupported verifier schema version "${schemaVersion}".`, "schemaVersion", sourcePath));
270
+ if (!ownerPackage) diagnostics.push(diagnostic("error", "guarantee_verifiers.missing_owner_package", "Verifier registry ownerPackage is required.", "ownerPackage", sourcePath));
271
+ const rawVerifiers = isRecord(value.verifiers) ? value.verifiers : {};
272
+ const verifiers = {};
273
+ for (const [id, entry] of Object.entries(rawVerifiers)) {
274
+ if (!isRecord(entry)) {
275
+ diagnostics.push(diagnostic("error", "guarantee_verifiers.invalid_entry", `Verifier "${id}" must be an object.`, `verifiers.${id}`, sourcePath));
276
+ continue;
277
+ }
278
+ const kind = stringValue(entry.kind);
279
+ verifiers[id] = {
280
+ kind,
281
+ ...typeof entry.ownerPackage === "string" ? { ownerPackage: entry.ownerPackage } : {},
282
+ ...typeof entry.spec === "string" ? { spec: entry.spec } : {},
283
+ ...typeof entry.caseId === "string" ? { caseId: entry.caseId } : {},
284
+ ...typeof entry.command === "string" ? { command: entry.command } : {},
285
+ ...Array.isArray(entry.args) ? { args: stringArray(entry.args) } : {},
286
+ ...typeof entry.testFile === "string" ? { testFile: entry.testFile } : {},
287
+ ...typeof entry.testName === "string" ? { testName: entry.testName } : {},
288
+ ...typeof entry.cwd === "string" ? { cwd: entry.cwd } : {},
289
+ ...numberValue(entry.timeoutSeconds) ? { timeoutSeconds: numberValue(entry.timeoutSeconds) } : {},
290
+ ...Array.isArray(entry.evidence) ? { evidence: stringArray(entry.evidence) } : {},
291
+ ...typeof entry.description === "string" ? { description: entry.description } : {}
292
+ };
293
+ if (!verifiers[id].kind) diagnostics.push(diagnostic("error", "guarantee_verifiers.missing_kind", `Verifier "${id}" is missing kind.`, `verifiers.${id}.kind`, sourcePath));
294
+ if (verifiers[id].kind && !KNOWN_VERIFIER_KINDS.has(verifiers[id].kind)) diagnostics.push(diagnostic("error", "guarantee_verifiers.invalid_kind", `Verifier "${id}" has unsupported kind "${verifiers[id].kind}".`, `verifiers.${id}.kind`, sourcePath));
295
+ }
296
+ return {
297
+ schemaVersion: TREESEED_GUARANTEE_VERIFIERS_SCHEMA_VERSION,
298
+ ownerPackage,
299
+ verifiers
300
+ };
301
+ }
302
+ function loadVerifierRegistry(workspaceRoot, path) {
303
+ const sourcePath = resolve(path);
304
+ const packageRoot = nearestPackageRoot(workspaceRoot, sourcePath);
305
+ const ownerPackage = ownerPackageFromRoot(packageRoot);
306
+ const diagnostics = [];
307
+ const value = readYamlFile(sourcePath, diagnostics);
308
+ const registry = value ? parseVerifierRegistry(value, diagnostics, sourcePath) : null;
309
+ if (registry && registry.ownerPackage !== ownerPackage) {
310
+ diagnostics.push(diagnostic("error", "guarantee_verifiers.owner_package_mismatch", `Verifier ownerPackage "${registry.ownerPackage}" must match package "${ownerPackage}".`, "ownerPackage", sourcePath));
311
+ }
312
+ return { sourcePath, ownerPackage, registry, diagnostics };
313
+ }
314
+ function loadTreeseedGuaranteeVerifierRegistry(input) {
315
+ return loadVerifierRegistry(resolve(input.workspaceRoot), input.path);
316
+ }
317
+ function discoverTreeseedGuarantees(input = { workspaceRoot: process.cwd() }) {
318
+ const workspaceRoot = resolve(input.workspaceRoot);
319
+ const guaranteePaths = walkFiles(workspaceRoot, (filePath) => filePath.endsWith(".guarantee.yaml"));
320
+ const verifierPaths = walkFiles(workspaceRoot, (filePath) => filePath.endsWith(".verifiers.yaml"));
321
+ const guarantees = guaranteePaths.map((path) => loadTreeseedGuaranteeManifest({ workspaceRoot, path }));
322
+ const verifierRegistries = verifierPaths.map((path) => loadVerifierRegistry(workspaceRoot, path));
323
+ return validateTreeseedGuaranteeRegistry({ workspaceRoot, guarantees, verifierRegistries, filter: input.filter });
324
+ }
325
+ function validateTreeseedGuarantee(input) {
326
+ return loadTreeseedGuaranteeManifest(input);
327
+ }
328
+ function allVerifierRefs(manifest) {
329
+ return [
330
+ ...manifest.api?.verifierRefs ?? [],
331
+ ...manifest.content?.verifierRefs ?? [],
332
+ ...manifest.audit?.verifierRefs ?? [],
333
+ ...(manifest.negativeCases ?? []).flatMap((entry) => entry.verifierRefs ?? [])
334
+ ];
335
+ }
336
+ function selectedByFilter(manifest, filter = {}) {
337
+ if (filter.gate && !manifest.gates.includes(filter.gate)) return false;
338
+ if (filter.type && manifest.type !== filter.type) return false;
339
+ if (filter.subtype && manifest.subtype !== filter.subtype) return false;
340
+ if (filter.ownerPackage && manifest.ownerPackage !== filter.ownerPackage) return false;
341
+ if (filter.status && manifest.status !== filter.status) return false;
342
+ if (filter.ids && filter.ids.length > 0 && !filter.ids.includes(manifest.id)) return false;
343
+ if (filter.journeyIndexes && filter.journeyIndexes.length > 0 && (!manifest.journeyIndex || !filter.journeyIndexes.includes(manifest.journeyIndex))) return false;
344
+ return true;
345
+ }
346
+ function validateFilter(filter, diagnostics) {
347
+ for (const field of ["type", "subtype"]) {
348
+ const value = filter?.[field];
349
+ if (value && !TAXONOMY_PATTERN.test(value)) diagnostics.push(diagnostic("error", `guarantee_filter.invalid_${field}`, `Filter ${field} must be lowercase kebab-case. Try "${normalizeTreeseedGuaranteeTaxonomy(value)}".`, field));
350
+ }
351
+ }
352
+ function filterTreeseedGuarantees(input) {
353
+ const valid = input.guarantees.filter((entry) => Boolean(entry.manifest));
354
+ const byId = new Map(valid.map((entry) => [entry.manifest.id, entry]));
355
+ const selected = /* @__PURE__ */ new Map();
356
+ for (const entry of valid) {
357
+ if (selectedByFilter(entry.manifest, input.filter)) selected.set(entry.manifest.id, entry);
358
+ }
359
+ if (input.includeDependencies !== false) {
360
+ const visit = (id) => {
361
+ const entry = byId.get(id);
362
+ if (!entry) return;
363
+ for (const dep of entry.manifest.dependencies.guarantees ?? []) {
364
+ const depEntry = byId.get(dep);
365
+ if (depEntry && !selected.has(dep)) {
366
+ selected.set(dep, depEntry);
367
+ visit(dep);
368
+ }
369
+ }
370
+ };
371
+ for (const id of [...selected.keys()]) visit(id);
372
+ }
373
+ return [...selected.values()].sort((a, b) => (a.manifest.journeyIndex ?? 99999) - (b.manifest.journeyIndex ?? 99999) || a.manifest.id.localeCompare(b.manifest.id));
374
+ }
375
+ function validateTreeseedGuaranteeRegistry(input) {
376
+ const diagnostics = [
377
+ ...input.guarantees.flatMap((entry) => entry.diagnostics),
378
+ ...(input.verifierRegistries ?? []).flatMap((entry) => entry.diagnostics)
379
+ ];
380
+ validateFilter(input.filter, diagnostics);
381
+ const valid = input.guarantees.filter((entry) => Boolean(entry.manifest));
382
+ const ids = /* @__PURE__ */ new Map();
383
+ const journeyIndexes = /* @__PURE__ */ new Map();
384
+ for (const entry of valid) {
385
+ const existing = ids.get(entry.manifest.id);
386
+ if (existing) diagnostics.push(diagnostic("error", "guarantee.duplicate_id", `Duplicate guarantee id "${entry.manifest.id}" also appears at ${existing.relativePath}.`, "id", entry.sourcePath));
387
+ ids.set(entry.manifest.id, entry);
388
+ if (entry.manifest.journeyIndex) {
389
+ const existingIndex = journeyIndexes.get(entry.manifest.journeyIndex);
390
+ if (existingIndex) diagnostics.push(diagnostic("error", "guarantee.duplicate_journey_index", `Duplicate journey index ${entry.manifest.journeyIndex} also appears at ${existingIndex.relativePath}.`, "journeyIndex", entry.sourcePath));
391
+ journeyIndexes.set(entry.manifest.journeyIndex, entry);
392
+ }
393
+ }
394
+ for (const entry of valid) {
395
+ for (const dep of entry.manifest.dependencies.guarantees ?? []) {
396
+ if (!ids.has(dep)) diagnostics.push(diagnostic("error", "guarantee.missing_dependency", `Missing guarantee dependency "${dep}".`, "dependencies.guarantees", entry.sourcePath));
397
+ }
398
+ for (const dep of entry.manifest.dependencies.journeys ?? []) {
399
+ if (!journeyIndexes.has(dep)) diagnostics.push(diagnostic("error", "guarantee.missing_journey_dependency", `Missing journey dependency "${dep}".`, "dependencies.journeys", entry.sourcePath));
400
+ if (entry.manifest.journeyIndex && dep >= entry.manifest.journeyIndex) diagnostics.push(diagnostic("error", "guarantee.forward_journey_dependency", `Journey dependency ${dep} must be lower than ${entry.manifest.journeyIndex}.`, "dependencies.journeys", entry.sourcePath));
401
+ }
402
+ }
403
+ const visiting = /* @__PURE__ */ new Set();
404
+ const visited = /* @__PURE__ */ new Set();
405
+ const visit = (id, chain) => {
406
+ if (visited.has(id)) return;
407
+ if (visiting.has(id)) {
408
+ diagnostics.push(diagnostic("error", "guarantee.dependency_cycle", `Guarantee dependency cycle: ${[...chain, id].join(" -> ")}.`, "dependencies.guarantees", ids.get(id)?.sourcePath));
409
+ return;
410
+ }
411
+ visiting.add(id);
412
+ for (const dep of ids.get(id)?.manifest.dependencies.guarantees ?? []) visit(dep, [...chain, id]);
413
+ visiting.delete(id);
414
+ visited.add(id);
415
+ };
416
+ for (const id of ids.keys()) visit(id, []);
417
+ const verifierIds = new Set((input.verifierRegistries ?? []).flatMap((entry) => Object.keys(entry.registry?.verifiers ?? {})));
418
+ const verifierKinds = new Map((input.verifierRegistries ?? []).flatMap(
419
+ (registry) => Object.entries(registry.registry?.verifiers ?? {}).map(([id, definition]) => [id, definition.kind])
420
+ ));
421
+ for (const entry of valid) {
422
+ for (const ref of allVerifierRefs(entry.manifest)) {
423
+ if (ref.startsWith("todo.")) {
424
+ if (entry.manifest.status === "active") diagnostics.push(diagnostic("error", "guarantee.todo_verifier_active", `Active guarantee cannot use placeholder verifier ref "${ref}".`, "verifierRefs", entry.sourcePath));
425
+ continue;
426
+ }
427
+ if (!verifierIds.has(ref)) {
428
+ const severity = entry.manifest.status === "active" ? "error" : "warning";
429
+ diagnostics.push(diagnostic(severity, "guarantee.missing_verifier_ref", `Verifier ref "${ref}" is not defined.`, "verifierRefs", entry.sourcePath));
430
+ }
431
+ if ((entry.manifest.gates.includes("release") || entry.manifest.gates.includes("security")) && verifierKinds.get(ref) === "manualEvidence") {
432
+ diagnostics.push(diagnostic("error", "guarantee.release_manual_evidence", `Release/security guarantee cannot depend on manual evidence verifier "${ref}".`, "verifierRefs", entry.sourcePath));
433
+ }
434
+ }
435
+ }
436
+ const selected = input.filter ? filterTreeseedGuarantees({ guarantees: input.guarantees, filter: input.filter }).length : void 0;
437
+ const errors = diagnostics.filter((entry) => entry.severity === "error").length;
438
+ const warnings = diagnostics.filter((entry) => entry.severity === "warning").length;
439
+ return {
440
+ ok: errors === 0,
441
+ workspaceRoot: resolve(input.workspaceRoot),
442
+ guarantees: input.guarantees,
443
+ verifierRegistries: input.verifierRegistries ?? [],
444
+ diagnostics,
445
+ counts: {
446
+ total: input.guarantees.length,
447
+ valid: valid.length,
448
+ ...selected !== void 0 ? { selected } : {},
449
+ errors,
450
+ warnings
451
+ }
452
+ };
453
+ }
454
+ function refs(contract) {
455
+ return contract?.verifierRefs ?? [];
456
+ }
457
+ function planTreeseedGuarantees(input) {
458
+ const registry = discoverTreeseedGuarantees({ workspaceRoot: input.workspaceRoot, filter: input.filter });
459
+ const selectedWithoutDeps = filterTreeseedGuarantees({ guarantees: registry.guarantees, filter: input.filter, includeDependencies: false });
460
+ const selectedIds = new Set(selectedWithoutDeps.map((entry) => entry.manifest.id));
461
+ const entries = filterTreeseedGuarantees({ guarantees: registry.guarantees, filter: input.filter, includeDependencies: input.includeDependencies !== false }).map((entry) => ({
462
+ id: entry.manifest.id,
463
+ ...entry.manifest.journeyIndex ? { journeyIndex: entry.manifest.journeyIndex } : {},
464
+ type: entry.manifest.type,
465
+ subtype: entry.manifest.subtype,
466
+ journey: entry.manifest.journey,
467
+ ownerPackage: entry.manifest.ownerPackage,
468
+ ...entry.manifest.surface ? { surface: entry.manifest.surface } : {},
469
+ status: entry.manifest.status,
470
+ gates: entry.manifest.gates,
471
+ sourcePath: entry.relativePath,
472
+ selected: selectedIds.has(entry.manifest.id),
473
+ dependency: !selectedIds.has(entry.manifest.id),
474
+ ...entry.manifest.scene?.manifest ? { sceneManifest: entry.manifest.scene.manifest } : {},
475
+ apiVerifierRefs: refs(entry.manifest.api),
476
+ contentVerifierRefs: refs(entry.manifest.content),
477
+ auditVerifierRefs: refs(entry.manifest.audit),
478
+ evidenceRequired: entry.manifest.evidence.required
479
+ }));
480
+ const errors = registry.diagnostics.filter((entry) => entry.severity === "error").length;
481
+ const warnings = registry.diagnostics.filter((entry) => entry.severity === "warning").length;
482
+ return {
483
+ ok: registry.ok,
484
+ workspaceRoot: resolve(input.workspaceRoot),
485
+ filter: input.filter ?? {},
486
+ environment: input.environment ?? "local",
487
+ entries,
488
+ diagnostics: registry.diagnostics,
489
+ counts: {
490
+ total: registry.counts.total,
491
+ selected: selectedWithoutDeps.length,
492
+ withDependencies: entries.length,
493
+ errors,
494
+ warnings
495
+ }
496
+ };
497
+ }
498
+ function csvEscape(value) {
499
+ const text = Array.isArray(value) ? value.join("; ") : String(value ?? "");
500
+ return /[",\n\r]/u.test(text) ? `"${text.replace(/"/gu, '""')}"` : text;
501
+ }
502
+ function exportTreeseedGuaranteesCsv(input) {
503
+ const rows = filterTreeseedGuarantees({ guarantees: input.guarantees, filter: input.filter, includeDependencies: false });
504
+ const header = [
505
+ "Guarantee ID",
506
+ "Journey Index",
507
+ "Type",
508
+ "Subtype",
509
+ "Journey",
510
+ "Owner Package",
511
+ "Surface",
512
+ "Status",
513
+ "Dependencies",
514
+ "Actor Roles",
515
+ "Forbidden Roles",
516
+ "Device Coverage",
517
+ "Preconditions",
518
+ "Scene Manifest",
519
+ "API Verifier Refs",
520
+ "Content Verifier Refs",
521
+ "Audit Verifier Refs",
522
+ "Negative Cases",
523
+ "Release Gates",
524
+ "Evidence Required",
525
+ "Notes",
526
+ "Source Path"
527
+ ];
528
+ const body = rows.map((entry) => [
529
+ entry.manifest.id,
530
+ entry.manifest.journeyIndex ?? "",
531
+ entry.manifest.type,
532
+ entry.manifest.subtype,
533
+ entry.manifest.journey,
534
+ entry.manifest.ownerPackage,
535
+ entry.manifest.surface ?? "",
536
+ entry.manifest.status,
537
+ [...entry.manifest.dependencies.guarantees ?? [], ...(entry.manifest.dependencies.journeys ?? []).map((id) => `journey:${id}`)],
538
+ entry.manifest.actors.allowed,
539
+ entry.manifest.actors.forbidden,
540
+ [...entry.manifest.devices.required, ...entry.manifest.devices.optional ?? []],
541
+ [...entry.manifest.preconditions.fixtures ?? [], ...entry.manifest.preconditions.notes ?? []],
542
+ entry.manifest.scene?.manifest ?? "",
543
+ entry.manifest.api?.verifierRefs ?? [],
544
+ entry.manifest.content?.verifierRefs ?? [],
545
+ entry.manifest.audit?.verifierRefs ?? [],
546
+ (entry.manifest.negativeCases ?? []).map((negativeCase) => negativeCase.id),
547
+ entry.manifest.gates,
548
+ entry.manifest.evidence.required,
549
+ entry.manifest.notes ?? [],
550
+ entry.relativePath
551
+ ]);
552
+ return [header, ...body].map((row) => row.map(csvEscape).join(",")).join("\n") + "\n";
553
+ }
554
+ function exportTreeseedGuaranteesJson(input) {
555
+ return {
556
+ schemaVersion: "treeseed.guarantees.export/v1",
557
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
558
+ workspaceRoot: input.registry.workspaceRoot,
559
+ guarantees: filterTreeseedGuarantees({ guarantees: input.registry.guarantees, filter: input.filter, includeDependencies: false }).map((entry) => ({
560
+ sourcePath: entry.relativePath,
561
+ ...entry.manifest
562
+ }))
563
+ };
564
+ }
565
+ function exportTreeseedGuaranteesMarkdown(input) {
566
+ const rows = filterTreeseedGuarantees({ guarantees: input.registry.guarantees, filter: input.filter, includeDependencies: false });
567
+ return [
568
+ "# TreeSeed Guarantees",
569
+ "",
570
+ `Generated from ${rows.length} guarantee manifests.`,
571
+ "",
572
+ "| ID | Type | Subtype | Journey | Status | Gates |",
573
+ "| --- | --- | --- | --- | --- | --- |",
574
+ ...rows.map((entry) => `| ${entry.manifest.id} | ${entry.manifest.type} | ${entry.manifest.subtype} | ${entry.manifest.journey.replace(/\|/gu, "\\|")} | ${entry.manifest.status} | ${entry.manifest.gates.join(", ")} |`),
575
+ ""
576
+ ].join("\n");
577
+ }
578
+ function writeTreeseedGuaranteesExport(input) {
579
+ const registry = discoverTreeseedGuarantees({ workspaceRoot: input.workspaceRoot, filter: input.filter });
580
+ const outputPath = resolve(input.workspaceRoot, input.output);
581
+ mkdirSync(dirname(outputPath), { recursive: true });
582
+ const content = input.format === "csv" ? exportTreeseedGuaranteesCsv({ guarantees: registry.guarantees, filter: input.filter }) : input.format === "json" ? `${JSON.stringify(exportTreeseedGuaranteesJson({ registry, filter: input.filter }), null, 2)}
583
+ ` : exportTreeseedGuaranteesMarkdown({ registry, filter: input.filter });
584
+ writeFileSync(outputPath, content, "utf8");
585
+ return { ok: registry.ok, outputPath, registry };
586
+ }
587
+ function verifierDefinitionsByRef(registries) {
588
+ const definitions = /* @__PURE__ */ new Map();
589
+ for (const registry of registries) {
590
+ for (const [ref, definition] of Object.entries(registry.registry?.verifiers ?? {})) {
591
+ definitions.set(ref, {
592
+ ref,
593
+ resolved: true,
594
+ sourcePath: registry.sourcePath,
595
+ ownerPackage: definition.ownerPackage ?? registry.ownerPackage,
596
+ definition: { ownerPackage: definition.ownerPackage ?? registry.ownerPackage, ...definition }
597
+ });
598
+ }
599
+ }
600
+ return definitions;
601
+ }
602
+ function resolveTreeseedGuaranteeVerifierRefs(input) {
603
+ const diagnostics = [];
604
+ const definitions = verifierDefinitionsByRef(input.verifierRegistries);
605
+ const resolutions = [...new Set(input.refs)].map((ref) => {
606
+ if (ref.startsWith("todo.")) {
607
+ const severity2 = input.status === "active" ? "error" : "warning";
608
+ diagnostics.push(diagnostic(severity2, "guarantee.todo_verifier_ref", `Verifier ref "${ref}" is a placeholder.`, "verifierRefs", input.sourcePath));
609
+ return { ref, resolved: false };
610
+ }
611
+ const resolved = definitions.get(ref);
612
+ if (resolved) return resolved;
613
+ const severity = input.status === "active" ? "error" : "warning";
614
+ diagnostics.push(diagnostic(severity, "guarantee.missing_verifier_ref", `Verifier ref "${ref}" is not defined.`, "verifierRefs", input.sourcePath));
615
+ return { ref, resolved: false };
616
+ });
617
+ return { ok: diagnostics.every((entry) => entry.severity !== "error"), resolutions, diagnostics };
618
+ }
619
+ function packageWorkspaceForOwner(ownerPackage) {
620
+ if (ownerPackage === "@treeseed/market") return ".";
621
+ const name = ownerPackage.replace(/^@treeseed\//u, "");
622
+ return `packages/${name}`;
623
+ }
624
+ function relativeEvidencePath(workspaceRoot, path) {
625
+ return relative(resolve(workspaceRoot), resolve(path)).replace(/\\/gu, "/");
626
+ }
627
+ async function writeCommandEvidence(input) {
628
+ const safeRef = slugifyTreeseedGuaranteeJourney(input.ref);
629
+ const evidencePath = resolve(input.outputRoot, "evidence", `${safeRef}.json`);
630
+ mkdirSync(dirname(evidencePath), { recursive: true });
631
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
632
+ try {
633
+ const result = await execFileAsync(input.command, input.args, {
634
+ cwd: input.cwd ? resolve(input.workspaceRoot, input.cwd) : resolve(input.workspaceRoot),
635
+ env: input.env ? { ...process.env, ...input.env } : process.env,
636
+ timeout: Math.max(1, input.timeoutSeconds ?? 300) * 1e3,
637
+ maxBuffer: 1024 * 1024 * 20
638
+ });
639
+ const completedAt = (/* @__PURE__ */ new Date()).toISOString();
640
+ writeFileSync(evidencePath, `${JSON.stringify({
641
+ ref: input.ref,
642
+ command: input.command,
643
+ args: input.args,
644
+ cwd: input.cwd ?? ".",
645
+ startedAt,
646
+ completedAt,
647
+ exitCode: 0,
648
+ env: evidenceEnvSummary(input.env),
649
+ stdout: result.stdout,
650
+ stderr: result.stderr
651
+ }, null, 2)}
652
+ `, "utf8");
653
+ return {
654
+ status: "passed",
655
+ summary: `${input.ref} passed.`,
656
+ evidence: [relativeEvidencePath(input.workspaceRoot, evidencePath)]
657
+ };
658
+ } catch (error) {
659
+ const completedAt = (/* @__PURE__ */ new Date()).toISOString();
660
+ const commandError = error;
661
+ writeFileSync(evidencePath, `${JSON.stringify({
662
+ ref: input.ref,
663
+ command: input.command,
664
+ args: input.args,
665
+ cwd: input.cwd ?? ".",
666
+ startedAt,
667
+ completedAt,
668
+ exitCode: commandError.code ?? 1,
669
+ env: evidenceEnvSummary(input.env),
670
+ stdout: commandError.stdout ?? "",
671
+ stderr: commandError.stderr ?? "",
672
+ error: commandError.message
673
+ }, null, 2)}
674
+ `, "utf8");
675
+ return {
676
+ status: "failed",
677
+ summary: `${input.ref} failed.`,
678
+ evidence: [relativeEvidencePath(input.workspaceRoot, evidencePath)],
679
+ diagnostics: [diagnostic("error", "guarantee.verifier_failed", commandError.message, input.ref)]
680
+ };
681
+ }
682
+ }
683
+ function evidenceEnvSummary(env) {
684
+ if (!env) return void 0;
685
+ return Object.fromEntries(Object.entries(env).map(([key, value]) => [
686
+ key,
687
+ /SECRET|TOKEN|KEY|PASSWORD/iu.test(key) && value ? "<redacted>" : value
688
+ ]));
689
+ }
690
+ function apiAcceptanceEnvironment(environment) {
691
+ const baseUrl = apiAcceptanceBaseUrl(environment);
692
+ const serviceId = process.env.TREESEED_ACCEPTANCE_SERVICE_ID ?? process.env.TREESEED_API_WEB_SERVICE_ID ?? process.env.TREESEED_WEB_SERVICE_ID ?? (environment === "local" ? "web" : void 0);
693
+ const serviceSecret = process.env.TREESEED_ACCEPTANCE_SERVICE_SECRET ?? process.env.TREESEED_API_WEB_SERVICE_SECRET ?? process.env.TREESEED_WEB_SERVICE_SECRET ?? (environment === "local" ? "treeseed-web-service-dev-secret" : void 0);
694
+ return {
695
+ TREESEED_ACCEPTANCE_ENVIRONMENT: environment,
696
+ TREESEED_API_BASE_URL: baseUrl,
697
+ TREESEED_ACCEPTANCE_SERVICE_ID: serviceId,
698
+ TREESEED_ACCEPTANCE_SERVICE_SECRET: serviceSecret
699
+ };
700
+ }
701
+ function apiAcceptanceBaseUrl(environment) {
702
+ if (process.env.TREESEED_API_BASE_URL?.trim()) return process.env.TREESEED_API_BASE_URL.trim().replace(/\/+$/u, "");
703
+ if (environment === "staging") return "https://api.preview.treeseed.dev";
704
+ if (environment === "prod") return "https://api.treeseed.dev";
705
+ return "http://127.0.0.1:3000";
706
+ }
707
+ async function defaultTreeseedGuaranteeVerifierExecutor(input) {
708
+ const definition = input.definition;
709
+ const ownerPackage = definition.ownerPackage ?? input.guarantee.manifest.ownerPackage;
710
+ const workspace = packageWorkspaceForOwner(ownerPackage);
711
+ if (definition.kind === "todo") {
712
+ return {
713
+ status: "blocked",
714
+ summary: `${input.ref} is a todo verifier.`,
715
+ diagnostics: [diagnostic("error", "guarantee.todo_verifier_execution", `Verifier ref "${input.ref}" is not executable.`, input.ref, input.guarantee.sourcePath)]
716
+ };
717
+ }
718
+ if (definition.kind === "manualEvidence") {
719
+ return { status: "skipped", summary: `${input.ref} requires manual evidence.`, evidence: definition.evidence ?? [] };
720
+ }
721
+ if (definition.kind === "scene") {
722
+ return { status: "passed", summary: `${input.ref} is covered by the guarantee scene step.`, evidence: definition.evidence ?? [] };
723
+ }
724
+ if (definition.kind === "apiAcceptanceCase") {
725
+ if (!definition.caseId) {
726
+ return { status: "blocked", summary: `${input.ref} missing caseId.`, diagnostics: [diagnostic("error", "guarantee.api_verifier_missing_case_id", `API verifier "${input.ref}" is missing caseId.`, input.ref, input.guarantee.sourcePath)] };
727
+ }
728
+ return writeCommandEvidence({
729
+ workspaceRoot: input.workspaceRoot,
730
+ outputRoot: input.outputRoot,
731
+ ref: input.ref,
732
+ command: "npm",
733
+ args: ["-w", "packages/api", "run", "test:acceptance", "--", "--environment", input.environment, "--base-url", apiAcceptanceBaseUrl(input.environment), "--case", definition.caseId, "--json"],
734
+ timeoutSeconds: definition.timeoutSeconds,
735
+ env: apiAcceptanceEnvironment(input.environment)
736
+ });
737
+ }
738
+ if (definition.kind === "vitestCase") {
739
+ if (!definition.testFile) {
740
+ return { status: "blocked", summary: `${input.ref} missing testFile.`, diagnostics: [diagnostic("error", "guarantee.vitest_verifier_missing_test_file", `Vitest verifier "${input.ref}" is missing testFile.`, input.ref, input.guarantee.sourcePath)] };
741
+ }
742
+ return writeCommandEvidence({
743
+ workspaceRoot: input.workspaceRoot,
744
+ outputRoot: input.outputRoot,
745
+ ref: input.ref,
746
+ command: "npm",
747
+ args: ["-w", workspace, "exec", "--", "vitest", "run", "--config", "./vitest.config.js", definition.testFile, ...definition.testName ? ["-t", definition.testName] : []],
748
+ timeoutSeconds: definition.timeoutSeconds
749
+ });
750
+ }
751
+ if (definition.kind === "packageScript") {
752
+ if (!definition.command) {
753
+ return { status: "blocked", summary: `${input.ref} missing command.`, diagnostics: [diagnostic("error", "guarantee.package_script_missing_command", `Package script verifier "${input.ref}" is missing command.`, input.ref, input.guarantee.sourcePath)] };
754
+ }
755
+ return writeCommandEvidence({
756
+ workspaceRoot: input.workspaceRoot,
757
+ outputRoot: input.outputRoot,
758
+ ref: input.ref,
759
+ command: "npm",
760
+ args: ["-w", workspace, "run", definition.command, "--", ...definition.args ?? []],
761
+ timeoutSeconds: definition.timeoutSeconds
762
+ });
763
+ }
764
+ if (definition.kind === "nodeScript") {
765
+ if (!definition.command) {
766
+ return { status: "blocked", summary: `${input.ref} missing command.`, diagnostics: [diagnostic("error", "guarantee.node_script_missing_command", `Node script verifier "${input.ref}" is missing command.`, input.ref, input.guarantee.sourcePath)] };
767
+ }
768
+ return writeCommandEvidence({
769
+ workspaceRoot: input.workspaceRoot,
770
+ outputRoot: input.outputRoot,
771
+ ref: input.ref,
772
+ command: "node",
773
+ args: ["--import", "tsx", definition.command, ...definition.args ?? []],
774
+ cwd: definition.cwd,
775
+ timeoutSeconds: definition.timeoutSeconds
776
+ });
777
+ }
778
+ return {
779
+ status: "blocked",
780
+ summary: `${input.ref} has unsupported verifier kind.`,
781
+ diagnostics: [diagnostic("error", "guarantee.unsupported_verifier_kind", `Unsupported verifier kind "${definition.kind}".`, input.ref, input.guarantee.sourcePath)]
782
+ };
783
+ }
784
+ async function defaultTreeseedGuaranteeSceneExecutor(input) {
785
+ try {
786
+ const scenes = await import("../scenes/index.js");
787
+ const devices = input.guarantee.manifest.devices.required;
788
+ if (devices.length > 1 && typeof scenes.runTreeseedSceneDeviceMatrix === "function") {
789
+ const report2 = await scenes.runTreeseedSceneDeviceMatrix({
790
+ projectRoot: input.workspaceRoot,
791
+ scene: input.scenePath,
792
+ environment: input.environment,
793
+ record: input.record,
794
+ mode: "acceptance",
795
+ devices
796
+ });
797
+ return {
798
+ status: report2.ok ? "passed" : "failed",
799
+ summary: report2.ok ? "Scene device matrix passed." : "Scene device matrix failed.",
800
+ evidence: [report2.matrixPath, ...(report2.runReports ?? []).map((entry) => entry.artifacts?.runRoot)].filter(Boolean).map((entry) => relativeEvidencePath(input.workspaceRoot, entry)),
801
+ diagnostics: report2.diagnostics ?? []
802
+ };
803
+ }
804
+ const report = await scenes.runTreeseedScene({
805
+ projectRoot: input.workspaceRoot,
806
+ scene: input.scenePath,
807
+ environment: input.environment,
808
+ device: input.device ?? devices[0],
809
+ record: input.record,
810
+ mode: "acceptance"
811
+ });
812
+ return {
813
+ status: report.ok ? "passed" : "failed",
814
+ summary: report.ok ? "Scene passed." : "Scene failed.",
815
+ evidence: [report.artifacts?.runRoot, report.playwrightTracePath].filter(Boolean).map((entry) => relativeEvidencePath(input.workspaceRoot, entry)),
816
+ diagnostics: report.diagnostics ?? []
817
+ };
818
+ } catch (error) {
819
+ return {
820
+ status: "failed",
821
+ summary: error instanceof Error ? error.message : String(error),
822
+ diagnostics: [diagnostic("error", "guarantee.scene_execution_failed", error instanceof Error ? error.message : String(error), "scene", input.guarantee.sourcePath)]
823
+ };
824
+ }
825
+ }
826
+ function markdownRunReport(report) {
827
+ return [
828
+ "# TreeSeed Guarantee Run",
829
+ "",
830
+ `Run: ${report.runId}`,
831
+ `Environment: ${report.environment}`,
832
+ `Started: ${report.startedAt}`,
833
+ `Completed: ${report.completedAt}`,
834
+ "",
835
+ `Passed: ${report.counts.passed}`,
836
+ `Failed: ${report.counts.failed}`,
837
+ `Skipped: ${report.counts.skipped}`,
838
+ `Blocked: ${report.counts.blocked}`,
839
+ `Release blocking failures: ${report.counts.releaseBlockingFailures}`,
840
+ "",
841
+ "| Guarantee | Status | Steps |",
842
+ "| --- | --- | --- |",
843
+ ...report.results.map((entry) => `| ${entry.id} | ${entry.status} | ${entry.steps.map((step) => `${step.id}:${step.status}`).join("<br>")} |`),
844
+ ""
845
+ ].join("\n");
846
+ }
847
+ function writeTreeseedGuaranteeRunReport(input) {
848
+ const diagnostics = [];
849
+ const outputRoot = resolve(input.report.outputRoot);
850
+ try {
851
+ mkdirSync(outputRoot, { recursive: true });
852
+ const planPath = resolve(outputRoot, "plan.json");
853
+ const reportPath = resolve(outputRoot, "report.json");
854
+ const markdownPath = resolve(outputRoot, "report.md");
855
+ const csvPath = resolve(outputRoot, "generated.csv");
856
+ writeFileSync(planPath, `${JSON.stringify(input.report.plan, null, 2)}
857
+ `, "utf8");
858
+ writeFileSync(reportPath, `${JSON.stringify(input.report, null, 2)}
859
+ `, "utf8");
860
+ writeFileSync(markdownPath, markdownRunReport(input.report), "utf8");
861
+ if (input.registry) writeFileSync(csvPath, exportTreeseedGuaranteesCsv({ guarantees: input.registry.guarantees, filter: input.report.filter }), "utf8");
862
+ else writeFileSync(csvPath, "", "utf8");
863
+ return { ok: true, outputRoot, planPath, reportPath, markdownPath, csvPath, diagnostics };
864
+ } catch (error) {
865
+ diagnostics.push(diagnostic("error", "guarantee.report_write_failed", error instanceof Error ? error.message : String(error), "outputRoot", outputRoot));
866
+ return {
867
+ ok: false,
868
+ outputRoot,
869
+ planPath: resolve(outputRoot, "plan.json"),
870
+ reportPath: resolve(outputRoot, "report.json"),
871
+ markdownPath: resolve(outputRoot, "report.md"),
872
+ csvPath: resolve(outputRoot, "generated.csv"),
873
+ diagnostics
874
+ };
875
+ }
876
+ }
877
+ function runIdFor(now) {
878
+ return now.toISOString().replace(/[:.]/gu, "-");
879
+ }
880
+ function releaseBlocking(manifest) {
881
+ return manifest.run?.requiredForRelease === true || manifest.gates.includes("release") || manifest.gates.includes("security") || manifest.gates.includes("migration");
882
+ }
883
+ async function runGuaranteeSteps(input) {
884
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
885
+ const steps = [];
886
+ const diagnostics = [];
887
+ const evidence = [];
888
+ const addStep = async (step, run) => {
889
+ const stepStartedAt = (/* @__PURE__ */ new Date()).toISOString();
890
+ const result = await run();
891
+ const completedAt = (/* @__PURE__ */ new Date()).toISOString();
892
+ const nextStep = {
893
+ ...step,
894
+ status: result.status,
895
+ summary: result.summary ?? step.summary,
896
+ evidence: result.evidence ?? step.evidence ?? [],
897
+ diagnostics: result.diagnostics ?? step.diagnostics ?? [],
898
+ startedAt: stepStartedAt,
899
+ completedAt
900
+ };
901
+ steps.push(nextStep);
902
+ evidence.push(...nextStep.evidence ?? []);
903
+ diagnostics.push(...nextStep.diagnostics ?? []);
904
+ };
905
+ const scene = input.guarantee.manifest.scene;
906
+ if (scene?.required && scene.manifest) {
907
+ const scenePath = resolve(dirname(input.guarantee.sourcePath), scene.manifest);
908
+ await addStep({ id: "scene", kind: "scene", status: "blocked" }, () => input.sceneExecutor({
909
+ workspaceRoot: input.workspaceRoot,
910
+ environment: input.environment,
911
+ runId: input.runId,
912
+ outputRoot: input.outputRoot,
913
+ guarantee: input.guarantee,
914
+ scenePath,
915
+ record: input.record ?? false,
916
+ device: input.device
917
+ }));
918
+ }
919
+ const verifierGroups = [
920
+ { kind: "api", refs: input.guarantee.manifest.api?.verifierRefs ?? [] },
921
+ { kind: "content", refs: input.guarantee.manifest.content?.verifierRefs ?? [] },
922
+ { kind: "audit", refs: input.guarantee.manifest.audit?.verifierRefs ?? [] },
923
+ { kind: "negative-case", refs: (input.guarantee.manifest.negativeCases ?? []).flatMap((entry) => entry.verifierRefs ?? []) }
924
+ ];
925
+ for (const group of verifierGroups) {
926
+ for (const ref of group.refs) {
927
+ const resolution = input.resolutions.get(ref);
928
+ if (!resolution?.definition) {
929
+ const missing = diagnostic("error", "guarantee.verifier_unresolved", `Verifier ref "${ref}" is not resolved.`, ref, input.guarantee.sourcePath);
930
+ steps.push({ id: ref, kind: group.kind, ref, status: "blocked", diagnostics: [missing], startedAt: (/* @__PURE__ */ new Date()).toISOString(), completedAt: (/* @__PURE__ */ new Date()).toISOString() });
931
+ diagnostics.push(missing);
932
+ continue;
933
+ }
934
+ const cacheKey = `${input.environment}:${group.kind}:${ref}`;
935
+ await addStep({ id: ref, kind: group.kind, ref, status: "blocked" }, async () => {
936
+ const cached = input.verifierCache.get(cacheKey);
937
+ if (cached) return { ...cached, summary: `${cached.summary ?? `${ref} passed.`} (cached)` };
938
+ const result = await input.verifierExecutor({
939
+ workspaceRoot: input.workspaceRoot,
940
+ environment: input.environment,
941
+ runId: input.runId,
942
+ outputRoot: input.outputRoot,
943
+ guarantee: input.guarantee,
944
+ ref,
945
+ definition: resolution.definition,
946
+ kind: group.kind
947
+ });
948
+ input.verifierCache.set(cacheKey, result);
949
+ return result;
950
+ });
951
+ }
952
+ }
953
+ const status = steps.some((step) => step.status === "failed") ? "failed" : steps.some((step) => step.status === "blocked") ? "blocked" : steps.some((step) => step.status === "skipped") ? "skipped" : "passed";
954
+ return {
955
+ id: input.guarantee.manifest.id,
956
+ ...input.guarantee.manifest.journeyIndex ? { journeyIndex: input.guarantee.manifest.journeyIndex } : {},
957
+ type: input.guarantee.manifest.type,
958
+ subtype: input.guarantee.manifest.subtype,
959
+ journey: input.guarantee.manifest.journey,
960
+ ownerPackage: input.guarantee.manifest.ownerPackage,
961
+ status,
962
+ selected: input.selected,
963
+ dependency: input.dependency,
964
+ sourcePath: input.guarantee.relativePath,
965
+ startedAt,
966
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
967
+ steps,
968
+ evidence,
969
+ diagnostics
970
+ };
971
+ }
972
+ async function runTreeseedGuarantees(input) {
973
+ const workspaceRoot = resolve(input.workspaceRoot);
974
+ const environment = input.environment ?? "local";
975
+ const startedAtDate = input.now ?? /* @__PURE__ */ new Date();
976
+ const startedAt = startedAtDate.toISOString();
977
+ const runId = runIdFor(startedAtDate);
978
+ const outputRoot = resolve(workspaceRoot, input.outputRoot ?? (input.evidenceTarget === "release" ? `.treeseed/guarantees/release/${runId}` : `.treeseed/guarantees/runs/${runId}`));
979
+ const filter = input.filter ?? {};
980
+ const registry = discoverTreeseedGuarantees({ workspaceRoot, filter });
981
+ const plan = planTreeseedGuarantees({ workspaceRoot, filter, environment, includeDependencies: input.includeDependencies });
982
+ const diagnostics = [...registry.diagnostics, ...plan.diagnostics];
983
+ const allResolutions = verifierDefinitionsByRef(registry.verifierRegistries);
984
+ const verifierCache = /* @__PURE__ */ new Map();
985
+ const selectedWithoutDeps = filterTreeseedGuarantees({ guarantees: registry.guarantees, filter, includeDependencies: false });
986
+ const selectedIds = new Set(selectedWithoutDeps.map((entry) => entry.manifest.id));
987
+ const runEntries = filterTreeseedGuarantees({ guarantees: registry.guarantees, filter, includeDependencies: input.includeDependencies !== false });
988
+ const results = [];
989
+ if (registry.ok && plan.ok) {
990
+ for (const entry of runEntries) {
991
+ if (entry.manifest.status !== "active") {
992
+ if (input.includePlanned) {
993
+ const now = (/* @__PURE__ */ new Date()).toISOString();
994
+ results.push({
995
+ id: entry.manifest.id,
996
+ ...entry.manifest.journeyIndex ? { journeyIndex: entry.manifest.journeyIndex } : {},
997
+ type: entry.manifest.type,
998
+ subtype: entry.manifest.subtype,
999
+ journey: entry.manifest.journey,
1000
+ ownerPackage: entry.manifest.ownerPackage,
1001
+ status: "skipped",
1002
+ selected: selectedIds.has(entry.manifest.id),
1003
+ dependency: !selectedIds.has(entry.manifest.id),
1004
+ sourcePath: entry.relativePath,
1005
+ startedAt: now,
1006
+ completedAt: now,
1007
+ steps: [{ id: "status", kind: "verifier", status: "skipped", summary: `Guarantee is ${entry.manifest.status}.`, startedAt: now, completedAt: now }],
1008
+ evidence: [],
1009
+ diagnostics: []
1010
+ });
1011
+ }
1012
+ continue;
1013
+ }
1014
+ const resolution = resolveTreeseedGuaranteeVerifierRefs({
1015
+ refs: allVerifierRefs(entry.manifest),
1016
+ verifierRegistries: registry.verifierRegistries,
1017
+ status: entry.manifest.status,
1018
+ sourcePath: entry.sourcePath
1019
+ });
1020
+ diagnostics.push(...resolution.diagnostics);
1021
+ if (!resolution.ok) {
1022
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1023
+ results.push({
1024
+ id: entry.manifest.id,
1025
+ ...entry.manifest.journeyIndex ? { journeyIndex: entry.manifest.journeyIndex } : {},
1026
+ type: entry.manifest.type,
1027
+ subtype: entry.manifest.subtype,
1028
+ journey: entry.manifest.journey,
1029
+ ownerPackage: entry.manifest.ownerPackage,
1030
+ status: "blocked",
1031
+ selected: selectedIds.has(entry.manifest.id),
1032
+ dependency: !selectedIds.has(entry.manifest.id),
1033
+ sourcePath: entry.relativePath,
1034
+ startedAt: now,
1035
+ completedAt: now,
1036
+ steps: [],
1037
+ evidence: [],
1038
+ diagnostics: resolution.diagnostics
1039
+ });
1040
+ continue;
1041
+ }
1042
+ results.push(await runGuaranteeSteps({
1043
+ workspaceRoot,
1044
+ environment,
1045
+ runId,
1046
+ outputRoot,
1047
+ guarantee: entry,
1048
+ selected: selectedIds.has(entry.manifest.id),
1049
+ dependency: !selectedIds.has(entry.manifest.id),
1050
+ resolutions: allResolutions,
1051
+ sceneExecutor: input.sceneExecutor ?? defaultTreeseedGuaranteeSceneExecutor,
1052
+ verifierExecutor: input.verifierExecutor ?? defaultTreeseedGuaranteeVerifierExecutor,
1053
+ verifierCache,
1054
+ record: input.record,
1055
+ device: input.device
1056
+ }));
1057
+ }
1058
+ }
1059
+ const completedAt = (/* @__PURE__ */ new Date()).toISOString();
1060
+ const releaseBlockingFailures = results.filter((result) => {
1061
+ const entry = runEntries.find((candidate) => candidate.manifest.id === result.id);
1062
+ return entry && releaseBlocking(entry.manifest) && ["failed", "blocked", ...input.failOnSkippedReleaseGuarantees === true ? ["skipped"] : []].includes(result.status);
1063
+ }).length;
1064
+ const counts = {
1065
+ planned: plan.entries.filter((entry) => entry.status !== "active").length,
1066
+ passed: results.filter((entry) => entry.status === "passed").length,
1067
+ failed: results.filter((entry) => entry.status === "failed").length,
1068
+ skipped: results.filter((entry) => entry.status === "skipped").length,
1069
+ blocked: results.filter((entry) => entry.status === "blocked").length,
1070
+ releaseBlockingFailures
1071
+ };
1072
+ const report = {
1073
+ ok: registry.ok && plan.ok && counts.failed === 0 && counts.blocked === 0 && releaseBlockingFailures === 0,
1074
+ runId,
1075
+ workspaceRoot,
1076
+ environment,
1077
+ filter,
1078
+ startedAt,
1079
+ completedAt,
1080
+ outputRoot,
1081
+ plan,
1082
+ results,
1083
+ diagnostics,
1084
+ counts
1085
+ };
1086
+ const writeResult = writeTreeseedGuaranteeRunReport({ report, registry });
1087
+ if (!writeResult.ok) {
1088
+ report.ok = false;
1089
+ report.diagnostics.push(...writeResult.diagnostics);
1090
+ }
1091
+ return report;
1092
+ }
1093
+ function createTreeseedGuaranteeStatusReport(input) {
1094
+ const registry = discoverTreeseedGuarantees({ workspaceRoot: input.workspaceRoot });
1095
+ const valid = registry.guarantees.filter((entry) => Boolean(entry.manifest));
1096
+ const byType = {};
1097
+ const byStatus = {};
1098
+ for (const entry of valid) {
1099
+ byType[entry.manifest.type] = (byType[entry.manifest.type] ?? 0) + 1;
1100
+ byStatus[entry.manifest.status] = (byStatus[entry.manifest.status] ?? 0) + 1;
1101
+ }
1102
+ return {
1103
+ ok: registry.ok,
1104
+ workspaceRoot: resolve(input.workspaceRoot),
1105
+ guaranteeRoots: sortedUnique(valid.map((entry) => dirname(entry.relativePath).split(sep).slice(0, 3).join("/"))),
1106
+ counts: registry.counts,
1107
+ byType,
1108
+ byStatus,
1109
+ verifierRegistries: registry.verifierRegistries.length,
1110
+ diagnostics: registry.diagnostics
1111
+ };
1112
+ }
1113
+ function assertPathInsideWorkspace(workspaceRoot, path) {
1114
+ const resolvedWorkspace = resolve(workspaceRoot);
1115
+ const resolvedPath = resolve(path);
1116
+ if (resolvedPath !== resolvedWorkspace && !resolvedPath.startsWith(`${resolvedWorkspace}${sep}`)) {
1117
+ throw new Error(`Path is outside workspace: ${path}`);
1118
+ }
1119
+ return resolvedPath;
1120
+ }
1121
+ function fileExists(path) {
1122
+ return existsSync(path) && statSync(path).isFile();
1123
+ }
1124
+ export {
1125
+ TREESEED_GUARANTEE_SCHEMA_VERSION,
1126
+ TREESEED_GUARANTEE_VERIFIERS_SCHEMA_VERSION,
1127
+ assertPathInsideWorkspace,
1128
+ createTreeseedGuaranteeStatusReport,
1129
+ discoverTreeseedGuarantees,
1130
+ exportTreeseedGuaranteesCsv,
1131
+ exportTreeseedGuaranteesJson,
1132
+ exportTreeseedGuaranteesMarkdown,
1133
+ fileExists,
1134
+ filterTreeseedGuarantees,
1135
+ loadTreeseedGuaranteeManifest,
1136
+ loadTreeseedGuaranteeVerifierRegistry,
1137
+ normalizeTreeseedGuaranteeTaxonomy,
1138
+ planTreeseedGuarantees,
1139
+ resolveTreeseedGuaranteeVerifierRefs,
1140
+ runTreeseedGuarantees,
1141
+ slugifyTreeseedGuaranteeJourney,
1142
+ validateTreeseedGuarantee,
1143
+ validateTreeseedGuaranteeRegistry,
1144
+ writeTreeseedGuaranteeRunReport,
1145
+ writeTreeseedGuaranteesExport
1146
+ };