@kontourai/flow-agents 4.0.0 → 4.1.0

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 (451) hide show
  1. package/.github/workflows/ci.yml +8 -0
  2. package/CHANGELOG.md +27 -0
  3. package/CONTEXT.md +5 -0
  4. package/agents/tool-security-reviewer.json +1 -1
  5. package/build/src/cli/init.js +35 -3
  6. package/build/src/cli/kit.js +95 -2
  7. package/build/src/cli/pull-work-provider.js +7 -1
  8. package/build/src/cli/validate-workflow-artifacts.js +53 -0
  9. package/build/src/cli/workflow.js +5 -1
  10. package/build/src/flow-kit/provision.d.ts +23 -0
  11. package/build/src/flow-kit/provision.js +99 -0
  12. package/build/src/flow-kit/validate.d.ts +52 -0
  13. package/build/src/flow-kit/validate.js +214 -9
  14. package/build/src/runtime-adapters.js +1 -1
  15. package/context/contracts/execution-contract.md +30 -1
  16. package/context/contracts/review-contract.md +4 -0
  17. package/context/contracts/trigger-guards.md +73 -0
  18. package/context/settings/backlog-provider-settings.json +1 -1
  19. package/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  20. package/dist/base/build/package.json +1 -1
  21. package/dist/base/build/src/cli/init.js +35 -3
  22. package/dist/base/build/src/cli/kit.js +95 -2
  23. package/dist/base/build/src/cli/pull-work-provider.js +7 -1
  24. package/dist/base/build/src/cli/validate-workflow-artifacts.js +53 -0
  25. package/dist/base/build/src/cli/workflow.js +5 -1
  26. package/dist/base/build/src/flow-kit/provision.d.ts +23 -0
  27. package/dist/base/build/src/flow-kit/provision.js +99 -0
  28. package/dist/base/build/src/flow-kit/validate.d.ts +52 -0
  29. package/dist/base/build/src/flow-kit/validate.js +214 -9
  30. package/dist/base/build/src/runtime-adapters.js +1 -1
  31. package/dist/base/context/contracts/execution-contract.md +30 -1
  32. package/dist/base/context/contracts/review-contract.md +4 -0
  33. package/dist/base/context/contracts/trigger-guards.md +73 -0
  34. package/dist/base/context/settings/backlog-provider-settings.json +1 -1
  35. package/dist/base/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  36. package/dist/base/docs/adr/0023-kit-provisioning.md +47 -0
  37. package/dist/base/docs/adr/index.md +1 -0
  38. package/dist/base/docs/architecture-engine-and-kits.md +17 -0
  39. package/dist/base/docs/context-map.md +3 -0
  40. package/dist/base/docs/decisions/backlog-readiness-source.md +89 -0
  41. package/dist/base/docs/decisions/index.md +1 -0
  42. package/dist/base/docs/developer-architecture.md +3 -3
  43. package/dist/base/docs/flow-kit-repository-contract.md +34 -3
  44. package/dist/base/docs/kit-authoring-guide.md +1 -1
  45. package/dist/base/docs/veritas-integration.md +12 -0
  46. package/dist/base/evals/ci/run-baseline.sh +4 -0
  47. package/dist/base/evals/integration/test_kit_provisioning.sh +112 -0
  48. package/dist/base/evals/integration/test_pull_work_provider.sh +18 -0
  49. package/dist/base/evals/integration/test_veritas_governance_kit.sh +256 -0
  50. package/dist/base/evals/integration/test_workflow_artifacts.sh +257 -0
  51. package/dist/base/evals/static/test_package.sh +6 -0
  52. package/dist/base/evals/static/test_workflow_skills.sh +16 -0
  53. package/dist/base/install.sh +1 -1
  54. package/dist/base/kits/builder/flows/publish-learn.flow.json +9 -1
  55. package/dist/base/kits/builder/skills/execute-plan/SKILL.md +4 -3
  56. package/dist/base/kits/builder/skills/pull-work/SKILL.md +12 -0
  57. package/dist/base/kits/builder/skills/review-work/SKILL.md +11 -0
  58. package/dist/base/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  59. package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  60. package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  61. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  62. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  63. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  64. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  65. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  66. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  67. package/dist/base/kits/veritas-governance/docs/README.md +141 -10
  68. package/dist/base/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  69. package/dist/base/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  70. package/dist/base/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  71. package/dist/base/kits/veritas-governance/kit.json +65 -0
  72. package/dist/base/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  73. package/dist/base/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  74. package/dist/base/schemas/backlog-provider-settings.schema.json +1 -1
  75. package/dist/base/schemas/workflow-waves.schema.json +347 -0
  76. package/dist/base/scripts/check-layer-boundary.mjs +98 -0
  77. package/dist/catalog.json +2 -0
  78. package/dist/claude-code/.claude/agents/tool-security-reviewer.md +2 -1
  79. package/dist/claude-code/.claude/skills/consult-standards/SKILL.md +73 -0
  80. package/dist/claude-code/.claude/skills/execute-plan/SKILL.md +4 -3
  81. package/dist/claude-code/.claude/skills/pull-work/SKILL.md +12 -0
  82. package/dist/claude-code/.claude/skills/review-work/SKILL.md +11 -0
  83. package/dist/claude-code/.claude/skills/standards-authoring/SKILL.md +87 -0
  84. package/dist/claude-code/build/package.json +1 -1
  85. package/dist/claude-code/build/src/cli/init.js +35 -3
  86. package/dist/claude-code/build/src/cli/kit.js +95 -2
  87. package/dist/claude-code/build/src/cli/pull-work-provider.js +7 -1
  88. package/dist/claude-code/build/src/cli/validate-workflow-artifacts.js +53 -0
  89. package/dist/claude-code/build/src/cli/workflow.js +5 -1
  90. package/dist/claude-code/build/src/flow-kit/provision.d.ts +23 -0
  91. package/dist/claude-code/build/src/flow-kit/provision.js +99 -0
  92. package/dist/claude-code/build/src/flow-kit/validate.d.ts +52 -0
  93. package/dist/claude-code/build/src/flow-kit/validate.js +214 -9
  94. package/dist/claude-code/build/src/runtime-adapters.js +1 -1
  95. package/dist/claude-code/context/contracts/execution-contract.md +30 -1
  96. package/dist/claude-code/context/contracts/review-contract.md +4 -0
  97. package/dist/claude-code/context/contracts/trigger-guards.md +73 -0
  98. package/dist/claude-code/context/settings/backlog-provider-settings.json +1 -1
  99. package/dist/claude-code/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  100. package/dist/claude-code/docs/adr/0023-kit-provisioning.md +47 -0
  101. package/dist/claude-code/docs/adr/index.md +1 -0
  102. package/dist/claude-code/docs/architecture-engine-and-kits.md +17 -0
  103. package/dist/claude-code/docs/context-map.md +3 -0
  104. package/dist/claude-code/docs/decisions/backlog-readiness-source.md +89 -0
  105. package/dist/claude-code/docs/decisions/index.md +1 -0
  106. package/dist/claude-code/docs/developer-architecture.md +3 -3
  107. package/dist/claude-code/docs/flow-kit-repository-contract.md +34 -3
  108. package/dist/claude-code/docs/kit-authoring-guide.md +1 -1
  109. package/dist/claude-code/docs/veritas-integration.md +12 -0
  110. package/dist/claude-code/evals/ci/run-baseline.sh +4 -0
  111. package/dist/claude-code/evals/integration/test_kit_provisioning.sh +112 -0
  112. package/dist/claude-code/evals/integration/test_pull_work_provider.sh +18 -0
  113. package/dist/claude-code/evals/integration/test_veritas_governance_kit.sh +256 -0
  114. package/dist/claude-code/evals/integration/test_workflow_artifacts.sh +257 -0
  115. package/dist/claude-code/evals/static/test_package.sh +6 -0
  116. package/dist/claude-code/evals/static/test_workflow_skills.sh +16 -0
  117. package/dist/claude-code/install.sh +1 -1
  118. package/dist/claude-code/kits/builder/flows/publish-learn.flow.json +9 -1
  119. package/dist/claude-code/kits/builder/skills/execute-plan/SKILL.md +4 -3
  120. package/dist/claude-code/kits/builder/skills/pull-work/SKILL.md +12 -0
  121. package/dist/claude-code/kits/builder/skills/review-work/SKILL.md +11 -0
  122. package/dist/claude-code/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  123. package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  124. package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  125. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  126. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  127. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  128. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  129. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  130. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  131. package/dist/claude-code/kits/veritas-governance/docs/README.md +141 -10
  132. package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  133. package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  134. package/dist/claude-code/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  135. package/dist/claude-code/kits/veritas-governance/kit.json +65 -0
  136. package/dist/claude-code/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  137. package/dist/claude-code/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  138. package/dist/claude-code/schemas/backlog-provider-settings.schema.json +1 -1
  139. package/dist/claude-code/schemas/workflow-waves.schema.json +347 -0
  140. package/dist/claude-code/scripts/check-layer-boundary.mjs +98 -0
  141. package/dist/codex/.agents/skills/builder-shape/context/contracts/execution-contract.md +30 -1
  142. package/dist/codex/.agents/skills/consult-standards/SKILL.md +73 -0
  143. package/dist/codex/.agents/skills/deliver/context/contracts/execution-contract.md +30 -1
  144. package/dist/codex/.agents/skills/design-probe/context/contracts/execution-contract.md +30 -1
  145. package/dist/codex/.agents/skills/execute-plan/SKILL.md +4 -3
  146. package/dist/codex/.agents/skills/execute-plan/context/contracts/execution-contract.md +30 -1
  147. package/dist/codex/.agents/skills/fix-bug/context/contracts/execution-contract.md +30 -1
  148. package/dist/codex/.agents/skills/idea-to-backlog/context/contracts/execution-contract.md +30 -1
  149. package/dist/codex/.agents/skills/plan-work/context/contracts/execution-contract.md +30 -1
  150. package/dist/codex/.agents/skills/pull-work/SKILL.md +12 -0
  151. package/dist/codex/.agents/skills/pull-work/context/contracts/execution-contract.md +30 -1
  152. package/dist/codex/.agents/skills/review-work/SKILL.md +11 -0
  153. package/dist/codex/.agents/skills/review-work/context/contracts/execution-contract.md +30 -1
  154. package/dist/codex/.agents/skills/standards-authoring/SKILL.md +87 -0
  155. package/dist/codex/.agents/skills/tdd-workflow/context/contracts/execution-contract.md +30 -1
  156. package/dist/codex/.agents/skills/verify-work/context/contracts/execution-contract.md +30 -1
  157. package/dist/codex/.codex/agents/tool-security-reviewer.toml +1 -1
  158. package/dist/codex/build/package.json +1 -1
  159. package/dist/codex/build/src/cli/init.js +35 -3
  160. package/dist/codex/build/src/cli/kit.js +95 -2
  161. package/dist/codex/build/src/cli/pull-work-provider.js +7 -1
  162. package/dist/codex/build/src/cli/validate-workflow-artifacts.js +53 -0
  163. package/dist/codex/build/src/cli/workflow.js +5 -1
  164. package/dist/codex/build/src/flow-kit/provision.d.ts +23 -0
  165. package/dist/codex/build/src/flow-kit/provision.js +99 -0
  166. package/dist/codex/build/src/flow-kit/validate.d.ts +52 -0
  167. package/dist/codex/build/src/flow-kit/validate.js +214 -9
  168. package/dist/codex/build/src/runtime-adapters.js +1 -1
  169. package/dist/codex/context/contracts/execution-contract.md +30 -1
  170. package/dist/codex/context/contracts/review-contract.md +4 -0
  171. package/dist/codex/context/contracts/trigger-guards.md +73 -0
  172. package/dist/codex/context/settings/backlog-provider-settings.json +1 -1
  173. package/dist/codex/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  174. package/dist/codex/docs/adr/0023-kit-provisioning.md +47 -0
  175. package/dist/codex/docs/adr/index.md +1 -0
  176. package/dist/codex/docs/architecture-engine-and-kits.md +17 -0
  177. package/dist/codex/docs/context-map.md +3 -0
  178. package/dist/codex/docs/decisions/backlog-readiness-source.md +89 -0
  179. package/dist/codex/docs/decisions/index.md +1 -0
  180. package/dist/codex/docs/developer-architecture.md +3 -3
  181. package/dist/codex/docs/flow-kit-repository-contract.md +34 -3
  182. package/dist/codex/docs/kit-authoring-guide.md +1 -1
  183. package/dist/codex/docs/veritas-integration.md +12 -0
  184. package/dist/codex/evals/ci/run-baseline.sh +4 -0
  185. package/dist/codex/evals/integration/test_kit_provisioning.sh +112 -0
  186. package/dist/codex/evals/integration/test_pull_work_provider.sh +18 -0
  187. package/dist/codex/evals/integration/test_veritas_governance_kit.sh +256 -0
  188. package/dist/codex/evals/integration/test_workflow_artifacts.sh +257 -0
  189. package/dist/codex/evals/static/test_package.sh +6 -0
  190. package/dist/codex/evals/static/test_workflow_skills.sh +16 -0
  191. package/dist/codex/install.sh +1 -1
  192. package/dist/codex/kits/builder/flows/publish-learn.flow.json +9 -1
  193. package/dist/codex/kits/builder/skills/execute-plan/SKILL.md +4 -3
  194. package/dist/codex/kits/builder/skills/pull-work/SKILL.md +12 -0
  195. package/dist/codex/kits/builder/skills/review-work/SKILL.md +11 -0
  196. package/dist/codex/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  197. package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  198. package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  199. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  200. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  201. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  202. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  203. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  204. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  205. package/dist/codex/kits/veritas-governance/docs/README.md +141 -10
  206. package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  207. package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  208. package/dist/codex/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  209. package/dist/codex/kits/veritas-governance/kit.json +65 -0
  210. package/dist/codex/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  211. package/dist/codex/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  212. package/dist/codex/schemas/backlog-provider-settings.schema.json +1 -1
  213. package/dist/codex/schemas/workflow-waves.schema.json +347 -0
  214. package/dist/codex/scripts/check-layer-boundary.mjs +98 -0
  215. package/dist/kiro/agents/tool-security-reviewer.json +1 -1
  216. package/dist/kiro/build/package.json +1 -1
  217. package/dist/kiro/build/src/cli/init.js +35 -3
  218. package/dist/kiro/build/src/cli/kit.js +95 -2
  219. package/dist/kiro/build/src/cli/pull-work-provider.js +7 -1
  220. package/dist/kiro/build/src/cli/validate-workflow-artifacts.js +53 -0
  221. package/dist/kiro/build/src/cli/workflow.js +5 -1
  222. package/dist/kiro/build/src/flow-kit/provision.d.ts +23 -0
  223. package/dist/kiro/build/src/flow-kit/provision.js +99 -0
  224. package/dist/kiro/build/src/flow-kit/validate.d.ts +52 -0
  225. package/dist/kiro/build/src/flow-kit/validate.js +214 -9
  226. package/dist/kiro/build/src/runtime-adapters.js +1 -1
  227. package/dist/kiro/context/contracts/execution-contract.md +30 -1
  228. package/dist/kiro/context/contracts/review-contract.md +4 -0
  229. package/dist/kiro/context/contracts/trigger-guards.md +73 -0
  230. package/dist/kiro/context/settings/backlog-provider-settings.json +1 -1
  231. package/dist/kiro/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  232. package/dist/kiro/docs/adr/0023-kit-provisioning.md +47 -0
  233. package/dist/kiro/docs/adr/index.md +1 -0
  234. package/dist/kiro/docs/architecture-engine-and-kits.md +17 -0
  235. package/dist/kiro/docs/context-map.md +3 -0
  236. package/dist/kiro/docs/decisions/backlog-readiness-source.md +89 -0
  237. package/dist/kiro/docs/decisions/index.md +1 -0
  238. package/dist/kiro/docs/developer-architecture.md +3 -3
  239. package/dist/kiro/docs/flow-kit-repository-contract.md +34 -3
  240. package/dist/kiro/docs/kit-authoring-guide.md +1 -1
  241. package/dist/kiro/docs/veritas-integration.md +12 -0
  242. package/dist/kiro/evals/ci/run-baseline.sh +4 -0
  243. package/dist/kiro/evals/integration/test_kit_provisioning.sh +112 -0
  244. package/dist/kiro/evals/integration/test_pull_work_provider.sh +18 -0
  245. package/dist/kiro/evals/integration/test_veritas_governance_kit.sh +256 -0
  246. package/dist/kiro/evals/integration/test_workflow_artifacts.sh +257 -0
  247. package/dist/kiro/evals/static/test_package.sh +6 -0
  248. package/dist/kiro/evals/static/test_workflow_skills.sh +16 -0
  249. package/dist/kiro/install.sh +1 -1
  250. package/dist/kiro/kits/builder/flows/publish-learn.flow.json +9 -1
  251. package/dist/kiro/kits/builder/skills/execute-plan/SKILL.md +4 -3
  252. package/dist/kiro/kits/builder/skills/pull-work/SKILL.md +12 -0
  253. package/dist/kiro/kits/builder/skills/review-work/SKILL.md +11 -0
  254. package/dist/kiro/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  255. package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  256. package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  257. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  258. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  259. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  260. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  261. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  262. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  263. package/dist/kiro/kits/veritas-governance/docs/README.md +141 -10
  264. package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  265. package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  266. package/dist/kiro/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  267. package/dist/kiro/kits/veritas-governance/kit.json +65 -0
  268. package/dist/kiro/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  269. package/dist/kiro/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  270. package/dist/kiro/schemas/backlog-provider-settings.schema.json +1 -1
  271. package/dist/kiro/schemas/workflow-waves.schema.json +347 -0
  272. package/dist/kiro/scripts/check-layer-boundary.mjs +98 -0
  273. package/dist/opencode/.opencode/agents/tool-security-reviewer.md +2 -1
  274. package/dist/opencode/.opencode/skills/consult-standards/SKILL.md +73 -0
  275. package/dist/opencode/.opencode/skills/execute-plan/SKILL.md +4 -3
  276. package/dist/opencode/.opencode/skills/pull-work/SKILL.md +12 -0
  277. package/dist/opencode/.opencode/skills/review-work/SKILL.md +11 -0
  278. package/dist/opencode/.opencode/skills/standards-authoring/SKILL.md +87 -0
  279. package/dist/opencode/build/package.json +1 -1
  280. package/dist/opencode/build/src/cli/init.js +35 -3
  281. package/dist/opencode/build/src/cli/kit.js +95 -2
  282. package/dist/opencode/build/src/cli/pull-work-provider.js +7 -1
  283. package/dist/opencode/build/src/cli/validate-workflow-artifacts.js +53 -0
  284. package/dist/opencode/build/src/cli/workflow.js +5 -1
  285. package/dist/opencode/build/src/flow-kit/provision.d.ts +23 -0
  286. package/dist/opencode/build/src/flow-kit/provision.js +99 -0
  287. package/dist/opencode/build/src/flow-kit/validate.d.ts +52 -0
  288. package/dist/opencode/build/src/flow-kit/validate.js +214 -9
  289. package/dist/opencode/build/src/runtime-adapters.js +1 -1
  290. package/dist/opencode/context/contracts/execution-contract.md +30 -1
  291. package/dist/opencode/context/contracts/review-contract.md +4 -0
  292. package/dist/opencode/context/contracts/trigger-guards.md +73 -0
  293. package/dist/opencode/context/settings/backlog-provider-settings.json +1 -1
  294. package/dist/opencode/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  295. package/dist/opencode/docs/adr/0023-kit-provisioning.md +47 -0
  296. package/dist/opencode/docs/adr/index.md +1 -0
  297. package/dist/opencode/docs/architecture-engine-and-kits.md +17 -0
  298. package/dist/opencode/docs/context-map.md +3 -0
  299. package/dist/opencode/docs/decisions/backlog-readiness-source.md +89 -0
  300. package/dist/opencode/docs/decisions/index.md +1 -0
  301. package/dist/opencode/docs/developer-architecture.md +3 -3
  302. package/dist/opencode/docs/flow-kit-repository-contract.md +34 -3
  303. package/dist/opencode/docs/kit-authoring-guide.md +1 -1
  304. package/dist/opencode/docs/veritas-integration.md +12 -0
  305. package/dist/opencode/evals/ci/run-baseline.sh +4 -0
  306. package/dist/opencode/evals/integration/test_kit_provisioning.sh +112 -0
  307. package/dist/opencode/evals/integration/test_pull_work_provider.sh +18 -0
  308. package/dist/opencode/evals/integration/test_veritas_governance_kit.sh +256 -0
  309. package/dist/opencode/evals/integration/test_workflow_artifacts.sh +257 -0
  310. package/dist/opencode/evals/static/test_package.sh +6 -0
  311. package/dist/opencode/evals/static/test_workflow_skills.sh +16 -0
  312. package/dist/opencode/install.sh +1 -1
  313. package/dist/opencode/kits/builder/flows/publish-learn.flow.json +9 -1
  314. package/dist/opencode/kits/builder/skills/execute-plan/SKILL.md +4 -3
  315. package/dist/opencode/kits/builder/skills/pull-work/SKILL.md +12 -0
  316. package/dist/opencode/kits/builder/skills/review-work/SKILL.md +11 -0
  317. package/dist/opencode/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  318. package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  319. package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  320. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  321. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  322. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  323. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  324. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  325. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  326. package/dist/opencode/kits/veritas-governance/docs/README.md +141 -10
  327. package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  328. package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  329. package/dist/opencode/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  330. package/dist/opencode/kits/veritas-governance/kit.json +65 -0
  331. package/dist/opencode/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  332. package/dist/opencode/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  333. package/dist/opencode/schemas/backlog-provider-settings.schema.json +1 -1
  334. package/dist/opencode/schemas/workflow-waves.schema.json +347 -0
  335. package/dist/opencode/scripts/check-layer-boundary.mjs +98 -0
  336. package/dist/pi/.pi/skills/consult-standards/SKILL.md +73 -0
  337. package/dist/pi/.pi/skills/execute-plan/SKILL.md +4 -3
  338. package/dist/pi/.pi/skills/pull-work/SKILL.md +12 -0
  339. package/dist/pi/.pi/skills/review-work/SKILL.md +11 -0
  340. package/dist/pi/.pi/skills/standards-authoring/SKILL.md +87 -0
  341. package/dist/pi/build/package.json +1 -1
  342. package/dist/pi/build/src/cli/init.js +35 -3
  343. package/dist/pi/build/src/cli/kit.js +95 -2
  344. package/dist/pi/build/src/cli/pull-work-provider.js +7 -1
  345. package/dist/pi/build/src/cli/validate-workflow-artifacts.js +53 -0
  346. package/dist/pi/build/src/cli/workflow.js +5 -1
  347. package/dist/pi/build/src/flow-kit/provision.d.ts +23 -0
  348. package/dist/pi/build/src/flow-kit/provision.js +99 -0
  349. package/dist/pi/build/src/flow-kit/validate.d.ts +52 -0
  350. package/dist/pi/build/src/flow-kit/validate.js +214 -9
  351. package/dist/pi/build/src/runtime-adapters.js +1 -1
  352. package/dist/pi/context/contracts/execution-contract.md +30 -1
  353. package/dist/pi/context/contracts/review-contract.md +4 -0
  354. package/dist/pi/context/contracts/trigger-guards.md +73 -0
  355. package/dist/pi/context/settings/backlog-provider-settings.json +1 -1
  356. package/dist/pi/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  357. package/dist/pi/docs/adr/0023-kit-provisioning.md +47 -0
  358. package/dist/pi/docs/adr/index.md +1 -0
  359. package/dist/pi/docs/architecture-engine-and-kits.md +17 -0
  360. package/dist/pi/docs/context-map.md +3 -0
  361. package/dist/pi/docs/decisions/backlog-readiness-source.md +89 -0
  362. package/dist/pi/docs/decisions/index.md +1 -0
  363. package/dist/pi/docs/developer-architecture.md +3 -3
  364. package/dist/pi/docs/flow-kit-repository-contract.md +34 -3
  365. package/dist/pi/docs/kit-authoring-guide.md +1 -1
  366. package/dist/pi/docs/veritas-integration.md +12 -0
  367. package/dist/pi/evals/ci/run-baseline.sh +4 -0
  368. package/dist/pi/evals/integration/test_kit_provisioning.sh +112 -0
  369. package/dist/pi/evals/integration/test_pull_work_provider.sh +18 -0
  370. package/dist/pi/evals/integration/test_veritas_governance_kit.sh +256 -0
  371. package/dist/pi/evals/integration/test_workflow_artifacts.sh +257 -0
  372. package/dist/pi/evals/static/test_package.sh +6 -0
  373. package/dist/pi/evals/static/test_workflow_skills.sh +16 -0
  374. package/dist/pi/install.sh +1 -1
  375. package/dist/pi/kits/builder/flows/publish-learn.flow.json +9 -1
  376. package/dist/pi/kits/builder/skills/execute-plan/SKILL.md +4 -3
  377. package/dist/pi/kits/builder/skills/pull-work/SKILL.md +12 -0
  378. package/dist/pi/kits/builder/skills/review-work/SKILL.md +11 -0
  379. package/dist/pi/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  380. package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  381. package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  382. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  383. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  384. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  385. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  386. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  387. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  388. package/dist/pi/kits/veritas-governance/docs/README.md +141 -10
  389. package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  390. package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  391. package/dist/pi/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  392. package/dist/pi/kits/veritas-governance/kit.json +65 -0
  393. package/dist/pi/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  394. package/dist/pi/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  395. package/dist/pi/schemas/backlog-provider-settings.schema.json +1 -1
  396. package/dist/pi/schemas/workflow-waves.schema.json +347 -0
  397. package/dist/pi/scripts/check-layer-boundary.mjs +98 -0
  398. package/docs/adr/0023-kit-provisioning.md +47 -0
  399. package/docs/adr/index.md +1 -0
  400. package/docs/architecture-engine-and-kits.md +17 -0
  401. package/docs/context-map.md +3 -0
  402. package/docs/decisions/backlog-readiness-source.md +89 -0
  403. package/docs/decisions/index.md +1 -0
  404. package/docs/developer-architecture.md +3 -3
  405. package/docs/flow-kit-repository-contract.md +34 -3
  406. package/docs/kit-authoring-guide.md +1 -1
  407. package/docs/veritas-integration.md +12 -0
  408. package/evals/ci/run-baseline.sh +4 -0
  409. package/evals/integration/test_kit_provisioning.sh +112 -0
  410. package/evals/integration/test_pull_work_provider.sh +18 -0
  411. package/evals/integration/test_veritas_governance_kit.sh +256 -0
  412. package/evals/integration/test_workflow_artifacts.sh +257 -0
  413. package/evals/static/test_package.sh +6 -0
  414. package/evals/static/test_workflow_skills.sh +16 -0
  415. package/kits/builder/flows/publish-learn.flow.json +9 -1
  416. package/kits/builder/skills/execute-plan/SKILL.md +4 -3
  417. package/kits/builder/skills/pull-work/SKILL.md +12 -0
  418. package/kits/builder/skills/review-work/SKILL.md +11 -0
  419. package/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  420. package/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  421. package/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  422. package/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  423. package/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  424. package/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  425. package/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  426. package/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  427. package/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  428. package/kits/veritas-governance/docs/README.md +141 -10
  429. package/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  430. package/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  431. package/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  432. package/kits/veritas-governance/kit.json +65 -0
  433. package/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  434. package/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  435. package/package.json +2 -1
  436. package/schemas/backlog-provider-settings.schema.json +1 -1
  437. package/schemas/workflow-waves.schema.json +347 -0
  438. package/scripts/check-layer-boundary.mjs +98 -0
  439. package/src/cli/builder-flow-runtime.test.mjs +86 -0
  440. package/src/cli/flow-resolver-composition.test.mjs +20 -1
  441. package/src/cli/init.ts +31 -3
  442. package/src/cli/kit-metadata-security.test.mjs +163 -1
  443. package/src/cli/kit-provisioning.test.mjs +122 -0
  444. package/src/cli/kit.ts +83 -2
  445. package/src/cli/pull-work-provider.ts +7 -1
  446. package/src/cli/validate-waves.test.mjs +134 -0
  447. package/src/cli/validate-workflow-artifacts.ts +47 -0
  448. package/src/cli/workflow.ts +7 -1
  449. package/src/flow-kit/provision.ts +118 -0
  450. package/src/flow-kit/validate.ts +233 -10
  451. package/src/runtime-adapters.ts +1 -1
