@kontourai/flow-agents 4.0.0 → 4.2.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 (507) hide show
  1. package/.github/workflows/ci.yml +8 -0
  2. package/CHANGELOG.md +34 -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/scripts/telemetry/lib/config.sh +29 -0
  19. package/context/settings/backlog-provider-settings.json +1 -1
  20. package/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  21. package/dist/base/build/package.json +1 -1
  22. package/dist/base/build/src/cli/init.js +35 -3
  23. package/dist/base/build/src/cli/kit.js +95 -2
  24. package/dist/base/build/src/cli/pull-work-provider.js +7 -1
  25. package/dist/base/build/src/cli/validate-workflow-artifacts.js +53 -0
  26. package/dist/base/build/src/cli/workflow.js +5 -1
  27. package/dist/base/build/src/flow-kit/provision.d.ts +23 -0
  28. package/dist/base/build/src/flow-kit/provision.js +99 -0
  29. package/dist/base/build/src/flow-kit/validate.d.ts +52 -0
  30. package/dist/base/build/src/flow-kit/validate.js +214 -9
  31. package/dist/base/build/src/runtime-adapters.js +1 -1
  32. package/dist/base/context/contracts/execution-contract.md +30 -1
  33. package/dist/base/context/contracts/review-contract.md +4 -0
  34. package/dist/base/context/contracts/trigger-guards.md +73 -0
  35. package/dist/base/context/scripts/telemetry/lib/config.sh +29 -0
  36. package/dist/base/context/settings/backlog-provider-settings.json +1 -1
  37. package/dist/base/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  38. package/dist/base/docs/adr/0023-kit-provisioning.md +47 -0
  39. package/dist/base/docs/adr/index.md +1 -0
  40. package/dist/base/docs/architecture-engine-and-kits.md +17 -0
  41. package/dist/base/docs/context-map.md +3 -0
  42. package/dist/base/docs/decisions/backlog-readiness-source.md +89 -0
  43. package/dist/base/docs/decisions/index.md +1 -0
  44. package/dist/base/docs/developer-architecture.md +3 -3
  45. package/dist/base/docs/flow-kit-repository-contract.md +34 -3
  46. package/dist/base/docs/kit-authoring-guide.md +1 -1
  47. package/dist/base/docs/veritas-integration.md +12 -0
  48. package/dist/base/evals/ci/run-baseline.sh +4 -0
  49. package/dist/base/evals/integration/test_kit_provisioning.sh +112 -0
  50. package/dist/base/evals/integration/test_liveness_console_relay.sh +91 -1
  51. package/dist/base/evals/integration/test_liveness_heartbeat.sh +66 -0
  52. package/dist/base/evals/integration/test_pull_work_provider.sh +18 -0
  53. package/dist/base/evals/integration/test_veritas_governance_kit.sh +256 -0
  54. package/dist/base/evals/integration/test_workflow_artifacts.sh +257 -0
  55. package/dist/base/evals/static/test_package.sh +6 -0
  56. package/dist/base/evals/static/test_workflow_skills.sh +16 -0
  57. package/dist/base/install.sh +1 -1
  58. package/dist/base/kits/builder/flows/publish-learn.flow.json +9 -1
  59. package/dist/base/kits/builder/skills/execute-plan/SKILL.md +4 -3
  60. package/dist/base/kits/builder/skills/pull-work/SKILL.md +12 -0
  61. package/dist/base/kits/builder/skills/review-work/SKILL.md +11 -0
  62. package/dist/base/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  63. package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  64. package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  65. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  66. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  67. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  68. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  69. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  70. package/dist/base/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  71. package/dist/base/kits/veritas-governance/docs/README.md +141 -10
  72. package/dist/base/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  73. package/dist/base/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  74. package/dist/base/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  75. package/dist/base/kits/veritas-governance/kit.json +65 -0
  76. package/dist/base/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  77. package/dist/base/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  78. package/dist/base/schemas/backlog-provider-settings.schema.json +1 -1
  79. package/dist/base/schemas/workflow-waves.schema.json +347 -0
  80. package/dist/base/scripts/check-layer-boundary.mjs +98 -0
  81. package/dist/base/scripts/hooks/claude-telemetry-hook.js +6 -0
  82. package/dist/base/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  83. package/dist/base/scripts/hooks/lib/liveness-write.js +109 -9
  84. package/dist/base/scripts/liveness/relay.sh +23 -11
  85. package/dist/base/scripts/telemetry/lib/config.sh +29 -0
  86. package/dist/catalog.json +2 -0
  87. package/dist/claude-code/.claude/agents/tool-security-reviewer.md +2 -1
  88. package/dist/claude-code/.claude/skills/consult-standards/SKILL.md +73 -0
  89. package/dist/claude-code/.claude/skills/execute-plan/SKILL.md +4 -3
  90. package/dist/claude-code/.claude/skills/pull-work/SKILL.md +12 -0
  91. package/dist/claude-code/.claude/skills/review-work/SKILL.md +11 -0
  92. package/dist/claude-code/.claude/skills/standards-authoring/SKILL.md +87 -0
  93. package/dist/claude-code/build/package.json +1 -1
  94. package/dist/claude-code/build/src/cli/init.js +35 -3
  95. package/dist/claude-code/build/src/cli/kit.js +95 -2
  96. package/dist/claude-code/build/src/cli/pull-work-provider.js +7 -1
  97. package/dist/claude-code/build/src/cli/validate-workflow-artifacts.js +53 -0
  98. package/dist/claude-code/build/src/cli/workflow.js +5 -1
  99. package/dist/claude-code/build/src/flow-kit/provision.d.ts +23 -0
  100. package/dist/claude-code/build/src/flow-kit/provision.js +99 -0
  101. package/dist/claude-code/build/src/flow-kit/validate.d.ts +52 -0
  102. package/dist/claude-code/build/src/flow-kit/validate.js +214 -9
  103. package/dist/claude-code/build/src/runtime-adapters.js +1 -1
  104. package/dist/claude-code/context/contracts/execution-contract.md +30 -1
  105. package/dist/claude-code/context/contracts/review-contract.md +4 -0
  106. package/dist/claude-code/context/contracts/trigger-guards.md +73 -0
  107. package/dist/claude-code/context/scripts/telemetry/lib/config.sh +29 -0
  108. package/dist/claude-code/context/settings/backlog-provider-settings.json +1 -1
  109. package/dist/claude-code/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  110. package/dist/claude-code/docs/adr/0023-kit-provisioning.md +47 -0
  111. package/dist/claude-code/docs/adr/index.md +1 -0
  112. package/dist/claude-code/docs/architecture-engine-and-kits.md +17 -0
  113. package/dist/claude-code/docs/context-map.md +3 -0
  114. package/dist/claude-code/docs/decisions/backlog-readiness-source.md +89 -0
  115. package/dist/claude-code/docs/decisions/index.md +1 -0
  116. package/dist/claude-code/docs/developer-architecture.md +3 -3
  117. package/dist/claude-code/docs/flow-kit-repository-contract.md +34 -3
  118. package/dist/claude-code/docs/kit-authoring-guide.md +1 -1
  119. package/dist/claude-code/docs/veritas-integration.md +12 -0
  120. package/dist/claude-code/evals/ci/run-baseline.sh +4 -0
  121. package/dist/claude-code/evals/integration/test_kit_provisioning.sh +112 -0
  122. package/dist/claude-code/evals/integration/test_liveness_console_relay.sh +91 -1
  123. package/dist/claude-code/evals/integration/test_liveness_heartbeat.sh +66 -0
  124. package/dist/claude-code/evals/integration/test_pull_work_provider.sh +18 -0
  125. package/dist/claude-code/evals/integration/test_veritas_governance_kit.sh +256 -0
  126. package/dist/claude-code/evals/integration/test_workflow_artifacts.sh +257 -0
  127. package/dist/claude-code/evals/static/test_package.sh +6 -0
  128. package/dist/claude-code/evals/static/test_workflow_skills.sh +16 -0
  129. package/dist/claude-code/install.sh +1 -1
  130. package/dist/claude-code/kits/builder/flows/publish-learn.flow.json +9 -1
  131. package/dist/claude-code/kits/builder/skills/execute-plan/SKILL.md +4 -3
  132. package/dist/claude-code/kits/builder/skills/pull-work/SKILL.md +12 -0
  133. package/dist/claude-code/kits/builder/skills/review-work/SKILL.md +11 -0
  134. package/dist/claude-code/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  135. package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  136. package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  137. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  138. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  139. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  140. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  141. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  142. package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  143. package/dist/claude-code/kits/veritas-governance/docs/README.md +141 -10
  144. package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  145. package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  146. package/dist/claude-code/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  147. package/dist/claude-code/kits/veritas-governance/kit.json +65 -0
  148. package/dist/claude-code/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  149. package/dist/claude-code/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  150. package/dist/claude-code/schemas/backlog-provider-settings.schema.json +1 -1
  151. package/dist/claude-code/schemas/workflow-waves.schema.json +347 -0
  152. package/dist/claude-code/scripts/check-layer-boundary.mjs +98 -0
  153. package/dist/claude-code/scripts/hooks/claude-telemetry-hook.js +6 -0
  154. package/dist/claude-code/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  155. package/dist/claude-code/scripts/hooks/lib/liveness-write.js +109 -9
  156. package/dist/claude-code/scripts/liveness/relay.sh +23 -11
  157. package/dist/claude-code/scripts/telemetry/lib/config.sh +29 -0
  158. package/dist/codex/.agents/skills/builder-shape/context/contracts/execution-contract.md +30 -1
  159. package/dist/codex/.agents/skills/consult-standards/SKILL.md +73 -0
  160. package/dist/codex/.agents/skills/deliver/context/contracts/execution-contract.md +30 -1
  161. package/dist/codex/.agents/skills/design-probe/context/contracts/execution-contract.md +30 -1
  162. package/dist/codex/.agents/skills/execute-plan/SKILL.md +4 -3
  163. package/dist/codex/.agents/skills/execute-plan/context/contracts/execution-contract.md +30 -1
  164. package/dist/codex/.agents/skills/fix-bug/context/contracts/execution-contract.md +30 -1
  165. package/dist/codex/.agents/skills/idea-to-backlog/context/contracts/execution-contract.md +30 -1
  166. package/dist/codex/.agents/skills/plan-work/context/contracts/execution-contract.md +30 -1
  167. package/dist/codex/.agents/skills/pull-work/SKILL.md +12 -0
  168. package/dist/codex/.agents/skills/pull-work/context/contracts/execution-contract.md +30 -1
  169. package/dist/codex/.agents/skills/review-work/SKILL.md +11 -0
  170. package/dist/codex/.agents/skills/review-work/context/contracts/execution-contract.md +30 -1
  171. package/dist/codex/.agents/skills/standards-authoring/SKILL.md +87 -0
  172. package/dist/codex/.agents/skills/tdd-workflow/context/contracts/execution-contract.md +30 -1
  173. package/dist/codex/.agents/skills/verify-work/context/contracts/execution-contract.md +30 -1
  174. package/dist/codex/.codex/agents/tool-security-reviewer.toml +1 -1
  175. package/dist/codex/build/package.json +1 -1
  176. package/dist/codex/build/src/cli/init.js +35 -3
  177. package/dist/codex/build/src/cli/kit.js +95 -2
  178. package/dist/codex/build/src/cli/pull-work-provider.js +7 -1
  179. package/dist/codex/build/src/cli/validate-workflow-artifacts.js +53 -0
  180. package/dist/codex/build/src/cli/workflow.js +5 -1
  181. package/dist/codex/build/src/flow-kit/provision.d.ts +23 -0
  182. package/dist/codex/build/src/flow-kit/provision.js +99 -0
  183. package/dist/codex/build/src/flow-kit/validate.d.ts +52 -0
  184. package/dist/codex/build/src/flow-kit/validate.js +214 -9
  185. package/dist/codex/build/src/runtime-adapters.js +1 -1
  186. package/dist/codex/context/contracts/execution-contract.md +30 -1
  187. package/dist/codex/context/contracts/review-contract.md +4 -0
  188. package/dist/codex/context/contracts/trigger-guards.md +73 -0
  189. package/dist/codex/context/scripts/telemetry/lib/config.sh +29 -0
  190. package/dist/codex/context/settings/backlog-provider-settings.json +1 -1
  191. package/dist/codex/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  192. package/dist/codex/docs/adr/0023-kit-provisioning.md +47 -0
  193. package/dist/codex/docs/adr/index.md +1 -0
  194. package/dist/codex/docs/architecture-engine-and-kits.md +17 -0
  195. package/dist/codex/docs/context-map.md +3 -0
  196. package/dist/codex/docs/decisions/backlog-readiness-source.md +89 -0
  197. package/dist/codex/docs/decisions/index.md +1 -0
  198. package/dist/codex/docs/developer-architecture.md +3 -3
  199. package/dist/codex/docs/flow-kit-repository-contract.md +34 -3
  200. package/dist/codex/docs/kit-authoring-guide.md +1 -1
  201. package/dist/codex/docs/veritas-integration.md +12 -0
  202. package/dist/codex/evals/ci/run-baseline.sh +4 -0
  203. package/dist/codex/evals/integration/test_kit_provisioning.sh +112 -0
  204. package/dist/codex/evals/integration/test_liveness_console_relay.sh +91 -1
  205. package/dist/codex/evals/integration/test_liveness_heartbeat.sh +66 -0
  206. package/dist/codex/evals/integration/test_pull_work_provider.sh +18 -0
  207. package/dist/codex/evals/integration/test_veritas_governance_kit.sh +256 -0
  208. package/dist/codex/evals/integration/test_workflow_artifacts.sh +257 -0
  209. package/dist/codex/evals/static/test_package.sh +6 -0
  210. package/dist/codex/evals/static/test_workflow_skills.sh +16 -0
  211. package/dist/codex/install.sh +1 -1
  212. package/dist/codex/kits/builder/flows/publish-learn.flow.json +9 -1
  213. package/dist/codex/kits/builder/skills/execute-plan/SKILL.md +4 -3
  214. package/dist/codex/kits/builder/skills/pull-work/SKILL.md +12 -0
  215. package/dist/codex/kits/builder/skills/review-work/SKILL.md +11 -0
  216. package/dist/codex/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  217. package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  218. package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  219. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  220. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  221. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  222. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  223. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  224. package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  225. package/dist/codex/kits/veritas-governance/docs/README.md +141 -10
  226. package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  227. package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  228. package/dist/codex/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  229. package/dist/codex/kits/veritas-governance/kit.json +65 -0
  230. package/dist/codex/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  231. package/dist/codex/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  232. package/dist/codex/schemas/backlog-provider-settings.schema.json +1 -1
  233. package/dist/codex/schemas/workflow-waves.schema.json +347 -0
  234. package/dist/codex/scripts/check-layer-boundary.mjs +98 -0
  235. package/dist/codex/scripts/hooks/claude-telemetry-hook.js +6 -0
  236. package/dist/codex/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  237. package/dist/codex/scripts/hooks/lib/liveness-write.js +109 -9
  238. package/dist/codex/scripts/liveness/relay.sh +23 -11
  239. package/dist/codex/scripts/telemetry/lib/config.sh +29 -0
  240. package/dist/kiro/agents/tool-security-reviewer.json +1 -1
  241. package/dist/kiro/build/package.json +1 -1
  242. package/dist/kiro/build/src/cli/init.js +35 -3
  243. package/dist/kiro/build/src/cli/kit.js +95 -2
  244. package/dist/kiro/build/src/cli/pull-work-provider.js +7 -1
  245. package/dist/kiro/build/src/cli/validate-workflow-artifacts.js +53 -0
  246. package/dist/kiro/build/src/cli/workflow.js +5 -1
  247. package/dist/kiro/build/src/flow-kit/provision.d.ts +23 -0
  248. package/dist/kiro/build/src/flow-kit/provision.js +99 -0
  249. package/dist/kiro/build/src/flow-kit/validate.d.ts +52 -0
  250. package/dist/kiro/build/src/flow-kit/validate.js +214 -9
  251. package/dist/kiro/build/src/runtime-adapters.js +1 -1
  252. package/dist/kiro/context/contracts/execution-contract.md +30 -1
  253. package/dist/kiro/context/contracts/review-contract.md +4 -0
  254. package/dist/kiro/context/contracts/trigger-guards.md +73 -0
  255. package/dist/kiro/context/scripts/telemetry/lib/config.sh +29 -0
  256. package/dist/kiro/context/settings/backlog-provider-settings.json +1 -1
  257. package/dist/kiro/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  258. package/dist/kiro/docs/adr/0023-kit-provisioning.md +47 -0
  259. package/dist/kiro/docs/adr/index.md +1 -0
  260. package/dist/kiro/docs/architecture-engine-and-kits.md +17 -0
  261. package/dist/kiro/docs/context-map.md +3 -0
  262. package/dist/kiro/docs/decisions/backlog-readiness-source.md +89 -0
  263. package/dist/kiro/docs/decisions/index.md +1 -0
  264. package/dist/kiro/docs/developer-architecture.md +3 -3
  265. package/dist/kiro/docs/flow-kit-repository-contract.md +34 -3
  266. package/dist/kiro/docs/kit-authoring-guide.md +1 -1
  267. package/dist/kiro/docs/veritas-integration.md +12 -0
  268. package/dist/kiro/evals/ci/run-baseline.sh +4 -0
  269. package/dist/kiro/evals/integration/test_kit_provisioning.sh +112 -0
  270. package/dist/kiro/evals/integration/test_liveness_console_relay.sh +91 -1
  271. package/dist/kiro/evals/integration/test_liveness_heartbeat.sh +66 -0
  272. package/dist/kiro/evals/integration/test_pull_work_provider.sh +18 -0
  273. package/dist/kiro/evals/integration/test_veritas_governance_kit.sh +256 -0
  274. package/dist/kiro/evals/integration/test_workflow_artifacts.sh +257 -0
  275. package/dist/kiro/evals/static/test_package.sh +6 -0
  276. package/dist/kiro/evals/static/test_workflow_skills.sh +16 -0
  277. package/dist/kiro/install.sh +1 -1
  278. package/dist/kiro/kits/builder/flows/publish-learn.flow.json +9 -1
  279. package/dist/kiro/kits/builder/skills/execute-plan/SKILL.md +4 -3
  280. package/dist/kiro/kits/builder/skills/pull-work/SKILL.md +12 -0
  281. package/dist/kiro/kits/builder/skills/review-work/SKILL.md +11 -0
  282. package/dist/kiro/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  283. package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  284. package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  285. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  286. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  287. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  288. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  289. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  290. package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  291. package/dist/kiro/kits/veritas-governance/docs/README.md +141 -10
  292. package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  293. package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  294. package/dist/kiro/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  295. package/dist/kiro/kits/veritas-governance/kit.json +65 -0
  296. package/dist/kiro/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  297. package/dist/kiro/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  298. package/dist/kiro/schemas/backlog-provider-settings.schema.json +1 -1
  299. package/dist/kiro/schemas/workflow-waves.schema.json +347 -0
  300. package/dist/kiro/scripts/check-layer-boundary.mjs +98 -0
  301. package/dist/kiro/scripts/hooks/claude-telemetry-hook.js +6 -0
  302. package/dist/kiro/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  303. package/dist/kiro/scripts/hooks/lib/liveness-write.js +109 -9
  304. package/dist/kiro/scripts/liveness/relay.sh +23 -11
  305. package/dist/kiro/scripts/telemetry/lib/config.sh +29 -0
  306. package/dist/opencode/.opencode/agents/tool-security-reviewer.md +2 -1
  307. package/dist/opencode/.opencode/skills/consult-standards/SKILL.md +73 -0
  308. package/dist/opencode/.opencode/skills/execute-plan/SKILL.md +4 -3
  309. package/dist/opencode/.opencode/skills/pull-work/SKILL.md +12 -0
  310. package/dist/opencode/.opencode/skills/review-work/SKILL.md +11 -0
  311. package/dist/opencode/.opencode/skills/standards-authoring/SKILL.md +87 -0
  312. package/dist/opencode/build/package.json +1 -1
  313. package/dist/opencode/build/src/cli/init.js +35 -3
  314. package/dist/opencode/build/src/cli/kit.js +95 -2
  315. package/dist/opencode/build/src/cli/pull-work-provider.js +7 -1
  316. package/dist/opencode/build/src/cli/validate-workflow-artifacts.js +53 -0
  317. package/dist/opencode/build/src/cli/workflow.js +5 -1
  318. package/dist/opencode/build/src/flow-kit/provision.d.ts +23 -0
  319. package/dist/opencode/build/src/flow-kit/provision.js +99 -0
  320. package/dist/opencode/build/src/flow-kit/validate.d.ts +52 -0
  321. package/dist/opencode/build/src/flow-kit/validate.js +214 -9
  322. package/dist/opencode/build/src/runtime-adapters.js +1 -1
  323. package/dist/opencode/context/contracts/execution-contract.md +30 -1
  324. package/dist/opencode/context/contracts/review-contract.md +4 -0
  325. package/dist/opencode/context/contracts/trigger-guards.md +73 -0
  326. package/dist/opencode/context/scripts/telemetry/lib/config.sh +29 -0
  327. package/dist/opencode/context/settings/backlog-provider-settings.json +1 -1
  328. package/dist/opencode/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  329. package/dist/opencode/docs/adr/0023-kit-provisioning.md +47 -0
  330. package/dist/opencode/docs/adr/index.md +1 -0
  331. package/dist/opencode/docs/architecture-engine-and-kits.md +17 -0
  332. package/dist/opencode/docs/context-map.md +3 -0
  333. package/dist/opencode/docs/decisions/backlog-readiness-source.md +89 -0
  334. package/dist/opencode/docs/decisions/index.md +1 -0
  335. package/dist/opencode/docs/developer-architecture.md +3 -3
  336. package/dist/opencode/docs/flow-kit-repository-contract.md +34 -3
  337. package/dist/opencode/docs/kit-authoring-guide.md +1 -1
  338. package/dist/opencode/docs/veritas-integration.md +12 -0
  339. package/dist/opencode/evals/ci/run-baseline.sh +4 -0
  340. package/dist/opencode/evals/integration/test_kit_provisioning.sh +112 -0
  341. package/dist/opencode/evals/integration/test_liveness_console_relay.sh +91 -1
  342. package/dist/opencode/evals/integration/test_liveness_heartbeat.sh +66 -0
  343. package/dist/opencode/evals/integration/test_pull_work_provider.sh +18 -0
  344. package/dist/opencode/evals/integration/test_veritas_governance_kit.sh +256 -0
  345. package/dist/opencode/evals/integration/test_workflow_artifacts.sh +257 -0
  346. package/dist/opencode/evals/static/test_package.sh +6 -0
  347. package/dist/opencode/evals/static/test_workflow_skills.sh +16 -0
  348. package/dist/opencode/install.sh +1 -1
  349. package/dist/opencode/kits/builder/flows/publish-learn.flow.json +9 -1
  350. package/dist/opencode/kits/builder/skills/execute-plan/SKILL.md +4 -3
  351. package/dist/opencode/kits/builder/skills/pull-work/SKILL.md +12 -0
  352. package/dist/opencode/kits/builder/skills/review-work/SKILL.md +11 -0
  353. package/dist/opencode/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  354. package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  355. package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  356. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  357. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  358. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  359. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  360. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  361. package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  362. package/dist/opencode/kits/veritas-governance/docs/README.md +141 -10
  363. package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  364. package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  365. package/dist/opencode/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  366. package/dist/opencode/kits/veritas-governance/kit.json +65 -0
  367. package/dist/opencode/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  368. package/dist/opencode/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  369. package/dist/opencode/schemas/backlog-provider-settings.schema.json +1 -1
  370. package/dist/opencode/schemas/workflow-waves.schema.json +347 -0
  371. package/dist/opencode/scripts/check-layer-boundary.mjs +98 -0
  372. package/dist/opencode/scripts/hooks/claude-telemetry-hook.js +6 -0
  373. package/dist/opencode/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  374. package/dist/opencode/scripts/hooks/lib/liveness-write.js +109 -9
  375. package/dist/opencode/scripts/liveness/relay.sh +23 -11
  376. package/dist/opencode/scripts/telemetry/lib/config.sh +29 -0
  377. package/dist/pi/.pi/skills/consult-standards/SKILL.md +73 -0
  378. package/dist/pi/.pi/skills/execute-plan/SKILL.md +4 -3
  379. package/dist/pi/.pi/skills/pull-work/SKILL.md +12 -0
  380. package/dist/pi/.pi/skills/review-work/SKILL.md +11 -0
  381. package/dist/pi/.pi/skills/standards-authoring/SKILL.md +87 -0
  382. package/dist/pi/build/package.json +1 -1
  383. package/dist/pi/build/src/cli/init.js +35 -3
  384. package/dist/pi/build/src/cli/kit.js +95 -2
  385. package/dist/pi/build/src/cli/pull-work-provider.js +7 -1
  386. package/dist/pi/build/src/cli/validate-workflow-artifacts.js +53 -0
  387. package/dist/pi/build/src/cli/workflow.js +5 -1
  388. package/dist/pi/build/src/flow-kit/provision.d.ts +23 -0
  389. package/dist/pi/build/src/flow-kit/provision.js +99 -0
  390. package/dist/pi/build/src/flow-kit/validate.d.ts +52 -0
  391. package/dist/pi/build/src/flow-kit/validate.js +214 -9
  392. package/dist/pi/build/src/runtime-adapters.js +1 -1
  393. package/dist/pi/context/contracts/execution-contract.md +30 -1
  394. package/dist/pi/context/contracts/review-contract.md +4 -0
  395. package/dist/pi/context/contracts/trigger-guards.md +73 -0
  396. package/dist/pi/context/scripts/telemetry/lib/config.sh +29 -0
  397. package/dist/pi/context/settings/backlog-provider-settings.json +1 -1
  398. package/dist/pi/context/settings/workspace-backlog-provider-settings.example.json +1 -1
  399. package/dist/pi/docs/adr/0023-kit-provisioning.md +47 -0
  400. package/dist/pi/docs/adr/index.md +1 -0
  401. package/dist/pi/docs/architecture-engine-and-kits.md +17 -0
  402. package/dist/pi/docs/context-map.md +3 -0
  403. package/dist/pi/docs/decisions/backlog-readiness-source.md +89 -0
  404. package/dist/pi/docs/decisions/index.md +1 -0
  405. package/dist/pi/docs/developer-architecture.md +3 -3
  406. package/dist/pi/docs/flow-kit-repository-contract.md +34 -3
  407. package/dist/pi/docs/kit-authoring-guide.md +1 -1
  408. package/dist/pi/docs/veritas-integration.md +12 -0
  409. package/dist/pi/evals/ci/run-baseline.sh +4 -0
  410. package/dist/pi/evals/integration/test_kit_provisioning.sh +112 -0
  411. package/dist/pi/evals/integration/test_liveness_console_relay.sh +91 -1
  412. package/dist/pi/evals/integration/test_liveness_heartbeat.sh +66 -0
  413. package/dist/pi/evals/integration/test_pull_work_provider.sh +18 -0
  414. package/dist/pi/evals/integration/test_veritas_governance_kit.sh +256 -0
  415. package/dist/pi/evals/integration/test_workflow_artifacts.sh +257 -0
  416. package/dist/pi/evals/static/test_package.sh +6 -0
  417. package/dist/pi/evals/static/test_workflow_skills.sh +16 -0
  418. package/dist/pi/install.sh +1 -1
  419. package/dist/pi/kits/builder/flows/publish-learn.flow.json +9 -1
  420. package/dist/pi/kits/builder/skills/execute-plan/SKILL.md +4 -3
  421. package/dist/pi/kits/builder/skills/pull-work/SKILL.md +12 -0
  422. package/dist/pi/kits/builder/skills/review-work/SKILL.md +11 -0
  423. package/dist/pi/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  424. package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  425. package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  426. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  427. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  428. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  429. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  430. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  431. package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  432. package/dist/pi/kits/veritas-governance/docs/README.md +141 -10
  433. package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  434. package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  435. package/dist/pi/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  436. package/dist/pi/kits/veritas-governance/kit.json +65 -0
  437. package/dist/pi/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  438. package/dist/pi/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  439. package/dist/pi/schemas/backlog-provider-settings.schema.json +1 -1
  440. package/dist/pi/schemas/workflow-waves.schema.json +347 -0
  441. package/dist/pi/scripts/check-layer-boundary.mjs +98 -0
  442. package/dist/pi/scripts/hooks/claude-telemetry-hook.js +6 -0
  443. package/dist/pi/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  444. package/dist/pi/scripts/hooks/lib/liveness-write.js +109 -9
  445. package/dist/pi/scripts/liveness/relay.sh +23 -11
  446. package/dist/pi/scripts/telemetry/lib/config.sh +29 -0
  447. package/docs/adr/0023-kit-provisioning.md +47 -0
  448. package/docs/adr/index.md +1 -0
  449. package/docs/architecture-engine-and-kits.md +17 -0
  450. package/docs/context-map.md +3 -0
  451. package/docs/decisions/backlog-readiness-source.md +89 -0
  452. package/docs/decisions/index.md +1 -0
  453. package/docs/developer-architecture.md +3 -3
  454. package/docs/flow-kit-repository-contract.md +34 -3
  455. package/docs/kit-authoring-guide.md +1 -1
  456. package/docs/veritas-integration.md +12 -0
  457. package/evals/ci/run-baseline.sh +4 -0
  458. package/evals/integration/test_kit_provisioning.sh +112 -0
  459. package/evals/integration/test_liveness_console_relay.sh +91 -1
  460. package/evals/integration/test_liveness_heartbeat.sh +66 -0
  461. package/evals/integration/test_pull_work_provider.sh +18 -0
  462. package/evals/integration/test_veritas_governance_kit.sh +256 -0
  463. package/evals/integration/test_workflow_artifacts.sh +257 -0
  464. package/evals/static/test_package.sh +6 -0
  465. package/evals/static/test_workflow_skills.sh +16 -0
  466. package/kits/builder/flows/publish-learn.flow.json +9 -1
  467. package/kits/builder/skills/execute-plan/SKILL.md +4 -3
  468. package/kits/builder/skills/pull-work/SKILL.md +12 -0
  469. package/kits/builder/skills/review-work/SKILL.md +11 -0
  470. package/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
  471. package/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
  472. package/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
  473. package/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
  474. package/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
  475. package/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
  476. package/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
  477. package/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
  478. package/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
  479. package/kits/veritas-governance/docs/README.md +141 -10
  480. package/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
  481. package/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
  482. package/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
  483. package/kits/veritas-governance/kit.json +65 -0
  484. package/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
  485. package/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
  486. package/package.json +2 -1
  487. package/schemas/backlog-provider-settings.schema.json +1 -1
  488. package/schemas/workflow-waves.schema.json +347 -0
  489. package/scripts/check-layer-boundary.mjs +98 -0
  490. package/scripts/hooks/claude-telemetry-hook.js +6 -0
  491. package/scripts/hooks/lib/liveness-heartbeat.js +42 -1
  492. package/scripts/hooks/lib/liveness-write.js +109 -9
  493. package/scripts/liveness/relay.sh +23 -11
  494. package/scripts/telemetry/lib/config.sh +29 -0
  495. package/src/cli/builder-flow-runtime.test.mjs +86 -0
  496. package/src/cli/flow-resolver-composition.test.mjs +20 -1
  497. package/src/cli/init.ts +31 -3
  498. package/src/cli/kit-metadata-security.test.mjs +163 -1
  499. package/src/cli/kit-provisioning.test.mjs +122 -0
  500. package/src/cli/kit.ts +83 -2
  501. package/src/cli/pull-work-provider.ts +7 -1
  502. package/src/cli/validate-waves.test.mjs +134 -0
  503. package/src/cli/validate-workflow-artifacts.ts +47 -0
  504. package/src/cli/workflow.ts +7 -1
  505. package/src/flow-kit/provision.ts +118 -0
  506. package/src/flow-kit/validate.ts +233 -10
  507. package/src/runtime-adapters.ts +1 -1
