@kontourai/flow-agents 0.1.1

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 (418) hide show
  1. package/.githooks/pre-push +11 -0
  2. package/.github/workflows/ci.yml +210 -0
  3. package/.github/workflows/docs-pages.yml +52 -0
  4. package/.github/workflows/publish-npm.yml +104 -0
  5. package/AGENTS.md +26 -0
  6. package/CHANGELOG.md +66 -0
  7. package/CODE_OF_CONDUCT.md +25 -0
  8. package/CONTEXT.md +300 -0
  9. package/CONTRIBUTING.md +44 -0
  10. package/LICENSE +201 -0
  11. package/README.md +129 -0
  12. package/SECURITY.md +33 -0
  13. package/agent-cards/dev.json +19 -0
  14. package/agents/dev.json +127 -0
  15. package/agents/tool-code-reviewer.json +61 -0
  16. package/agents/tool-dependencies-updater.json +118 -0
  17. package/agents/tool-explore-config.json +92 -0
  18. package/agents/tool-explore-deps.json +92 -0
  19. package/agents/tool-explore-entry.json +92 -0
  20. package/agents/tool-explore-patterns.json +92 -0
  21. package/agents/tool-explore-structure.json +92 -0
  22. package/agents/tool-explore-tests.json +92 -0
  23. package/agents/tool-planner.json +57 -0
  24. package/agents/tool-playwright.json +145 -0
  25. package/agents/tool-security-reviewer.json +56 -0
  26. package/agents/tool-verifier.json +61 -0
  27. package/agents/tool-worker.json +58 -0
  28. package/build/src/cli/console-learning-projection.js +123 -0
  29. package/build/src/cli/docs-preview.js +39 -0
  30. package/build/src/cli/effective-backlog-settings.js +102 -0
  31. package/build/src/cli/export-bookmarks.js +38 -0
  32. package/build/src/cli/fixture-retirement-audit.js +140 -0
  33. package/build/src/cli/flow-kit.js +138 -0
  34. package/build/src/cli/import-bookmarks.js +50 -0
  35. package/build/src/cli/init.js +239 -0
  36. package/build/src/cli/instinct-cli.js +93 -0
  37. package/build/src/cli/promote-workflow-artifact.js +63 -0
  38. package/build/src/cli/publish-change-helper.js +154 -0
  39. package/build/src/cli/pull-work-provider.js +469 -0
  40. package/build/src/cli/runtime-adapter.js +23 -0
  41. package/build/src/cli/telemetry-doctor.js +221 -0
  42. package/build/src/cli/usage-feedback.js +443 -0
  43. package/build/src/cli/validate-hook-influence.js +152 -0
  44. package/build/src/cli/validate-source-tree.js +31 -0
  45. package/build/src/cli/validate-workflow-artifacts.js +486 -0
  46. package/build/src/cli/veritas-governance.js +262 -0
  47. package/build/src/cli/workflow-artifact-cleanup-audit.js +272 -0
  48. package/build/src/cli/workflow-sidecar.js +816 -0
  49. package/build/src/cli.js +89 -0
  50. package/build/src/flow-kit/validate.js +75 -0
  51. package/build/src/lib/args.js +45 -0
  52. package/build/src/lib/fs.js +62 -0
  53. package/build/src/lib/workflow-learning-projection.js +334 -0
  54. package/build/src/runtime-adapters.js +146 -0
  55. package/build/src/tools/build-universal-bundles.js +397 -0
  56. package/build/src/tools/common.js +56 -0
  57. package/build/src/tools/filter-installed-packs.js +132 -0
  58. package/build/src/tools/generate-context-map.js +198 -0
  59. package/build/src/tools/validate-package.js +64 -0
  60. package/build/src/tools/validate-source-tree.js +622 -0
  61. package/console.telemetry.json +176 -0
  62. package/context/base-rules.md +17 -0
  63. package/context/code-review-standards.md +62 -0
  64. package/context/coding-standards.md +42 -0
  65. package/context/common/orchestrators.md +12 -0
  66. package/context/common/subagents.md +28 -0
  67. package/context/contracts/artifact-contract.md +182 -0
  68. package/context/contracts/builder-kit-workflow-state-contract.md +319 -0
  69. package/context/contracts/delivery-contract.md +69 -0
  70. package/context/contracts/execution-contract.md +53 -0
  71. package/context/contracts/governance-adapter-contract.md +67 -0
  72. package/context/contracts/planning-contract.md +85 -0
  73. package/context/contracts/review-contract.md +104 -0
  74. package/context/contracts/sandbox-policy.md +52 -0
  75. package/context/contracts/verification-contract.md +134 -0
  76. package/context/contracts/work-item-contract.md +215 -0
  77. package/context/deferred/demo-mode.md +33 -0
  78. package/context/deferred/languages/go.md +31 -0
  79. package/context/deferred/languages/python.md +31 -0
  80. package/context/deferred/languages/typescript.md +34 -0
  81. package/context/deferred/parallelization.md +35 -0
  82. package/context/deferred/worktree-isolation.md +24 -0
  83. package/context/development-workflow.md +50 -0
  84. package/context/scripts/context-budget/budget-scan.sh +166 -0
  85. package/context/scripts/detect-tools.sh +3 -0
  86. package/context/scripts/discover-agents.sh +28 -0
  87. package/context/scripts/git-status.sh +49 -0
  88. package/context/scripts/hooks/config-protection.js +79 -0
  89. package/context/scripts/hooks/desktop-notify.sh +39 -0
  90. package/context/scripts/hooks/governance-audit.sh +135 -0
  91. package/context/scripts/hooks/lib/audit-transport.sh +40 -0
  92. package/context/scripts/hooks/lib/hook-flags.js +49 -0
  93. package/context/scripts/hooks/lib/patterns.sh +57 -0
  94. package/context/scripts/hooks/lib/resolve-formatter.js +80 -0
  95. package/context/scripts/hooks/post-edit-accumulator.js +66 -0
  96. package/context/scripts/hooks/pre-commit-quality.js +194 -0
  97. package/context/scripts/hooks/quality-gate.js +93 -0
  98. package/context/scripts/hooks/report-only-guard.js +21 -0
  99. package/context/scripts/hooks/run-hook.js +136 -0
  100. package/context/scripts/hooks/stop-format-typecheck.js +141 -0
  101. package/context/scripts/hooks/stop-goal-fit.js +337 -0
  102. package/context/scripts/hooks/workflow-steering.js +250 -0
  103. package/context/scripts/telemetry/console-presets.sh +14 -0
  104. package/context/scripts/telemetry/install-console-config.sh +214 -0
  105. package/context/scripts/telemetry/lib/config.sh +85 -0
  106. package/context/scripts/telemetry/lib/enrich.sh +115 -0
  107. package/context/scripts/telemetry/lib/redact.sh +22 -0
  108. package/context/scripts/telemetry/lib/session.sh +63 -0
  109. package/context/scripts/telemetry/lib/transport.sh +183 -0
  110. package/context/scripts/telemetry/lib/usage.sh +29 -0
  111. package/context/scripts/telemetry/sync-agents.sh +173 -0
  112. package/context/scripts/telemetry/telemetry.conf +23 -0
  113. package/context/scripts/telemetry/telemetry.sh +387 -0
  114. package/context/scripts/validate-package.sh +89 -0
  115. package/context/settings/backlog-provider-settings.json +54 -0
  116. package/context/templates/core/identity.md +26 -0
  117. package/context/templates/core/user.md +15 -0
  118. package/docs/_config.yml +15 -0
  119. package/docs/_layouts/default.html +87 -0
  120. package/docs/adr/0001-flow-agents-consumes-flow.md +77 -0
  121. package/docs/adr/0002-flow-kits-as-extension-unit.md +13 -0
  122. package/docs/adr/0003-flow-agents-coordinates-kits-and-adapters.md +13 -0
  123. package/docs/adr/0004-gates-expect-surface-claims.md +15 -0
  124. package/docs/adr/0005-kubernetes-inspired-resource-contracts.md +48 -0
  125. package/docs/adr/0006-typescript-first-source-policy.md +98 -0
  126. package/docs/agent-system-guidebook.md +391 -0
  127. package/docs/agent-usage-feedback-loop.md +351 -0
  128. package/docs/assets/favicon.svg +13 -0
  129. package/docs/assets/og-image.png +0 -0
  130. package/docs/assets/site.css +774 -0
  131. package/docs/assets/site.js +139 -0
  132. package/docs/configurable-workflow-routing.md +174 -0
  133. package/docs/context-map.md +145 -0
  134. package/docs/developer-architecture.md +145 -0
  135. package/docs/developer-hook-setup.md +61 -0
  136. package/docs/fixture-ownership.md +44 -0
  137. package/docs/flow-kit-repository-contract.md +180 -0
  138. package/docs/index.md +129 -0
  139. package/docs/kontour-resource-contract.md +358 -0
  140. package/docs/migrations.md +64 -0
  141. package/docs/north-star.md +322 -0
  142. package/docs/operating-layers.md +110 -0
  143. package/docs/repository-structure.md +132 -0
  144. package/docs/sandbox-policy.md +56 -0
  145. package/docs/skills-map.md +203 -0
  146. package/docs/standards-register.md +96 -0
  147. package/docs/veritas-integration.md +165 -0
  148. package/docs/work-item-adapters.md +72 -0
  149. package/docs/workflow-artifact-lifecycle.md +141 -0
  150. package/docs/workflow-eval-strategy.md +295 -0
  151. package/docs/workflow-shared-contracts.md +51 -0
  152. package/docs/workflow-usage-guide.md +443 -0
  153. package/evals/ARCHITECTURE.md +143 -0
  154. package/evals/CONVENTIONS.md +58 -0
  155. package/evals/README.md +128 -0
  156. package/evals/acceptance/run.sh +29 -0
  157. package/evals/acceptance/test_claude_harness.sh +242 -0
  158. package/evals/acceptance/test_codex_harness.sh +108 -0
  159. package/evals/acceptance/test_kiro_harness.sh +128 -0
  160. package/evals/cases/dev/404.html +97 -0
  161. package/evals/cases/dev/code-review.yaml +44 -0
  162. package/evals/cases/dev/dashboard.html +300 -0
  163. package/evals/cases/dev/deliver.yaml +66 -0
  164. package/evals/cases/dev/dependency-update.yaml +16 -0
  165. package/evals/cases/dev/explore.yaml +20 -0
  166. package/evals/cases/dev/index.html +370 -0
  167. package/evals/cases/dev/package-lock.json +28 -0
  168. package/evals/cases/dev/package.json +16 -0
  169. package/evals/cases/dev/plan-work.yaml +20 -0
  170. package/evals/cases/dev/promptfooconfig.yaml +666 -0
  171. package/evals/cases/dev/search-first.yaml +20 -0
  172. package/evals/cases/dev/tdd-workflow.yaml +48 -0
  173. package/evals/cases/dev/verify-work.yaml +44 -0
  174. package/evals/cases/dev/workflow.yaml +34 -0
  175. package/evals/ci/run-baseline.sh +283 -0
  176. package/evals/fixtures/backlog-provider-settings/global-default.json +44 -0
  177. package/evals/fixtures/backlog-provider-settings/project-override.json +53 -0
  178. package/evals/fixtures/builder-kit-workflow-state/baseline-freshness-resolution-hint.json +139 -0
  179. package/evals/fixtures/builder-kit-workflow-state/direct-primitive-stop.json +59 -0
  180. package/evals/fixtures/builder-kit-workflow-state/empty-board-route-shape.json +55 -0
  181. package/evals/fixtures/builder-kit-workflow-state/happy-path.json +71 -0
  182. package/evals/fixtures/builder-kit-workflow-state/mid-work-resume.json +80 -0
  183. package/evals/fixtures/builder-kit-workflow-state/missing-prestep-recovery.json +65 -0
  184. package/evals/fixtures/builder-kit-workflow-state/product-build-chaining.json +60 -0
  185. package/evals/fixtures/builder-kit-workflow-state/stale-continuation-requires-new-probe.json +57 -0
  186. package/evals/fixtures/console-learning-projection/artifacts/console-learning-correction/learning.json +50 -0
  187. package/evals/fixtures/console-learning-projection/artifacts/console-learning-open-route/learning.json +41 -0
  188. package/evals/fixtures/flow-kit-repository/invalid-absolute-path/kit.json +8 -0
  189. package/evals/fixtures/flow-kit-repository/invalid-asset-section/flows/review.flow.json +6 -0
  190. package/evals/fixtures/flow-kit-repository/invalid-asset-section/kit.json +11 -0
  191. package/evals/fixtures/flow-kit-repository/invalid-duplicate-flow/flows/review.flow.json +6 -0
  192. package/evals/fixtures/flow-kit-repository/invalid-duplicate-flow/kit.json +9 -0
  193. package/evals/fixtures/flow-kit-repository/invalid-id/flows/review.flow.json +6 -0
  194. package/evals/fixtures/flow-kit-repository/invalid-id/kit.json +8 -0
  195. package/evals/fixtures/flow-kit-repository/invalid-malformed-json/kit.json +8 -0
  196. package/evals/fixtures/flow-kit-repository/invalid-missing-flow/kit.json +8 -0
  197. package/evals/fixtures/flow-kit-repository/invalid-missing-id/flows/review.flow.json +6 -0
  198. package/evals/fixtures/flow-kit-repository/invalid-missing-id/kit.json +7 -0
  199. package/evals/fixtures/flow-kit-repository/invalid-missing-schema-version/flows/review.flow.json +6 -0
  200. package/evals/fixtures/flow-kit-repository/invalid-missing-schema-version/kit.json +7 -0
  201. package/evals/fixtures/flow-kit-repository/invalid-name/flows/review.flow.json +6 -0
  202. package/evals/fixtures/flow-kit-repository/invalid-name/kit.json +8 -0
  203. package/evals/fixtures/flow-kit-repository/invalid-schema-version/flows/review.flow.json +6 -0
  204. package/evals/fixtures/flow-kit-repository/invalid-schema-version/kit.json +8 -0
  205. package/evals/fixtures/flow-kit-repository/invalid-traversal/kit.json +8 -0
  206. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/adapters/example.json +3 -0
  207. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/assets/example.txt +1 -0
  208. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/docs/README.md +3 -0
  209. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/flows/runtime.flow.json +26 -0
  210. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit-evals/example.json +3 -0
  211. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit-skills/mixed/SKILL.md +3 -0
  212. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit.json +44 -0
  213. package/evals/fixtures/flow-kit-repository/valid-local-kit/docs/README.md +3 -0
  214. package/evals/fixtures/flow-kit-repository/valid-local-kit/flows/review.flow.json +26 -0
  215. package/evals/fixtures/flow-kit-repository/valid-local-kit/kit.json +20 -0
  216. package/evals/fixtures/hook-influence/cases.json +336 -0
  217. package/evals/fixtures/pull-work-provider/github-issues.json +170 -0
  218. package/evals/fixtures/pull-work-wip-shepherding/global-wip-informs.json +43 -0
  219. package/evals/fixtures/pull-work-wip-shepherding/personal-wip-blocks.json +42 -0
  220. package/evals/fixtures/surface-trust/accepted-claim-trust-report.json +31 -0
  221. package/evals/fixtures/surface-trust/artifact-absent.json +19 -0
  222. package/evals/fixtures/surface-trust/integrity-mismatch-trust-report.json +32 -0
  223. package/evals/fixtures/surface-trust/missing-authority-trust-report.json +27 -0
  224. package/evals/fixtures/surface-trust/provider-absent.json +19 -0
  225. package/evals/fixtures/surface-trust/rejected-claim-trust-report.json +30 -0
  226. package/evals/fixtures/surface-trust/stale-claim-trust-snapshot.json +31 -0
  227. package/evals/fixtures/usage-feedback/sample-full.jsonl +11 -0
  228. package/evals/fixtures/usage-feedback/sample-outcomes.jsonl +1 -0
  229. package/evals/fixtures/veritas-governance-adapter/fake-veritas-pass.sh +18 -0
  230. package/evals/fixtures/veritas-governance-adapter/fake-veritas-secret-fail.sh +10 -0
  231. package/evals/fixtures/veritas-governance-adapter/fake-veritas-unconfigured.sh +4 -0
  232. package/evals/integration/test_bundle_install.sh +541 -0
  233. package/evals/integration/test_console_learning_projection.sh +192 -0
  234. package/evals/integration/test_context_map.sh +65 -0
  235. package/evals/integration/test_effective_backlog_settings.sh +58 -0
  236. package/evals/integration/test_fixture_retirement_audit.sh +58 -0
  237. package/evals/integration/test_flow_agents_statusline.sh +93 -0
  238. package/evals/integration/test_flow_kit_repository.sh +90 -0
  239. package/evals/integration/test_goal_fit_hook.sh +482 -0
  240. package/evals/integration/test_hook_category_behaviors.sh +190 -0
  241. package/evals/integration/test_hook_influence_cases.sh +69 -0
  242. package/evals/integration/test_local_flow_kit_install.sh +145 -0
  243. package/evals/integration/test_publish_change_helper.sh +176 -0
  244. package/evals/integration/test_pull_work_provider.sh +140 -0
  245. package/evals/integration/test_runtime_adapter_activation.sh +106 -0
  246. package/evals/integration/test_telemetry.sh +485 -0
  247. package/evals/integration/test_telemetry_doctor.sh +193 -0
  248. package/evals/integration/test_usage_feedback_dashboard.sh +169 -0
  249. package/evals/integration/test_usage_feedback_global.sh +117 -0
  250. package/evals/integration/test_usage_feedback_import.sh +227 -0
  251. package/evals/integration/test_usage_feedback_outcomes.sh +165 -0
  252. package/evals/integration/test_usage_feedback_report.sh +263 -0
  253. package/evals/integration/test_veritas_governance_adapter.sh +235 -0
  254. package/evals/integration/test_workflow_artifact_cleanup_audit.sh +287 -0
  255. package/evals/integration/test_workflow_artifacts.sh +1247 -0
  256. package/evals/integration/test_workflow_sidecar_writer.sh +2112 -0
  257. package/evals/integration/test_workflow_steering_hook.sh +337 -0
  258. package/evals/lib/assertions/delegated-to.js +40 -0
  259. package/evals/lib/assertions/max-tool-calls.js +15 -0
  260. package/evals/lib/assertions/no-write-tools.js +27 -0
  261. package/evals/lib/assertions/pass-at-k.js +39 -0
  262. package/evals/lib/assertions/telemetry-utils.js +105 -0
  263. package/evals/lib/assertions/tool-called.js +39 -0
  264. package/evals/lib/assertions/verify-after-fix.js +61 -0
  265. package/evals/lib/claude-judge.sh +40 -0
  266. package/evals/lib/claude-provider.sh +74 -0
  267. package/evals/lib/codex-judge.sh +39 -0
  268. package/evals/lib/codex-provider.sh +81 -0
  269. package/evals/lib/eval-dev.sh +5 -0
  270. package/evals/lib/eval-judge.sh +22 -0
  271. package/evals/lib/eval-provider.sh +26 -0
  272. package/evals/lib/eval-report.sh +73 -0
  273. package/evals/lib/kiro-dev.sh +4 -0
  274. package/evals/lib/kiro-judge.sh +17 -0
  275. package/evals/lib/kiro-provider.sh +62 -0
  276. package/evals/lib/node.sh +111 -0
  277. package/evals/promptfooconfig.yaml +70 -0
  278. package/evals/run.sh +309 -0
  279. package/evals/static/test_evidence_refs.sh +141 -0
  280. package/evals/static/test_package.sh +407 -0
  281. package/evals/static/test_repo_hooks.sh +68 -0
  282. package/evals/static/test_universal_bundles.sh +274 -0
  283. package/evals/static/test_workflow_skills.sh +1207 -0
  284. package/install.sh +64 -0
  285. package/integrations/veritas/flow-agents.adapter.json +138 -0
  286. package/integrations/veritas/flow-agents.authority-settings.json +26 -0
  287. package/integrations/veritas/flow-agents.repo-standards.json +82 -0
  288. package/kits/builder/flows/build.flow.json +218 -0
  289. package/kits/builder/flows/shape.flow.json +127 -0
  290. package/kits/builder/kit.json +19 -0
  291. package/kits/catalog.json +11 -0
  292. package/package.json +130 -0
  293. package/packaging/README.md +60 -0
  294. package/packaging/manifest.json +173 -0
  295. package/packaging/packs.json +69 -0
  296. package/powers/dependency-checker/POWER.md +20 -0
  297. package/powers/dependency-checker/mcp.json +20 -0
  298. package/powers/playwright/POWER.md +25 -0
  299. package/powers/playwright/mcp.json +12 -0
  300. package/prompts/code-audit.md +123 -0
  301. package/prompts/kcommit.md +88 -0
  302. package/schemas/backlog-provider-settings.schema.json +138 -0
  303. package/schemas/workflow-acceptance.schema.json +216 -0
  304. package/schemas/workflow-critique.schema.json +113 -0
  305. package/schemas/workflow-evidence.schema.json +357 -0
  306. package/schemas/workflow-handoff.schema.json +52 -0
  307. package/schemas/workflow-learning.schema.json +223 -0
  308. package/schemas/workflow-release.schema.json +172 -0
  309. package/schemas/workflow-state.schema.json +80 -0
  310. package/scripts/README.md +111 -0
  311. package/scripts/build-universal-bundles.js +3 -0
  312. package/scripts/check-content-boundary.cjs +99 -0
  313. package/scripts/context-budget/budget-scan.sh +166 -0
  314. package/scripts/detect-tools.sh +3 -0
  315. package/scripts/discover-agents.sh +28 -0
  316. package/scripts/effective-backlog-settings.js +2 -0
  317. package/scripts/filter-installed-packs.js +2 -0
  318. package/scripts/flow-kit.js +2 -0
  319. package/scripts/generate-context-map.js +2 -0
  320. package/scripts/git-status.sh +49 -0
  321. package/scripts/hooks/claude-hook-adapter.js +174 -0
  322. package/scripts/hooks/claude-telemetry-hook.js +115 -0
  323. package/scripts/hooks/codex-hook-adapter.js +176 -0
  324. package/scripts/hooks/codex-telemetry-hook.js +95 -0
  325. package/scripts/hooks/config-protection.js +79 -0
  326. package/scripts/hooks/desktop-notify.sh +39 -0
  327. package/scripts/hooks/governance-audit.sh +135 -0
  328. package/scripts/hooks/lib/audit-transport.sh +40 -0
  329. package/scripts/hooks/lib/hook-flags.js +49 -0
  330. package/scripts/hooks/lib/patterns.sh +57 -0
  331. package/scripts/hooks/lib/resolve-formatter.js +80 -0
  332. package/scripts/hooks/post-edit-accumulator.js +66 -0
  333. package/scripts/hooks/pre-commit-quality.js +194 -0
  334. package/scripts/hooks/quality-gate.js +93 -0
  335. package/scripts/hooks/report-only-guard.js +21 -0
  336. package/scripts/hooks/run-hook.js +136 -0
  337. package/scripts/hooks/stop-format-typecheck.js +141 -0
  338. package/scripts/hooks/stop-goal-fit.js +337 -0
  339. package/scripts/hooks/workflow-steering.js +250 -0
  340. package/scripts/install-codex-home.sh +106 -0
  341. package/scripts/package.json +3 -0
  342. package/scripts/promote-workflow-artifact.js +2 -0
  343. package/scripts/publish-change-helper.js +2 -0
  344. package/scripts/pull-work-provider.js +2 -0
  345. package/scripts/setup-repo-hooks.sh +8 -0
  346. package/scripts/statusline/flow-agents-statusline.js +157 -0
  347. package/scripts/telemetry/console-presets.sh +14 -0
  348. package/scripts/telemetry/install-console-config.sh +214 -0
  349. package/scripts/telemetry/lib/config.sh +85 -0
  350. package/scripts/telemetry/lib/enrich.sh +115 -0
  351. package/scripts/telemetry/lib/redact.sh +22 -0
  352. package/scripts/telemetry/lib/session.sh +63 -0
  353. package/scripts/telemetry/lib/transport.sh +183 -0
  354. package/scripts/telemetry/lib/usage.sh +29 -0
  355. package/scripts/telemetry/sync-agents.sh +173 -0
  356. package/scripts/telemetry/telemetry.conf +23 -0
  357. package/scripts/telemetry/telemetry.sh +387 -0
  358. package/scripts/usage-feedback.js +2 -0
  359. package/scripts/validate-hook-influence-cases.js +2 -0
  360. package/scripts/validate-package.sh +89 -0
  361. package/scripts/validate-source-tree.js +9 -0
  362. package/skills/agentic-engineering/SKILL.md +62 -0
  363. package/skills/browser-test/SKILL.md +51 -0
  364. package/skills/builder-shape/SKILL.md +76 -0
  365. package/skills/context-budget/SKILL.md +40 -0
  366. package/skills/deliver/SKILL.md +241 -0
  367. package/skills/dependency-update/SKILL.md +68 -0
  368. package/skills/design-probe/SKILL.md +107 -0
  369. package/skills/eval-rebuild/SKILL.md +39 -0
  370. package/skills/evidence-gate/SKILL.md +186 -0
  371. package/skills/execute-plan/SKILL.md +110 -0
  372. package/skills/explore/SKILL.md +137 -0
  373. package/skills/feedback-loop/SKILL.md +87 -0
  374. package/skills/fix-bug/SKILL.md +133 -0
  375. package/skills/frontend-design/SKILL.md +80 -0
  376. package/skills/github-cli/SKILL.md +63 -0
  377. package/skills/idea-to-backlog/SKILL.md +267 -0
  378. package/skills/knowledge-capture/SKILL.md +55 -0
  379. package/skills/learning-review/SKILL.md +115 -0
  380. package/skills/pickup-probe/SKILL.md +114 -0
  381. package/skills/plan-work/SKILL.md +176 -0
  382. package/skills/pull-work/SKILL.md +309 -0
  383. package/skills/release-readiness/SKILL.md +121 -0
  384. package/skills/review-work/SKILL.md +161 -0
  385. package/skills/search-first/SKILL.md +66 -0
  386. package/skills/tdd-workflow/SKILL.md +140 -0
  387. package/skills/verify-work/SKILL.md +109 -0
  388. package/src/cli/console-learning-projection.ts +140 -0
  389. package/src/cli/effective-backlog-settings.ts +99 -0
  390. package/src/cli/fixture-retirement-audit.ts +154 -0
  391. package/src/cli/flow-kit.ts +139 -0
  392. package/src/cli/init.ts +248 -0
  393. package/src/cli/promote-workflow-artifact.ts +64 -0
  394. package/src/cli/publish-change-helper.ts +143 -0
  395. package/src/cli/pull-work-provider.ts +481 -0
  396. package/src/cli/runtime-adapter.ts +24 -0
  397. package/src/cli/telemetry-doctor.ts +243 -0
  398. package/src/cli/usage-feedback.ts +418 -0
  399. package/src/cli/validate-hook-influence.ts +119 -0
  400. package/src/cli/validate-source-tree.ts +30 -0
  401. package/src/cli/validate-workflow-artifacts.ts +411 -0
  402. package/src/cli/veritas-governance.ts +322 -0
  403. package/src/cli/workflow-artifact-cleanup-audit.ts +281 -0
  404. package/src/cli/workflow-sidecar.ts +676 -0
  405. package/src/cli.ts +95 -0
  406. package/src/flow-kit/validate.ts +74 -0
  407. package/src/lib/args.ts +43 -0
  408. package/src/lib/fs.ts +62 -0
  409. package/src/lib/workflow-learning-projection.ts +491 -0
  410. package/src/runtime-adapters.ts +154 -0
  411. package/src/tools/build-universal-bundles.ts +366 -0
  412. package/src/tools/common.ts +61 -0
  413. package/src/tools/filter-installed-packs.ts +129 -0
  414. package/src/tools/generate-context-map.ts +199 -0
  415. package/src/tools/validate-package.ts +57 -0
  416. package/src/tools/validate-source-tree.ts +488 -0
  417. package/tsconfig.json +19 -0
  418. package/veritas.claims.json +6 -0
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ # test_hook_influence_cases.sh - behavioral hook-influence fixture contracts
3
+ set -uo pipefail
4
+
5
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6
+ source "$ROOT/evals/lib/node.sh"
7
+
8
+ errors=0
9
+
10
+ _pass() { echo " ✓ $1"; }
11
+ _fail() { echo " ✗ $1"; errors=$((errors + 1)); }
12
+
13
+ CASES="$ROOT/evals/fixtures/hook-influence/cases.json"
14
+ VALIDATOR="$ROOT/scripts/validate-hook-influence-cases.js"
15
+
16
+ if [[ -f "$CASES" ]]; then
17
+ _pass "hook influence case fixture exists"
18
+ else
19
+ _fail "hook influence case fixture missing"
20
+ fi
21
+
22
+ if [[ -f "$VALIDATOR" ]]; then
23
+ _pass "hook influence case validator exists"
24
+ else
25
+ _fail "hook influence case validator missing"
26
+ fi
27
+
28
+ if flow_agents_node "$VALIDATOR" "$CASES" > /tmp/flow-agents-hook-influence.out 2> /tmp/flow-agents-hook-influence.err; then
29
+ _pass "hook influence behavioral cases validate"
30
+ else
31
+ _fail "hook influence behavioral cases failed validation: $(cat /tmp/flow-agents-hook-influence.out /tmp/flow-agents-hook-influence.err)"
32
+ fi
33
+
34
+ if rg -q '"tier": "adapter"' "$CASES" \
35
+ && rg -q '"tier": "live-acceptance"' "$CASES" \
36
+ && rg -q '"tier": "installed-command"' "$CASES" \
37
+ && rg -q '"tier": "documented-runtime-gap"' "$CASES" \
38
+ && rg -q '"tier": "design-target"' "$CASES"; then
39
+ _pass "hook influence cases distinguish adapter, live, installed-command, documented runtime-gap, and design-target evidence"
40
+ else
41
+ _fail "hook influence cases do not distinguish required evidence tiers"
42
+ fi
43
+
44
+ if rg -q 'FLOW_AGENTS_ACCEPTANCE_CLAUDE_LLM=1' "$CASES" \
45
+ && rg -q '"runtime_scope": \["kiro-cli"\]' "$CASES" \
46
+ && rg -q 'codex exec exposes project hook guidance' "$CASES"; then
47
+ _pass "hook influence cases cover Claude, Kiro, and Codex runtime boundaries"
48
+ else
49
+ _fail "hook influence cases miss a runtime boundary"
50
+ fi
51
+
52
+ if rg -q 'dev-builder-build-requires-pickup-probe-before-plan' "$CASES" \
53
+ && rg -q 'dev-builder-review-before-verify-after-execute' "$CASES" \
54
+ && rg -q 'dev-verify-fail-preserves-trace-before-rework' "$CASES" \
55
+ && rg -q 'codex-claude-strict-stop-adapter-contract' "$CASES"; then
56
+ _pass "hook influence cases cover #62 Builder Kit loop categories"
57
+ else
58
+ _fail "hook influence cases miss a required #62 Builder Kit loop category"
59
+ fi
60
+
61
+ rm -f /tmp/flow-agents-hook-influence.out /tmp/flow-agents-hook-influence.err
62
+
63
+ if [[ "$errors" -eq 0 ]]; then
64
+ echo "Hook influence case integration passed."
65
+ exit 0
66
+ fi
67
+
68
+ echo "Hook influence case integration failed: $errors issue(s)."
69
+ exit 1
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env bash
2
+ # test_local_flow_kit_install.sh — Exercise local Flow Kit install/list/status behavior.
3
+ set -uo pipefail
4
+
5
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6
+ source "$ROOT/evals/lib/node.sh"
7
+
8
+ errors=0
9
+ TMP_DIR="$(mktemp -d)"
10
+ trap 'rm -rf "$TMP_DIR"' EXIT
11
+
12
+ pass() { echo " ✓ $1"; }
13
+ fail() { echo " ✗ $1"; errors=$((errors + 1)); }
14
+
15
+ CLI="$ROOT/scripts/flow-kit.js"
16
+ VALID_SRC="$ROOT/evals/fixtures/flow-kit-repository/valid-local-kit"
17
+ INVALID_SRC="$ROOT/evals/fixtures/flow-kit-repository/invalid-missing-flow"
18
+ DEST="$TMP_DIR/install-dest"
19
+ REGISTRY="$DEST/kits/local/installed-kits.json"
20
+ CATALOG_HASH_BEFORE="$(shasum -a 256 "$ROOT/kits/catalog.json" | awk '{print $1}')"
21
+ mkdir -p "$DEST"
22
+
23
+ echo "=== Local Flow Kit Install Checks ==="
24
+
25
+ install_output="$TMP_DIR/install.out"
26
+ if flow_agents_node "$CLI" install-local "$VALID_SRC" --dest "$DEST" >"$install_output" 2>&1; then
27
+ pass "valid local kit installs into temp destination"
28
+ else
29
+ fail "valid local kit install failed"
30
+ sed -n '1,160p' "$install_output"
31
+ fi
32
+
33
+ if node - "$REGISTRY" <<'NODE'
34
+ const fs = require("node:fs");
35
+ const path = require("node:path");
36
+ const registry = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
37
+ const entry = registry.kits[0];
38
+ for (const key of ["id", "source", "hash", "installed_at", "installed_path", "state"]) {
39
+ if (!(key in entry)) throw new Error(`missing metadata key: ${key}`);
40
+ }
41
+ if (entry.id !== "example-kit") throw new Error(`unexpected id: ${entry.id}`);
42
+ if (!entry.hash.startsWith("sha256:")) throw new Error("hash should include sha256 prefix");
43
+ if (Number.isNaN(Date.parse(entry.installed_at))) throw new Error("installed_at should be ISO parseable");
44
+ if (!fs.existsSync(path.join(entry.installed_path, "kit.json"))) throw new Error("installed kit copy missing kit.json");
45
+ console.log("ok");
46
+ NODE
47
+ then
48
+ pass "install records required provenance metadata"
49
+ else
50
+ fail "install metadata is incomplete"
51
+ fi
52
+
53
+ registry_hash_before_invalid="$(shasum -a 256 "$REGISTRY" | awk '{print $1}')"
54
+ invalid_output="$TMP_DIR/invalid.out"
55
+ if flow_agents_node "$CLI" install-local "$INVALID_SRC" --dest "$DEST" >"$invalid_output" 2>&1; then
56
+ fail "invalid local kit install should fail"
57
+ sed -n '1,160p' "$invalid_output"
58
+ elif rg -q 'Flow Kit repository validation failed' "$invalid_output" \
59
+ && [[ "$registry_hash_before_invalid" == "$(shasum -a 256 "$REGISTRY" | awk '{print $1}')" ]]; then
60
+ pass "invalid kit fails validation before registry mutation"
61
+ else
62
+ fail "invalid kit failure did not preserve registry or diagnostic"
63
+ sed -n '1,160p' "$invalid_output"
64
+ fi
65
+
66
+ registry_hash_before_idempotent="$(shasum -a 256 "$REGISTRY" | awk '{print $1}')"
67
+ idempotent_output="$TMP_DIR/idempotent.out"
68
+ if flow_agents_node "$CLI" install-local "$VALID_SRC" --dest "$DEST" >"$idempotent_output" 2>&1 \
69
+ && rg -q "already installed" "$idempotent_output" \
70
+ && [[ "$registry_hash_before_idempotent" == "$(shasum -a 256 "$REGISTRY" | awk '{print $1}')" ]]; then
71
+ pass "same-source reinstall is idempotent"
72
+ else
73
+ fail "same-source reinstall was not idempotent"
74
+ sed -n '1,160p' "$idempotent_output"
75
+ fi
76
+
77
+ CONFLICT_SRC="$TMP_DIR/conflict-source"
78
+ cp -R "$VALID_SRC" "$CONFLICT_SRC"
79
+ printf '\nconflict copy\n' >> "$CONFLICT_SRC/docs/README.md"
80
+ conflict_output="$TMP_DIR/conflict.out"
81
+ registry_hash_before_conflict="$(shasum -a 256 "$REGISTRY" | awk '{print $1}')"
82
+ if flow_agents_node "$CLI" install-local "$CONFLICT_SRC" --dest "$DEST" >"$conflict_output" 2>&1; then
83
+ fail "different source with existing kit id should conflict"
84
+ sed -n '1,160p' "$conflict_output"
85
+ elif rg -q 'conflict: kit' "$conflict_output" \
86
+ && [[ "$registry_hash_before_conflict" == "$(shasum -a 256 "$REGISTRY" | awk '{print $1}')" ]]; then
87
+ pass "different-source duplicate id conflicts without mutation"
88
+ else
89
+ fail "duplicate id conflict did not preserve registry or diagnostic"
90
+ sed -n '1,160p' "$conflict_output"
91
+ fi
92
+
93
+ force_conflict_output="$TMP_DIR/force-conflict.out"
94
+ if flow_agents_node "$CLI" install-local "$CONFLICT_SRC" --dest "$DEST" --force >"$force_conflict_output" 2>&1; then
95
+ fail "--force should not replace a different-source duplicate id"
96
+ sed -n '1,160p' "$force_conflict_output"
97
+ elif rg -q 'conflict: kit' "$force_conflict_output" \
98
+ && [[ "$registry_hash_before_conflict" == "$(shasum -a 256 "$REGISTRY" | awk '{print $1}')" ]]; then
99
+ pass "--force preserves different-source duplicate id conflict"
100
+ else
101
+ fail "--force duplicate id conflict did not preserve registry or diagnostic"
102
+ sed -n '1,160p' "$force_conflict_output"
103
+ fi
104
+
105
+ update_output="$TMP_DIR/update.out"
106
+ if flow_agents_node "$CLI" install-local "$CONFLICT_SRC" --dest "$DEST" --update >"$update_output" 2>&1 \
107
+ && rg -q "updated local kit" "$update_output" \
108
+ && rg -q "$CONFLICT_SRC" "$REGISTRY"; then
109
+ pass "explicit update replaces duplicate id source"
110
+ else
111
+ fail "explicit update did not replace duplicate id source"
112
+ sed -n '1,160p' "$update_output"
113
+ fi
114
+
115
+ list_output="$TMP_DIR/list.out"
116
+ status_output="$TMP_DIR/status.out"
117
+ if flow_agents_node "$CLI" list --dest "$DEST" >"$list_output" 2>&1 \
118
+ && flow_agents_node "$CLI" status --dest "$DEST" example-kit >"$status_output" 2>&1 \
119
+ && rg -q 'example-kit' "$list_output" \
120
+ && rg -q 'source=' "$list_output" \
121
+ && rg -q 'installed_at=' "$list_output" \
122
+ && rg -q '"id": "example-kit"' "$status_output" \
123
+ && rg -q '"state": "installed"' "$status_output"; then
124
+ pass "list and status expose installed kit provenance without mutation"
125
+ else
126
+ fail "list/status output missing expected provenance"
127
+ sed -n '1,160p' "$list_output"
128
+ sed -n '1,160p' "$status_output"
129
+ fi
130
+
131
+ CATALOG_HASH_AFTER="$(shasum -a 256 "$ROOT/kits/catalog.json" | awk '{print $1}')"
132
+ if [[ "$CATALOG_HASH_BEFORE" == "$CATALOG_HASH_AFTER" ]]; then
133
+ pass "local installs do not mutate source kits/catalog.json"
134
+ else
135
+ fail "source kits/catalog.json changed during local install test"
136
+ fi
137
+
138
+ echo ""
139
+ if [[ "$errors" -eq 0 ]]; then
140
+ echo "Local Flow Kit install checks passed."
141
+ exit 0
142
+ fi
143
+
144
+ echo "Local Flow Kit install checks failed: $errors issue(s)."
145
+ exit 1
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ SCRIPT="$ROOT/scripts/publish-change-helper.js"
6
+ TMPDIR_EVAL="$(mktemp -d)"
7
+ trap 'rm -rf "$TMPDIR_EVAL"' EXIT
8
+
9
+ errors=0
10
+ pass() { echo " ✓ $1"; }
11
+ fail() { echo " ✗ $1"; errors=$((errors + 1)); }
12
+
13
+ json_query() {
14
+ node -e 'const fs=require("fs"); let cur=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); for (const part of process.argv[2].split(".")) cur=Array.isArray(cur) ? cur[Number(part)] : cur[part]; console.log(cur);' "$1" "$2"
15
+ }
16
+
17
+ echo "=== Publish Change Helper ==="
18
+
19
+ BODY="$TMPDIR_EVAL/body.md"
20
+ cat > "$BODY" <<'MD'
21
+ Summary line.
22
+
23
+ - first item
24
+ - second item
25
+
26
+ ```sh
27
+ printf 'hello\n'
28
+ ```
29
+
30
+ Closes #60
31
+ MD
32
+
33
+ cat > "$TMPDIR_EVAL/render-input.json" <<JSON
34
+ {
35
+ "provider": "github",
36
+ "change_provider": {"role": "ChangeProvider", "kind": "github"},
37
+ "title": "Workflow hardening",
38
+ "body_file": "$BODY",
39
+ "expected_closing_refs": ["kontourai/flow-agents#60"]
40
+ }
41
+ JSON
42
+
43
+ node "$SCRIPT" render \
44
+ --input-json "$TMPDIR_EVAL/render-input.json" \
45
+ --body-out "$TMPDIR_EVAL/rendered-body.md" \
46
+ > "$TMPDIR_EVAL/rendered.json"
47
+ status=$?
48
+ [[ "$status" -eq 0 ]] && pass "renders change request successfully" || fail "renders change request successfully"
49
+
50
+ cmp -s "$BODY" "$TMPDIR_EVAL/rendered-body.md" && pass "body file rendering preserves multiline markdown exactly" || fail "body file rendering preserves multiline markdown exactly"
51
+ node -e 'const fs=require("fs"); const expected=fs.readFileSync(process.argv[1],"utf8"); const actual=JSON.parse(fs.readFileSync(process.argv[2],"utf8")).body; process.exit(actual === expected ? 0 : 1);' "$BODY" "$TMPDIR_EVAL/rendered.json"
52
+ [[ "$?" -eq 0 ]] && pass "rendered JSON body preserves real multiline text" || fail "rendered JSON body preserves real multiline text"
53
+ [[ "$(json_query "$TMPDIR_EVAL/rendered.json" "change_provider.role")" == "ChangeProvider" ]] && pass "rendered request keeps provider-neutral ChangeProvider role" || fail "rendered request keeps provider-neutral ChangeProvider role"
54
+
55
+ cat > "$TMPDIR_EVAL/closing-pass.json" <<'JSON'
56
+ {
57
+ "provider": "github",
58
+ "default_owner": "kontourai",
59
+ "default_repo": "flow-agents",
60
+ "expected_closing_refs": ["#60"],
61
+ "provider_output": {
62
+ "recognized_closing_refs": ["kontourai/flow-agents#60"]
63
+ }
64
+ }
65
+ JSON
66
+
67
+ node "$SCRIPT" validate-closing-refs \
68
+ --input-json "$TMPDIR_EVAL/closing-pass.json" \
69
+ > "$TMPDIR_EVAL/closing-pass.out"
70
+ status=$?
71
+ [[ "$status" -eq 0 ]] && pass "recognized closing refs pass validation" || fail "recognized closing refs pass validation"
72
+ [[ "$(json_query "$TMPDIR_EVAL/closing-pass.out" "status")" == "pass" ]] && pass "closing ref pass result is explicit" || fail "closing ref pass result is explicit"
73
+
74
+ cat > "$TMPDIR_EVAL/closing-missing.json" <<'JSON'
75
+ {
76
+ "provider": "github",
77
+ "default_owner": "kontourai",
78
+ "default_repo": "flow-agents",
79
+ "expected_closing_refs": ["#60"],
80
+ "provider_output": {
81
+ "recognized_closing_refs": []
82
+ }
83
+ }
84
+ JSON
85
+
86
+ if node "$SCRIPT" validate-closing-refs \
87
+ --input-json "$TMPDIR_EVAL/closing-missing.json" \
88
+ > "$TMPDIR_EVAL/closing-missing.out" \
89
+ 2> "$TMPDIR_EVAL/closing-missing.err"; then
90
+ fail "missing recognized closing refs should fail"
91
+ elif [[ "$(json_query "$TMPDIR_EVAL/closing-missing.out" "status")" == "fail" ]] && rg -q "missing recognized closing refs" "$TMPDIR_EVAL/closing-missing.err"; then
92
+ pass "missing closing refs fail with actionable output"
93
+ else
94
+ fail "missing closing refs failure was not actionable"
95
+ fi
96
+
97
+ cat > "$TMPDIR_EVAL/docs-files.json" <<'JSON'
98
+ {"files": ["docs/workflow-usage-guide.md", "docs/work-item-adapters.md"]}
99
+ JSON
100
+ cat > "$TMPDIR_EVAL/empty-checks.json" <<'JSON'
101
+ []
102
+ JSON
103
+
104
+ node "$SCRIPT" evaluate-provider-checks \
105
+ --change-files-json "$TMPDIR_EVAL/docs-files.json" \
106
+ --provider-checks-json "$TMPDIR_EVAL/empty-checks.json" \
107
+ > "$TMPDIR_EVAL/docs-checks.out"
108
+ status=$?
109
+ [[ "$status" -eq 0 ]] && pass "docs-only missing provider checks are accepted as skip" || fail "docs-only missing provider checks are accepted as skip"
110
+ [[ "$(json_query "$TMPDIR_EVAL/docs-checks.out" "evidence_status")" == "skip" ]] && pass "docs-only missing checks map to evidence skip" || fail "docs-only missing checks map to evidence skip"
111
+ [[ "$(json_query "$TMPDIR_EVAL/docs-checks.out" "release_gate_status")" == "not_required" ]] && pass "docs-only missing checks map to release not_required" || fail "docs-only missing checks map to release not_required"
112
+
113
+ for risk in runtime schema package hook security; do
114
+ case "$risk" in
115
+ runtime) path="scripts/flow-kit.js" ;;
116
+ schema) path="schemas/workflow-evidence.schema.json" ;;
117
+ package) path="package.json" ;;
118
+ hook) path="scripts/hooks/quality-gate.js" ;;
119
+ security) path="security/policy.md" ;;
120
+ esac
121
+ printf '{"files":["%s"]}\n' "$path" > "$TMPDIR_EVAL/$risk-files.json"
122
+ if node "$SCRIPT" evaluate-provider-checks \
123
+ --change-files-json "$TMPDIR_EVAL/$risk-files.json" \
124
+ --provider-checks-json "$TMPDIR_EVAL/empty-checks.json" \
125
+ > "$TMPDIR_EVAL/$risk-checks.out" \
126
+ 2> "$TMPDIR_EVAL/$risk-checks.err"; then
127
+ fail "$risk missing provider checks should not pass"
128
+ elif [[ "$(json_query "$TMPDIR_EVAL/$risk-checks.out" "evidence_status")" == "not_verified" ]] \
129
+ && [[ "$(json_query "$TMPDIR_EVAL/$risk-checks.out" "release_gate_status")" == "hold" ]]; then
130
+ pass "$risk missing provider checks map to not_verified and hold"
131
+ else
132
+ fail "$risk missing provider checks did not map to not_verified and hold"
133
+ fi
134
+ done
135
+
136
+ mkdir -p "$TMPDIR_EVAL/final-state"
137
+ cat > "$TMPDIR_EVAL/final-state/evidence.json" <<'JSON'
138
+ {
139
+ "schema_version": "1.0",
140
+ "task_slug": "final-state",
141
+ "updated_at": "2026-05-29T00:00:00Z",
142
+ "verdict": "pass",
143
+ "summary": "Final orchestrated evidence passed.",
144
+ "checks": [
145
+ {"id": "focused-tests", "kind": "test", "status": "pass", "summary": "Focused tests passed."}
146
+ ]
147
+ }
148
+ JSON
149
+ cat > "$TMPDIR_EVAL/final-state/release.json" <<'JSON'
150
+ {
151
+ "schema_version": "1.0",
152
+ "task_slug": "final-state",
153
+ "updated_at": "2026-05-29T00:00:00Z",
154
+ "decision": "merge",
155
+ "scope": "Final state reconciliation fixture.",
156
+ "summary": "Final release state passed.",
157
+ "evidence_ref": "evidence.json",
158
+ "gates": [
159
+ {"id": "merge", "kind": "merge", "status": "pass", "required": true, "summary": "Merge gate passed.", "evidence_refs": ["evidence.json"]}
160
+ ],
161
+ "rollback_plan": {"status": "not_required", "summary": "Merge-only fixture."}
162
+ }
163
+ JSON
164
+
165
+ node "$SCRIPT" reconcile-final-state "$TMPDIR_EVAL/final-state" > "$TMPDIR_EVAL/reconcile.out"
166
+ status=$?
167
+ [[ "$status" -eq 0 ]] && pass "final reconciled evidence and release sidecars pass" || fail "final reconciled evidence and release sidecars pass"
168
+ [[ "$(json_query "$TMPDIR_EVAL/reconcile.out" "status")" == "pass" ]] && pass "final reconciliation result is explicit" || fail "final reconciliation result is explicit"
169
+
170
+ if [[ "$errors" -eq 0 ]]; then
171
+ echo "Publish change helper checks passed"
172
+ else
173
+ echo "Publish change helper checks failed: $errors"
174
+ fi
175
+
176
+ exit "$errors"
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ SETTINGS="$ROOT/context/settings/backlog-provider-settings.json"
6
+ FIXTURE="$ROOT/evals/fixtures/pull-work-provider/github-issues.json"
7
+ SCRIPT="$ROOT/scripts/pull-work-provider.js"
8
+ TMPDIR_EVAL="$(mktemp -d)"
9
+ trap 'rm -rf "$TMPDIR_EVAL"' EXIT
10
+
11
+ errors=0
12
+ pass() { echo " ✓ $1"; }
13
+ fail() { echo " ✗ $1"; errors=$((errors + 1)); }
14
+
15
+ json_query() {
16
+ node -e 'const fs=require("fs"); let cur=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); for (const part of process.argv[2].split(".")) cur=part==="length" ? cur.length : (Array.isArray(cur) ? cur[Number(part)] : cur[part]); console.log(cur);' "$1" "$2"
17
+ }
18
+
19
+ echo "=== Pull Work Provider Normalization ==="
20
+
21
+ node "$SCRIPT" \
22
+ --settings-json "$SETTINGS" \
23
+ --issues-json "$FIXTURE" \
24
+ --resolved-ref 'kontourai/flow#2=closed' \
25
+ --current-ref main \
26
+ --current-sha cccccccccccccccccccccccccccccccccccccccc \
27
+ --changed-file docs/readme.md \
28
+ --commits-since dddddddddddddddddddddddddddddddddddddddd=2 \
29
+ --commits-since eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=12 \
30
+ --now 2026-06-03T00:00:00Z \
31
+ > "$TMPDIR_EVAL/normalized.json"
32
+ status=$?
33
+ [[ "$status" -eq 0 ]] && pass "normalizer exits successfully" || fail "normalizer exits successfully"
34
+
35
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.id")" == "github:kontourai/flow-agents#22" ]] && pass "normalizes provider-qualified id" || fail "normalizes provider-qualified id"
36
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.source_provider.role")" == "WorkItemProvider" ]] && pass "preserves work item provider ref" || fail "preserves work item provider ref"
37
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.board_membership.role")" == "BoardProvider" ]] && pass "preserves board provider ref" || fail "preserves board provider ref"
38
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.artifact_refs.0")" == ".flow-agents/flow-agents-kit-platform-backlog/flow-agents-kit-platform-backlog--idea-to-backlog.md" ]] && pass "preserves source artifact ref" || fail "preserves source artifact ref"
39
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.blockers.0.ref.owner")" == "kontourai" ]] && pass "preserves blocker owner" || fail "preserves blocker owner"
40
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.blockers.0.ref.repo")" == "flow" ]] && pass "preserves cross-repo blocker repo" || fail "preserves cross-repo blocker repo"
41
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.dependency_impacts.0.ref.owner")" == "kontourai" ]] && pass "projects prose blocker impact owner" || fail "projects prose blocker impact owner"
42
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.dependency_impacts.0.ref.repo")" == "flow" ]] && pass "projects prose blocker impact repo" || fail "projects prose blocker impact repo"
43
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.dependency_impacts.0.cross_repo")" == "true" ]] && pass "marks prose blocker impact cross-repo" || fail "marks prose blocker impact cross-repo"
44
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.dependency_impacts.0.known_status")" == "closed" ]] && pass "projects resolved prose blocker status" || fail "projects resolved prose blocker status"
45
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.dependency_impacts.0.impact_state")" == "resolved" ]] && pass "projects resolved prose blocker impact state" || fail "projects resolved prose blocker impact state"
46
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.0.readiness.classification")" == "ready" ]] && pass "#22 ready when flow#2 is closed" || fail "#22 ready when flow#2 is closed"
47
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.1.readiness.classification")" == "blocked" ]] && pass "blocked item classified blocked" || fail "blocked item classified blocked"
48
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.2.readiness.classification")" == "related-only" ]] && pass "research item classified related-only" || fail "research item classified related-only"
49
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.3.readiness.classification")" == "in_progress" ]] && pass "in-progress item classified in_progress" || fail "in-progress item classified in_progress"
50
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.4.readiness.classification")" == "stale" ]] && pass "old unshaped item classified stale" || fail "old unshaped item classified stale"
51
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.planned_base_ref")" == "main" ]] && pass "marker normalizes planned_base_ref" || fail "marker normalizes planned_base_ref"
52
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.planned_base_sha")" == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ]] && pass "marker normalizes planned_base_sha" || fail "marker normalizes planned_base_sha"
53
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.planned_at")" == "2026-06-03T03:23:14Z" ]] && pass "marker normalizes planned_at" || fail "marker normalizes planned_at"
54
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.planning_artifact_ref")" == ".flow-agents/idea-to-backlog-source-revision-structured-blockers/idea-to-backlog-source-revision-structured-blockers--plan.md" ]] && pass "marker normalizes planning_artifact_ref" || fail "marker normalizes planning_artifact_ref"
55
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.planning_scope_refs.0")" == "skills/idea-to-backlog/SKILL.md" ]] && pass "marker normalizes planning_scope_refs" || fail "marker normalizes planning_scope_refs"
56
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.source_revisions.1.repo")" == "kontourai/flow" ]] && pass "marker preserves repo-scoped source_revisions" || fail "marker preserves repo-scoped source_revisions"
57
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.0.ref.owner")" == "kontourai" ]] && pass "structured blocker preserves provider owner" || fail "structured blocker preserves provider owner"
58
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.0.ref.repo")" == "flow" ]] && pass "structured blocker preserves provider repo" || fail "structured blocker preserves provider repo"
59
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.0.ref.number")" == "2" ]] && pass "structured blocker preserves provider number" || fail "structured blocker preserves provider number"
60
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.1.type")" == "text" ]] && pass "structured blocker preserves text blocker" || fail "structured blocker preserves text blocker"
61
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.1.evidence")" == "Product decision on rollout scope." ]] && pass "structured blocker preserves text evidence" || fail "structured blocker preserves text evidence"
62
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.blockers.2.evidence")" == "Blocked by product decision on rollout scope." ]] && pass "prose blocker remains alongside structured blockers" || fail "prose blocker remains alongside structured blockers"
63
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.5.readiness.classification")" == "blocked" ]] && pass "text blocker keeps marker item blocked" || fail "text blocker keeps marker item blocked"
64
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.6.blockers.0.ref.repo")" == "flow-agents" ]] && pass "invalid marker falls back to prose blocker repo" || fail "invalid marker falls back to prose blocker repo"
65
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.6.readiness.classification")" == "blocked" ]] && pass "invalid marker fallback preserves blocked readiness" || fail "invalid marker fallback preserves blocked readiness"
66
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.7.revision_freshness.classification")" == "fresh" ]] && pass "fresh item freshness classified fresh" || fail "fresh item freshness classified fresh"
67
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.7.revision_freshness.planned_base_sha")" == "cccccccccccccccccccccccccccccccccccccccc" ]] && pass "freshness preserves planned base sha" || fail "freshness preserves planned base sha"
68
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.7.revision_freshness.current_sha")" == "cccccccccccccccccccccccccccccccccccccccc" ]] && pass "freshness reports current sha" || fail "freshness reports current sha"
69
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.7.revision_freshness.planned_age_days")" == "1" ]] && pass "freshness reports planned age" || fail "freshness reports planned age"
70
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.8.revision_freshness.classification")" == "drifted" ]] && pass "drifted item freshness classified drifted" || fail "drifted item freshness classified drifted"
71
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.8.revision_freshness.commits_since_planned_base")" == "2" ]] && pass "drifted item reports commits since planned base" || fail "drifted item reports commits since planned base"
72
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.8.revision_freshness.planning_scope_intersections.length")" == "0" ]] && pass "drifted item reports no scope intersections" || fail "drifted item reports no scope intersections"
73
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.9.revision_freshness.classification")" == "stale" ]] && pass "stale item freshness classified stale" || fail "stale item freshness classified stale"
74
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.9.revision_freshness.route_recommendation.target")" == "idea-to-backlog" ]] && pass "stale item routes back to idea-to-backlog" || fail "stale item routes back to idea-to-backlog"
75
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.9.readiness.classification")" == "stale" ]] && pass "stale freshness constrains readiness" || fail "stale freshness constrains readiness"
76
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.10.revision_freshness.classification")" == "not_verified" ]] && pass "legacy item without planned_base_sha is not_verified" || fail "legacy item without planned_base_sha is not_verified"
77
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.10.revision_freshness.reasons.0.code")" == "missing_planned_base_sha" ]] && pass "legacy item records missing planned_base_sha reason" || fail "legacy item records missing planned_base_sha reason"
78
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.10.readiness.classification")" == "ready" ]] && pass "legacy freshness gap preserves readiness while reporting not_verified freshness" || fail "legacy freshness gap preserves readiness while reporting not_verified freshness"
79
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.blockers.0.ref.owner")" == "kontourai" ]] && pass "structured-only blocker preserves owner" || fail "structured-only blocker preserves owner"
80
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.blockers.0.ref.repo")" == "flow" ]] && pass "structured-only blocker preserves cross-repo repo" || fail "structured-only blocker preserves cross-repo repo"
81
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.blockers.0.ref.number")" == "2" ]] && pass "structured-only blocker preserves number" || fail "structured-only blocker preserves number"
82
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.ref.owner")" == "kontourai" ]] && pass "structured-only dependency impact preserves owner" || fail "structured-only dependency impact preserves owner"
83
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.ref.repo")" == "flow" ]] && pass "structured-only dependency impact preserves repo" || fail "structured-only dependency impact preserves repo"
84
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.ref.number")" == "2" ]] && pass "structured-only dependency impact preserves number" || fail "structured-only dependency impact preserves number"
85
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.source.type")" == "provider_ref" ]] && pass "structured-only dependency impact records source blocker type" || fail "structured-only dependency impact records source blocker type"
86
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.source.evidence")" == "Requires Flow contract issue first." ]] && pass "structured-only dependency impact records source evidence" || fail "structured-only dependency impact records source evidence"
87
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.cross_repo")" == "true" ]] && pass "structured-only dependency impact is cross-repo" || fail "structured-only dependency impact is cross-repo"
88
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.known_status")" == "closed" ]] && pass "structured-only dependency impact records resolved status" || fail "structured-only dependency impact records resolved status"
89
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.dependency_impacts.0.impact_state")" == "resolved" ]] && pass "structured-only dependency impact state is resolved" || fail "structured-only dependency impact state is resolved"
90
+ [[ "$(json_query "$TMPDIR_EVAL/normalized.json" "items.11.readiness.classification")" == "ready" ]] && pass "structured-only item ready when cross-repo blocker is closed" || fail "structured-only item ready when cross-repo blocker is closed"
91
+
92
+ node "$SCRIPT" \
93
+ --settings-json "$SETTINGS" \
94
+ --issues-json "$FIXTURE" \
95
+ --current-ref main \
96
+ --current-sha ffffffffffffffffffffffffffffffffffffffff \
97
+ --now 2026-06-03T00:00:00Z \
98
+ > "$TMPDIR_EVAL/missing-drift-evidence.json"
99
+ [[ "$(json_query "$TMPDIR_EVAL/missing-drift-evidence.json" "items.8.revision_freshness.classification")" == "not_verified" ]] && pass "moved target without drift evidence is not_verified" || fail "moved target without drift evidence is not_verified"
100
+ [[ "$(json_query "$TMPDIR_EVAL/missing-drift-evidence.json" "items.8.revision_freshness.reasons.1.code")" == "missing_drift_evidence" ]] && pass "moved target records missing drift evidence reason" || fail "moved target records missing drift evidence reason"
101
+ [[ "$(json_query "$TMPDIR_EVAL/missing-drift-evidence.json" "items.8.readiness.classification")" == "blocked" ]] && pass "missing drift evidence blocks ready classification" || fail "missing drift evidence blocks ready classification"
102
+
103
+ node "$SCRIPT" \
104
+ --settings-json "$SETTINGS" \
105
+ --issues-json "$FIXTURE" \
106
+ --current-ref main \
107
+ --current-sha cccccccccccccccccccccccccccccccccccccccc \
108
+ --changed-file context/contracts/work-item-contract.md \
109
+ --commits-since dddddddddddddddddddddddddddddddddddddddd=2 \
110
+ --now 2026-06-03T00:00:00Z \
111
+ > "$TMPDIR_EVAL/material-contract-drift.json"
112
+ [[ "$(json_query "$TMPDIR_EVAL/material-contract-drift.json" "items.8.revision_freshness.classification")" == "stale" ]] && pass "contract drift marks non-scoped planned item stale" || fail "contract drift marks non-scoped planned item stale"
113
+ [[ "$(json_query "$TMPDIR_EVAL/material-contract-drift.json" "items.8.revision_freshness.reasons.2.code")" == "material_freshness_files_changed" ]] && pass "contract drift records material freshness reason" || fail "contract drift records material freshness reason"
114
+ [[ "$(json_query "$TMPDIR_EVAL/material-contract-drift.json" "items.9.revision_freshness.planning_scope_intersections.0")" == "context/contracts/work-item-contract.md" ]] && pass "stale item reports planning scope intersection" || fail "stale item reports planning scope intersection"
115
+
116
+ node "$SCRIPT" \
117
+ --settings-json - \
118
+ --issues-json "$FIXTURE" \
119
+ --resolved-ref 'kontourai/flow#2=closed' \
120
+ < "$SETTINGS" \
121
+ > "$TMPDIR_EVAL/stdin-settings.json"
122
+ [[ "$(json_query "$TMPDIR_EVAL/stdin-settings.json" "items.0.readiness.classification")" == "ready" ]] && pass "normalizer accepts stdin settings JSON" || fail "normalizer accepts stdin settings JSON"
123
+
124
+ node "$SCRIPT" \
125
+ --settings-json "$SETTINGS" \
126
+ --issues-json "$FIXTURE" \
127
+ > "$TMPDIR_EVAL/unresolved.json"
128
+ [[ "$(json_query "$TMPDIR_EVAL/unresolved.json" "items.0.readiness.classification")" == "blocked" ]] && pass "#22 blocked when flow#2 state is unknown" || fail "#22 blocked when flow#2 state is unknown"
129
+ [[ "$(json_query "$TMPDIR_EVAL/unresolved.json" "items.5.readiness.classification")" == "blocked" ]] && pass "marker item blocked when provider ref and text blocker are unresolved" || fail "marker item blocked when provider ref and text blocker are unresolved"
130
+ [[ "$(json_query "$TMPDIR_EVAL/unresolved.json" "items.11.dependency_impacts.0.known_status")" == "unknown" ]] && pass "structured-only dependency impact records unknown status without resolved ref" || fail "structured-only dependency impact records unknown status without resolved ref"
131
+ [[ "$(json_query "$TMPDIR_EVAL/unresolved.json" "items.11.dependency_impacts.0.impact_state")" == "unknown" ]] && pass "structured-only dependency impact state is unknown without resolved ref" || fail "structured-only dependency impact state is unknown without resolved ref"
132
+ [[ "$(json_query "$TMPDIR_EVAL/unresolved.json" "items.11.readiness.classification")" == "blocked" ]] && pass "structured-only blocker blocks without prose parsing" || fail "structured-only blocker blocks without prose parsing"
133
+
134
+ if [[ "$errors" -eq 0 ]]; then
135
+ echo "Pull work provider checks passed"
136
+ else
137
+ echo "Pull work provider checks failed: $errors"
138
+ fi
139
+
140
+ exit "$errors"