@@ -804,7 +804,13 @@ export function main(argv = process.argv.slice(2)) {
804
804
  const freshness = revisionFreshness(item, freshnessInputs);
805
805
  return { ...item, dependency_impacts: dependencyImpacts(item, resolved), revision_freshness: freshness, readiness: applyFreshnessToReadiness(classify(item, settings, resolved), freshness) };
806
806
  });
807
- console.log(JSON.stringify({ items }, null, 2));
807
+ // A configured BoardProvider is the canonical readiness source (docs/decisions/backlog-readiness-source.md).
808
+ // Reaching this issue-level listing path with a board configured is a bypass that must be loud, never silent.
809
+ const bypassedBoard = asRecord(asRecord(settings.board_provider)?.board);
810
+ const warnings = bypassedBoard
811
+ ? [{ code: "board_provider_bypassed", message: "A BoardProvider is configured but this pass used WorkItemProvider issue-level listing; board-driven selection is the canonical readiness source. Surface this bypass in the pull-work artifact instead of treating issue listing as a silent fallback." }]
812
+ : [];
813
+ console.log(JSON.stringify({ items, warnings }, null, 2));
808
814
  return 0;
809
815
  }
810
816
  // Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
@@ -18,6 +18,7 @@ const sidecarSchemas = {
18
18
  "critique.json": "schemas/workflow-critique.schema.json",
19
19
  "release.json": "schemas/workflow-release.schema.json",
20
20
  "learning.json": "schemas/workflow-learning.schema.json",
21
+ "waves.json": "schemas/workflow-waves.schema.json",
21
22
  };