@@ -7,26 +7,36 @@
7
7
  # never forked). The Console side ingests this record type and projects the fleet view + runs the
8
8
  # janitor (console repo #125); this script is only the flow-agents EMIT half.
9
9
  #
10
- # STRICTLY OPTIONAL and local-first (ADR 0012 §5): a no-op unless FLOW_AGENTS_CONSOLE_LIVENESS_RELAY
11
- # is enabled AND a console endpoint is configured. Best-effort throughout it must NEVER block, slow,
12
- # or fail the local liveness write that already happened before this was invoked. Every failure path
13
- # is a quiet `exit 0`.
10
+ # STRICTLY OPTIONAL and local-first (ADR 0012 §5): a no-op unless the liveness relay is enabled AND a
11
+ # console endpoint is configured. Enablement is conf-driven (#567, parity with economics #469): an
12
+ # operator sets `console_liveness_relay=1` in the console conf (or it defaults on once a console url
13
+ # resolves) — NOT an env var. config.sh (sourced below) is the authoritative, trust-gated decision
14
+ # and also supplies the endpoint/token/tenant from the conf. Best-effort throughout — it must NEVER
15
+ # block, slow, or fail the local liveness write that already happened before this was invoked. Every
16
+ # failure path is a quiet `exit 0`.
14
17
  #
15
18
  # Invoked (fully detached, best-effort) from scripts/hooks/lib/liveness-write.js after the durable
16
19
  # local append. Usage: relay.sh '<liveness-event-json>'
17
20
  set -uo pipefail
18
21
 
19
- # Opt-in gate — off by default.
20
- case "${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}" in
21
- 1 | true | TRUE | yes | on) ;;
22
- *) exit 0 ;;
23
- esac
24
-
25
22
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || exit 0
26
23
 
27
24
  # transport.sh sources ${TELEMETRY_DIR}/lib/redact.sh at load — point it at the telemetry lib dir,
28
25
  # then reuse the SAME console POST core the telemetry mirror uses.
29
26
  export TELEMETRY_DIR="${TELEMETRY_DIR:-$SCRIPT_DIR/../telemetry}"
27
+
28
+ # Source config.sh FIRST (best-effort, like economics-record.sh) so the conf resolves enablement
29
+ # (FLOW_AGENTS_CONSOLE_LIVENESS_RELAY) and the endpoint/token/tenant — trust-gated for default-path
30
+ # confs. This is what makes conf-only operation work with NO env var set.
31
+ # shellcheck source=/dev/null
32
+ [[ -f "$TELEMETRY_DIR/lib/config.sh" ]] && source "$TELEMETRY_DIR/lib/config.sh" 2>/dev/null || true
33
+
34
+ # Opt-in gate — off by default, now honoring the conf-derived value config.sh just resolved.
35
+ case "${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}" in
36
+ 1 | true | TRUE | yes | on) ;;
37
+ *) exit 0 ;;
38
+ esac
39
+
30
40
  [[ -f "$TELEMETRY_DIR/lib/transport.sh" ]] || exit 0