22
23
  // Runtime coordination records live below a session but are not workflow
23
24
  // sidecars. Recursing into them would validate continuation-driver/state.json
@@ -386,11 +387,63 @@ function validateSidecar(file) {
386
387
  issues.push({ path: file, message: "deploy decision requires post_deploy_checks to be planned or pass" });
387
388
  }
388
389
  }
390
+ if (path.basename(file) === "waves.json") {
391
+ validateWaves(file, value, issues);
392
+ }
389
393
  if (path.basename(file) === "state.json" && value && typeof value === "object" && !Array.isArray(value) && !("branch" in value)) {
390
394
  warnings.push({ path: file, message: "state.json has no branch field (legacy/pre-#289 session) — re-run `ensure-session` to backfill agent/<actor>/<slug>." });
391
395
  }
392
396
  return { issues, warnings };
393
397
  }
398
+ // #663 slice 1: wave-result reconciliation is machine-checkable, not prose. The schema
399
+ // (schemas/workflow-waves.schema.json) validates the shape; these semantic checks enforce the
400
+ // cross-record arithmetic the mini schema engine cannot express: exactly one terminal status
401
+ // record per declared worker, no undeclared reporters, reconciliation counts that match the
402
+ // records, and a `complete` claim that is impossible while any expected worker lacks a
403
+ // worker-landed terminal status. Missing workers must be recorded explicitly as not_reported —
404
+ // a reconciled wave never silently absorbs a dropped worker. Enforcement here is data-level
405
+ // validation only; stop-hook refusal of wave completion is #663 part 3 (slice 2).
406
+ function validateWaves(file, value, issues) {
407
+ const waves = Array.isArray(value?.waves) ? value.waves : [];
408
+ waves.forEach((wave, index) => {
409
+ const loc = `waves.json.waves[${index}]`;
410
+ const expected = Array.isArray(wave?.expected_workers) ? wave.expected_workers : [];
411
+ const results = Array.isArray(wave?.worker_results) ? wave.worker_results : [];
412
+ const expectedIds = expected.map((w) => w?.worker_id).filter((id) => typeof id === "string" && id.length > 0);
413
+ const expectedIdSet = new Set(expectedIds);
414
+ if (expectedIdSet.size !== expectedIds.length)
415
+ issues.push({ path: file, message: `${loc}.expected_workers must declare unique worker_id values` });
416
+ const resultIds = results.map((r) => r?.worker_id).filter((id) => typeof id === "string" && id.length > 0);
417
+ const seen = new Set();
418
+ for (const id of resultIds) {
419
+ if (seen.has(id))
420
+ issues.push({ path: file, message: `${loc}.worker_results has more than one terminal status record for worker ${id}; each worker lands exactly one` });
421
+ seen.add(id);
422
+ if (!expectedIdSet.has(id))
423
+ issues.push({ path: file, message: `${loc}.worker_results records worker ${id} that is not declared in expected_workers; declare every worker in the manifest before dispatch` });
424
+ }
425
+ const reconciliation = wave?.reconciliation;
426
+ if (!reconciliation || typeof reconciliation !== "object" || Array.isArray(reconciliation))
427
+ return;
428
+ const expectedCount = expectedIds.length;
429
+ const reportedIds = new Set(results.filter((r) => ["completed", "failed", "blocked"].includes(r?.status) && expectedIdSet.has(r?.worker_id)).map((r) => r.worker_id));
430
+ const reportedCount = reportedIds.size;
431
+ if (reconciliation.expected_count !== expectedCount)
432
+ issues.push({ path: file, message: `${loc}.reconciliation.expected_count is ${reconciliation.expected_count} but expected_workers declares ${expectedCount}` });
433
+ if (reconciliation.reported_count !== reportedCount)
434
+ issues.push({ path: file, message: `${loc}.reconciliation.reported_count is ${reconciliation.reported_count} but ${reportedCount} of ${expectedCount} expected workers have a worker-landed terminal status (completed|failed|blocked)` });
435
+ const missing = expectedIds.filter((id) => !results.some((r) => r?.worker_id === id));
436
+ for (const id of missing)
437
+ issues.push({ path: file, message: `${loc} is reconciled but worker ${id} has no terminal status record; record it explicitly as not_reported — never silently absorb a missing worker` });
438
+ const notReported = results.filter((r) => r?.status === "not_reported" && expectedIdSet.has(r?.worker_id));
439
+ if (reconciliation.status === "complete" && (missing.length > 0 || notReported.length > 0 || reportedCount !== expectedCount)) {
440
+ issues.push({ path: file, message: `${loc}.reconciliation.status complete requires every expected worker to have a worker-landed terminal status; got ${reportedCount} of ${expectedCount} reported` });
441
+ }
442
+ if (reconciliation.status === "incomplete" && missing.length === 0 && notReported.length === 0 && reportedCount === expectedCount) {
443
+ issues.push({ path: file, message: `${loc}.reconciliation.status incomplete contradicts the records: all ${expectedCount} expected workers reported` });
444
+ }
445
+ });
446
+ }
394
447
  function validateLearningCorrections(file, status, records, issues) {
395
448
  records.forEach((record, index) => {
396
449
  const correction = record?.correction;
@@ -733,7 +733,11 @@ function assertDistinctReviewActor(sessionDir, slug) {
733
733
  const assignment = readActiveAssignment(sessionDir, slug);
734
734
  const caller = resolveCurrentAssignmentActor();
735
735
  if (assignment.actor_key === caller.actorKey) {
736
- throw new Error("workflow critique requires a reviewer identity distinct from the active implementation assignment actor");
736
+ throw new Error("workflow critique requires a reviewer identity distinct from the active implementation assignment actor. " +
737
+ "The reviewer identity is derived from the runtime actor, so an orchestrator that implemented and now reviews " +
738
+ "resolves to the same actor. To record an independent review, run the reviewer under a distinct actor: set " +
739
+ "FLOW_AGENTS_ACTOR=<reviewer-id> on the reviewing process, or run the reviewer in a separate runtime session " +
740
+ "(the runtime session id seeds the actor).");
737
741
  }
738
742
  return caller;
739
743
  }
@@ -0,0 +1,23 @@
1
+ export type ProvisionedFile = {
2
+ id: string;
3
+ target: string;
4
+ };
5
+ export type ProvisionPlanEntry = ProvisionedFile & {
6
+ source: string;
7
+ destination: string;
8
+ };
9
+ export type ProvisionResult = {
10
+ kit_id: string;
11
+ kit_hash?: string;
12
+ files: ProvisionPlanEntry[];
13
+ manifest_path?: string;
14
+ dry_run: boolean;
15
+ };
16
+ export declare class ProvisionConflictError extends Error {
17
+ readonly conflicts: ProvisionPlanEntry[];
18
+ constructor(conflicts: ProvisionPlanEntry[]);
19
+ }
20
+ export declare function provisionKit(kitDir: string, targetDir: string, options?: {
21
+ force?: boolean;
22
+ dryRun?: boolean;
23
+ }): Promise<ProvisionResult>;
@@ -0,0 +1,99 @@
1
+ import * as crypto from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { atomicCopyFile, atomicWriteJson, canonicalProspectivePath, walkFiles } from "../lib/fs.js";
5
+ import { PROVISION_MANIFEST_DIR, assertKitRepository } from "./validate.js";
6
+ export class ProvisionConflictError extends Error {
7
+ conflicts;
8
+ constructor(conflicts) {
9
+ super(`provisioning conflicts with ${conflicts.length} existing destination(s)`);
10
+ this.name = "ProvisionConflictError";
11
+ this.conflicts = conflicts;
12
+ }
13
+ }
14
+ function kitContentHash(kitDir) {
15
+ const hash = crypto.createHash("sha256");
16
+ for (const file of walkFiles(kitDir)) {
17
+ const rel = path.relative(kitDir, file).split(path.sep).join("/");
18
+ if (rel.split("/").some((part) => [".git", "__pycache__", ".pytest_cache"].includes(part)))
19
+ continue;
20
+ hash.update(rel);
21
+ hash.update("\0");
22
+ hash.update(fs.readFileSync(file));
23
+ hash.update("\0");
24
+ }
25
+ return `sha256:${hash.digest("hex")}`;
26
+ }
27
+ function isContained(root, candidate) {
28
+ const relative = path.relative(root, candidate);
29
+ return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
30
+ }
31
+ function assertSafeDestination(rootReal, destination) {
32
+ const prospective = canonicalProspectivePath(destination);
33
+ if (!isContained(rootReal, prospective))
34
+ throw new Error(`provision target escapes consumer repository: ${destination}`);
35
+ if (!fs.existsSync(destination))
36
+ return;
37
+ const stat = fs.lstatSync(destination);
38
+ if (stat.isSymbolicLink())
39
+ throw new Error(`refusing provision target symlink: ${destination}`);
40
+ if (!stat.isFile())
41
+ throw new Error(`provision target is not a regular file: ${destination}`);
42
+ }
43
+ function manifestProvisions(manifest) {
44
+ if (!Array.isArray(manifest.provisions))
45
+ return [];
46
+ return manifest.provisions.map((entry) => {
47
+ const record = entry;
48
+ return {
49
+ id: String(record.id),
50
+ path: String(record.path),
51
+ target: path.posix.normalize(String(record.target).replace(/\\/g, "/")),
52
+ ...(typeof record.description === "string" ? { description: record.description } : {}),
53
+ };
54
+ });
55
+ }
56
+ export async function provisionKit(kitDir, targetDir, options = {}) {
57
+ const kitRoot = fs.realpathSync(path.resolve(kitDir));
58
+ const targetPath = path.resolve(targetDir);
59
+ if (!fs.existsSync(targetPath) || !fs.statSync(targetPath).isDirectory()) {
60
+ throw new Error(`provision target must exist and be a directory: ${targetPath}`);
61
+ }
62
+ const targetRoot = fs.realpathSync(targetPath);
63
+ const manifest = await assertKitRepository(kitRoot);
64
+ const kitId = String(manifest.id);
65
+ const files = manifestProvisions(manifest).map((entry) => ({
66
+ id: entry.id,
67
+ target: entry.target,
68
+ source: path.resolve(kitRoot, entry.path),
69
+ destination: path.resolve(targetRoot, ...entry.target.split("/")),
70
+ }));
71
+ for (const file of files)
72
+ assertSafeDestination(targetRoot, file.destination);
73
+ // Defense in depth against a source swapped to a link after validation: re-assert the
74
+ // link-resolved source stays inside the kit before we read and copy its bytes.
75
+ for (const file of files) {
76
+ const realSource = fs.realpathSync(file.source);
77
+ if (realSource !== kitRoot && !realSource.startsWith(`${kitRoot}${path.sep}`)) {
78
+ throw new Error(`provision source escapes the kit directory: ${file.id}`);
79
+ }
80
+ }
81
+ const conflicts = options.force ? [] : files.filter((file) => fs.existsSync(file.destination));
82
+ if (conflicts.length)
83
+ throw new ProvisionConflictError(conflicts);
84
+ const kitHash = kitContentHash(kitRoot);
85
+ if (options.dryRun || files.length === 0)
86
+ return { kit_id: kitId, kit_hash: kitHash, files, dry_run: Boolean(options.dryRun) };
87
+ const manifestPath = path.join(targetRoot, ...PROVISION_MANIFEST_DIR.split("/"), `${kitId}.json`);
88
+ assertSafeDestination(targetRoot, manifestPath);
89
+ for (const file of files)
90
+ atomicCopyFile(targetRoot, file.source, file.destination);
91
+ atomicWriteJson(targetRoot, manifestPath, {
92
+ schema_version: "1.0",
93
+ kit_id: kitId,
94
+ kit_hash: kitHash,
95
+ provisioned_at: new Date().toISOString(),
96
+ files: files.map(({ id, target }) => ({ id, target })),
97
+ });
98
+ return { kit_id: kitId, kit_hash: kitHash, files, manifest_path: manifestPath, dry_run: false };
99
+ }
@@ -4,6 +4,13 @@ export interface KitDependencyEntry {
4
4
  kit_id: string;
5
5
  reason?: string;
6
6
  }
7
+ export interface KitProvisionEntry {
8
+ id: string;
9
+ path: string;
10
+ target: string;
11
+ description?: string;
12
+ }
13
+ export declare const PROVISION_MANIFEST_DIR = ".kontourai/flow-agents/provisions";
7
14
  export interface KitWorkflowTriggerEntry {
8
15
  id: string;
9
16
  when: string;
@@ -25,6 +32,18 @@ export interface KitHookInfluenceExpectationEntry {
25
32
  must_include_guidance: string[];
26
33
  must_include_actions: string[];
27
34
  }
35
+ export interface KitAgentSpawnTriggerGuards {
36
+ dedup_key: string;
37
+ cooldown_seconds: number;
38
+ daily_cap: number;
39
+ max_concurrent: number;
40
+ }
41
+ export interface KitAgentSpawnTriggerEntry {
42
+ id: string;
43
+ description: string;
44
+ spawns_agent_runs: boolean;
45
+ guards?: KitAgentSpawnTriggerGuards;
46
+ }
28
47
  export type KitSkillRole = "entrypoint" | "profile" | "step" | "shared-primitive" | "extension";
29
48
  export interface KitSkillRoleEntry {
30
49
  skill_id: string;
@@ -61,6 +80,29 @@ export declare function parseKitHookInfluenceExpectations(manifest: Record<strin
61
80
  entries: KitHookInfluenceExpectationEntry[];
62
81
  errors: string[];
63
82
  };
83
+ /**
84
+ * Parse and shape-validate a kit manifest's optional `agent_spawn_triggers` field:
85
+ * perimeter trigger surfaces (check failures, schedules, watchers) that spawn agent
86
+ * runs, plus their guard config. Contract: context/contracts/trigger-guards.md.
87
+ *
88
+ * Shape rules (ERRORS):
89
+ * - `agent_spawn_triggers` (if present) must be an array of objects.
90
+ * - `id` must match the workflow-trigger identifier pattern and be unique.
91
+ * - `description` must be a non-empty string.
92
+ * - `spawns_agent_runs` must be a boolean.
93
+ * - `guards` (if present) must be an object with exactly the four guard fields when
94
+ * complete: `dedup_key` non-empty string; `cooldown_seconds`, `daily_cap`,
95
+ * `max_concurrent` integers >= 1. Unknown guard fields are errors.
96
+ *
97
+ * Guard-completeness (WARNINGS, never errors — declaration-first rollout, #664):
98
+ * - an entry with `spawns_agent_runs: true` and missing or incomplete `guards`
99
+ * produces a warning naming the missing guard fields and the contract doc.
100
+ */
101
+ export declare function parseKitAgentSpawnTriggers(manifest: Record<string, unknown>, manifestPath: string): {
102
+ entries: KitAgentSpawnTriggerEntry[];
103
+ errors: string[];
104
+ warnings: string[];
105
+ };
64
106
  export declare function parseKitSkillRoles(manifest: Record<string, unknown>, manifestPath: string): {
65
107
  entries: KitSkillRoleEntry[];
66
108
  errors: string[];
@@ -126,4 +168,14 @@ export interface KitTargetsResult {
126
168
  */
127
169
  export declare function deriveKitTargets(manifest: Record<string, unknown>, kitDir?: string, sourceRoot?: string): Promise<KitTargetsResult>;
128
170
  export declare function validateKitRepository(kitDir: string): Promise<string[]>;
171
+ /**
172
+ * Repository validation with a non-blocking warnings channel alongside the blocking
173
+ * errors `validateKitRepository` has always returned. Warnings are advisory quality
174
+ * findings (today: an agent-spawning trigger surface declared without complete guard
175
+ * config — context/contracts/trigger-guards.md); they never fail validation.
176
+ */
177
+ export declare function validateKitRepositoryDiagnostics(kitDir: string): Promise<{
178
+ errors: string[];
179
+ warnings: string[];
180
+ }>;
129
181
  export declare function assertKitRepository(kitDir: string): Promise<Record<string, unknown>>;
@@ -5,19 +5,24 @@ import { parseKitFlowStepActions, workflowTriggerIdentifier } from "./action-met
5
5
  import { validateActionRepositoryMetadata } from "./action-repository-validation.js";
6
6
  export { isObservableBuilderArtifactRef, isSafeBuilderArtifactRef, parseKitFlowStepActions } from "./action-metadata.js";
7
7
  // Extension-only asset classes: validated by Flow Agents. Flows are validated by @kontourai/flow.
8
- const EXTENSION_ASSET_CLASSES = ["skills", "docs", "adapters", "evals", "assets"];
8
+ const EXTENSION_ASSET_CLASSES = ["skills", "docs", "adapters", "evals", "assets", "provisions"];
9
9
  // Core container fields owned by kontourai/flow (flow-kit-container.schema.json).
10
10
  // agent-extension fields are skills, docs, adapters, evals, assets.
11
11
  const CORE_CONTAINER_FIELDS = new Set(["schema_version", "id", "name", "description", "product_name", "flows"]);
12
- const AGENT_EXTENSION_CLASSES = new Set(["skills", "docs", "adapters", "evals", "assets"]);
12
+ const AGENT_EXTENSION_CLASSES = new Set(["skills", "docs", "adapters", "evals", "assets", "provisions"]);
13
13
  // Flow Agents-recognized metadata fields that are neither core container fields nor
14
14
  // agent-extension asset classes. Recognized here so they are never misreported as
15
15
  // unknown third-party extension namespaces. `dependencies` declares cross-kit skill
16
16
  // dependencies (extension-layer ownership; see docs/adr/0019-kit-dependency-ownership.md),
17
17
  // workflow_triggers / hook_influence_expectations declare kit-owned runtime influence,
18
- // and first_party is legacy catalog/marketplace metadata. It does not grant runtime
19
- // capability or steering privilege.
20
- const KNOWN_METADATA_FIELDS = new Set(["dependencies", "workflow_triggers", "hook_influence_expectations", "flow_step_actions", "skill_roles", "first_party"]);
18
+ // agent_spawn_triggers declares perimeter trigger surfaces that spawn agent runs plus
19
+ // their guard config (context/contracts/trigger-guards.md), and first_party is legacy
20
+ // catalog/marketplace metadata. It does not grant runtime capability or steering privilege.
21
+ const KNOWN_METADATA_FIELDS = new Set(["dependencies", "workflow_triggers", "hook_influence_expectations", "flow_step_actions", "skill_roles", "first_party", "agent_spawn_triggers"]);
22
+ // Consumer-repo-relative directory (posix, lowercase) where the engine writes its own
23
+ // per-kit provision manifest. Reserved: a provision may not target inside it. Shared with
24
+ // provision.ts so the reservation and the actual manifest write stay in agreement.
25
+ export const PROVISION_MANIFEST_DIR = ".kontourai/flow-agents/provisions";
21
26
  /**
22
27
  * Parse and shape-validate a kit manifest's `dependencies` field (Flow Agents
23
28
  * extension-layer metadata; see docs/adr/0019-kit-dependency-ownership.md).
@@ -221,6 +226,120 @@ export function parseKitHookInfluenceExpectations(manifest, manifestPath) {
221
226
  });
222
227
  return { entries, errors };
223
228
  }
229
+ const AGENT_SPAWN_TRIGGER_GUARD_FIELDS = ["dedup_key", "cooldown_seconds", "daily_cap", "max_concurrent"];
230
+ /**
231
+ * Parse and shape-validate a kit manifest's optional `agent_spawn_triggers` field:
232
+ * perimeter trigger surfaces (check failures, schedules, watchers) that spawn agent
233
+ * runs, plus their guard config. Contract: context/contracts/trigger-guards.md.
234
+ *
235
+ * Shape rules (ERRORS):
236
+ * - `agent_spawn_triggers` (if present) must be an array of objects.
237
+ * - `id` must match the workflow-trigger identifier pattern and be unique.
238
+ * - `description` must be a non-empty string.
239
+ * - `spawns_agent_runs` must be a boolean.
240
+ * - `guards` (if present) must be an object with exactly the four guard fields when
241
+ * complete: `dedup_key` non-empty string; `cooldown_seconds`, `daily_cap`,
242
+ * `max_concurrent` integers >= 1. Unknown guard fields are errors.
243
+ *
244
+ * Guard-completeness (WARNINGS, never errors — declaration-first rollout, #664):
245
+ * - an entry with `spawns_agent_runs: true` and missing or incomplete `guards`
246
+ * produces a warning naming the missing guard fields and the contract doc.
247
+ */
248
+ export function parseKitAgentSpawnTriggers(manifest, manifestPath) {
249
+ const entries = [];
250
+ const errors = [];
251
+ const warnings = [];
252
+ const raw = manifest.agent_spawn_triggers;
253
+ if (raw === undefined)
254
+ return { entries, errors, warnings };
255
+ if (!Array.isArray(raw)) {
256
+ errors.push(`${manifestPath}: .agent_spawn_triggers must be a list`);
257
+ return { entries, errors, warnings };
258
+ }
259
+ const fields = new Set(["id", "description", "spawns_agent_runs", "guards"]);
260
+ const seen = new Set();
261
+ raw.forEach((entry, index) => {
262
+ if (typeof entry !== "object" || entry === null) {
263
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}] must be an object`);
264
+ return;
265
+ }
266
+ const record = entry;
267
+ const unknown = Object.keys(record).filter((field) => !fields.has(field));
268
+ if (unknown.length > 0) {
269
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}] contains unsupported field(s): ${unknown.join(", ")}`);
270
+ return;
271
+ }
272
+ const id = record.id;
273
+ if (!workflowTriggerIdentifier(id)) {
274
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].id must match ^[a-z0-9]+(?:[.-][a-z0-9]+)*$`);
275
+ return;
276
+ }
277
+ if (seen.has(id)) {
278
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].id duplicates '${id}'`);
279
+ return;
280
+ }
281
+ seen.add(id);
282
+ if (typeof record.description !== "string" || !record.description.trim()) {
283
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].description must be a non-empty string`);
284
+ return;
285
+ }
286
+ if (typeof record.spawns_agent_runs !== "boolean") {
287
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].spawns_agent_runs must be a boolean`);
288
+ return;
289
+ }
290
+ let guards;
291
+ let guardsShapeValid = true;
292
+ const missingGuardFields = [];
293
+ if (record.guards !== undefined) {
294
+ if (typeof record.guards !== "object" || record.guards === null || Array.isArray(record.guards)) {
295
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].guards must be an object when present`);
296
+ return;
297
+ }
298
+ const guardRecord = record.guards;
299
+ const guardFieldSet = new Set(AGENT_SPAWN_TRIGGER_GUARD_FIELDS);
300
+ const unknownGuards = Object.keys(guardRecord).filter((field) => !guardFieldSet.has(field));
301
+ if (unknownGuards.length > 0) {
302
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].guards contains unsupported field(s): ${unknownGuards.join(", ")}`);
303
+ return;
304
+ }
305
+ if (guardRecord.dedup_key !== undefined && (typeof guardRecord.dedup_key !== "string" || !guardRecord.dedup_key.trim())) {
306
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].guards.dedup_key must be a non-empty string`);
307
+ guardsShapeValid = false;
308
+ }
309
+ for (const field of ["cooldown_seconds", "daily_cap", "max_concurrent"]) {
310
+ const value = guardRecord[field];
311
+ if (value !== undefined && (typeof value !== "number" || !Number.isInteger(value) || value < 1)) {
312
+ errors.push(`${manifestPath}: agent_spawn_triggers[${index}].guards.${field} must be an integer >= 1`);
313
+ guardsShapeValid = false;
314
+ }
315
+ }
316
+ if (!guardsShapeValid)
317
+ return;
318
+ for (const field of AGENT_SPAWN_TRIGGER_GUARD_FIELDS) {
319
+ if (guardRecord[field] === undefined)
320
+ missingGuardFields.push(field);
321
+ }
322
+ if (missingGuardFields.length === 0) {
323
+ guards = {
324
+ dedup_key: guardRecord.dedup_key,
325
+ cooldown_seconds: guardRecord.cooldown_seconds,
326
+ daily_cap: guardRecord.daily_cap,
327
+ max_concurrent: guardRecord.max_concurrent,
328
+ };
329
+ }
330
+ }
331
+ else {
332
+ missingGuardFields.push(...AGENT_SPAWN_TRIGGER_GUARD_FIELDS);
333
+ }
334
+ if (record.spawns_agent_runs === true && missingGuardFields.length > 0) {
335
+ warnings.push(`${manifestPath}: agent_spawn_triggers[${index}] ('${id}') spawns agent runs without complete guard config` +
336
+ ` (missing: ${missingGuardFields.join(", ")}); declare dedup_key, cooldown_seconds, daily_cap, and max_concurrent` +
337
+ ` per context/contracts/trigger-guards.md`);
338
+ }
339
+ entries.push({ id, description: record.description, spawns_agent_runs: record.spawns_agent_runs, ...(guards ? { guards } : {}) });
340
+ });
341
+ return { entries, errors, warnings };
342
+ }
224
343
  export function parseKitSkillRoles(manifest, manifestPath) {
225
344
  const entries = [];
226
345
  const errors = [];
@@ -393,7 +512,17 @@ export async function deriveKitTargets(manifest, kitDir = "", sourceRoot = proce
393
512
  };
394
513
  }
395
514
  export async function validateKitRepository(kitDir) {
515
+ return (await validateKitRepositoryDiagnostics(kitDir)).errors;
516
+ }
517
+ /**
518
+ * Repository validation with a non-blocking warnings channel alongside the blocking
519
+ * errors `validateKitRepository` has always returned. Warnings are advisory quality
520
+ * findings (today: an agent-spawning trigger surface declared without complete guard
521
+ * config — context/contracts/trigger-guards.md); they never fail validation.
522
+ */
523
+ export async function validateKitRepositoryDiagnostics(kitDir) {
396
524
  const errors = [];
525
+ const warnings = [];
397
526
  const manifestPath = path.join(kitDir, "kit.json");
398
527
  let manifest;
399
528
  try {
@@ -401,14 +530,16 @@ export async function validateKitRepository(kitDir) {
401
530
  }
402
531
  catch (error) {
403
532
  errors.push(`${manifestPath}: invalid JSON: ${error.message}`);
404
- return errors;
533
+ return { errors, warnings };
405
534
  }
406
535
  errors.push(...await delegateCoreContainerValidation(kitDir, manifest));
407
536
  errors.push(...validateExtensionAssets(kitDir, manifestPath, manifest));
408
- errors.push(...validateAgentMetadata(kitDir, manifestPath, manifest));
537
+ const metadata = validateAgentMetadata(kitDir, manifestPath, manifest);
538
+ errors.push(...metadata.errors);
539
+ warnings.push(...metadata.warnings);
409
540
  if (manifest.first_party !== undefined && typeof manifest.first_party !== "boolean")
410
541
  errors.push(`${manifestPath}: .first_party must be a boolean when present`);
411
- return errors;
542
+ return { errors, warnings };
412
543
  }
413
544
  function validateExtensionAssets(kitDir, manifestPath, manifest) {
414
545
  const errors = [];
@@ -429,11 +560,15 @@ function validateExtensionAssets(kitDir, manifestPath, manifest) {
429
560
  const record = entry;
430
561
  const id = record.id;
431
562
  const rel = record.path;
563
+ const kitId = typeof manifest.id === "string" ? manifest.id : "";
432
564
  if (typeof id === "string") {
433
565
  if (seen.has(id))
434
566
  errors.push(`${manifestPath}: ${section}[${index}].id duplicates`);
435
567
  seen.add(id);
436
568
  }
569
+ if (section === "provisions" && (typeof id !== "string" || !kitId || !id.startsWith(`${kitId}.`))) {
570
+ errors.push(`${manifestPath}: provisions[${index}].id must be prefixed with '${kitId}.'`);
571
+ }
437
572
  if (typeof rel !== "string" || !rel) {
438
573
  errors.push(`${manifestPath}: ${section}[${index}].path must be a string`);
439
574
  return;
@@ -442,6 +577,10 @@ function validateExtensionAssets(kitDir, manifestPath, manifest) {
442
577
  errors.push(`${manifestPath}: ${section}[${index}].path must be relative`);
443
578
  return;
444
579
  }
580
+ if (rel.replace(/\\/g, "/").split("/").includes("..")) {
581
+ errors.push(`${manifestPath}: ${section}[${index}].path must not contain traversal segments`);
582
+ return;
583
+ }
445
584
  const resolved = path.resolve(kitDir, rel);
446
585
  const root = path.resolve(kitDir);
447
586
  if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {
@@ -451,12 +590,73 @@ function validateExtensionAssets(kitDir, manifestPath, manifest) {
451
590
  if (!fs.existsSync(resolved)) {
452
591
  errors.push(`${manifestPath}: ${section}[${index}].path points at missing asset: ${rel}`);
453
592
  }
593
+ else if (section === "provisions") {
594
+ if (!fs.statSync(resolved).isFile()) {
595
+ errors.push(`${manifestPath}: provisions[${index}].path must point at a file: ${rel}`);
596
+ }
597
+ else {
598
+ // A provisioned source is copied byte-for-byte into a consumer repo, so a symlink that
599
+ // resolves outside the kit would exfiltrate arbitrary readable host files. Require the
600
+ // link-resolved real path to stay inside the kit.
601
+ const realResolved = fs.realpathSync(resolved);
602
+ const realRoot = fs.realpathSync(root);
603
+ if (realResolved !== realRoot && !realResolved.startsWith(`${realRoot}${path.sep}`)) {
604
+ errors.push(`${manifestPath}: provisions[${index}].path must not resolve outside the kit directory`);
605
+ }
606
+ }
607
+ }
608
+ });
609
+ }
610
+ const rawProvisions = manifest.provisions;
611
+ if (Array.isArray(rawProvisions)) {
612
+ const targets = new Set();
613
+ rawProvisions.forEach((entry, index) => {
614
+ if (typeof entry !== "object" || entry === null)
615
+ return;
616
+ const record = entry;
617
+ if (record.description !== undefined && typeof record.description !== "string") {
618
+ errors.push(`${manifestPath}: provisions[${index}].description must be a string when present`);
619
+ }
620
+ const target = record.target;
621
+ if (typeof target !== "string" || target.trim().length === 0) {
622
+ errors.push(`${manifestPath}: provisions[${index}].target must be a non-empty string`);
623
+ return;
624
+ }
625
+ if (path.isAbsolute(target) || path.win32.isAbsolute(target)) {
626
+ errors.push(`${manifestPath}: provisions[${index}].target must be relative`);
627
+ return;
628
+ }
629
+ const segments = target.replace(/\\/g, "/").split("/");
630
+ if (segments.includes("..")) {
631
+ errors.push(`${manifestPath}: provisions[${index}].target must not contain traversal segments`);
632
+ return;
633
+ }
634
+ const normalized = path.posix.normalize(segments.join("/"));
635
+ if (normalized === "." || normalized.startsWith("..")) {
636
+ errors.push(`${manifestPath}: provisions[${index}].target must stay inside the consumer repository`);
637
+ return;
638
+ }
639
+ // Case-fold reserved-directory and collision checks: on a case-insensitive filesystem
640
+ // `.GIT/` still lands in the real `.git`, and README.md/readme.md still collide.
641
+ const lowered = normalized.toLowerCase();
642
+ if (lowered === ".git" || lowered.startsWith(".git/")) {
643
+ errors.push(`${manifestPath}: provisions[${index}].target must not be inside .git`);
644
+ return;
645
+ }
646
+ if (lowered === PROVISION_MANIFEST_DIR || lowered.startsWith(`${PROVISION_MANIFEST_DIR}/`)) {
647
+ errors.push(`${manifestPath}: provisions[${index}].target must not be inside the provision manifest namespace (${PROVISION_MANIFEST_DIR}/)`);
648
+ return;
649
+ }
650
+ if (targets.has(lowered))
651
+ errors.push(`${manifestPath}: provisions[${index}].target duplicates '${normalized}'`);
652
+ targets.add(lowered);
454
653
  });
455
654
  }
456
655
  return errors;
457
656
  }
458
657
  function validateAgentMetadata(kitDir, manifestPath, manifest) {
459
658
  const errors = [];
659
+ const warnings = [];
460
660
  const depResult = parseKitDependencies(manifest, manifestPath);
461
661
  for (const err of depResult.errors)
462
662
  errors.push(err);
@@ -466,6 +666,11 @@ function validateAgentMetadata(kitDir, manifestPath, manifest) {
466
666
  const hookExpectationResult = parseKitHookInfluenceExpectations(manifest, manifestPath);
467
667
  for (const err of hookExpectationResult.errors)
468
668
  errors.push(err);
669
+ const agentSpawnTriggerResult = parseKitAgentSpawnTriggers(manifest, manifestPath);
670
+ for (const err of agentSpawnTriggerResult.errors)
671
+ errors.push(err);
672
+ for (const warning of agentSpawnTriggerResult.warnings)
673
+ warnings.push(warning);
469
674
  const flowStepActionResult = parseKitFlowStepActions(manifest, manifestPath);
470
675
  for (const err of flowStepActionResult.errors)
471
676
  errors.push(err);
@@ -475,7 +680,7 @@ function validateAgentMetadata(kitDir, manifestPath, manifest) {
475
680
  if ((manifest.skill_roles !== undefined || manifest.flow_step_actions !== undefined) && skillRoleResult.errors.length === 0) {
476
681
  errors.push(...validateActionRepositoryMetadata({ kitDir, manifestPath, manifest, actions: flowStepActionResult.entries, skillRoles: skillRoleResult.entries }));
477
682
  }
478
- return errors;
683
+ return { errors, warnings };
479
684
  }
480
685
  export async function assertKitRepository(kitDir) {
481
686
  const errors = await validateKitRepository(kitDir);
@@ -3,7 +3,7 @@ import * as path from "node:path";
3
3
  import { atomicCopyFile, atomicWriteJson, ensureSafeDirectory, readJson, relPath } from "./lib/fs.js";
4
4
  import { flowAgentsArtifactRoot } from "./lib/local-artifact-root.js";
5
5
  import { parseKitDependencies, parseKitHookInfluenceExpectations, parseKitWorkflowTriggers } from "./flow-kit/validate.js";
6
- const ASSET_CLASSES = ["flows", "skills", "docs", "adapters", "evals", "assets"];
6
+ const ASSET_CLASSES = ["flows", "skills", "docs", "adapters", "evals", "assets", "provisions"];
7
7
  const KIT_ID_RE = /^[a-z][a-z0-9-]*$/;
8
8
  function assetPath(root, value) {
9
9
  if (path.isAbsolute(value))