31
41
  # shellcheck source=/dev/null
32
42
  source "$TELEMETRY_DIR/lib/transport.sh" 2>/dev/null || exit 0
@@ -73,7 +83,9 @@ record="$(printf '%s' "$event_json" | jq -c '{
73
83
  ttlSeconds: (.ttlSeconds // null),
74
84
  host: (.host // null),
75
85
  branch: (.branch // null),
76
- artifact_dir: (.artifact_dir // .artifactDir // null)
86
+ artifact_dir: (.artifact_dir // .artifactDir // null),
87
+ source: (.source // null),
88
+ activity: (.activity // null)
77
89
  }' 2>/dev/null)" || exit 0
78
90
  [[ -z "$record" || "$record" == "null" ]] && exit 0
79
91
 
@@ -109,6 +109,13 @@ FLOW_AGENTS_CONSOLE_ECONOMICS_ENDPOINT_URL="${FLOW_AGENTS_CONSOLE_ECONOMICS_ENDP
109
109
  # Set (non-empty) only when the config file carries an explicit console_economics_relay key —
110
110
  # distinguishes "operator said 0/1" from "key absent" for the default-on rule below.
111
111
  console_economics_relay_raw=""
112
+ # Liveness relay (#567): same conf-driven, opt-out-not-silent-off shape as economics (#469) so an
113
+ # operator enables the hosted liveness mirror via console_liveness_relay=1 in the conf, NOT an env
114
+ # var/.profile. A caller-pre-set env var is the starting point; the config key overrides it; absent
115
+ # any key the default-on rule below turns it on once a console telemetry sink resolves.
116
+ FLOW_AGENTS_CONSOLE_LIVENESS_RELAY="${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}"
117
+ FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL="${FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL:-}"
118
+ console_liveness_relay_raw=""
112
119
  # Pricing registry source (consumed by lib/pricing.sh). Explicit file/URL win;
113
120
  # otherwise lib/pricing.sh uses the bundled pricing.json offline.
114
121
  TELEMETRY_PRICING_FILE="${TELEMETRY_PRICING_FILE:-${FLOW_AGENTS_PRICING_FILE:-}}"
@@ -164,6 +171,17 @@ if [[ -f "$TELEMETRY_CONFIG_FILE" ]]; then
164
171
  esac
165
172
  ;;
166
173
  console_economics_endpoint_url) FLOW_AGENTS_CONSOLE_ECONOMICS_ENDPOINT_URL="$value" ;;
174
+ console_liveness_relay)
175
+ case "$(echo "$value" | tr '[:upper:]' '[:lower:]')" in
176
+ 1|true|yes|on) console_liveness_relay_raw="1" ;;
177
+ 0|false|no|off) console_liveness_relay_raw="0" ;;
178
+ *)
179
+ printf 'warning: config.sh: unrecognized console_liveness_relay value %q; treating as off\n' "$value" >&2
180
+ console_liveness_relay_raw="$value"
181
+ ;;
182
+ esac
183
+ ;;
184
+ console_liveness_endpoint_url) FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL="$value" ;;
167
185
  console_pricing_url) TELEMETRY_PRICING_URL="$value" ;;
168
186
  pricing_url) TELEMETRY_PRICING_URL="$value" ;;
169
187
  pricing_file) TELEMETRY_PRICING_FILE="$value" ;;
@@ -186,6 +204,17 @@ elif [[ -z "$FLOW_AGENTS_CONSOLE_ECONOMICS_RELAY" \
186
204
  FLOW_AGENTS_CONSOLE_ECONOMICS_RELAY=1
187
205
  fi
188
206
 
207
+ # Liveness relay default-on rule (#567), identical shape to economics above: an explicit
208
+ # console_liveness_relay config key always wins; otherwise, once a console telemetry sink resolves,
209
+ # the relay defaults ON unless a caller already pre-set FLOW_AGENTS_CONSOLE_LIVENESS_RELAY in the
210
+ # environment. relay.sh's own opt-in gate reads this exact variable.
211
+ if [[ -n "$console_liveness_relay_raw" ]]; then
212
+ FLOW_AGENTS_CONSOLE_LIVENESS_RELAY="$console_liveness_relay_raw"
213
+ elif [[ -z "$FLOW_AGENTS_CONSOLE_LIVENESS_RELAY" \
214
+ && ( -n "${CONSOLE_TELEMETRY_URL:-}" || -n "${CONSOLE_TELEMETRY_ENDPOINT_URL:-}" ) ]]; then
215
+ FLOW_AGENTS_CONSOLE_LIVENESS_RELAY=1
216
+ fi
217
+
189
218
  # Pricing URL is explicit-only (env or config). Do not derive the console
190
219
  # pricing endpoint by default; the bundled registry is the reliable offline floor.
191
220
 
@@ -1860,6 +1860,92 @@ test("publish-change reports an external capability gap and self-authored result
1860
1860
  await releaseBuilderFlowAssignment({ sessionDir: session.sessionDir, reason: `test cleanup for ${ambient.actorKey}` });
1861
1861
  });
1862
1862
 
1863
+ async function advanceSessionToPrOpen(session) {
1864
+ await startBuilderFlowSession({ sessionDir: session.sessionDir });
1865
+ const steps = [
1866
+ () => [bundleClaim({ expectation: "selected-work", claimType: "builder.pull-work.selected", subjectType: "work-item" })],
1867
+ () => [
1868
+ bundleClaim({ expectation: "pickup-probe-readiness", claimType: "builder.design-probe.pickup-readiness", subjectType: "work-item" }),
1869
+ bundleClaim({ expectation: "probe-decisions-or-accepted-gaps", claimType: "builder.design-probe.decisions", subjectType: "decision" }),
1870
+ ],
1871
+ () => [bundleClaim({ expectation: "implementation-plan", claimType: "builder.plan.implementation", subjectType: "artifact" })],
1872
+ () => [bundleClaim({ expectation: "implementation-scope", claimType: "builder.execute.scope", subjectType: "change" })],
1873
+ () => [bundleClaim({ expectation: "tests-evidence", claimType: "builder.verify.tests", subjectType: "flow-step" }), ...verifiedTestsPrerequisites(session)],
1874
+ () => [bundleClaim({ expectation: "merge-readiness", claimType: "builder.merge-ready.readiness", subjectType: "change" })],
1875
+ ];
1876
+ let latest = null;
1877
+ for (const entries of steps) latest = await writeAndSync(session, entries());
1878
+ assert.equal(latest.run.state.current_step, "pr-open");
1879
+ return latest;
1880
+ }
1881
+
1882
+ test("pr-open route-back with missing_evidence returns the run to verify and supports repair re-entry (#695 item a)", async () => {
1883
+ const session = makeSession("propen-routeback");
1884
+ await advanceSessionToPrOpen(session);
1885
+
1886
+ // The #663 wedge scenario: a trust divergence is discovered at pr-open. A failing
1887
+ // pull-request-opened claim declaring the missing_evidence route reason must land
1888
+ // the canonical run back at verify — the sanctioned repair surface — not throw.
1889
+ const failureTimestamp = new Date().toISOString();
1890
+ const routed = await writeAndSync(session, [bundleClaim({
1891
+ expectation: "pull-request-opened",
1892
+ claimType: "builder.pr-open.pull-request",
1893
+ subjectType: "pull-request",
1894
+ status: "fail",
1895
+ routeReason: "missing_evidence",
1896
+ timestamp: failureTimestamp,
1897
+ })]);
1898
+
1899
+ assert.equal(routed.attached, true);
1900
+ assert.equal(routed.run.state.current_step, "verify");
1901
+ const routeBacks = routed.run.state.transitions.filter((transition) => transition.type === "route_back");
1902
+ assert.equal(routeBacks.length, 1);
1903
+ assert.equal(routeBacks[0].from_step, "pr-open");
1904
+ assert.equal(routeBacks[0].to_step, "verify");
1905
+ assert.equal(routeBacks[0].route_reason, "missing_evidence");
1906
+ assert.equal(routeBacks[0].gate_id, "builder.publish-learn:pr-open-gate");
1907
+ assert.equal(routed.projection.flow_run.route_back_attempt, 1);
1908
+ assert.equal(routed.projection.flow_run.route_back_max_attempts, 3);
1909
+ assert.match(routed.projection.next_action.summary, /Route-back history: attempt 1\/3 returned to `verify` for `missing_evidence`/);
1910
+
1911
+ // Repair loop: fresh verify evidence re-passes verify, fresh merge-readiness
1912
+ // re-passes merge-ready, and the run returns to pr-open.
1913
+ const repairedAt = new Date(Date.parse(routed.run.state.transitions.at(-1).at) + 1).toISOString();
1914
+ const reverified = await writeAndSync(session, [
1915
+ withIdentitySuffix(bundleClaim({ expectation: "tests-evidence", claimType: "builder.verify.tests", subjectType: "flow-step", timestamp: repairedAt }), "repair"),
1916
+ ...verifiedTestsPrerequisites(session, repairedAt).map((entry, index) => withIdentitySuffix(entry, `repair-${index}`)),
1917
+ ]);
1918
+ assert.equal(reverified.run.state.current_step, "merge-ready");
1919
+ const returned = await writeAndSync(session, [
1920
+ withIdentitySuffix(bundleClaim({ expectation: "merge-readiness", claimType: "builder.merge-ready.readiness", subjectType: "change", timestamp: new Date().toISOString() }), "repair"),
1921
+ ]);
1922
+ assert.equal(returned.run.state.current_step, "pr-open");
1923
+ });
1924
+
1925
+ test("pr-open route-back with an undeclared reason still throws and mutates nothing", async () => {
1926
+ const session = makeSession("propen-undeclared-reason");
1927
+ await advanceSessionToPrOpen(session);
1928
+
1929
+ const flowDirectory = runDir(session.slug, session.projectRoot);
1930
+ const beforeState = readJson(path.join(flowDirectory, "state.json"));
1931
+ const beforeManifest = readJson(path.join(flowDirectory, FLOW_RUN_EVIDENCE_MANIFEST_PATH));
1932
+
1933
+ writeBundle(session.sessionDir, [bundleClaim({
1934
+ expectation: "pull-request-opened",
1935
+ claimType: "builder.pr-open.pull-request",
1936
+ subjectType: "pull-request",
1937
+ status: "fail",
1938
+ routeReason: "stale_critique",
1939
+ timestamp: new Date().toISOString(),
1940
+ })]);
1941
+ await assert.rejects(
1942
+ () => syncBuilderFlowSession({ sessionDir: session.sessionDir }),
1943
+ /route_reason.*is not declared by gate builder\.publish-learn:pr-open-gate/,
1944
+ );
1945
+ assert.deepEqual(readJson(path.join(flowDirectory, "state.json")), beforeState);
1946
+ assert.deepEqual(readJson(path.join(flowDirectory, FLOW_RUN_EVIDENCE_MANIFEST_PATH)), beforeManifest);
1947
+ });
1948
+
1863
1949
  test("recovery loads the slug-bound run, restores every matching projection, and preserves every Flow byte", async () => {
1864
1950
  const session = makeSession("recover-active");
1865
1951
  await startBuilderFlowSession({ sessionDir: session.sessionDir });
@@ -4,7 +4,9 @@ import fs from "node:fs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
 
7
- import { resolveEffectiveFlowDefinition, resolveFlowFilePath } from "../../build/src/lib/flow-resolver.js";
7
+ import { validateDefinition } from "@kontourai/flow";
8
+
9
+ import { resolveEffectiveFlowDefinition, resolveFlowFilePath, resolveFlowStep } from "../../build/src/lib/flow-resolver.js";
8
10
 
9
11
  const REPO_ROOT = path.resolve(import.meta.dirname, "../..");
10
12
 
@@ -26,6 +28,23 @@ test("effective Builder definition materializes uses_flow and Flow-native comple
26
28
  );
27
29
  });
28
30
 
31
+ test("composed pr-open-gate declares the missing_evidence repair route to verify (#695 item a)", () => {
32
+ const definition = resolveEffectiveFlowDefinition("builder.build", REPO_ROOT);
33
+ assert.ok(definition);
34
+ const gate = definition.gates["builder.publish-learn:pr-open-gate"];
35
+ assert.deepEqual(gate.on_route_back, { missing_evidence: "verify", default: "verify" });
36
+ assert.deepEqual(gate.route_back_policy, { max_attempts: 3, on_exceeded: "block" });
37
+ // Every declared route-back target must exist in the EFFECTIVE step set — the
38
+ // composed definition (where `verify` lives) must stay a valid Flow definition.
39
+ assert.doesNotThrow(() => validateDefinition(definition));
40
+ // The live resolver surfaces the declared reasons at the composed step, which is
41
+ // what record-gate-claim's --route-reason validation reads.
42
+ const step = resolveFlowStep("builder.build", "pr-open", REPO_ROOT);
43
+ assert.ok(step);
44
+ assert.equal(step.gateId, "builder.publish-learn:pr-open-gate");
45
+ assert.deepEqual([...step.routeBackReasons].sort(), ["default", "missing_evidence"]);
46
+ });
47
+
29
48
  test("installed package definitions resolve when a consumer repo has no kits directory", () => {
30
49
  const consumer = fs.mkdtempSync(path.join(os.tmpdir(), "flow-agents-consumer-"));
31
50
  const resolved = resolveFlowFilePath("builder", "build", "builder.build", consumer, false);
package/src/cli/init.ts CHANGED
@@ -8,6 +8,7 @@ import { createInterface } from "node:readline/promises";
8
8
  import { stdin as input, stdout as output } from "node:process";
9
9
  import { parseArgs, flagBool, flagList, flagString } from "../lib/args.js";
10
10
  import { activateCodexLocal } from "../runtime-adapters.js";
11
+ import { provisionKit, ProvisionConflictError } from "../flow-kit/provision.js";
11
12
  import { main as buildBundles } from "../tools/build-universal-bundles.js";
12
13
  import { root } from "../tools/common.js";
13
14
  import { defaultCodexHome, durableInstallRecordPath, skillsManifestPath } from "../lib/local-artifact-root.js";
@@ -640,7 +641,21 @@ function installBundle(bundle: string, options: InitOptions): number {
640
641
  return result.status ?? 1;
641
642
  }
642
643
 
643
- function activateKits(options: InitOptions): number {
644
+ function kitPathForInit(kitId: string, dest: string): string | null {
645
+ const catalogPath = path.join(root, "kits", "catalog.json");
646
+ if (fs.existsSync(catalogPath)) {
647
+ const catalog = JSON.parse(fs.readFileSync(catalogPath, "utf8")) as { kits?: unknown[] };
648
+ const entry = Array.isArray(catalog.kits)
649
+ ? catalog.kits.find((item) => typeof item === "object" && item !== null && (item as Record<string, unknown>).id === kitId)
650
+ : undefined;
651
+ const rel = entry && typeof entry === "object" ? (entry as Record<string, unknown>).path : undefined;
652
+ if (typeof rel === "string") return path.resolve(root, rel);
653
+ }
654
+ const installed = path.join(dest, "kits", "local", "repositories", kitId);
655
+ return fs.existsSync(installed) ? installed : null;
656
+ }
657
+
658
+ async function activateKits(options: InitOptions): Promise<number> {
644
659
  const activeKitIds = options.activeKitIds ?? [];
645
660
  if (!options.activateKits || activeKitIds.length === 0 || options.runtime !== "codex") return 0;
646
661
  const result = activateCodexLocal(options.dest, options.dest, { kitIdFilter: activeKitIds });
@@ -650,6 +665,19 @@ function activateKits(options: InitOptions): number {
650
665
  }
651
666
  const generated = Array.isArray(result.generated_runtime_files) ? result.generated_runtime_files : [];
652
667
  console.log(`Activated ${generated.length} Codex local runtime asset(s)`);
668
+ for (const kitId of activeKitIds) {
669
+ const kitDir = kitPathForInit(kitId, options.dest);
670
+ if (!kitDir) throw new Error(`activated kit '${kitId}' could not be resolved for provisioning`);
671
+ try {
672
+ const provisioned = await provisionKit(kitDir, options.dest);
673
+ if (provisioned.files.length > 0) console.log(`Provisioned ${provisioned.files.length} file(s) from kit '${kitId}'`);
674
+ } catch (error) {
675
+ if (!(error instanceof ProvisionConflictError)) throw error;
676
+ for (const conflict of error.conflicts) {
677
+ console.warn(`flow-agents init: warning: skipped existing provision '${conflict.target}' from kit '${kitId}'`);
678
+ }
679
+ }
680
+ }
653
681
  return 0;
654
682
  }
655
683
 
@@ -867,7 +895,7 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
867
895
  const installed = result.status ?? 1;
868
896
  if (installed !== 0) return installed;
869
897
  writeInstallRecord(options.dest, "codex", true, options.activeKitIds ?? []);
870
- return activateKits(options);
898
+ return await activateKits(options);
871
899
  }
872
900
  // --global for pi: NOT_VERIFIED (no documented global dir). Warn and fall through to workspace install.
873
901
  if (options.global && options.runtime === "pi") {
@@ -881,7 +909,7 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
881
909
  const installed = installBundle(bundle, options);
882
910
  if (installed !== 0) return installed;
883
911
  writeInstallRecord(options.dest, options.runtime, options.global, options.activeKitIds ?? []);
884
- const activated = activateKits(options);
912
+ const activated = await activateKits(options);
885
913
  // G2/G3: shared post-install auto-verify + summary tail. Applies
886
914
  // identically whether main() reached here via headlessOptions() or
887
915
  // interactiveOptions() -- never changes `activated`'s exit code.
@@ -7,7 +7,7 @@ import { createRequire, syncBuiltinESMExports } from "node:module";
7
7
 
8
8
  import { readKitInventory } from "../../build/src/runtime-adapters.js";
9
9
  import { main as validateHookInfluence } from "../../build/src/cli/validate-hook-influence.js";
10
- import { parseKitFlowStepActions, parseKitSkillRoles, validateKitRepository } from "../../build/src/flow-kit/validate.js";
10
+ import { parseKitAgentSpawnTriggers, parseKitFlowStepActions, parseKitSkillRoles, validateKitRepository, validateKitRepositoryDiagnostics } from "../../build/src/flow-kit/validate.js";
11
11
  import { observeBuilderArtifactsForProgress } from "../../build/src/builder-gate-action-envelope.js";
12
12
 
13
13
  const require = createRequire(import.meta.url);
@@ -908,3 +908,165 @@ test("workflowTriggersFor returns Knowledge's structured capture trigger", () =>
908
908
  assert.match(trigger.steering, /Keep the session on `knowledge\.ingest`/);
909
909
  assert.match(trigger.steering, /unsupported-runtime blocker/);
910
910
  });
911
+
912
+ test("agent spawn trigger metadata accepts a fully guarded declaration without errors or warnings", () => {
913
+ const result = parseKitAgentSpawnTriggers({
914
+ agent_spawn_triggers: [
915
+ {
916
+ id: "on-check-failure",
917
+ description: "Escalates failing checks to a headless agent run.",
918
+ spawns_agent_runs: true,
919
+ guards: { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 },
920
+ },
921
+ {
922
+ id: "notify-only",
923
+ description: "Fires a notification; never spawns agent runs.",
924
+ spawns_agent_runs: false,
925
+ },
926
+ ],
927
+ }, "fixture/kit.json");
928
+
929
+ assert.deepEqual(result.errors, []);
930
+ assert.deepEqual(result.warnings, []);
931
+ assert.equal(result.entries.length, 2);
932
+ assert.deepEqual(result.entries[0].guards, { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 });
933
+ assert.equal(result.entries[1].guards, undefined);
934
+ });
935
+
936
+ test("agent spawn trigger without guards warns (never errors) when it spawns agent runs", () => {
937
+ const missing = parseKitAgentSpawnTriggers({
938
+ agent_spawn_triggers: [
939
+ { id: "on-schedule", description: "Scheduled automation spawning agent runs.", spawns_agent_runs: true },
940
+ ],
941
+ }, "fixture/kit.json");
942
+ assert.deepEqual(missing.errors, []);
943
+ assert.equal(missing.warnings.length, 1);
944
+ assert.match(missing.warnings[0], /agent_spawn_triggers\[0\] \('on-schedule'\) spawns agent runs without complete guard config/);
945
+ assert.match(missing.warnings[0], /missing: dedup_key, cooldown_seconds, daily_cap, max_concurrent/);
946
+ assert.match(missing.warnings[0], /context\/contracts\/trigger-guards\.md/);
947
+ assert.equal(missing.entries.length, 1);
948
+
949
+ const incomplete = parseKitAgentSpawnTriggers({
950
+ agent_spawn_triggers: [
951
+ { id: "on-check-failure", description: "Escalation.", spawns_agent_runs: true, guards: { cooldown_seconds: 900 } },
952
+ ],
953
+ }, "fixture/kit.json");
954
+ assert.deepEqual(incomplete.errors, []);
955
+ assert.equal(incomplete.warnings.length, 1);
956
+ assert.match(incomplete.warnings[0], /missing: dedup_key, daily_cap, max_concurrent/);
957
+
958
+ const nonSpawning = parseKitAgentSpawnTriggers({
959
+ agent_spawn_triggers: [
960
+ { id: "notify-only", description: "Notification only.", spawns_agent_runs: false },
961
+ ],
962
+ }, "fixture/kit.json");
963
+ assert.deepEqual(nonSpawning.errors, []);
964
+ assert.deepEqual(nonSpawning.warnings, []);
965
+ });
966
+
967
+ test("agent spawn trigger metadata rejects malformed shapes as errors", () => {
968
+ const notAList = parseKitAgentSpawnTriggers({ agent_spawn_triggers: {} }, "fixture/kit.json");
969
+ assert.match(notAList.errors.join("\n"), /\.agent_spawn_triggers must be a list/);
970
+
971
+ const result = parseKitAgentSpawnTriggers({
972
+ agent_spawn_triggers: [
973
+ { id: "Bad Id", description: "x", spawns_agent_runs: true },
974
+ { id: "dup", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 } },
975
+ { id: "dup", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 } },
976
+ { id: "no-description", spawns_agent_runs: true },
977
+ { id: "no-boolean", description: "x", spawns_agent_runs: "yes" },
978
+ { id: "bad-guards", description: "x", spawns_agent_runs: true, guards: [] },
979
+ { id: "bad-guard-values", description: "x", spawns_agent_runs: true, guards: { dedup_key: " ", cooldown_seconds: 0, daily_cap: 1.5, max_concurrent: -1 } },
980
+ { id: "unknown-guard", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1, burst: 5 } },
981
+ { id: "unknown-field", description: "x", spawns_agent_runs: true, command: "private-bypass" },
982
+ ],
983
+ }, "fixture/kit.json");
984
+
985
+ const errors = result.errors.join("\n");
986
+ assert.match(errors, /agent_spawn_triggers\[0\]\.id must match/);
987
+ assert.match(errors, /agent_spawn_triggers\[2\]\.id duplicates 'dup'/);
988
+ assert.match(errors, /agent_spawn_triggers\[3\]\.description must be a non-empty string/);
989
+ assert.match(errors, /agent_spawn_triggers\[4\]\.spawns_agent_runs must be a boolean/);
990
+ assert.match(errors, /agent_spawn_triggers\[5\]\.guards must be an object/);
991
+ assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.dedup_key must be a non-empty string/);
992
+ assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.cooldown_seconds must be an integer >= 1/);
993
+ assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.daily_cap must be an integer >= 1/);
994
+ assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.max_concurrent must be an integer >= 1/);
995
+ assert.match(errors, /agent_spawn_triggers\[7\]\.guards contains unsupported field\(s\): burst/);
996
+ assert.match(errors, /agent_spawn_triggers\[8\] contains unsupported field\(s\): command/);
997
+ // Malformed entries fail shape validation; only the first 'dup' entry (valid shape) parses.
998
+ assert.equal(result.entries.length, 1);
999
+ // Shape violations are errors, never demoted to the guard-completeness warning channel.
1000
+ assert.deepEqual(result.warnings, []);
1001
+ });
1002
+
1003
+ test("kit repository diagnostics carry the guardless-spawn warning and never leak it into errors", async () => {
1004
+ const root = tempRoot("flow-agents-agent-spawn-trigger-repo-");
1005
+ const kit = path.join(root, "builder");
1006
+ fs.cpSync("kits/builder", kit, { recursive: true });
1007
+ const manifestFile = path.join(kit, "kit.json");
1008
+ const manifest = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
1009
+ manifest.agent_spawn_triggers = [
1010
+ { id: "on-check-failure", description: "Escalates failing checks to a headless agent run.", spawns_agent_runs: true },
1011
+ ];
1012
+ writeJson(manifestFile, manifest);
1013
+
1014
+ const diagnostics = await validateKitRepositoryDiagnostics(kit);
1015
+ assert.deepEqual(diagnostics.errors, []);
1016
+ assert.equal(diagnostics.warnings.length, 1);
1017
+ assert.match(diagnostics.warnings[0], /spawns agent runs without complete guard config/);
1018
+ // validateKitRepository keeps its errors-only contract: a warning is not an error.
1019
+ assert.deepEqual(await validateKitRepository(kit), []);
1020
+
1021
+ // A fully guarded declaration is clean on both channels.
1022
+ manifest.agent_spawn_triggers[0].guards = { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 };
1023
+ writeJson(manifestFile, manifest);
1024
+ const guarded = await validateKitRepositoryDiagnostics(kit);
1025
+ assert.deepEqual(guarded.errors, []);
1026
+ assert.deepEqual(guarded.warnings, []);
1027
+
1028
+ // agent_spawn_triggers is recognized Flow Agents metadata, not a third-party namespace.
1029
+ const { deriveKitTargets } = await import("../../build/src/flow-kit/validate.js");
1030
+ const targets = await deriveKitTargets(manifest, kit);
1031
+ assert.deepEqual(targets.third_party_extensions, []);
1032
+ });
1033
+
1034
+ test("kit install surfaces the guardless-spawn warning non-blockingly for BOTH source forms (local path and git URL)", async () => {
1035
+ const { execFileSync } = await import("node:child_process");
1036
+ const root = tempRoot("flow-agents-agent-spawn-trigger-install-");
1037
+ const kitSource = path.join(root, "guarded-kit");
1038
+ fs.mkdirSync(path.join(kitSource, "flows"), { recursive: true });
1039
+ writeJson(path.join(kitSource, "kit.json"), {
1040
+ schema_version: "1.0",
1041
+ id: "guardless-demo",
1042
+ name: "Guardless Demo Kit",
1043
+ flows: [{ id: "demo.flow", path: "flows/demo.flow.json" }],
1044
+ agent_spawn_triggers: [
1045
+ { id: "on-check-failure", description: "Escalates failing checks to a headless agent run.", spawns_agent_runs: true },
1046
+ ],
1047
+ });
1048
+ writeJson(path.join(kitSource, "flows", "demo.flow.json"), {
1049
+ id: "demo.flow",
1050
+ version: "1.0",
1051
+ steps: [{ id: "only", next: null }],
1052
+ gates: {},
1053
+ });
1054
+ const cli = path.resolve("build/src/cli.js");
1055
+ const runInstall = (source, destName) => {
1056
+ return execFileSync(process.execPath, [cli, "kit", "install", source, "--dest", path.join(root, destName)], { encoding: "utf8" });
1057
+ };
1058
+
1059
+ // Local-path source form.
1060
+ const localOut = runInstall(kitSource, "dest-local");
1061
+ assert.match(localOut, /warning: .*agent_spawn_triggers\[0\] \('on-check-failure'\) spawns agent runs without complete guard config/);
1062
+ assert.match(localOut, /installed local kit 'guardless-demo'/);
1063
+
1064
+ // Git-URL source form (file:// clone of the same kit).
1065
+ const git = (args, cwd) => execFileSync("git", ["-c", "user.email=kit-test@example.invalid", "-c", "user.name=kit-test", ...args], { cwd, encoding: "utf8" });
1066
+ git(["init", "--quiet"], kitSource);
1067
+ git(["add", "-A"], kitSource);
1068
+ git(["commit", "--quiet", "-m", "kit fixture"], kitSource);
1069
+ const gitOut = runInstall(`file://${kitSource}`, "dest-git");
1070
+ assert.match(gitOut, /warning: .*agent_spawn_triggers\[0\] \('on-check-failure'\) spawns agent runs without complete guard config/);
1071
+ assert.match(gitOut, /installed git kit 'guardless-demo'/);
1072
+ });
@@ -0,0 +1,122 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { spawnSync } from "node:child_process";
7
+
8
+ import { validateKitRepository } from "../../build/src/flow-kit/validate.js";
9
+ import { provisionKit, ProvisionConflictError } from "../../build/src/flow-kit/provision.js";
10
+
11
+ const FLOW = {
12
+ id: "fixture.review",
13
+ version: "1.0",
14
+ steps: [{ id: "review", next: "done" }, { id: "done", next: null }],
15
+ gates: {},
16
+ };
17
+
18
+ function fixture(provisions) {
19
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-unit-"));
20
+ fs.mkdirSync(path.join(dir, "flows"));
21
+ fs.mkdirSync(path.join(dir, "payload"));
22
+ fs.writeFileSync(path.join(dir, "flows", "review.flow.json"), JSON.stringify(FLOW));
23
+ fs.writeFileSync(path.join(dir, "payload", "one.txt"), "one-new\n");
24
+ fs.writeFileSync(path.join(dir, "payload", "two.txt"), "two-new\n");
25
+ fs.writeFileSync(path.join(dir, "kit.json"), JSON.stringify({
26
+ schema_version: "1.0",
27
+ id: "fixture",
28
+ name: "Fixture",
29
+ flows: [{ id: "fixture.review", path: "flows/review.flow.json" }],
30
+ provisions,
31
+ }));
32
+ return dir;
33
+ }
34
+
35
+ const entry = (id, source, target) => ({ id: `fixture.${id}`, path: `payload/${source}`, target });
36
+
37
+ test("provision validation rejects unsafe and duplicate normalized targets", async () => {
38
+ const cases = [
39
+ [[entry("one", "one.txt", "../escape.txt")], "traversal segments"],
40
+ [[entry("one", "one.txt", path.resolve("/tmp/escape.txt"))], "must be relative"],
41
+ [[entry("one", "one.txt", ".git/config")], "must not be inside .git"],
42
+ [[entry("one", "one.txt", ".GIT/hooks/pre-push")], "must not be inside .git"],
43
+ [[entry("one", "one.txt", "docs//same.txt"), entry("two", "two.txt", "docs/same.txt")], "target duplicates"],
44
+ [[entry("one", "one.txt", "README.md"), entry("two", "two.txt", "readme.md")], "target duplicates"],
45
+ [[entry("one", "one.txt", ".kontourai/flow-agents/provisions/fixture.json")], "provision manifest namespace"],
46
+ [[{ id: "fixture.one", path: "payload/../payload/one.txt", target: "out.txt" }], "must not contain traversal segments"],
47
+ ];
48
+ for (const [provisions, message] of cases) {
49
+ const errors = await validateKitRepository(fixture(provisions));
50
+ assert.equal(errors.some((error) => error.includes(message)), true, errors.join("\n"));
51
+ }
52
+ });
53
+
54
+ test("provision core preflights conflicts before writing and force overwrites", async () => {
55
+ const kit = fixture([entry("one", "one.txt", "docs/one.txt"), entry("two", "two.txt", "docs/two.txt")]);
56
+ const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-target-"));
57
+ fs.mkdirSync(path.join(target, "docs"));
58
+ fs.writeFileSync(path.join(target, "docs", "two.txt"), "keep\n");
59
+
60
+ await assert.rejects(() => provisionKit(kit, target), (error) => error instanceof ProvisionConflictError && error.conflicts.length === 1);
61
+ assert.equal(fs.existsSync(path.join(target, "docs", "one.txt")), false);
62
+ assert.equal(fs.readFileSync(path.join(target, "docs", "two.txt"), "utf8"), "keep\n");
63
+
64
+ const result = await provisionKit(kit, target, { force: true });
65
+ assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "one-new\n");
66
+ assert.equal(fs.readFileSync(path.join(target, "docs", "two.txt"), "utf8"), "two-new\n");
67
+ const manifest = JSON.parse(fs.readFileSync(result.manifest_path, "utf8"));
68
+ assert.equal(manifest.schema_version, "1.0");
69
+ assert.equal(manifest.kit_id, "fixture");
70
+ assert.match(manifest.kit_hash, /^sha256:[a-f0-9]{64}$/);
71
+ assert.deepEqual(manifest.files, [{ id: "fixture.one", target: "docs/one.txt" }, { id: "fixture.two", target: "docs/two.txt" }]);
72
+ });
73
+
74
+ test("provision core dry-run writes neither files nor manifest", async () => {
75
+ const kit = fixture([entry("one", "one.txt", "docs/one.txt")]);
76
+ const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-dry-"));
77
+ const result = await provisionKit(kit, target, { dryRun: true });
78
+ assert.equal(result.dry_run, true);
79
+ assert.equal(fs.existsSync(path.join(target, "docs", "one.txt")), false);
80
+ assert.equal(fs.existsSync(path.join(target, ".kontourai")), false);
81
+ });
82
+
83
+ test("provision core rejects destination paths whose existing ancestor escapes through a symlink", async () => {
84
+ const kit = fixture([entry("one", "one.txt", "linked/one.txt")]);
85
+ const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-link-target-"));
86
+ const outside = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-link-outside-"));
87
+ fs.symlinkSync(outside, path.join(target, "linked"), "dir");
88
+ await assert.rejects(() => provisionKit(kit, target), /escapes consumer repository/);
89
+ assert.equal(fs.existsSync(path.join(outside, "one.txt")), false);
90
+ });
91
+
92
+ test("provision rejects a source that resolves outside the kit through a symlink", async () => {
93
+ const kit = fixture([entry("host", "host.txt", "copied.txt")]);
94
+ const outside = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-src-outside-"));
95
+ const secret = path.join(outside, "secret.txt");
96
+ fs.writeFileSync(secret, "off-kit-secret\n");
97
+ fs.symlinkSync(secret, path.join(kit, "payload", "host.txt"));
98
+
99
+ const errors = await validateKitRepository(kit);
100
+ assert.equal(errors.some((error) => error.includes("must not resolve outside the kit directory")), true, errors.join("\n"));
101
+
102
+ const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-src-target-"));
103
+ await assert.rejects(() => provisionKit(kit, target), /escapes the kit directory|validation failed/);
104
+ assert.equal(fs.existsSync(path.join(target, "copied.txt")), false);
105
+ });
106
+
107
+ test("init activation provisions create-only and reports rerun conflicts without failing", () => {
108
+ const kit = fixture([entry("one", "one.txt", "docs/one.txt")]);
109
+ const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-init-"));
110
+ const install = spawnSync(process.execPath, ["build/src/cli.js", "kit", "install", kit, "--dest", target], { encoding: "utf8" });
111
+ assert.equal(install.status, 0, `${install.stdout}\n${install.stderr}`);
112
+ const args = ["build/src/cli.js", "init", "--runtime", "codex", "--dest", target, "--telemetry-sink", "local-files", "--activate-kit", "fixture", "--yes"];
113
+ const first = spawnSync(process.execPath, args, { encoding: "utf8" });
114
+ assert.equal(first.status, 0, `${first.stdout}\n${first.stderr}`);
115
+ assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "one-new\n");
116
+
117
+ fs.writeFileSync(path.join(target, "docs", "one.txt"), "consumer-owned\n");
118
+ const second = spawnSync(process.execPath, args, { encoding: "utf8" });
119
+ assert.equal(second.status, 0, `${second.stdout}\n${second.stderr}`);
120
+ assert.match(`${second.stdout}\n${second.stderr}`, /skipped existing provision 'docs\/one.txt'/);
121
+ assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "consumer-owned\n");
122
+ });