@hassangameryt/freeflow 0.3.0 → 0.5.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 (692) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +6 -2
  3. package/.codex-plugin/plugin.json +9 -9
  4. package/README.md +190 -127
  5. package/assets/feedback-loop.png +0 -0
  6. package/assets/freeflow_workflow_map.png +0 -0
  7. package/assets/workflow.png +0 -0
  8. package/{skills → capabilities}/output-router/SKILL.md +21 -17
  9. package/{skills → capabilities}/output-router/references/safety-policy.md +1 -1
  10. package/capabilities/output-router/references/setup.md +110 -0
  11. package/command-surface.json +62 -7
  12. package/hooks/freeflow-runtime-context.mjs +572 -154
  13. package/hooks/hooks.json +26 -1
  14. package/hooks/tests/check-runtime-context-hook.sh +375 -0
  15. package/package.json +24 -24
  16. package/pi-extension/dist/index.js +264 -80
  17. package/pi-extension/dist/integrations/mcp-config.js +29 -0
  18. package/pi-extension/dist/output-router/host-producer-identification.js +232 -0
  19. package/pi-extension/dist/output-router/native-safety-net.js +216 -0
  20. package/pi-extension/dist/output-router/observed-tool-routing.js +122 -0
  21. package/pi-extension/dist/output-router/renderers.js +1023 -0
  22. package/pi-extension/dist/output-router/router-tools.js +554 -0
  23. package/pi-extension/dist/output-router/schemas.js +383 -0
  24. package/pi-extension/dist/output-router/status.js +744 -0
  25. package/pi-extension/dist/output-router/utils.js +502 -0
  26. package/pi-extension/dist/runtime/runtime-context.js +798 -0
  27. package/pi-extension/dist/settings/settings-tui.js +314 -0
  28. package/pi-extension/dist/settings/settings-ui.js +1487 -0
  29. package/pi-extension/freeflow/index.js +1 -0
  30. package/pi-extension/src/index.ts +230 -56
  31. package/pi-extension/src/{host-producer-identification.ts → output-router/host-producer-identification.ts} +37 -7
  32. package/pi-extension/src/{native-safety-net.ts → output-router/native-safety-net.ts} +8 -12
  33. package/pi-extension/src/{observed-tool-routing.ts → output-router/observed-tool-routing.ts} +19 -11
  34. package/pi-extension/src/{renderers.ts → output-router/renderers.ts} +246 -55
  35. package/pi-extension/src/{router-tools.ts → output-router/router-tools.ts} +130 -29
  36. package/pi-extension/src/{schemas.ts → output-router/schemas.ts} +171 -43
  37. package/pi-extension/src/output-router/status.ts +791 -0
  38. package/pi-extension/src/{utils.ts → output-router/utils.ts} +80 -18
  39. package/pi-extension/src/runtime/runtime-context.ts +895 -0
  40. package/pi-extension/src/settings/settings-tui.ts +408 -0
  41. package/pi-extension/src/settings/settings-ui.ts +1730 -0
  42. package/pi-extension/tests/integration/pi-extension.test.js +4020 -0
  43. package/pi-extension/tests/output-router/observed-producers.test.js +132 -0
  44. package/pi-extension/tests/output-router/search.test.js +722 -0
  45. package/pi-extension/tests/settings/settings-tui.test.js +243 -0
  46. package/router/dist/benchmarks/benchmark-harness.d.ts +16 -13
  47. package/router/dist/benchmarks/benchmark-harness.js +62 -62
  48. package/router/dist/benchmarks/benchmarks.d.ts +80 -73
  49. package/router/dist/benchmarks/benchmarks.js +860 -761
  50. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +71 -67
  51. package/router/dist/benchmarks/codex-qa-benchmarks.js +429 -390
  52. package/router/dist/benchmarks/command-benchmarks.d.ts +107 -92
  53. package/router/dist/benchmarks/command-benchmarks.js +616 -571
  54. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +64 -56
  55. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +679 -613
  56. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +103 -95
  57. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +1188 -1103
  58. package/router/dist/benchmarks/context-saving-baseline.d.ts +47 -41
  59. package/router/dist/benchmarks/context-saving-baseline.js +405 -374
  60. package/router/dist/benchmarks/index-benchmarks.d.ts +74 -69
  61. package/router/dist/benchmarks/index-benchmarks.js +761 -661
  62. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +80 -69
  63. package/router/dist/benchmarks/storage-policy-benchmarks.js +549 -469
  64. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +43 -34
  65. package/router/dist/benchmarks/vault-index-benchmarks.js +294 -229
  66. package/router/dist/config/config.d.ts +62 -55
  67. package/router/dist/config/config.js +552 -373
  68. package/router/dist/config/router-contract.d.ts +2 -2
  69. package/router/dist/config/router-contract.js +38 -38
  70. package/router/dist/config/schema.d.ts +19 -10
  71. package/router/dist/config/schema.js +586 -538
  72. package/router/dist/config/types.d.ts +413 -361
  73. package/router/dist/config/types.js +19 -8
  74. package/router/dist/evidence/bounded-evidence.d.ts +26 -26
  75. package/router/dist/evidence/bounded-evidence.js +265 -252
  76. package/router/dist/evidence/evidence-range-selector.d.ts +16 -14
  77. package/router/dist/evidence/evidence-range-selector.js +192 -191
  78. package/router/dist/evidence/evidence-search.d.ts +18 -16
  79. package/router/dist/evidence/evidence-search.js +401 -377
  80. package/router/dist/evidence/evidence.d.ts +17 -17
  81. package/router/dist/evidence/evidence.js +163 -159
  82. package/router/dist/evidence/failure-contracts.d.ts +25 -15
  83. package/router/dist/evidence/failure-contracts.js +132 -126
  84. package/router/dist/evidence/line-ranges.d.ts +17 -15
  85. package/router/dist/evidence/line-ranges.js +18 -18
  86. package/router/dist/experiments/local-index.d.ts +47 -41
  87. package/router/dist/experiments/local-index.js +477 -458
  88. package/router/dist/local/local-traversal.d.ts +18 -0
  89. package/router/dist/local/local-traversal.js +334 -0
  90. package/router/dist/processing/engine.d.ts +94 -70
  91. package/router/dist/processing/engine.js +462 -364
  92. package/router/dist/processing/reducers.d.ts +208 -194
  93. package/router/dist/processing/reducers.js +1434 -1256
  94. package/router/dist/processing/renderers.d.ts +24 -18
  95. package/router/dist/processing/renderers.js +161 -152
  96. package/router/dist/processing/scripts.d.ts +80 -67
  97. package/router/dist/processing/scripts.js +343 -290
  98. package/router/dist/repo/repo-traversal.d.ts +9 -9
  99. package/router/dist/repo/repo-traversal.js +205 -202
  100. package/router/dist/routing/observed-reducers.d.ts +25 -19
  101. package/router/dist/routing/observed-reducers.js +559 -545
  102. package/router/dist/routing/observed-routing.d.ts +23 -14
  103. package/router/dist/routing/observed-routing.js +319 -318
  104. package/router/dist/routing/parsers.d.ts +10 -10
  105. package/router/dist/routing/parsers.js +454 -406
  106. package/router/dist/routing/run-filters.d.ts +45 -41
  107. package/router/dist/routing/run-filters.js +215 -207
  108. package/router/dist/routing/run-reducers.d.ts +45 -26
  109. package/router/dist/routing/run-reducers.js +102 -90
  110. package/router/dist/sandbox/adapter-roots.d.ts +34 -26
  111. package/router/dist/sandbox/adapter-roots.js +43 -41
  112. package/router/dist/sandbox/eryx-python-adapter.d.ts +9 -5
  113. package/router/dist/sandbox/eryx-python-adapter.js +659 -588
  114. package/router/dist/sandbox/jq-wasm-adapter.d.ts +3 -3
  115. package/router/dist/sandbox/jq-wasm-adapter.js +319 -311
  116. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +9 -5
  117. package/router/dist/sandbox/quickjs-wasi-adapter.js +336 -333
  118. package/router/dist/sandbox/script-sandbox.d.ts +105 -84
  119. package/router/dist/sandbox/script-sandbox.js +294 -260
  120. package/router/dist/setup/script-transform-adapters.d.ts +23 -19
  121. package/router/dist/setup/script-transform-adapters.js +223 -204
  122. package/router/dist/tools/batch.d.ts +27 -16
  123. package/router/dist/tools/batch.js +493 -416
  124. package/router/dist/tools/run.d.ts +47 -35
  125. package/router/dist/tools/run.js +1172 -1087
  126. package/router/dist/tools/search.d.ts +53 -31
  127. package/router/dist/tools/search.js +1224 -1065
  128. package/router/dist/transform/engine.d.ts +121 -96
  129. package/router/dist/transform/engine.js +1853 -1736
  130. package/router/dist/vault/vault-index.d.ts +97 -78
  131. package/router/dist/vault/vault-index.js +347 -342
  132. package/router/dist/vault/vault.d.ts +109 -74
  133. package/router/dist/vault/vault.js +528 -533
  134. package/runtime/interaction-contract.md +16 -0
  135. package/skills/bypass/SKILL.md +52 -38
  136. package/skills/commit-work/SKILL.md +54 -46
  137. package/skills/commit-work/references/staging-decisions.md +46 -24
  138. package/skills/decision-gate/SKILL.md +48 -0
  139. package/skills/design-for-depth/SKILL.md +75 -59
  140. package/skills/design-for-depth/references/design-pressure-signals.md +56 -7
  141. package/skills/design-for-depth/references/interface-design-loop.md +156 -0
  142. package/skills/design-for-depth/references/software-design-philosophy.md +32 -3
  143. package/skills/diagnose-failure/SKILL.md +65 -60
  144. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +36 -0
  145. package/skills/diagnose-failure/references/flaky-and-performance.md +30 -18
  146. package/skills/discuss/SKILL.md +121 -0
  147. package/skills/discuss/references/checkpoints.md +66 -0
  148. package/skills/evaluate-skill/SKILL.md +62 -53
  149. package/skills/evaluate-skill/references/definition-schema.md +345 -0
  150. package/skills/evaluate-skill/references/evaluation-design.md +86 -0
  151. package/skills/evaluate-skill/references/execution-and-evidence.md +85 -0
  152. package/skills/evaluate-skill/references/review-and-revision.md +51 -0
  153. package/skills/evaluate-skill/scripts/lib/definitions.mjs +296 -0
  154. package/skills/evaluate-skill/scripts/lib/evidence.mjs +46 -0
  155. package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +60 -0
  156. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +148 -0
  157. package/skills/evaluate-skill/scripts/lib/grade-support.mjs +126 -0
  158. package/skills/evaluate-skill/scripts/lib/grade-workspace.mjs +192 -0
  159. package/skills/evaluate-skill/scripts/lib/grade.mjs +56 -0
  160. package/skills/evaluate-skill/scripts/lib/pi.mjs +489 -0
  161. package/skills/evaluate-skill/scripts/lib/process.mjs +79 -0
  162. package/skills/evaluate-skill/scripts/lib/rpc.mjs +444 -0
  163. package/skills/evaluate-skill/scripts/lib/runner.mjs +346 -0
  164. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +409 -0
  165. package/skills/evaluate-skill/scripts/lib/view.mjs +337 -0
  166. package/skills/evaluate-skill/scripts/pi-guard.mjs +164 -0
  167. package/skills/evaluate-skill/scripts/skill-eval.mjs +101 -0
  168. package/skills/execute-work/SKILL.md +99 -0
  169. package/skills/execute-work/references/code-practices.md +78 -0
  170. package/skills/execute-work/references/execution-loop.md +77 -0
  171. package/skills/finish-branch/SKILL.md +117 -0
  172. package/skills/finish-branch/references/integration-options.md +80 -0
  173. package/skills/handoff/SKILL.md +65 -39
  174. package/skills/handoff/references/templates.md +104 -27
  175. package/skills/launch-work/SKILL.md +116 -0
  176. package/skills/launch-work/references/launch-readiness.md +85 -0
  177. package/skills/migration-work/SKILL.md +115 -0
  178. package/skills/migration-work/references/migration-lifecycle.md +82 -0
  179. package/skills/mode-contract/SKILL.md +72 -52
  180. package/skills/release-work/SKILL.md +118 -0
  181. package/skills/release-work/references/release-evidence.md +78 -0
  182. package/skills/review-artifact/SKILL.md +77 -69
  183. package/skills/review-artifact/references/reviewer-prompt.md +133 -42
  184. package/skills/review-work/SKILL.md +82 -57
  185. package/skills/review-work/references/reviewer-prompt.md +97 -60
  186. package/skills/review-work/references/security-risk-lens.md +67 -0
  187. package/skills/setup-freeflow/SKILL.md +54 -68
  188. package/skills/setup-freeflow/references/activation-contract.md +84 -69
  189. package/skills/setup-freeflow/references/host-setup.md +50 -17
  190. package/skills/simplify-code/SKILL.md +80 -0
  191. package/skills/simplify-code/references/simplification-patterns.md +70 -0
  192. package/skills/tdd/SKILL.md +96 -0
  193. package/skills/tdd/references/test-design.md +96 -0
  194. package/skills/track-work/SKILL.md +84 -0
  195. package/skills/track-work/references/working-record-schema.md +378 -0
  196. package/skills/verify-work/SKILL.md +59 -38
  197. package/skills/verify-work/references/browser-runtime-evidence.md +55 -0
  198. package/skills/verify-work/references/integration-evidence.md +51 -0
  199. package/skills/verify-work/references/performance-evidence.md +57 -0
  200. package/skills/workflow/SKILL.md +53 -59
  201. package/skills/workflow/references/domain-skill-composition.md +57 -0
  202. package/skills/workflow/references/workflow-loop.md +92 -0
  203. package/skills/write-plan/SKILL.md +85 -58
  204. package/skills/write-plan/references/plan-shapes.md +132 -46
  205. package/skills/write-skill/SKILL.md +82 -51
  206. package/skills/write-skill/references/activation-boundaries.md +62 -0
  207. package/skills/write-skill/references/agent-first-instructions.md +87 -0
  208. package/skills/write-skill/references/progressive-disclosure.md +63 -0
  209. package/skills/write-skill/scripts/lib/skill-author.mjs +653 -0
  210. package/skills/write-skill/scripts/skill-author.mjs +104 -0
  211. package/skills/write-spec/SKILL.md +65 -54
  212. package/skills/write-spec/references/artifact-standards.md +60 -41
  213. package/skills/write-spec/references/decision-records.md +77 -0
  214. package/skills/write-spec/references/spec-shapes.md +119 -60
  215. package/evals/README.md +0 -32
  216. package/evals/fixtures/copy-conventions.md +0 -31
  217. package/evals/fixtures/output-router/README.md +0 -12
  218. package/evals/fixtures/output-router/failed-command-output.txt +0 -9
  219. package/evals/fixtures/output-router/large-router-manual.md +0 -63
  220. package/evals/fixtures/output-router/native-large-output.txt +0 -40
  221. package/evals/fixtures/output-router/noisy-test-output.txt +0 -30
  222. package/evals/fixtures/output-router/verification-output.txt +0 -8
  223. package/evals/fixtures/tiny-artifact-review-app/README.md +0 -5
  224. package/evals/fixtures/tiny-artifact-review-app/docs/billing-policy.md +0 -10
  225. package/evals/fixtures/tiny-artifact-review-app/docs/specs/billing-webhook-api-draft.md +0 -21
  226. package/evals/fixtures/tiny-artifact-review-app/docs/specs/failed-payment-grace-period.md +0 -24
  227. package/evals/fixtures/tiny-artifact-review-app/docs/specs/immediate-downgrade.md +0 -17
  228. package/evals/fixtures/tiny-artifact-review-app/tests/billing.test.md +0 -8
  229. package/evals/fixtures/tiny-commit-ambiguous-app/.freeflow-eval-setup.sh +0 -15
  230. package/evals/fixtures/tiny-commit-ambiguous-app/README.md +0 -3
  231. package/evals/fixtures/tiny-commit-ambiguous-app/src/billing.ts +0 -5
  232. package/evals/fixtures/tiny-commit-ambiguous-app/src/settings-page.ts +0 -1
  233. package/evals/fixtures/tiny-commit-ambiguous-app/tests/settings.test.md +0 -5
  234. package/evals/fixtures/tiny-commit-app/.freeflow-eval-setup.sh +0 -14
  235. package/evals/fixtures/tiny-commit-app/README.md +0 -3
  236. package/evals/fixtures/tiny-commit-app/docs/specs/settings-title.md +0 -5
  237. package/evals/fixtures/tiny-commit-app/src/billing.ts +0 -5
  238. package/evals/fixtures/tiny-commit-app/src/settings-page.ts +0 -1
  239. package/evals/fixtures/tiny-commit-app/tests/settings.test.md +0 -5
  240. package/evals/fixtures/tiny-commit-everything-app/.freeflow-eval-setup.sh +0 -15
  241. package/evals/fixtures/tiny-commit-everything-app/README.md +0 -3
  242. package/evals/fixtures/tiny-commit-everything-app/docs/specs/settings-title.md +0 -5
  243. package/evals/fixtures/tiny-commit-everything-app/src/billing.ts +0 -5
  244. package/evals/fixtures/tiny-commit-everything-app/src/settings-page.ts +0 -1
  245. package/evals/fixtures/tiny-commit-everything-app/tests/settings.test.md +0 -5
  246. package/evals/fixtures/tiny-commit-staged-app/.freeflow-eval-setup.sh +0 -15
  247. package/evals/fixtures/tiny-commit-staged-app/README.md +0 -3
  248. package/evals/fixtures/tiny-commit-staged-app/docs/specs/settings-title.md +0 -5
  249. package/evals/fixtures/tiny-commit-staged-app/src/billing.ts +0 -5
  250. package/evals/fixtures/tiny-commit-staged-app/src/settings-page.ts +0 -1
  251. package/evals/fixtures/tiny-commit-staged-app/tests/settings.test.md +0 -5
  252. package/evals/fixtures/tiny-commit-staged-mixed-app/.freeflow-eval-setup.sh +0 -15
  253. package/evals/fixtures/tiny-commit-staged-mixed-app/README.md +0 -3
  254. package/evals/fixtures/tiny-commit-staged-mixed-app/docs/billing-policy.md +0 -3
  255. package/evals/fixtures/tiny-commit-staged-mixed-app/docs/release-notes.md +0 -3
  256. package/evals/fixtures/tiny-commit-staged-mixed-app/src/billing.ts +0 -5
  257. package/evals/fixtures/tiny-dashboard-stale-app/README.md +0 -11
  258. package/evals/fixtures/tiny-dashboard-stale-app/src/api-client.ts +0 -13
  259. package/evals/fixtures/tiny-dashboard-stale-app/src/dashboard-data.ts +0 -19
  260. package/evals/fixtures/tiny-dashboard-stale-app/tests/dashboard-data.test.md +0 -9
  261. package/evals/fixtures/tiny-decision-destination-app/README.md +0 -6
  262. package/evals/fixtures/tiny-decision-destination-app/src/risk.ts +0 -8
  263. package/evals/fixtures/tiny-decision-destination-app/tests/risk.test.md +0 -4
  264. package/evals/fixtures/tiny-design-depth-app/README.md +0 -15
  265. package/evals/fixtures/tiny-design-depth-app/src/routes.ts +0 -25
  266. package/evals/fixtures/tiny-design-depth-app/src/sendEmail.ts +0 -3
  267. package/evals/fixtures/tiny-design-depth-app/src/sendSms.ts +0 -3
  268. package/evals/fixtures/tiny-design-depth-app/src/telemetry.ts +0 -3
  269. package/evals/fixtures/tiny-design-depth-app/tests/routes.test.md +0 -12
  270. package/evals/fixtures/tiny-eval-method-app/README.md +0 -8
  271. package/evals/fixtures/tiny-eval-method-app/evals/reports/review-pr-eval-result.md +0 -5
  272. package/evals/fixtures/tiny-eval-method-app/evals/reports/triage-question-failure.md +0 -17
  273. package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.diff +0 -11
  274. package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.md +0 -3
  275. package/evals/fixtures/tiny-eval-method-app/skills/review-pr/SKILL.md +0 -10
  276. package/evals/fixtures/tiny-eval-method-app/skills/triage-question/SKILL.md +0 -10
  277. package/evals/fixtures/tiny-execute-plan-app/README.md +0 -5
  278. package/evals/fixtures/tiny-execute-plan-app/checks/settings-and-billing-check.sh +0 -5
  279. package/evals/fixtures/tiny-execute-plan-app/docs/billing-policy.md +0 -10
  280. package/evals/fixtures/tiny-execute-plan-app/docs/plans/immediate-downgrade-plan.md +0 -11
  281. package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-plan.md +0 -12
  282. package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-with-bad-check.md +0 -15
  283. package/evals/fixtures/tiny-execute-plan-app/docs/plans/unverified-billing-plan.md +0 -9
  284. package/evals/fixtures/tiny-execute-plan-app/docs/specs/failed-payment-grace-period.md +0 -9
  285. package/evals/fixtures/tiny-execute-plan-app/docs/specs/settings-title.md +0 -9
  286. package/evals/fixtures/tiny-execute-plan-app/src/billing.ts +0 -7
  287. package/evals/fixtures/tiny-execute-plan-app/src/settings-page.ts +0 -1
  288. package/evals/fixtures/tiny-execute-plan-app/tests/billing.test.md +0 -7
  289. package/evals/fixtures/tiny-execute-plan-app/tests/settings.test.md +0 -5
  290. package/evals/fixtures/tiny-execute-review-loop-app/README.md +0 -5
  291. package/evals/fixtures/tiny-execute-review-loop-app/docs/billing-policy.md +0 -9
  292. package/evals/fixtures/tiny-execute-review-loop-app/docs/plans/settings-title-plan.md +0 -12
  293. package/evals/fixtures/tiny-execute-review-loop-app/docs/review/previous-agent-summary.md +0 -15
  294. package/evals/fixtures/tiny-execute-review-loop-app/docs/review/review-pass-1-non-pass.md +0 -11
  295. package/evals/fixtures/tiny-execute-review-loop-app/docs/specs/settings-title.md +0 -9
  296. package/evals/fixtures/tiny-execute-review-loop-app/src/billing.ts +0 -7
  297. package/evals/fixtures/tiny-execute-review-loop-app/src/settings-page.ts +0 -1
  298. package/evals/fixtures/tiny-execute-review-loop-app/tests/billing.test.md +0 -7
  299. package/evals/fixtures/tiny-execute-review-loop-app/tests/settings.test.md +0 -5
  300. package/evals/fixtures/tiny-flaky-session-app/README.md +0 -10
  301. package/evals/fixtures/tiny-flaky-session-app/src/session-timeout.ts +0 -13
  302. package/evals/fixtures/tiny-flaky-session-app/tests/session-timeout.test.md +0 -8
  303. package/evals/fixtures/tiny-handoff-app/README.md +0 -5
  304. package/evals/fixtures/tiny-handoff-app/docs/billing-policy.md +0 -10
  305. package/evals/fixtures/tiny-handoff-app/docs/handoffs/old-agent-handoff.md +0 -8
  306. package/evals/fixtures/tiny-handoff-app/docs/plans/billing-retry-plan.md +0 -11
  307. package/evals/fixtures/tiny-handoff-app/src/billing.ts +0 -7
  308. package/evals/fixtures/tiny-handoff-report-app/README.md +0 -3
  309. package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.diff +0 -1
  310. package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.md +0 -1
  311. package/evals/fixtures/tiny-handoff-report-app/evals/scores/hof-003-score.txt +0 -4
  312. package/evals/fixtures/tiny-plan-app/README.md +0 -5
  313. package/evals/fixtures/tiny-plan-app/docs/billing-policy.md +0 -10
  314. package/evals/fixtures/tiny-plan-app/docs/specs/failed-payment-grace-period.md +0 -25
  315. package/evals/fixtures/tiny-plan-app/src/billing.ts +0 -17
  316. package/evals/fixtures/tiny-plan-app/src/settings-page.ts +0 -1
  317. package/evals/fixtures/tiny-plan-app/tests/billing.test.md +0 -8
  318. package/evals/fixtures/tiny-plan-app/tests/settings.test.md +0 -5
  319. package/evals/fixtures/tiny-plan-strict-api-app/README.md +0 -3
  320. package/evals/fixtures/tiny-plan-strict-api-app/docs/billing-policy.md +0 -5
  321. package/evals/fixtures/tiny-plan-strict-api-app/docs/specs/billing-webhook-api.md +0 -25
  322. package/evals/fixtures/tiny-plan-strict-api-app/src/billing.ts +0 -5
  323. package/evals/fixtures/tiny-plan-strict-api-app/src/webhooks.ts +0 -3
  324. package/evals/fixtures/tiny-plan-strict-api-app/tests/billing-webhook.test.md +0 -8
  325. package/evals/fixtures/tiny-post-setup-invalid-config-app/.freeflow/config.json +0 -3
  326. package/evals/fixtures/tiny-post-setup-invalid-config-app/AGENTS.md +0 -15
  327. package/evals/fixtures/tiny-post-setup-invalid-config-app/README.md +0 -16
  328. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/auth-review.md +0 -15
  329. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/billing-policy.md +0 -10
  330. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/copy-conventions.md +0 -15
  331. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/auth-middleware.ts +0 -12
  332. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/billing.ts +0 -20
  333. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/login-copy.ts +0 -1
  334. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/settings-page.ts +0 -1
  335. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/auth-middleware.test.md +0 -8
  336. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/billing.test.md +0 -8
  337. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/copy.test.md +0 -7
  338. package/evals/fixtures/tiny-post-setup-missing-config-app/AGENTS.md +0 -15
  339. package/evals/fixtures/tiny-post-setup-missing-config-app/README.md +0 -16
  340. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/auth-review.md +0 -15
  341. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/billing-policy.md +0 -10
  342. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/copy-conventions.md +0 -15
  343. package/evals/fixtures/tiny-post-setup-missing-config-app/src/auth-middleware.ts +0 -12
  344. package/evals/fixtures/tiny-post-setup-missing-config-app/src/billing.ts +0 -20
  345. package/evals/fixtures/tiny-post-setup-missing-config-app/src/login-copy.ts +0 -1
  346. package/evals/fixtures/tiny-post-setup-missing-config-app/src/settings-page.ts +0 -1
  347. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/auth-middleware.test.md +0 -8
  348. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/billing.test.md +0 -8
  349. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/copy.test.md +0 -7
  350. package/evals/fixtures/tiny-post-setup-source-conflict-app/.freeflow/config.json +0 -3
  351. package/evals/fixtures/tiny-post-setup-source-conflict-app/AGENTS.md +0 -15
  352. package/evals/fixtures/tiny-post-setup-source-conflict-app/README.md +0 -16
  353. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/auth-review.md +0 -15
  354. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/billing-policy.md +0 -10
  355. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/copy-conventions.md +0 -15
  356. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/auth-middleware.ts +0 -12
  357. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/billing.ts +0 -20
  358. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/login-copy.ts +0 -1
  359. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/settings-page.ts +0 -1
  360. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/auth-middleware.test.md +0 -8
  361. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/billing.test.md +0 -8
  362. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/copy.test.md +0 -7
  363. package/evals/fixtures/tiny-report-performance-app/README.md +0 -11
  364. package/evals/fixtures/tiny-report-performance-app/docs/performance.md +0 -10
  365. package/evals/fixtures/tiny-report-performance-app/src/report-summary.ts +0 -29
  366. package/evals/fixtures/tiny-report-performance-app/tests/report-performance.test.md +0 -8
  367. package/evals/fixtures/tiny-review-request-app/README.md +0 -3
  368. package/evals/fixtures/tiny-review-request-app/docs/billing-policy.md +0 -5
  369. package/evals/fixtures/tiny-review-request-app/docs/plans/billing-webhook-api.md +0 -19
  370. package/evals/fixtures/tiny-review-request-app/docs/review/previous-agent-summary.md +0 -20
  371. package/evals/fixtures/tiny-review-request-app/docs/specs/billing-webhook-api.md +0 -25
  372. package/evals/fixtures/tiny-review-request-app/src/billing.ts +0 -11
  373. package/evals/fixtures/tiny-review-request-app/src/webhooks.ts +0 -19
  374. package/evals/fixtures/tiny-review-request-app/tests/billing-webhook.test.md +0 -8
  375. package/evals/fixtures/tiny-review-work-app/README.md +0 -5
  376. package/evals/fixtures/tiny-review-work-app/docs/billing-policy.md +0 -9
  377. package/evals/fixtures/tiny-review-work-app/docs/plans/settings-title-plan.md +0 -12
  378. package/evals/fixtures/tiny-review-work-app/docs/review/previous-agent-summary.md +0 -15
  379. package/evals/fixtures/tiny-review-work-app/docs/specs/settings-title.md +0 -9
  380. package/evals/fixtures/tiny-review-work-app/src/billing.ts +0 -7
  381. package/evals/fixtures/tiny-review-work-app/src/settings-page.ts +0 -1
  382. package/evals/fixtures/tiny-review-work-app/tests/billing.test.md +0 -7
  383. package/evals/fixtures/tiny-review-work-app/tests/settings.test.md +0 -5
  384. package/evals/fixtures/tiny-saas-app/README.md +0 -16
  385. package/evals/fixtures/tiny-saas-app/docs/auth-review.md +0 -15
  386. package/evals/fixtures/tiny-saas-app/docs/billing-policy.md +0 -10
  387. package/evals/fixtures/tiny-saas-app/docs/copy-conventions.md +0 -15
  388. package/evals/fixtures/tiny-saas-app/docs/specs/settings-title.md +0 -13
  389. package/evals/fixtures/tiny-saas-app/src/auth-middleware.ts +0 -12
  390. package/evals/fixtures/tiny-saas-app/src/billing.ts +0 -20
  391. package/evals/fixtures/tiny-saas-app/src/login-copy.ts +0 -1
  392. package/evals/fixtures/tiny-saas-app/src/settings-page.ts +0 -1
  393. package/evals/fixtures/tiny-saas-app/tests/auth-middleware.test.md +0 -8
  394. package/evals/fixtures/tiny-saas-app/tests/billing.test.md +0 -8
  395. package/evals/fixtures/tiny-saas-app/tests/copy.test.md +0 -7
  396. package/evals/fixtures/tiny-setup-agents-app/AGENTS.md +0 -6
  397. package/evals/fixtures/tiny-setup-both-app/AGENTS.md +0 -5
  398. package/evals/fixtures/tiny-setup-both-app/CLAUDE.md +0 -5
  399. package/evals/fixtures/tiny-setup-claude-app/CLAUDE.md +0 -6
  400. package/evals/fixtures/tiny-setup-codex-rules-app/.codex/rules/shell.rules +0 -5
  401. package/evals/fixtures/tiny-setup-codex-rules-app/AGENTS.md +0 -6
  402. package/evals/fixtures/tiny-setup-conflict-app/AGENTS.md +0 -6
  403. package/evals/fixtures/tiny-setup-existing-block-app/AGENTS.md +0 -14
  404. package/evals/fixtures/tiny-setup-four-rules-app/CLAUDE.md +0 -6
  405. package/evals/fixtures/tiny-skill-dev-app/README.md +0 -10
  406. package/evals/fixtures/tiny-skill-dev-app/evals/prompts/review-pr-001.txt +0 -8
  407. package/evals/fixtures/tiny-skill-dev-app/evals/reports/review-pr-failure.md +0 -17
  408. package/evals/fixtures/tiny-skill-dev-app/skills/review-pr/SKILL.md +0 -13
  409. package/evals/fixtures/tiny-team-app/README.md +0 -5
  410. package/evals/fixtures/tiny-team-app/docs/product.md +0 -6
  411. package/evals/fixtures/tiny-team-app/src/teams.ts +0 -9
  412. package/evals/fixtures/tiny-team-app/src/users.ts +0 -5
  413. package/evals/fixtures/tiny-team-app/tests/teams.test.md +0 -7
  414. package/evals/fixtures/tiny-verify-app/README.md +0 -5
  415. package/evals/fixtures/tiny-verify-app/src/settings-nav.ts +0 -1
  416. package/evals/fixtures/tiny-verify-app/src/settings-page.ts +0 -1
  417. package/evals/fixtures/tiny-verify-app/tests/settings.test.md +0 -7
  418. package/evals/prompts/aon-001.txt +0 -2
  419. package/evals/prompts/byp-001.txt +0 -2
  420. package/evals/prompts/byp-002.txt +0 -2
  421. package/evals/prompts/cap-001.txt +0 -3
  422. package/evals/prompts/cap-002.txt +0 -3
  423. package/evals/prompts/cmd-001.txt +0 -3
  424. package/evals/prompts/cmd-002.txt +0 -3
  425. package/evals/prompts/cmd-003.txt +0 -6
  426. package/evals/prompts/cmd-004.txt +0 -5
  427. package/evals/prompts/cmd-005.txt +0 -5
  428. package/evals/prompts/cmd-006.txt +0 -5
  429. package/evals/prompts/cmd-007.txt +0 -5
  430. package/evals/prompts/cmd-008.txt +0 -5
  431. package/evals/prompts/cmd-009.txt +0 -8
  432. package/evals/prompts/cmd-010.txt +0 -5
  433. package/evals/prompts/cmd-011.txt +0 -5
  434. package/evals/prompts/cmd-012.txt +0 -5
  435. package/evals/prompts/cmd-013.txt +0 -5
  436. package/evals/prompts/cmd-014.txt +0 -7
  437. package/evals/prompts/cmd-015.txt +0 -7
  438. package/evals/prompts/cmd-016.txt +0 -5
  439. package/evals/prompts/cmt-001.txt +0 -1
  440. package/evals/prompts/cmt-002.txt +0 -1
  441. package/evals/prompts/cmt-003.txt +0 -1
  442. package/evals/prompts/cmt-004.txt +0 -1
  443. package/evals/prompts/cmt-005.txt +0 -1
  444. package/evals/prompts/dfd-001.txt +0 -3
  445. package/evals/prompts/dia-001.txt +0 -3
  446. package/evals/prompts/dia-002.txt +0 -3
  447. package/evals/prompts/dia-003.txt +0 -3
  448. package/evals/prompts/dis-001.txt +0 -5
  449. package/evals/prompts/dis-002.txt +0 -5
  450. package/evals/prompts/esk-001.txt +0 -5
  451. package/evals/prompts/esk-002.txt +0 -5
  452. package/evals/prompts/esk-003.txt +0 -5
  453. package/evals/prompts/grc-001.txt +0 -3
  454. package/evals/prompts/hof-001.txt +0 -3
  455. package/evals/prompts/hof-002.txt +0 -1
  456. package/evals/prompts/hof-003.txt +0 -1
  457. package/evals/prompts/hof-004.txt +0 -1
  458. package/evals/prompts/hof-005.txt +0 -1
  459. package/evals/prompts/ivg-001.txt +0 -1
  460. package/evals/prompts/ivg-002.txt +0 -11
  461. package/evals/prompts/ivg-003.txt +0 -1
  462. package/evals/prompts/ivg-004.txt +0 -1
  463. package/evals/prompts/mode-001.txt +0 -3
  464. package/evals/prompts/mode-002.txt +0 -1
  465. package/evals/prompts/mode-003.txt +0 -3
  466. package/evals/prompts/mode-004.txt +0 -3
  467. package/evals/prompts/mode-005.txt +0 -3
  468. package/evals/prompts/mode-006.txt +0 -3
  469. package/evals/prompts/mode-007.txt +0 -3
  470. package/evals/prompts/otr-001.txt +0 -3
  471. package/evals/prompts/otr-002.txt +0 -3
  472. package/evals/prompts/rar-001.txt +0 -5
  473. package/evals/prompts/rar-002.txt +0 -3
  474. package/evals/prompts/rar-003.txt +0 -6
  475. package/evals/prompts/rar-004.txt +0 -15
  476. package/evals/prompts/rar-005.txt +0 -10
  477. package/evals/prompts/rbr-001.txt +0 -3
  478. package/evals/prompts/rbr-002.txt +0 -3
  479. package/evals/prompts/rbr-003.txt +0 -7
  480. package/evals/prompts/rev-001.txt +0 -3
  481. package/evals/prompts/rev-002.txt +0 -5
  482. package/evals/prompts/rev-003.txt +0 -6
  483. package/evals/prompts/rev-004.txt +0 -1
  484. package/evals/prompts/rev-005.txt +0 -15
  485. package/evals/prompts/rev-006.txt +0 -5
  486. package/evals/prompts/stp-001.txt +0 -1
  487. package/evals/prompts/stp-002.txt +0 -1
  488. package/evals/prompts/stp-003.txt +0 -1
  489. package/evals/prompts/stp-004.txt +0 -1
  490. package/evals/prompts/stp-005.txt +0 -1
  491. package/evals/prompts/stp-006.txt +0 -1
  492. package/evals/prompts/stp-007.txt +0 -1
  493. package/evals/prompts/stp-008.txt +0 -1
  494. package/evals/prompts/stp-009.txt +0 -1
  495. package/evals/prompts/stp-010.txt +0 -1
  496. package/evals/prompts/stp-011.txt +0 -1
  497. package/evals/prompts/vfy-003.txt +0 -1
  498. package/evals/prompts/wpl-001.txt +0 -3
  499. package/evals/prompts/wpl-002.txt +0 -5
  500. package/evals/prompts/wpl-003.txt +0 -3
  501. package/evals/prompts/wpl-004.txt +0 -5
  502. package/evals/prompts/wpl-005.txt +0 -1
  503. package/evals/prompts/wrc-001.txt +0 -10
  504. package/evals/prompts/wrc-002.txt +0 -3
  505. package/evals/prompts/wsk-001.txt +0 -6
  506. package/evals/prompts/wsp-001.txt +0 -5
  507. package/evals/prompts/wsp-002.txt +0 -15
  508. package/evals/prompts/wsp-003.txt +0 -3
  509. package/evals/prompts/wsp-004.txt +0 -15
  510. package/evals/prompts/wsp-005.txt +0 -5
  511. package/evals/prompts/wsp-006.txt +0 -12
  512. package/evals/prompts/wsp-007.txt +0 -9
  513. package/evals/prompts/wsp-008.txt +0 -13
  514. package/evals/prompts/xpl-001.txt +0 -1
  515. package/evals/prompts/xpl-002.txt +0 -3
  516. package/evals/prompts/xpl-003.txt +0 -3
  517. package/evals/prompts/xpl-004.txt +0 -3
  518. package/evals/prompts/xpl-005.txt +0 -5
  519. package/evals/prompts/xpl-006.txt +0 -3
  520. package/evals/registries/adversarial-evals.json +0 -39
  521. package/evals/registries/fixture-evals.json +0 -2513
  522. package/evals/registries/handoff-evals.json +0 -74
  523. package/evals/registries/legacy-evals.json +0 -147
  524. package/evals/registries/skill-evidence.json +0 -193
  525. package/evals/registries/verify-work-evals.json +0 -46
  526. package/evals/reports/acceptance/v0.1-acceptance-report.md +0 -130
  527. package/evals/reports/by-command-surface/command-surface-1-report.md +0 -45
  528. package/evals/reports/by-command-surface/command-surface-10-report.md +0 -76
  529. package/evals/reports/by-command-surface/command-surface-11-report.md +0 -77
  530. package/evals/reports/by-command-surface/command-surface-12-report.md +0 -91
  531. package/evals/reports/by-command-surface/command-surface-13-report.md +0 -64
  532. package/evals/reports/by-command-surface/command-surface-14-report.md +0 -66
  533. package/evals/reports/by-command-surface/command-surface-15-report.md +0 -124
  534. package/evals/reports/by-command-surface/command-surface-16-report.md +0 -39
  535. package/evals/reports/by-command-surface/command-surface-2-report.md +0 -80
  536. package/evals/reports/by-command-surface/command-surface-3-report.md +0 -86
  537. package/evals/reports/by-command-surface/command-surface-4-report.md +0 -76
  538. package/evals/reports/by-command-surface/command-surface-5-report.md +0 -80
  539. package/evals/reports/by-command-surface/command-surface-6-report.md +0 -74
  540. package/evals/reports/by-command-surface/command-surface-7-report.md +0 -84
  541. package/evals/reports/by-command-surface/command-surface-8-report.md +0 -79
  542. package/evals/reports/by-command-surface/command-surface-9-report.md +0 -79
  543. package/evals/reports/by-command-surface/command-surface-matrix.md +0 -91
  544. package/evals/reports/by-skill/bypass-1-report.md +0 -124
  545. package/evals/reports/by-skill/capture-decisions-1-report.md +0 -99
  546. package/evals/reports/by-skill/capture-decisions-2-report.md +0 -102
  547. package/evals/reports/by-skill/commit-work-1-report.md +0 -165
  548. package/evals/reports/by-skill/commit-work-2-report.md +0 -109
  549. package/evals/reports/by-skill/design-for-depth-1-report.md +0 -95
  550. package/evals/reports/by-skill/diagnose-failure-1-report.md +0 -91
  551. package/evals/reports/by-skill/diagnose-failure-2-report.md +0 -94
  552. package/evals/reports/by-skill/discover-1-report.md +0 -118
  553. package/evals/reports/by-skill/evaluate-skill-2-report.md +0 -71
  554. package/evals/reports/by-skill/execute-plan-1-report.md +0 -103
  555. package/evals/reports/by-skill/execute-plan-2-report.md +0 -112
  556. package/evals/reports/by-skill/execute-plan-3-report.md +0 -87
  557. package/evals/reports/by-skill/grill-context-1-report.md +0 -103
  558. package/evals/reports/by-skill/handoff-1-report.md +0 -123
  559. package/evals/reports/by-skill/handoff-2-report.md +0 -105
  560. package/evals/reports/by-skill/handoff-3-report.md +0 -100
  561. package/evals/reports/by-skill/handoff-7-report.md +0 -77
  562. package/evals/reports/by-skill/interview-gate-1-report.md +0 -63
  563. package/evals/reports/by-skill/interview-gate-2-report.md +0 -105
  564. package/evals/reports/by-skill/mode-contract-1-report.md +0 -74
  565. package/evals/reports/by-skill/mode-contract-2-report.md +0 -87
  566. package/evals/reports/by-skill/mode-contract-3-report.md +0 -65
  567. package/evals/reports/by-skill/mode-contract-4-report.md +0 -71
  568. package/evals/reports/by-skill/mode-contract-5-report.md +0 -70
  569. package/evals/reports/by-skill/output-router-1-report.md +0 -76
  570. package/evals/reports/by-skill/output-router-2-report.md +0 -65
  571. package/evals/reports/by-skill/research-1-report.md +0 -144
  572. package/evals/reports/by-skill/research-brief-1-report.md +0 -94
  573. package/evals/reports/by-skill/research-brief-2-report.md +0 -75
  574. package/evals/reports/by-skill/review-artifact-1-report.md +0 -91
  575. package/evals/reports/by-skill/review-artifact-2-report.md +0 -79
  576. package/evals/reports/by-skill/review-artifact-3-report.md +0 -120
  577. package/evals/reports/by-skill/review-artifact-4-report.md +0 -89
  578. package/evals/reports/by-skill/review-artifact-5-report.md +0 -66
  579. package/evals/reports/by-skill/review-work-1-report.md +0 -85
  580. package/evals/reports/by-skill/review-work-2-report.md +0 -87
  581. package/evals/reports/by-skill/review-work-3-report.md +0 -104
  582. package/evals/reports/by-skill/review-work-4-report.md +0 -108
  583. package/evals/reports/by-skill/review-work-5-report.md +0 -73
  584. package/evals/reports/by-skill/review-work-6-report.md +0 -66
  585. package/evals/reports/by-skill/setup-freeflow-1-report.md +0 -199
  586. package/evals/reports/by-skill/setup-freeflow-2-report.md +0 -105
  587. package/evals/reports/by-skill/setup-freeflow-3-report.md +0 -105
  588. package/evals/reports/by-skill/setup-freeflow-4-report.md +0 -88
  589. package/evals/reports/by-skill/setup-freeflow-5-report.md +0 -115
  590. package/evals/reports/by-skill/skill-authoring-1-report.md +0 -81
  591. package/evals/reports/by-skill/verify-work-1-report.md +0 -111
  592. package/evals/reports/by-skill/verify-work-2-report.md +0 -120
  593. package/evals/reports/by-skill/workflow-1-report.md +0 -65
  594. package/evals/reports/by-skill/write-plan-1-report.md +0 -123
  595. package/evals/reports/by-skill/write-plan-2-report.md +0 -98
  596. package/evals/reports/by-skill/write-plan-3-report.md +0 -110
  597. package/evals/reports/by-skill/write-spec-1-report.md +0 -88
  598. package/evals/reports/by-skill/write-spec-2-report.md +0 -89
  599. package/evals/reports/by-skill/write-spec-3-report.md +0 -90
  600. package/evals/reports/by-skill/write-spec-4-report.md +0 -167
  601. package/evals/reports/harness/claude-harness-1-report.md +0 -103
  602. package/evals/reports/harness/eval-harness-1-report.md +0 -91
  603. package/evals/reports/iterations/iteration-1-report.md +0 -71
  604. package/evals/reports/iterations/iteration-2-report.md +0 -78
  605. package/evals/reports/iterations/iteration-3-report.md +0 -118
  606. package/evals/reports/iterations/iteration-4-report.md +0 -131
  607. package/evals/reports/iterations/iteration-5-report.md +0 -149
  608. package/evals/reports/iterations/iteration-6-report.md +0 -136
  609. package/evals/reports/runtime/always-on-runtime-1-report.md +0 -107
  610. package/evals/reports/runtime/context-mode-normalized-benchmark-1-report.md +0 -52
  611. package/evals/reports/runtime/context-mode-real-deep-baseline-1-report.md +0 -410
  612. package/evals/reports/runtime/context-mode-real-deep-final-slice-11-report.md +0 -203
  613. package/evals/reports/runtime/context-mode-real-deep-final-slice-11-review.md +0 -51
  614. package/evals/reports/runtime/context-saving-native-tools-baseline-1-report.md +0 -99
  615. package/evals/reports/runtime/eryx-python-compatibility-reprobe-1-report.md +0 -166
  616. package/evals/reports/runtime/eryx-python-proof-spike-1-report.md +0 -96
  617. package/evals/reports/runtime/eryx-python-proof-spike-2-report.md +0 -151
  618. package/evals/reports/runtime/eryx-python-script-derive-execution-1-report.md +0 -233
  619. package/evals/reports/runtime/jq-script-derive-execution-1-report.md +0 -215
  620. package/evals/reports/runtime/jq-wasm-proof-spike-1-report.md +0 -67
  621. package/evals/reports/runtime/output-router-benchmark-1-report.md +0 -81
  622. package/evals/reports/runtime/output-router-capture-derive-provider-eval-1-report.md +0 -35
  623. package/evals/reports/runtime/output-router-codex-large-index-sqlite-adhoc-report.md +0 -150
  624. package/evals/reports/runtime/output-router-codex-qa-benchmark-1-report.md +0 -46
  625. package/evals/reports/runtime/output-router-command-benchmark-1-report.md +0 -62
  626. package/evals/reports/runtime/output-router-index-benchmark-1-report.md +0 -64
  627. package/evals/reports/runtime/output-router-regression-1-report.md +0 -81
  628. package/evals/reports/runtime/output-router-transform-eval-1-report.md +0 -28
  629. package/evals/reports/runtime/pi-observed-routing-eval-1-report.md +0 -44
  630. package/evals/reports/runtime/quickjs-script-derive-execution-1-report.md +0 -159
  631. package/evals/reports/runtime/quickjs-wasi-proof-spike-1-report.md +0 -55
  632. package/evals/reports/runtime/render-format-row-protocol-1-report.md +0 -58
  633. package/evals/reports/runtime/script-sandbox-adapter-selection-review-1-report.md +0 -84
  634. package/evals/reports/runtime/script-sandbox-probe-resource-hardening-1-report.md +0 -51
  635. package/evals/reports/runtime/storage-policy-benchmark-1-report.md +0 -176
  636. package/evals/reports/runtime/vault-index-storage-spike-1-report.md +0 -39
  637. package/evals/reports/runtime/workflow-context-hook-1-report.md +0 -82
  638. package/evals/runbooks/adversarial-eval-runbook.md +0 -28
  639. package/evals/runbooks/fixture-eval-runbook.md +0 -137
  640. package/evals/runbooks/handoff-eval-runbook.md +0 -22
  641. package/evals/runbooks/verify-work-eval-runbook.md +0 -27
  642. package/evals/scripts/audit-command-surface.sh +0 -160
  643. package/evals/scripts/check-activation-contract.sh +0 -121
  644. package/evals/scripts/check-runtime-context-hook.sh +0 -183
  645. package/evals/scripts/grade-fixture-eval.sh +0 -446
  646. package/evals/scripts/run-claude-fixture-eval.sh +0 -26
  647. package/evals/scripts/run-codex-fixture-eval.sh +0 -26
  648. package/evals/scripts/run-eryx-python-proof-spike.js +0 -559
  649. package/evals/scripts/run-fixture-eval-by-id.sh +0 -23
  650. package/evals/scripts/run-fixture-eval.sh +0 -464
  651. package/evals/scripts/run-jq-wasm-proof-spike.js +0 -299
  652. package/evals/scripts/run-output-router-transform-eval.js +0 -115
  653. package/evals/scripts/run-pi-observed-routing-eval.js +0 -478
  654. package/evals/scripts/run-quickjs-wasi-proof-spike.js +0 -339
  655. package/evals/scripts/skill-evidence.sh +0 -316
  656. package/evals/scripts/validate-release-metadata.sh +0 -486
  657. package/evals/suites/v0.1-acceptance-suite.md +0 -131
  658. package/pi-extension/dist/host-producer-identification.js +0 -186
  659. package/pi-extension/dist/mcp-config.js +0 -30
  660. package/pi-extension/dist/native-safety-net.js +0 -209
  661. package/pi-extension/dist/observed-tool-routing.js +0 -114
  662. package/pi-extension/dist/renderers.js +0 -835
  663. package/pi-extension/dist/router-tools.js +0 -438
  664. package/pi-extension/dist/runtime-context.js +0 -288
  665. package/pi-extension/dist/schemas.js +0 -254
  666. package/pi-extension/dist/status.js +0 -449
  667. package/pi-extension/dist/utils.js +0 -467
  668. package/pi-extension/src/runtime-context.ts +0 -347
  669. package/pi-extension/src/status.ts +0 -505
  670. package/plugin-docs/README.md +0 -40
  671. package/plugin-docs/adr/0001-three-modes.md +0 -27
  672. package/plugin-docs/adr/0002-evals-before-hooks.md +0 -17
  673. package/plugin-docs/adr/0003-release-boundary.md +0 -21
  674. package/plugin-docs/adr/0004-discover-replaces-shallow-discovery-skills.md +0 -26
  675. package/plugin-docs/adr/README.md +0 -10
  676. package/plugin-docs/architecture.md +0 -89
  677. package/plugin-docs/output-router.md +0 -396
  678. package/plugin-docs/release-evidence.md +0 -77
  679. package/plugin-docs/skills.md +0 -44
  680. package/plugin-docs/workflow.md +0 -57
  681. package/skills/diagnose-failure/references/feedback-loop-catalog.md +0 -25
  682. package/skills/discover/ARTIFACT-DESTINATIONS.md +0 -58
  683. package/skills/discover/CHECKPOINTS.md +0 -74
  684. package/skills/discover/SKILL.md +0 -173
  685. package/skills/evaluate-skill/references/eval-patterns.md +0 -41
  686. package/skills/evaluate-skill/references/grading-priority.md +0 -33
  687. package/skills/execute-plan/SKILL.md +0 -133
  688. package/skills/execute-plan/references/execution-map.md +0 -122
  689. package/skills/interview-gate/SKILL.md +0 -90
  690. package/skills/setup-freeflow/references/output-router-setup.md +0 -102
  691. package/skills/workflow/references/workflow-map.md +0 -104
  692. /package/pi-extension/src/{mcp-config.ts → integrations/mcp-config.ts} +0 -0
@@ -1,1219 +1,1304 @@
1
1
  import { createHash } from "node:crypto";
2
- import { commandOutputFingerprints, createVault, findExactDuplicateCommandOutput, storeCommandOutput, storeMetadataOutput, storeTextOutput, } from "../vault/vault.js";
2
+ import {
3
+ commandOutputFingerprints,
4
+ createVault,
5
+ findExactDuplicateCommandOutput,
6
+ storeCommandOutput,
7
+ storeMetadataOutput,
8
+ storeTextOutput,
9
+ } from "../vault/vault.js";
3
10
  import { DEFAULT_ROUTER_THRESHOLDS, DEFAULT_STORAGE_POLICY } from "../config/config.js";
4
11
  import { executeSandboxedScriptOperation, freeflowTransform, validateTransformInput } from "../transform/engine.js";
5
12
  import { assembleTextEvidence, byteLength, countLines } from "../evidence/evidence.js";
6
13
  import { parseCommandOutput } from "../routing/parsers.js";
7
- import { applyRunOutputFilters, hasRunOutputFilters, normalizeRunOutputFilters, } from "../routing/run-filters.js";
8
- import { parserWithReducer, reducerImportantLines, selectRunReducerRoute, } from "../routing/run-reducers.js";
14
+ import { applyRunOutputFilters, hasRunOutputFilters, normalizeRunOutputFilters } from "../routing/run-filters.js";
15
+ import { parserWithReducer, reducerImportantLines, selectRunReducerRoute } from "../routing/run-reducers.js";
9
16
  export async function freeflowRun(options, runner) {
10
- const preserve = options.preserve ?? "important";
11
- const producerValidation = normalizeRunProducer(options);
12
- if (!producerValidation.ok) {
13
- return runProducerValidationFailureResult({
14
- preserve,
15
- message: producerValidation.message,
16
- path: producerValidation.path,
17
- });
18
- }
19
- const runProducer = producerValidation.producer;
20
- const command = runProducer.command;
21
- const validationProducer = runProducer.kind === "script" ? { kind: "script", name: `script:${runProducer.script.language}` } : runProducer.producer;
22
- const filterValidation = normalizeRunOutputFilters(options.filters);
23
- if (!filterValidation.ok) {
24
- return commandFilterValidationFailureResult({
25
- command,
26
- producer: validationProducer,
27
- preserve,
28
- message: filterValidation.message,
29
- path: filterValidation.path,
30
- });
31
- }
32
- const scriptFilterValidation = normalizeRunScriptFilter(options.scriptFilter);
33
- if (!scriptFilterValidation.ok) {
34
- return commandScriptFilterValidationFailureResult({
35
- command,
36
- producer: validationProducer,
37
- preserve,
38
- message: scriptFilterValidation.message,
39
- path: scriptFilterValidation.path,
40
- });
41
- }
42
- const filters = hasRunOutputFilters(filterValidation.filters) ? filterValidation.filters : undefined;
43
- const scriptFilter = scriptFilterValidation.scriptFilter;
44
- const thresholds = { ...DEFAULT_ROUTER_THRESHOLDS, ...options.thresholds };
45
- const vaultOptions = {};
46
- if (options.vaultRoot !== undefined) {
47
- vaultOptions.root = options.vaultRoot;
48
- }
49
- if (options.vaultRetention !== undefined) {
50
- vaultOptions.retention = options.vaultRetention;
51
- }
52
- const vault = createVault(vaultOptions);
53
- let runResult;
54
- let producer = runProducer.kind === "command" ? runProducer.producer : { kind: "script", name: `script:${runProducer.script.language}` };
55
- let scriptProducer;
56
- if (runProducer.kind === "command") {
57
- try {
58
- const runRequest = { command: runProducer.command };
59
- if (options.cwd !== undefined) {
60
- runRequest.cwd = options.cwd;
61
- }
62
- if (options.timeoutMs !== undefined) {
63
- runRequest.timeoutMs = options.timeoutMs;
64
- }
65
- runResult = await runner.run(runRequest);
66
- }
67
- catch (error) {
68
- const message = error instanceof Error ? error.message : String(error);
69
- return {
70
- toolStatus: "error",
71
- decisionId: decisionId("run-error", commandText(command), message),
72
- preserve,
73
- outputId: "",
74
- execution: { status: "failed", exitCode: null },
75
- producer,
76
- persistence: { status: "not_persisted", recoverability: "none" },
77
- routing: {
78
- status: "failed",
79
- route: "run",
80
- reason: `Adapter-provided runner failed before command output could be captured: ${message}`,
81
- },
82
- recovery: {
83
- how: "No command output was captured. Retry through the host-approved runner or use the host-native shell tool if direct raw behavior is required.",
84
- },
85
- };
86
- }
87
- }
88
- else {
89
- const scriptExecutionOptions = {
90
- operation: runScriptProducerOperation(runProducer.script),
91
- scriptSandboxAdapters: options.scriptSandboxAdapters ?? [],
92
- };
93
- const limits = scriptProducerLimits(runProducer.script, options.timeoutMs);
94
- if (limits !== undefined) {
95
- Object.assign(scriptExecutionOptions, { limits });
96
- }
97
- if (options.scriptTransform !== undefined) {
98
- Object.assign(scriptExecutionOptions, { scriptTransform: options.scriptTransform });
99
- }
100
- const scriptExecution = await executeSandboxedScriptOperation(scriptExecutionOptions);
101
- scriptProducer = runScriptProducerMetadata(runProducer.script, scriptExecution);
102
- producer = scriptProducerDescriptor(runProducer.script, scriptExecution);
103
- if (!scriptExecution.ok) {
104
- return scriptProducerExecutionFailureResult({
105
- command,
106
- preserve,
107
- producer,
108
- scriptProducer,
109
- execution: scriptExecution,
110
- });
111
- }
112
- runResult = scriptExecutionResult(scriptExecution);
113
- }
114
- const combined = runResult.combined ?? combineOutputSections(runResult.stdout, runResult.stderr);
115
- let record;
116
- let duplicate;
117
- const fingerprints = commandOutputFingerprints({
118
- command,
119
- stdout: runResult.stdout,
120
- stderr: runResult.stderr,
121
- combined,
122
- executionStatus: runResult.executionStatus,
123
- exitCode: runResult.exitCode,
124
- ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
17
+ const preserve = options.preserve ?? "important";
18
+ const producerValidation = normalizeRunProducer(options);
19
+ if (!producerValidation.ok) {
20
+ return runProducerValidationFailureResult({
21
+ preserve,
22
+ message: producerValidation.message,
23
+ path: producerValidation.path,
24
+ });
25
+ }
26
+ const runProducer = producerValidation.producer;
27
+ const command = runProducer.command;
28
+ const validationProducer =
29
+ runProducer.kind === "script"
30
+ ? { kind: "script", name: `script:${runProducer.script.language}` }
31
+ : runProducer.producer;
32
+ const filterValidation = normalizeRunOutputFilters(options.filters);
33
+ if (!filterValidation.ok) {
34
+ return commandFilterValidationFailureResult({
35
+ command,
36
+ producer: validationProducer,
37
+ preserve,
38
+ message: filterValidation.message,
39
+ path: filterValidation.path,
40
+ });
41
+ }
42
+ const scriptFilterValidation = normalizeRunScriptFilter(options.scriptFilter);
43
+ if (!scriptFilterValidation.ok) {
44
+ return commandScriptFilterValidationFailureResult({
45
+ command,
46
+ producer: validationProducer,
47
+ preserve,
48
+ message: scriptFilterValidation.message,
49
+ path: scriptFilterValidation.path,
125
50
  });
51
+ }
52
+ const filters = hasRunOutputFilters(filterValidation.filters) ? filterValidation.filters : undefined;
53
+ const scriptFilter = scriptFilterValidation.scriptFilter;
54
+ const thresholds = { ...DEFAULT_ROUTER_THRESHOLDS, ...options.thresholds };
55
+ const vaultOptions = {};
56
+ if (options.vaultRoot !== undefined) {
57
+ vaultOptions.root = options.vaultRoot;
58
+ }
59
+ if (options.vaultRetention !== undefined) {
60
+ vaultOptions.retention = options.vaultRetention;
61
+ }
62
+ const vault = createVault(vaultOptions);
63
+ let runResult;
64
+ let producer =
65
+ runProducer.kind === "command"
66
+ ? runProducer.producer
67
+ : { kind: "script", name: `script:${runProducer.script.language}` };
68
+ let scriptProducer;
69
+ if (runProducer.kind === "command") {
126
70
  try {
127
- duplicate = await findExactDuplicateCommandOutput(vault, {
128
- sessionId: options.sessionId,
129
- fingerprints,
130
- });
71
+ const runRequest = { command: runProducer.command };
72
+ if (options.cwd !== undefined) {
73
+ runRequest.cwd = options.cwd;
74
+ }
75
+ if (options.timeoutMs !== undefined) {
76
+ runRequest.timeoutMs = options.timeoutMs;
77
+ }
78
+ runResult = await runner.run(runRequest);
79
+ } catch (error) {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ return {
82
+ toolStatus: "error",
83
+ decisionId: decisionId("run-error", commandText(command), message),
84
+ preserve,
85
+ outputId: "",
86
+ execution: { status: "failed", exitCode: null },
87
+ producer,
88
+ persistence: { status: "not_persisted", recoverability: "none" },
89
+ routing: {
90
+ status: "failed",
91
+ route: "run",
92
+ reason: `Adapter-provided runner failed before command output could be captured: ${message}`,
93
+ },
94
+ recovery: {
95
+ how: "No command output was captured. Retry through the host-approved runner or use the host-native shell tool if direct raw behavior is required.",
96
+ },
97
+ };
131
98
  }
132
- catch {
133
- duplicate = undefined;
99
+ } else {
100
+ const scriptExecutionOptions = {
101
+ operation: runScriptProducerOperation(runProducer.script),
102
+ scriptSandboxAdapters: options.scriptSandboxAdapters ?? [],
103
+ };
104
+ const limits = scriptProducerLimits(runProducer.script, options.timeoutMs);
105
+ if (limits !== undefined) {
106
+ Object.assign(scriptExecutionOptions, { limits });
134
107
  }
135
- const storagePolicy = options.storagePolicy ?? DEFAULT_STORAGE_POLICY;
136
- const storageParser = parseCommandOutput({
137
- command,
138
- executionStatus: runResult.executionStatus,
139
- exitCode: runResult.exitCode,
140
- stdout: runResult.stdout,
141
- stderr: runResult.stderr,
142
- combined,
143
- ...(options.goal !== undefined ? { goal: options.goal } : {}),
144
- });
145
- const reducerRoute = selectRunReducerRoute({
108
+ if (options.scriptTransform !== undefined) {
109
+ Object.assign(scriptExecutionOptions, { scriptTransform: options.scriptTransform });
110
+ }
111
+ const scriptExecution = await executeSandboxedScriptOperation(scriptExecutionOptions);
112
+ scriptProducer = runScriptProducerMetadata(runProducer.script, scriptExecution);
113
+ producer = scriptProducerDescriptor(runProducer.script, scriptExecution);
114
+ if (!scriptExecution.ok) {
115
+ return scriptProducerExecutionFailureResult({
146
116
  command,
147
- ...(options.goal !== undefined ? { goal: options.goal } : {}),
148
- executionStatus: runResult.executionStatus,
149
- stdout: runResult.stdout,
150
- stderr: runResult.stderr,
151
- combined,
152
117
  preserve,
153
- thresholds,
154
- hasFilters: filters !== undefined,
155
- hasScriptFilter: scriptFilter !== undefined,
118
+ producer,
119
+ scriptProducer,
120
+ execution: scriptExecution,
121
+ });
122
+ }
123
+ runResult = scriptExecutionResult(scriptExecution);
124
+ }
125
+ const combined = runResult.combined ?? combineOutputSections(runResult.stdout, runResult.stderr);
126
+ let record;
127
+ let duplicate;
128
+ const fingerprints = commandOutputFingerprints({
129
+ command,
130
+ stdout: runResult.stdout,
131
+ stderr: runResult.stderr,
132
+ combined,
133
+ executionStatus: runResult.executionStatus,
134
+ exitCode: runResult.exitCode,
135
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
136
+ });
137
+ try {
138
+ duplicate = await findExactDuplicateCommandOutput(vault, {
139
+ sessionId: options.sessionId,
140
+ fingerprints,
156
141
  });
157
- const storageInput = {
158
- policy: storagePolicy,
159
- command,
160
- producerKind: runProducer.kind,
161
- preserve,
162
- executionStatus: runResult.executionStatus,
163
- outputBytes: byteLength(combined),
164
- outputLines: countLines(combined),
165
- thresholds,
166
- parserName: storageParser.parser.name,
167
- hasFilters: filters !== undefined,
168
- hasScriptFilter: scriptFilter !== undefined,
169
- hasReducer: reducerRoute.status === "selected",
142
+ } catch {
143
+ duplicate = undefined;
144
+ }
145
+ const storagePolicy = options.storagePolicy ?? DEFAULT_STORAGE_POLICY;
146
+ const storageParser = parseCommandOutput({
147
+ command,
148
+ executionStatus: runResult.executionStatus,
149
+ exitCode: runResult.exitCode,
150
+ stdout: runResult.stdout,
151
+ stderr: runResult.stderr,
152
+ combined,
153
+ ...(options.goal !== undefined ? { goal: options.goal } : {}),
154
+ });
155
+ const reducerRoute = selectRunReducerRoute({
156
+ command,
157
+ ...(options.goal !== undefined ? { goal: options.goal } : {}),
158
+ executionStatus: runResult.executionStatus,
159
+ stdout: runResult.stdout,
160
+ stderr: runResult.stderr,
161
+ combined,
162
+ preserve,
163
+ thresholds,
164
+ hasFilters: filters !== undefined,
165
+ hasScriptFilter: scriptFilter !== undefined,
166
+ });
167
+ const storageInput = {
168
+ policy: storagePolicy,
169
+ command,
170
+ producerKind: runProducer.kind,
171
+ preserve,
172
+ executionStatus: runResult.executionStatus,
173
+ outputBytes: byteLength(combined),
174
+ outputLines: countLines(combined),
175
+ thresholds,
176
+ parserName: storageParser.parser.name,
177
+ hasFilters: filters !== undefined,
178
+ hasScriptFilter: scriptFilter !== undefined,
179
+ hasReducer: reducerRoute.status === "selected",
180
+ };
181
+ if (options.goal !== undefined) {
182
+ Object.assign(storageInput, { goal: options.goal });
183
+ }
184
+ if (duplicate !== undefined) {
185
+ Object.assign(storageInput, { duplicate });
186
+ }
187
+ const storageDecision = decideCommandStorage(storageInput);
188
+ const execution = {
189
+ status: runResult.executionStatus,
190
+ exitCode: runResult.exitCode,
191
+ };
192
+ if (runResult.durationMs !== undefined) {
193
+ Object.assign(execution, { durationMs: runResult.durationMs });
194
+ }
195
+ try {
196
+ const storeOptions = {
197
+ sessionId: options.sessionId,
198
+ command,
199
+ stdout: runResult.stdout,
200
+ stderr: runResult.stderr,
201
+ combined,
202
+ executionStatus: runResult.executionStatus,
203
+ exitCode: runResult.exitCode,
204
+ decisionIds: [decisionId("run", commandText(command), options.sessionId)],
205
+ producer,
170
206
  };
171
- if (options.goal !== undefined) {
172
- Object.assign(storageInput, { goal: options.goal });
173
- }
174
- if (duplicate !== undefined) {
175
- Object.assign(storageInput, { duplicate });
207
+ if (options.cwd !== undefined) {
208
+ Object.assign(storeOptions, { cwd: options.cwd });
176
209
  }
177
- const storageDecision = decideCommandStorage(storageInput);
178
- const execution = {
179
- status: runResult.executionStatus,
180
- exitCode: runResult.exitCode,
181
- };
182
210
  if (runResult.durationMs !== undefined) {
183
- Object.assign(execution, { durationMs: runResult.durationMs });
184
- }
185
- try {
186
- const storeOptions = {
187
- sessionId: options.sessionId,
188
- command,
189
- stdout: runResult.stdout,
190
- stderr: runResult.stderr,
191
- combined,
192
- executionStatus: runResult.executionStatus,
193
- exitCode: runResult.exitCode,
194
- decisionIds: [decisionId("run", commandText(command), options.sessionId)],
195
- producer,
196
- };
197
- if (options.cwd !== undefined) {
198
- Object.assign(storeOptions, { cwd: options.cwd });
199
- }
200
- if (runResult.durationMs !== undefined) {
201
- Object.assign(storeOptions, { durationMs: runResult.durationMs });
202
- }
203
- const metadataStoreOptions = {
204
- vault,
205
- sessionId: options.sessionId,
206
- command,
207
- runResult,
208
- combined,
209
- fingerprints,
210
- storageDecision,
211
- parserName: storageParser.parser.name,
212
- producer,
213
- };
214
- if (options.cwd !== undefined) {
215
- Object.assign(metadataStoreOptions, { cwd: options.cwd });
216
- }
217
- record = storageDecision.mode === "exact"
218
- ? await storeCommandOutput(vault, storeOptions)
219
- : await storeCommandMetadataOutput(metadataStoreOptions);
220
- const routeOptions = {
221
- outputId: record.outputId,
222
- command,
223
- executionStatus: runResult.executionStatus,
224
- exitCode: runResult.exitCode,
225
- stdout: runResult.stdout,
226
- stderr: runResult.stderr,
227
- combined,
228
- preserve,
229
- thresholds,
230
- storage: storageDecision,
231
- };
232
- if (filters !== undefined) {
233
- routeOptions.filters = filters;
234
- }
235
- if (options.goal !== undefined) {
236
- routeOptions.goal = options.goal;
237
- }
238
- if (reducerRoute.status === "selected") {
239
- routeOptions.reducer = reducerRoute;
240
- }
241
- let routing;
242
- const duplicateForRouting = duplicate && preserve !== "full" && filters === undefined && scriptFilter === undefined ? duplicate : undefined;
243
- if (duplicateForRouting) {
244
- routing = routeDuplicateCommandOutput({
245
- outputId: record.outputId,
246
- duplicate: duplicateForRouting,
247
- storage: storageDecision,
248
- command,
249
- executionStatus: runResult.executionStatus,
250
- exitCode: runResult.exitCode,
251
- });
252
- }
253
- else if (scriptFilter) {
254
- const scriptRouteOptions = {
255
- routeOptions,
256
- rawRecord: record,
257
- sessionId: options.sessionId,
258
- scriptFilter,
259
- scriptSandboxAdapters: options.scriptSandboxAdapters ?? [],
260
- };
261
- if (options.vaultRoot !== undefined) {
262
- Object.assign(scriptRouteOptions, { vaultRoot: options.vaultRoot });
263
- }
264
- if (options.vaultRetention !== undefined) {
265
- Object.assign(scriptRouteOptions, { vaultRetention: options.vaultRetention });
266
- }
267
- if (options.scriptTransform !== undefined) {
268
- Object.assign(scriptRouteOptions, { scriptTransform: options.scriptTransform });
269
- }
270
- routing = await routeScriptFilteredOutput(scriptRouteOptions);
271
- }
272
- else {
273
- if (routeOptions.reducer?.status === "selected" && record.kind === "command" && storageDecision.mode === "exact") {
274
- routeOptions.reducerRecord = await storeReducerOutput({
275
- vault,
276
- sessionId: options.sessionId,
277
- rawRecord: record,
278
- reducer: routeOptions.reducer,
279
- });
280
- }
281
- routing = routeCommandOutput(routeOptions);
282
- }
283
- return {
284
- toolStatus: "ok",
285
- decisionId: routing.decisionId,
286
- outputId: record.outputId,
287
- recordId: record.recordId,
288
- preserve,
289
- execution,
290
- producer: record.producer,
291
- persistence: record.persistence,
292
- ...(routing.lineage !== undefined ? { lineage: routing.lineage } : record.lineage !== undefined ? { lineage: record.lineage } : {}),
293
- ...(routing.failure !== undefined ? { failure: routing.failure } : {}),
294
- ...(routing.transformExecution !== undefined ? { transformExecution: routing.transformExecution } : {}),
295
- ...(routing.evidence !== undefined ? { evidence: routing.evidence } : {}),
296
- routing: {
297
- status: routing.routingStatus,
298
- route: "run",
299
- reason: routing.reason,
300
- },
301
- summary: routing.summary,
302
- importantLines: routing.importantLines,
303
- parser: routing.parser,
304
- ...(routing.filters !== undefined ? { filters: routing.filters } : {}),
305
- ...(scriptProducer !== undefined ? { scriptProducer } : {}),
306
- ...(routing.scriptFilter !== undefined ? { scriptFilter: routing.scriptFilter } : {}),
307
- ...(routing.reducer !== undefined ? { reducer: routing.reducer } : {}),
308
- recovery: routing.recovery ?? commandRecoveryHint(record.outputId, storageDecision),
309
- };
211
+ Object.assign(storeOptions, { durationMs: runResult.durationMs });
212
+ }
213
+ const metadataStoreOptions = {
214
+ vault,
215
+ sessionId: options.sessionId,
216
+ command,
217
+ runResult,
218
+ combined,
219
+ fingerprints,
220
+ storageDecision,
221
+ parserName: storageParser.parser.name,
222
+ producer,
223
+ };
224
+ if (options.cwd !== undefined) {
225
+ Object.assign(metadataStoreOptions, { cwd: options.cwd });
226
+ }
227
+ record =
228
+ storageDecision.mode === "exact"
229
+ ? await storeCommandOutput(vault, storeOptions)
230
+ : await storeCommandMetadataOutput(metadataStoreOptions);
231
+ const routeOptions = {
232
+ outputId: record.outputId,
233
+ command,
234
+ executionStatus: runResult.executionStatus,
235
+ exitCode: runResult.exitCode,
236
+ stdout: runResult.stdout,
237
+ stderr: runResult.stderr,
238
+ combined,
239
+ preserve,
240
+ thresholds,
241
+ storage: storageDecision,
242
+ };
243
+ if (filters !== undefined) {
244
+ routeOptions.filters = filters;
310
245
  }
311
- catch (error) {
312
- const message = error instanceof Error ? error.message : String(error);
313
- return commandRoutingFailureResult({
314
- command,
315
- outputId: record?.outputId ?? "",
316
- record,
317
- preserve,
318
- execution,
319
- stdout: runResult.stdout,
320
- stderr: runResult.stderr,
321
- combined,
322
- errorMessage: message,
323
- storage: storageDecision,
324
- producer,
325
- ...(scriptProducer !== undefined ? { scriptProducer } : {}),
246
+ if (options.goal !== undefined) {
247
+ routeOptions.goal = options.goal;
248
+ }
249
+ if (reducerRoute.status === "selected") {
250
+ routeOptions.reducer = reducerRoute;
251
+ }
252
+ let routing;
253
+ const duplicateForRouting =
254
+ duplicate && preserve !== "full" && filters === undefined && scriptFilter === undefined ? duplicate : undefined;
255
+ if (duplicateForRouting) {
256
+ routing = routeDuplicateCommandOutput({
257
+ outputId: record.outputId,
258
+ duplicate: duplicateForRouting,
259
+ storage: storageDecision,
260
+ command,
261
+ executionStatus: runResult.executionStatus,
262
+ exitCode: runResult.exitCode,
263
+ });
264
+ } else if (scriptFilter) {
265
+ const scriptRouteOptions = {
266
+ routeOptions,
267
+ rawRecord: record,
268
+ sessionId: options.sessionId,
269
+ scriptFilter,
270
+ scriptSandboxAdapters: options.scriptSandboxAdapters ?? [],
271
+ };
272
+ if (options.vaultRoot !== undefined) {
273
+ Object.assign(scriptRouteOptions, { vaultRoot: options.vaultRoot });
274
+ }
275
+ if (options.vaultRetention !== undefined) {
276
+ Object.assign(scriptRouteOptions, { vaultRetention: options.vaultRetention });
277
+ }
278
+ if (options.scriptTransform !== undefined) {
279
+ Object.assign(scriptRouteOptions, { scriptTransform: options.scriptTransform });
280
+ }
281
+ routing = await routeScriptFilteredOutput(scriptRouteOptions);
282
+ } else {
283
+ if (
284
+ routeOptions.reducer?.status === "selected" &&
285
+ record.kind === "command" &&
286
+ storageDecision.mode === "exact"
287
+ ) {
288
+ routeOptions.reducerRecord = await storeReducerOutput({
289
+ vault,
290
+ sessionId: options.sessionId,
291
+ rawRecord: record,
292
+ reducer: routeOptions.reducer,
326
293
  });
294
+ }
295
+ routing = routeCommandOutput(routeOptions);
327
296
  }
328
- }
329
- function routeDuplicateCommandOutput(options) {
330
- const currentVaultText = options.storage.mode === "duplicate-metadata"
331
- ? `Current run stored metadata-only as outputId=${options.outputId}; exact raw output remains recoverable from prior outputId=${options.duplicate.outputId}.`
332
- : options.outputId === options.duplicate.outputId
333
- ? `Current run resolved to the same outputId=${options.outputId}.`
334
- : `Current raw output was vaulted as outputId=${options.outputId}.`;
335
- const statusText = `executionStatus=${options.executionStatus} exitCode=${options.exitCode}`;
336
297
  return {
337
- decisionId: decisionId("run-route", options.outputId, "exact-duplicate", options.duplicate.outputId),
338
- routingStatus: "partial",
339
- reason: `Exact duplicate run output matched previous outputId=${options.duplicate.outputId} by exact output hash and producer/cwd/status fingerprint (${statusText}); returning a compact duplicate note instead of re-injecting repeated output. ${currentVaultText}`,
340
- summary: `Run output is an exact duplicate of previous outputId=${options.duplicate.outputId}. ${currentVaultText}`,
341
- importantLines: [],
342
- parser: {
343
- name: "duplicate-output",
344
- confidence: 1,
345
- fidelity: "exact",
346
- compressed: true,
347
- counts: { duplicateOutputs: 1 },
348
- },
298
+ toolStatus: "ok",
299
+ decisionId: routing.decisionId,
300
+ outputId: record.outputId,
301
+ recordId: record.recordId,
302
+ preserve,
303
+ execution,
304
+ producer: record.producer,
305
+ persistence: record.persistence,
306
+ ...(routing.lineage !== undefined
307
+ ? { lineage: routing.lineage }
308
+ : record.lineage !== undefined
309
+ ? { lineage: record.lineage }
310
+ : {}),
311
+ ...(routing.failure !== undefined ? { failure: routing.failure } : {}),
312
+ ...(routing.transformExecution !== undefined ? { transformExecution: routing.transformExecution } : {}),
313
+ ...(routing.evidence !== undefined ? { evidence: routing.evidence } : {}),
314
+ routing: {
315
+ status: routing.routingStatus,
316
+ route: "run",
317
+ reason: routing.reason,
318
+ },
319
+ summary: routing.summary,
320
+ importantLines: routing.importantLines,
321
+ parser: routing.parser,
322
+ ...(routing.filters !== undefined ? { filters: routing.filters } : {}),
323
+ ...(scriptProducer !== undefined ? { scriptProducer } : {}),
324
+ ...(routing.scriptFilter !== undefined ? { scriptFilter: routing.scriptFilter } : {}),
325
+ ...(routing.reducer !== undefined ? { reducer: routing.reducer } : {}),
326
+ recovery: routing.recovery ?? commandRecoveryHint(record.outputId, storageDecision),
349
327
  };
328
+ } catch (error) {
329
+ const message = error instanceof Error ? error.message : String(error);
330
+ return commandRoutingFailureResult({
331
+ command,
332
+ outputId: record?.outputId ?? "",
333
+ record,
334
+ preserve,
335
+ execution,
336
+ stdout: runResult.stdout,
337
+ stderr: runResult.stderr,
338
+ combined,
339
+ errorMessage: message,
340
+ storage: storageDecision,
341
+ producer,
342
+ ...(scriptProducer !== undefined ? { scriptProducer } : {}),
343
+ });
344
+ }
345
+ }
346
+ function routeDuplicateCommandOutput(options) {
347
+ const currentVaultText =
348
+ options.storage.mode === "duplicate-metadata"
349
+ ? `Current run stored metadata-only as outputId=${options.outputId}; exact raw output remains recoverable from prior outputId=${options.duplicate.outputId}.`
350
+ : options.outputId === options.duplicate.outputId
351
+ ? `Current run resolved to the same outputId=${options.outputId}.`
352
+ : `Current raw output was vaulted as outputId=${options.outputId}.`;
353
+ const statusText = `executionStatus=${options.executionStatus} exitCode=${options.exitCode}`;
354
+ return {
355
+ decisionId: decisionId("run-route", options.outputId, "exact-duplicate", options.duplicate.outputId),
356
+ routingStatus: "partial",
357
+ reason: `Exact duplicate run output matched previous outputId=${options.duplicate.outputId} by exact output hash and producer/cwd/status fingerprint (${statusText}); returning a compact duplicate note instead of re-injecting repeated output. ${currentVaultText}`,
358
+ summary: `Run output is an exact duplicate of previous outputId=${options.duplicate.outputId}. ${currentVaultText}`,
359
+ importantLines: [],
360
+ parser: {
361
+ name: "duplicate-output",
362
+ confidence: 1,
363
+ fidelity: "exact",
364
+ compressed: true,
365
+ counts: { duplicateOutputs: 1 },
366
+ },
367
+ };
350
368
  }
351
369
  function commandRecoveryHint(outputId, storage) {
352
- if (storage.mode === "exact") {
353
- return {
354
- how: `Use freeflow_search with source.kind=vault and outputId=${outputId} to recover exact run output.`,
355
- outputId,
356
- };
357
- }
358
- if (storage.mode === "duplicate-metadata" && storage.exactRecoveryOutputId) {
359
- return {
360
- how: `Current run record is metadata-only outputId=${outputId}; exact duplicate raw output is recoverable with freeflow_search source.kind=vault outputId=${storage.exactRecoveryOutputId}.`,
361
- outputId: storage.exactRecoveryOutputId,
362
- };
363
- }
370
+ if (storage.mode === "exact") {
371
+ return {
372
+ how: `Use freeflow_search with source.kind=vault and outputId=${outputId} to recover exact run output.`,
373
+ outputId,
374
+ };
375
+ }
376
+ if (storage.mode === "duplicate-metadata" && storage.exactRecoveryOutputId) {
364
377
  return {
365
- how: `Current run record is metadata-only outputId=${outputId}; exact raw output was not vaulted by storagePolicy=${storage.policy}. Rerun with preserve=full or a verification/diagnosis goal if exact recovery is required.`,
378
+ how: `Current run record is metadata-only outputId=${outputId}; exact duplicate raw output is recoverable with freeflow_search source.kind=vault outputId=${storage.exactRecoveryOutputId}.`,
379
+ outputId: storage.exactRecoveryOutputId,
366
380
  };
381
+ }
382
+ return {
383
+ how: `Current run record is metadata-only outputId=${outputId}; exact raw output was not vaulted by storagePolicy=${storage.policy}. Rerun with preserve=full or a verification/diagnosis goal if exact recovery is required.`,
384
+ };
367
385
  }
368
386
  function commandStorageReason(storage) {
369
- if (!storage || storage.mode === "exact") {
370
- return "raw output was vaulted";
371
- }
372
- if (storage.mode === "duplicate-metadata" && storage.exactRecoveryOutputId) {
373
- return `current output was stored as metadata-only with exact duplicate recovery from outputId=${storage.exactRecoveryOutputId}`;
374
- }
375
- return `current output was stored as metadata-only by storagePolicy=${storage.policy}; exact raw output was not vaulted`;
387
+ if (!storage || storage.mode === "exact") {
388
+ return "raw output was vaulted";
389
+ }
390
+ if (storage.mode === "duplicate-metadata" && storage.exactRecoveryOutputId) {
391
+ return `current output was stored as metadata-only with exact duplicate recovery from outputId=${storage.exactRecoveryOutputId}`;
392
+ }
393
+ return `current output was stored as metadata-only by storagePolicy=${storage.policy}; exact raw output was not vaulted`;
376
394
  }
377
395
  function decideCommandStorage(options) {
378
- const exactnessSensitive = commandOutputIsExactnessSensitive(options);
379
- if (options.policy === "store-everything") {
380
- return { policy: options.policy, mode: "exact", exactnessSensitive, reason: "storagePolicy=store-everything stores every run output exactly." };
381
- }
382
- if (!exactnessSensitive) {
383
- return {
384
- policy: options.policy,
385
- mode: "metadata-only",
386
- exactnessSensitive,
387
- reason: "Small non-sensitive successful run output is stored metadata-only by storagePolicy=hybrid-dedupe.",
388
- };
389
- }
390
- if (options.duplicate?.outputId && !options.hasScriptFilter) {
391
- return {
392
- policy: options.policy,
393
- mode: "duplicate-metadata",
394
- exactnessSensitive,
395
- exactRecoveryOutputId: options.duplicate.outputId,
396
- reason: `Exactness-sensitive run output duplicates prior exact outputId=${options.duplicate.outputId}; current record stores metadata only.`,
397
- };
398
- }
396
+ const exactnessSensitive = commandOutputIsExactnessSensitive(options);
397
+ if (options.policy === "store-everything") {
398
+ return {
399
+ policy: options.policy,
400
+ mode: "exact",
401
+ exactnessSensitive,
402
+ reason: "storagePolicy=store-everything stores every run output exactly.",
403
+ };
404
+ }
405
+ if (!exactnessSensitive) {
406
+ return {
407
+ policy: options.policy,
408
+ mode: "metadata-only",
409
+ exactnessSensitive,
410
+ reason: "Small non-sensitive successful run output is stored metadata-only by storagePolicy=hybrid-dedupe.",
411
+ };
412
+ }
413
+ if (options.duplicate?.outputId && !options.hasScriptFilter) {
399
414
  return {
400
- policy: options.policy,
401
- mode: "exact",
402
- exactnessSensitive,
403
- reason: "Run output is exactness-sensitive or large/noisy; storagePolicy=hybrid-dedupe stores it exactly.",
415
+ policy: options.policy,
416
+ mode: "duplicate-metadata",
417
+ exactnessSensitive,
418
+ exactRecoveryOutputId: options.duplicate.outputId,
419
+ reason: `Exactness-sensitive run output duplicates prior exact outputId=${options.duplicate.outputId}; current record stores metadata only.`,
404
420
  };
421
+ }
422
+ return {
423
+ policy: options.policy,
424
+ mode: "exact",
425
+ exactnessSensitive,
426
+ reason: "Run output is exactness-sensitive or large/noisy; storagePolicy=hybrid-dedupe stores it exactly.",
427
+ };
405
428
  }
406
429
  function commandOutputIsExactnessSensitive(options) {
407
- if (options.preserve === "full" || options.executionStatus !== "success" || options.hasFilters || options.hasScriptFilter || options.hasReducer) {
408
- return true;
409
- }
410
- if (options.producerKind === "script") {
411
- return true;
412
- }
413
- if (options.outputBytes > options.thresholds.largeOutputBytes || options.outputLines > options.thresholds.largeOutputLines) {
414
- return true;
415
- }
416
- const goalText = `${options.goal ?? ""} ${commandText(options.command)}`.toLowerCase();
417
- if (/\b(verify|verification|test|tests|lint|typecheck|type-check|diagnos|debug|build|ci)\b/.test(goalText)) {
418
- return true;
419
- }
420
- return options.parserName !== "generic";
430
+ if (
431
+ options.preserve === "full" ||
432
+ options.executionStatus !== "success" ||
433
+ options.hasFilters ||
434
+ options.hasScriptFilter ||
435
+ options.hasReducer
436
+ ) {
437
+ return true;
438
+ }
439
+ if (options.producerKind === "script") {
440
+ return true;
441
+ }
442
+ if (
443
+ options.outputBytes > options.thresholds.largeOutputBytes ||
444
+ options.outputLines > options.thresholds.largeOutputLines
445
+ ) {
446
+ return true;
447
+ }
448
+ const goalText = `${options.goal ?? ""} ${commandText(options.command)}`.toLowerCase();
449
+ if (/\b(verify|verification|test|tests|lint|typecheck|type-check|diagnos|debug|build|ci)\b/.test(goalText)) {
450
+ return true;
451
+ }
452
+ return options.parserName !== "generic";
421
453
  }
422
454
  async function storeCommandMetadataOutput(options) {
423
- const metadata = {
424
- storagePolicy: options.storageDecision.policy,
425
- storageDecision: options.storageDecision.mode,
426
- storageReason: options.storageDecision.reason,
427
- command: options.command,
428
- executionStatus: options.runResult.executionStatus,
429
- exitCode: options.runResult.exitCode,
430
- parserName: options.parserName,
431
- exactnessSensitive: options.storageDecision.exactnessSensitive,
432
- byteCounts: {
433
- stdout: byteLength(options.runResult.stdout),
434
- stderr: byteLength(options.runResult.stderr),
435
- combined: byteLength(options.combined),
436
- },
437
- lineCounts: {
438
- stdout: countLines(options.runResult.stdout),
439
- stderr: countLines(options.runResult.stderr),
440
- combined: countLines(options.combined),
441
- },
442
- fingerprints: options.fingerprints,
443
- };
444
- if (options.cwd !== undefined) {
445
- metadata.cwd = options.cwd;
446
- }
447
- if (options.runResult.durationMs !== undefined) {
448
- metadata.durationMs = options.runResult.durationMs;
449
- }
450
- if (options.storageDecision.exactRecoveryOutputId !== undefined) {
451
- metadata.exactRecoveryOutputId = options.storageDecision.exactRecoveryOutputId;
452
- }
453
- return storeMetadataOutput(options.vault, {
454
- sessionId: options.sessionId,
455
- sourceKind: options.producer.kind === "script" ? "script" : "other",
456
- rawLineCount: countLines(options.combined),
457
- rawByteCount: byteLength(options.combined),
458
- rawSha256: hash(options.combined),
459
- decisionIds: [decisionId("run-metadata", commandText(options.command), options.sessionId, options.storageDecision.mode)],
460
- producer: options.producer,
461
- metadata,
462
- });
455
+ const metadata = {
456
+ storagePolicy: options.storageDecision.policy,
457
+ storageDecision: options.storageDecision.mode,
458
+ storageReason: options.storageDecision.reason,
459
+ command: options.command,
460
+ executionStatus: options.runResult.executionStatus,
461
+ exitCode: options.runResult.exitCode,
462
+ parserName: options.parserName,
463
+ exactnessSensitive: options.storageDecision.exactnessSensitive,
464
+ byteCounts: {
465
+ stdout: byteLength(options.runResult.stdout),
466
+ stderr: byteLength(options.runResult.stderr),
467
+ combined: byteLength(options.combined),
468
+ },
469
+ lineCounts: {
470
+ stdout: countLines(options.runResult.stdout),
471
+ stderr: countLines(options.runResult.stderr),
472
+ combined: countLines(options.combined),
473
+ },
474
+ fingerprints: options.fingerprints,
475
+ };
476
+ if (options.cwd !== undefined) {
477
+ metadata.cwd = options.cwd;
478
+ }
479
+ if (options.runResult.durationMs !== undefined) {
480
+ metadata.durationMs = options.runResult.durationMs;
481
+ }
482
+ if (options.storageDecision.exactRecoveryOutputId !== undefined) {
483
+ metadata.exactRecoveryOutputId = options.storageDecision.exactRecoveryOutputId;
484
+ }
485
+ return storeMetadataOutput(options.vault, {
486
+ sessionId: options.sessionId,
487
+ sourceKind: options.producer.kind === "script" ? "script" : "other",
488
+ rawLineCount: countLines(options.combined),
489
+ rawByteCount: byteLength(options.combined),
490
+ rawSha256: hash(options.combined),
491
+ decisionIds: [
492
+ decisionId("run-metadata", commandText(options.command), options.sessionId, options.storageDecision.mode),
493
+ ],
494
+ producer: options.producer,
495
+ metadata,
496
+ });
463
497
  }
464
498
  function normalizeRunProducer(options) {
465
- const hasCommand = options.command !== undefined && options.command !== null;
466
- const hasScript = options.script !== undefined && options.script !== null;
467
- if (hasCommand === hasScript) {
468
- return {
469
- ok: false,
470
- path: "$",
471
- message: hasCommand
472
- ? "freeflow_run accepts either command or script, not both."
473
- : "freeflow_run requires either command or script.",
474
- };
475
- }
476
- if (hasCommand) {
477
- const command = options.command;
478
- if (typeof command === "string") {
479
- if (command.trim().length === 0) {
480
- return { ok: false, path: "$.command", message: "Expected non-empty shell command string." };
481
- }
482
- return { ok: true, producer: { kind: "command", command, producer: { kind: "command" } } };
483
- }
484
- if (Array.isArray(command) && command.length > 0 && command.every((part) => typeof part === "string" && part.length > 0)) {
485
- return { ok: true, producer: { kind: "command", command, producer: { kind: "command" } } };
486
- }
487
- return { ok: false, path: "$.command", message: "Expected non-empty shell command string or command argument array." };
488
- }
489
- const scriptValidation = normalizeRunScriptProducer(options.script);
490
- if (!scriptValidation.ok) {
491
- return scriptValidation;
499
+ const hasCommand = options.command !== undefined && options.command !== null;
500
+ const hasScript = options.script !== undefined && options.script !== null;
501
+ if (hasCommand === hasScript) {
502
+ return {
503
+ ok: false,
504
+ path: "$",
505
+ message: hasCommand
506
+ ? "freeflow_run accepts either command or script, not both."
507
+ : "freeflow_run requires either command or script.",
508
+ };
509
+ }
510
+ if (hasCommand) {
511
+ const command = options.command;
512
+ if (typeof command === "string") {
513
+ if (command.trim().length === 0) {
514
+ return { ok: false, path: "$.command", message: "Expected non-empty shell command string." };
515
+ }
516
+ return { ok: true, producer: { kind: "command", command, producer: { kind: "command" } } };
517
+ }
518
+ if (
519
+ Array.isArray(command) &&
520
+ command.length > 0 &&
521
+ command.every((part) => typeof part === "string" && part.length > 0)
522
+ ) {
523
+ return { ok: true, producer: { kind: "command", command, producer: { kind: "command" } } };
492
524
  }
493
525
  return {
494
- ok: true,
495
- producer: {
496
- kind: "script",
497
- command: scriptCommandDescriptor(scriptValidation.script),
498
- script: scriptValidation.script,
499
- },
526
+ ok: false,
527
+ path: "$.command",
528
+ message: "Expected non-empty shell command string or command argument array.",
500
529
  };
530
+ }
531
+ const scriptValidation = normalizeRunScriptProducer(options.script);
532
+ if (!scriptValidation.ok) {
533
+ return scriptValidation;
534
+ }
535
+ return {
536
+ ok: true,
537
+ producer: {
538
+ kind: "script",
539
+ command: scriptCommandDescriptor(scriptValidation.script),
540
+ script: scriptValidation.script,
541
+ },
542
+ };
501
543
  }
502
544
  function normalizeRunScriptProducer(input) {
503
- if (!isRecord(input)) {
504
- return { ok: false, path: "$.script", message: "freeflow_run script must be an object." };
505
- }
506
- const operation = { kind: "script" };
507
- if (input.language !== undefined) {
508
- operation.language = input.language;
509
- }
510
- if (input.code !== undefined) {
511
- operation.code = input.code;
512
- }
513
- if (input.label !== undefined) {
514
- operation.label = input.label;
515
- }
516
- const candidate = {
517
- sources: runScriptFilterSources("ffout_run_script_producer_validation"),
518
- operation,
519
- };
520
- if (input.limits !== undefined) {
521
- candidate.limits = input.limits;
522
- }
523
- const validation = validateTransformInput(candidate);
524
- if (!validation.ok) {
525
- const issue = validation.issues[0] ?? { path: "$.script", message: "Invalid script producer." };
526
- return {
527
- ok: false,
528
- path: issue.path.replace(/^\$\.operation/, "$.script").replace(/^\$\.limits/, "$.script.limits"),
529
- message: issue.message,
530
- };
531
- }
532
- const script = {
533
- language: input.language,
534
- code: input.code,
545
+ if (!isRecord(input)) {
546
+ return { ok: false, path: "$.script", message: "freeflow_run script must be an object." };
547
+ }
548
+ const operation = { kind: "script" };
549
+ if (input.language !== undefined) {
550
+ operation.language = input.language;
551
+ }
552
+ if (input.code !== undefined) {
553
+ operation.code = input.code;
554
+ }
555
+ if (input.label !== undefined) {
556
+ operation.label = input.label;
557
+ }
558
+ const candidate = {
559
+ sources: runScriptFilterSources("ffout_run_script_producer_validation"),
560
+ operation,
561
+ };
562
+ if (input.limits !== undefined) {
563
+ candidate.limits = input.limits;
564
+ }
565
+ const validation = validateTransformInput(candidate);
566
+ if (!validation.ok) {
567
+ const issue = validation.issues[0] ?? { path: "$.script", message: "Invalid script producer." };
568
+ return {
569
+ ok: false,
570
+ path: issue.path.replace(/^\$\.operation/, "$.script").replace(/^\$\.limits/, "$.script.limits"),
571
+ message: issue.message,
535
572
  };
536
- if (input.label !== undefined) {
537
- script.label = input.label;
538
- }
539
- if (input.limits !== undefined) {
540
- script.limits = input.limits;
541
- }
542
- return { ok: true, script };
573
+ }
574
+ const script = {
575
+ language: input.language,
576
+ code: input.code,
577
+ };
578
+ if (input.label !== undefined) {
579
+ script.label = input.label;
580
+ }
581
+ if (input.limits !== undefined) {
582
+ script.limits = input.limits;
583
+ }
584
+ return { ok: true, script };
543
585
  }
544
586
  function runScriptProducerOperation(script) {
545
- const operation = {
546
- kind: "script",
547
- language: script.language,
548
- code: script.code,
549
- };
550
- if (script.label !== undefined) {
551
- operation.label = script.label;
552
- }
553
- return operation;
587
+ const operation = {
588
+ kind: "script",
589
+ language: script.language,
590
+ code: script.code,
591
+ };
592
+ if (script.label !== undefined) {
593
+ operation.label = script.label;
594
+ }
595
+ return operation;
554
596
  }
555
597
  function scriptProducerLimits(script, timeoutMs) {
556
- if (timeoutMs === undefined || script.limits?.timeoutMs !== undefined) {
557
- return script.limits;
558
- }
559
- return { ...(script.limits ?? {}), timeoutMs };
598
+ if (timeoutMs === undefined || script.limits?.timeoutMs !== undefined) {
599
+ return script.limits;
600
+ }
601
+ return { ...(script.limits ?? {}), timeoutMs };
560
602
  }
561
603
  function scriptExecutionResult(execution) {
562
- const result = execution.result;
563
- return {
564
- stdout: result.stdout ?? "",
565
- stderr: result.stderr ?? "",
566
- executionStatus: scriptExecutionStatus(result.status),
567
- exitCode: result.exitCode ?? (result.status === "success" ? 0 : null),
568
- combined: combineOutputSections(result.stdout ?? "", result.stderr ?? ""),
569
- ...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
570
- };
604
+ const result = execution.result;
605
+ return {
606
+ stdout: result.stdout ?? "",
607
+ stderr: result.stderr ?? "",
608
+ executionStatus: scriptExecutionStatus(result.status),
609
+ exitCode: result.exitCode ?? (result.status === "success" ? 0 : null),
610
+ combined: combineOutputSections(result.stdout ?? "", result.stderr ?? ""),
611
+ ...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
612
+ };
571
613
  }
572
614
  function scriptExecutionStatus(status) {
573
- if (status === "success") {
574
- return "success";
575
- }
576
- if (status === "timed_out") {
577
- return "timed_out";
578
- }
579
- return "failed";
615
+ if (status === "success") {
616
+ return "success";
617
+ }
618
+ if (status === "timed_out") {
619
+ return "timed_out";
620
+ }
621
+ return "failed";
580
622
  }
581
623
  function runScriptProducerMetadata(script, execution) {
582
- const metadata = {
583
- status: execution.ok ? execution.result.status : execution.executionStatus === "unavailable" ? "unavailable" : "failed",
584
- language: script.language,
585
- policy: "sandboxed",
586
- rawScriptPersistence: "disabled",
587
- codeSha256: scriptCodeSha256(script),
588
- limits: execution.limits,
589
- operation: execution.operation,
624
+ const metadata = {
625
+ status: execution.ok
626
+ ? execution.result.status
627
+ : execution.executionStatus === "unavailable"
628
+ ? "unavailable"
629
+ : "failed",
630
+ language: script.language,
631
+ policy: "sandboxed",
632
+ rawScriptPersistence: "disabled",
633
+ codeSha256: scriptCodeSha256(script),
634
+ limits: execution.limits,
635
+ operation: execution.operation,
636
+ };
637
+ if (script.label !== undefined) {
638
+ metadata.label = script.label;
639
+ }
640
+ if (execution.ok) {
641
+ metadata.adapterId = execution.adapterId;
642
+ metadata.adapterVersion = execution.adapterVersion;
643
+ if (execution.runtime !== undefined) {
644
+ metadata.runtime = execution.runtime;
645
+ }
646
+ metadata.stdoutBytes = byteLength(execution.result.stdout ?? "");
647
+ metadata.stderrBytes = byteLength(execution.result.stderr ?? "");
648
+ if (execution.result.exitCode !== undefined) {
649
+ metadata.exitCode = execution.result.exitCode;
650
+ }
651
+ if (execution.result.durationMs !== undefined) {
652
+ metadata.durationMs = execution.result.durationMs;
653
+ }
654
+ } else {
655
+ if (execution.adapterId !== undefined) {
656
+ metadata.adapterId = execution.adapterId;
657
+ }
658
+ if (execution.adapterVersion !== undefined) {
659
+ metadata.adapterVersion = execution.adapterVersion;
660
+ }
661
+ metadata.failure = { kind: execution.failureKind, message: execution.message };
662
+ metadata.transformExecution = {
663
+ status: execution.executionStatus,
664
+ failureKind: execution.failureKind,
665
+ message: execution.message,
590
666
  };
591
- if (script.label !== undefined) {
592
- metadata.label = script.label;
593
- }
594
- if (execution.ok) {
595
- metadata.adapterId = execution.adapterId;
596
- metadata.adapterVersion = execution.adapterVersion;
597
- if (execution.runtime !== undefined) {
598
- metadata.runtime = execution.runtime;
599
- }
600
- metadata.stdoutBytes = byteLength(execution.result.stdout ?? "");
601
- metadata.stderrBytes = byteLength(execution.result.stderr ?? "");
602
- if (execution.result.exitCode !== undefined) {
603
- metadata.exitCode = execution.result.exitCode;
604
- }
605
- if (execution.result.durationMs !== undefined) {
606
- metadata.durationMs = execution.result.durationMs;
607
- }
608
- }
609
- else {
610
- if (execution.adapterId !== undefined) {
611
- metadata.adapterId = execution.adapterId;
612
- }
613
- if (execution.adapterVersion !== undefined) {
614
- metadata.adapterVersion = execution.adapterVersion;
615
- }
616
- metadata.failure = { kind: execution.failureKind, message: execution.message };
617
- metadata.transformExecution = {
618
- status: execution.executionStatus,
619
- failureKind: execution.failureKind,
620
- message: execution.message,
621
- };
622
- }
623
- return metadata;
667
+ }
668
+ return metadata;
624
669
  }
625
670
  function scriptProducerDescriptor(script, execution) {
626
- const descriptor = {
627
- kind: "script",
628
- name: script.label ?? `script:${script.language}`,
629
- };
630
- if (execution.ok) {
631
- descriptor.adapter = execution.adapterId;
632
- }
633
- else if (execution.adapterId !== undefined) {
634
- descriptor.adapter = execution.adapterId;
635
- }
636
- return descriptor;
671
+ const descriptor = {
672
+ kind: "script",
673
+ name: script.label ?? `script:${script.language}`,
674
+ };
675
+ if (execution.ok) {
676
+ descriptor.adapter = execution.adapterId;
677
+ } else if (execution.adapterId !== undefined) {
678
+ descriptor.adapter = execution.adapterId;
679
+ }
680
+ return descriptor;
637
681
  }
638
682
  function scriptCommandDescriptor(script) {
639
- const label = script.label ? ` label=${JSON.stringify(script.label)}` : "";
640
- return `script:${script.language} code=${scriptCodeSha256(script)}${label}`;
683
+ const label = script.label ? ` label=${JSON.stringify(script.label)}` : "";
684
+ return `script:${script.language} code=${scriptCodeSha256(script)}${label}`;
641
685
  }
642
686
  function scriptCodeSha256(script) {
643
- return `sha256_${hash(script.code)}`;
687
+ return `sha256_${hash(script.code)}`;
644
688
  }
645
689
  function runProducerValidationFailureResult(options) {
646
- return {
647
- toolStatus: "error",
648
- decisionId: decisionId("run-producer-validation", options.path, options.message),
649
- outputId: "",
650
- preserve: options.preserve,
651
- execution: { status: "failed", exitCode: null },
652
- producer: { kind: "other", name: "freeflow_run" },
653
- persistence: { status: "not_persisted", recoverability: "none" },
654
- routing: {
655
- status: "failed",
656
- route: "run",
657
- reason: `Invalid freeflow_run producer at ${options.path}: ${options.message}`,
658
- },
659
- summary: "Run producer was not executed because freeflow_run input was invalid.",
660
- recovery: {
661
- how: "No command or script output was captured. Fix the freeflow_run producer input and rerun.",
662
- },
663
- };
690
+ return {
691
+ toolStatus: "error",
692
+ decisionId: decisionId("run-producer-validation", options.path, options.message),
693
+ outputId: "",
694
+ preserve: options.preserve,
695
+ execution: { status: "failed", exitCode: null },
696
+ producer: { kind: "other", name: "freeflow_run" },
697
+ persistence: { status: "not_persisted", recoverability: "none" },
698
+ routing: {
699
+ status: "failed",
700
+ route: "run",
701
+ reason: `Invalid freeflow_run producer at ${options.path}: ${options.message}`,
702
+ },
703
+ summary: "Run producer was not executed because freeflow_run input was invalid.",
704
+ recovery: {
705
+ how: "No command or script output was captured. Fix the freeflow_run producer input and rerun.",
706
+ },
707
+ };
664
708
  }
665
709
  function scriptProducerExecutionFailureResult(options) {
666
- return {
667
- toolStatus: "error",
668
- decisionId: decisionId("run-script-producer", commandText(options.command), options.execution.failureKind, options.execution.message),
669
- outputId: "",
670
- preserve: options.preserve,
671
- execution: { status: "failed", exitCode: null },
672
- producer: options.producer,
673
- scriptProducer: options.scriptProducer,
674
- failure: {
675
- kind: options.execution.failureKind,
676
- message: options.execution.message,
677
- },
678
- transformExecution: {
679
- status: options.execution.executionStatus,
680
- failureKind: options.execution.failureKind,
681
- message: options.execution.message,
682
- },
683
- persistence: { status: "not_persisted", recoverability: "none" },
684
- routing: {
685
- status: "failed",
686
- route: "run",
687
- reason: `Sandboxed script producer could not execute: ${options.execution.message}`,
688
- },
689
- summary: "Script producer was not executed; no stdout/stderr was captured.",
690
- recovery: {
691
- how: "No script output was captured. Enable scriptTransform with a proof-backed sandbox adapter, fix the script producer input, or use a shell command when host execution is intentionally required.",
692
- },
693
- };
710
+ return {
711
+ toolStatus: "error",
712
+ decisionId: decisionId(
713
+ "run-script-producer",
714
+ commandText(options.command),
715
+ options.execution.failureKind,
716
+ options.execution.message,
717
+ ),
718
+ outputId: "",
719
+ preserve: options.preserve,
720
+ execution: { status: "failed", exitCode: null },
721
+ producer: options.producer,
722
+ scriptProducer: options.scriptProducer,
723
+ failure: {
724
+ kind: options.execution.failureKind,
725
+ message: options.execution.message,
726
+ },
727
+ transformExecution: {
728
+ status: options.execution.executionStatus,
729
+ failureKind: options.execution.failureKind,
730
+ message: options.execution.message,
731
+ },
732
+ persistence: { status: "not_persisted", recoverability: "none" },
733
+ routing: {
734
+ status: "failed",
735
+ route: "run",
736
+ reason: `Sandboxed script producer could not execute: ${options.execution.message}`,
737
+ },
738
+ summary: "Script producer was not executed; no stdout/stderr was captured.",
739
+ recovery: {
740
+ how: "No script output was captured. Enable scriptTransform with a proof-backed sandbox adapter, fix the script producer input, or use a shell command when host execution is intentionally required.",
741
+ },
742
+ };
694
743
  }
695
744
  function commandFilterValidationFailureResult(options) {
696
- return {
697
- toolStatus: "error",
698
- decisionId: decisionId("run-filter-validation", commandText(options.command), options.path, options.message),
699
- outputId: "",
700
- preserve: options.preserve,
701
- execution: { status: "failed", exitCode: null },
702
- producer: options.producer,
703
- persistence: { status: "not_persisted", recoverability: "none" },
704
- routing: {
705
- status: "failed",
706
- route: "run",
707
- reason: `Invalid freeflow_run filters at ${options.path}: ${options.message}`,
708
- },
709
- summary: "Run producer was not executed because freeflow_run filters were invalid.",
710
- recovery: {
711
- how: "No command or script output was captured. Fix the declarative filter and rerun through freeflow_run.",
712
- },
713
- };
745
+ return {
746
+ toolStatus: "error",
747
+ decisionId: decisionId("run-filter-validation", commandText(options.command), options.path, options.message),
748
+ outputId: "",
749
+ preserve: options.preserve,
750
+ execution: { status: "failed", exitCode: null },
751
+ producer: options.producer,
752
+ persistence: { status: "not_persisted", recoverability: "none" },
753
+ routing: {
754
+ status: "failed",
755
+ route: "run",
756
+ reason: `Invalid freeflow_run filters at ${options.path}: ${options.message}`,
757
+ },
758
+ summary: "Run producer was not executed because freeflow_run filters were invalid.",
759
+ recovery: {
760
+ how: "No command or script output was captured. Fix the declarative filter and rerun through freeflow_run.",
761
+ },
762
+ };
714
763
  }
715
764
  function commandScriptFilterValidationFailureResult(options) {
716
- return {
717
- toolStatus: "error",
718
- decisionId: decisionId("run-script-filter-validation", commandText(options.command), options.path, options.message),
719
- outputId: "",
720
- preserve: options.preserve,
721
- execution: { status: "failed", exitCode: null },
722
- producer: options.producer,
723
- persistence: { status: "not_persisted", recoverability: "none" },
724
- routing: {
725
- status: "failed",
726
- route: "run",
727
- reason: `Invalid freeflow_run scriptFilter at ${options.path}: ${options.message}`,
728
- },
729
- summary: "Run producer was not executed because freeflow_run scriptFilter was invalid.",
730
- recovery: {
731
- how: "No command or script output was captured. Fix the sandboxed script filter and rerun through freeflow_run.",
732
- },
733
- };
765
+ return {
766
+ toolStatus: "error",
767
+ decisionId: decisionId("run-script-filter-validation", commandText(options.command), options.path, options.message),
768
+ outputId: "",
769
+ preserve: options.preserve,
770
+ execution: { status: "failed", exitCode: null },
771
+ producer: options.producer,
772
+ persistence: { status: "not_persisted", recoverability: "none" },
773
+ routing: {
774
+ status: "failed",
775
+ route: "run",
776
+ reason: `Invalid freeflow_run scriptFilter at ${options.path}: ${options.message}`,
777
+ },
778
+ summary: "Run producer was not executed because freeflow_run scriptFilter was invalid.",
779
+ recovery: {
780
+ how: "No command or script output was captured. Fix the sandboxed script filter and rerun through freeflow_run.",
781
+ },
782
+ };
734
783
  }
735
784
  function commandRoutingFailureResult(options) {
736
- const { stream, text } = routedCommandText({
737
- outputId: options.outputId,
738
- command: options.command,
739
- executionStatus: options.execution.status,
740
- exitCode: options.execution.exitCode,
741
- stdout: options.stdout,
742
- stderr: options.stderr,
743
- combined: options.combined,
744
- preserve: options.preserve,
745
- thresholds: DEFAULT_ROUTER_THRESHOLDS,
746
- });
747
- const fallback = assembleTextEvidence({ stream, text });
748
- const parser = {
749
- name: "router-fallback",
750
- confidence: 0,
751
- fidelity: fallback.fidelity,
752
- compressed: fallback.compressed,
753
- };
754
- const recovery = options.outputId
755
- ? options.storage !== undefined
756
- ? commandRecoveryHint(options.outputId, options.storage)
757
- : {
758
- how: `Routing failed after vault capture; use freeflow_search with source.kind=vault and outputId=${options.outputId} to recover exact run output.`,
759
- outputId: options.outputId,
760
- }
761
- : {
762
- how: "Run output could not be vaulted. A bounded in-memory preview was returned; rerun through the appropriate producer if exact recovery is required.",
763
- };
764
- return {
765
- toolStatus: "error",
766
- decisionId: decisionId("run-route-error", commandText(options.command), options.errorMessage),
767
- outputId: options.outputId,
768
- ...(options.record !== undefined ? { recordId: options.record.recordId } : {}),
769
- preserve: options.preserve,
770
- execution: options.execution,
771
- producer: options.record?.producer ?? options.producer,
772
- persistence: options.record?.persistence ?? { status: "not_persisted", recoverability: "none" },
773
- ...(options.record?.lineage !== undefined ? { lineage: options.record.lineage } : {}),
774
- ...(options.scriptProducer !== undefined ? { scriptProducer: options.scriptProducer } : {}),
775
- routing: {
776
- status: "failed",
777
- route: "run",
778
- reason: `Run producer executed, but Freeflow routing failed after execution: ${options.errorMessage}`,
779
- },
780
- summary: "Run producer executed, but Freeflow routing failed after execution.",
781
- importantLines: fallback.importantLines,
782
- parser,
783
- recovery,
784
- };
785
+ const { stream, text } = routedCommandText({
786
+ outputId: options.outputId,
787
+ command: options.command,
788
+ executionStatus: options.execution.status,
789
+ exitCode: options.execution.exitCode,
790
+ stdout: options.stdout,
791
+ stderr: options.stderr,
792
+ combined: options.combined,
793
+ preserve: options.preserve,
794
+ thresholds: DEFAULT_ROUTER_THRESHOLDS,
795
+ });
796
+ const fallback = assembleTextEvidence({ stream, text });
797
+ const parser = {
798
+ name: "router-fallback",
799
+ confidence: 0,
800
+ fidelity: fallback.fidelity,
801
+ compressed: fallback.compressed,
802
+ };
803
+ const recovery = options.outputId
804
+ ? options.storage !== undefined
805
+ ? commandRecoveryHint(options.outputId, options.storage)
806
+ : {
807
+ how: `Routing failed after vault capture; use freeflow_search with source.kind=vault and outputId=${options.outputId} to recover exact run output.`,
808
+ outputId: options.outputId,
809
+ }
810
+ : {
811
+ how: "Run output could not be vaulted. A bounded in-memory preview was returned; rerun through the appropriate producer if exact recovery is required.",
812
+ };
813
+ return {
814
+ toolStatus: "error",
815
+ decisionId: decisionId("run-route-error", commandText(options.command), options.errorMessage),
816
+ outputId: options.outputId,
817
+ ...(options.record !== undefined ? { recordId: options.record.recordId } : {}),
818
+ preserve: options.preserve,
819
+ execution: options.execution,
820
+ producer: options.record?.producer ?? options.producer,
821
+ persistence: options.record?.persistence ?? { status: "not_persisted", recoverability: "none" },
822
+ ...(options.record?.lineage !== undefined ? { lineage: options.record.lineage } : {}),
823
+ ...(options.scriptProducer !== undefined ? { scriptProducer: options.scriptProducer } : {}),
824
+ routing: {
825
+ status: "failed",
826
+ route: "run",
827
+ reason: `Run producer executed, but Freeflow routing failed after execution: ${options.errorMessage}`,
828
+ },
829
+ summary: "Run producer executed, but Freeflow routing failed after execution.",
830
+ importantLines: fallback.importantLines,
831
+ parser,
832
+ recovery,
833
+ };
785
834
  }
786
835
  // Keep exactness-sensitive command routing aligned with
787
- // skills/output-router/references/safety-policy.md.
836
+ // capabilities/output-router/references/safety-policy.md.
788
837
  function routeCommandOutput(options) {
789
- const outputBytes = byteLength(options.combined);
790
- const outputLines = countLines(options.combined);
791
- const isLarge = outputBytes > options.thresholds.largeOutputBytes || outputLines > options.thresholds.largeOutputLines;
792
- const parseInput = {
793
- command: options.command,
794
- executionStatus: options.executionStatus,
795
- exitCode: options.exitCode,
796
- stdout: options.stdout,
797
- stderr: options.stderr,
798
- combined: options.combined,
838
+ const outputBytes = byteLength(options.combined);
839
+ const outputLines = countLines(options.combined);
840
+ const isLarge =
841
+ outputBytes > options.thresholds.largeOutputBytes || outputLines > options.thresholds.largeOutputLines;
842
+ const parseInput = {
843
+ command: options.command,
844
+ executionStatus: options.executionStatus,
845
+ exitCode: options.exitCode,
846
+ stdout: options.stdout,
847
+ stderr: options.stderr,
848
+ combined: options.combined,
849
+ };
850
+ if (options.goal !== undefined) {
851
+ Object.assign(parseInput, { goal: options.goal });
852
+ }
853
+ const parsed = parseCommandOutput(parseInput);
854
+ const parser = parsed.parser;
855
+ const statusText = `executionStatus=${options.executionStatus} exitCode=${options.exitCode}`;
856
+ const parserText = parserTextFor(parser);
857
+ if (options.filters) {
858
+ return routeFilteredOutput({ ...options, filters: options.filters }, parsed, statusText);
859
+ }
860
+ if (options.preserve === "full") {
861
+ return routeFullOutput(options, parsed, outputBytes, outputLines, statusText);
862
+ }
863
+ if (options.executionStatus !== "success") {
864
+ return {
865
+ decisionId: decisionId("run-route", options.outputId, options.executionStatus, "failed", parser.name),
866
+ routingStatus: "routed",
867
+ reason: `Command failed or did not complete (${statusText}); selected failure evidence was returned and ${commandStorageReason(options.storage)} before routing (${parserText}).`,
868
+ summary: parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`,
869
+ importantLines: parsed.importantLines,
870
+ parser,
799
871
  };
800
- if (options.goal !== undefined) {
801
- Object.assign(parseInput, { goal: options.goal });
802
- }
803
- const parsed = parseCommandOutput(parseInput);
804
- const parser = parsed.parser;
805
- const statusText = `executionStatus=${options.executionStatus} exitCode=${options.exitCode}`;
806
- const parserText = parserTextFor(parser);
807
- if (options.filters) {
808
- return routeFilteredOutput({ ...options, filters: options.filters }, parsed, statusText);
809
- }
810
- if (options.preserve === "full") {
811
- return routeFullOutput(options, parsed, outputBytes, outputLines, statusText);
812
- }
813
- if (options.executionStatus !== "success") {
814
- return {
815
- decisionId: decisionId("run-route", options.outputId, options.executionStatus, "failed", parser.name),
816
- routingStatus: "routed",
817
- reason: `Command failed or did not complete (${statusText}); selected failure evidence was returned and ${commandStorageReason(options.storage)} before routing (${parserText}).`,
818
- summary: parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`,
819
- importantLines: parsed.importantLines,
820
- parser,
821
- };
822
- }
823
- if (options.reducer) {
824
- return routeReducedCommandOutput({ ...options, reducer: options.reducer }, parsed, statusText);
825
- }
826
- if (isLarge) {
827
- return {
828
- decisionId: decisionId("run-route", options.outputId, "large-success", parser.name),
829
- routingStatus: "partial",
830
- reason: `Large successful run output (${outputBytes} bytes, ${outputLines} lines): ${commandStorageReason(options.storage)}; bounded important lines were returned instead of full output (${parserText}).`,
831
- summary: parsed.summary ?? `Command succeeded with ${outputLines} output lines and ${outputBytes} bytes.`,
832
- importantLines: parsed.importantLines,
833
- parser,
834
- };
835
- }
836
- const nearRaw = selectNearRawSuccessfulLines(options);
837
- const nearRawParser = parserWithEvidence(parser, nearRaw);
872
+ }
873
+ if (options.reducer) {
874
+ return routeReducedCommandOutput({ ...options, reducer: options.reducer }, parsed, statusText);
875
+ }
876
+ if (isLarge) {
838
877
  return {
839
- decisionId: decisionId("run-route", options.outputId, "small-success", parser.name, nearRaw.fidelity),
840
- routingStatus: nearRaw.fidelity === "exact" ? "routed" : "partial",
841
- reason: `Small successful run output: ${commandStorageReason(options.storage)}; routed evidence was returned near-raw from the captured execution (${parserTextFor(nearRawParser)}).`,
842
- summary: parsed.summary ?? `Command success with exitCode=${options.exitCode}.`,
843
- importantLines: nearRaw.importantLines,
844
- parser: nearRawParser,
878
+ decisionId: decisionId("run-route", options.outputId, "large-success", parser.name),
879
+ routingStatus: "partial",
880
+ reason: `Large successful run output (${outputBytes} bytes, ${outputLines} lines): ${commandStorageReason(options.storage)}; bounded important lines were returned instead of full output (${parserText}).`,
881
+ summary: parsed.summary ?? `Command succeeded with ${outputLines} output lines and ${outputBytes} bytes.`,
882
+ importantLines: parsed.importantLines,
883
+ parser,
845
884
  };
885
+ }
886
+ const nearRaw = selectNearRawSuccessfulLines(options);
887
+ const nearRawParser = parserWithEvidence(parser, nearRaw);
888
+ return {
889
+ decisionId: decisionId("run-route", options.outputId, "small-success", parser.name, nearRaw.fidelity),
890
+ routingStatus: nearRaw.fidelity === "exact" ? "routed" : "partial",
891
+ reason: `Small successful run output: ${commandStorageReason(options.storage)}; routed evidence was returned near-raw from the captured execution (${parserTextFor(nearRawParser)}).`,
892
+ summary: parsed.summary ?? `Command success with exitCode=${options.exitCode}.`,
893
+ importantLines: nearRaw.importantLines,
894
+ parser: nearRawParser,
895
+ };
846
896
  }
847
897
  function routeReducedCommandOutput(options, parsed, statusText) {
848
- const importantLines = reducerImportantLines(options.reducer);
849
- const parser = parserWithReducer(parsed.parser, options.reducer);
850
- return {
851
- decisionId: decisionId("run-route", options.outputId, "reducer", options.reducer.result.name, options.reducer.result.version),
852
- routingStatus: "partial",
853
- reason: `Reducer ${options.reducer.result.name}@${options.reducer.result.version} selected for successful run output (${statusText}); raw output was vaulted before deterministic reduction (${parserTextFor(parser)}).`,
854
- summary: options.reducer.result.visibleText,
855
- importantLines,
856
- parser,
857
- reducer: runReducerMetadata(options.outputId, options.reducer, options.reducerRecord),
858
- ...(options.reducerRecord?.lineage !== undefined ? { lineage: options.reducerRecord.lineage } : {}),
859
- recovery: commandReducerRecoveryHint(options.outputId, options.reducerRecord?.outputId),
860
- };
898
+ const importantLines = reducerImportantLines(options.reducer);
899
+ const parser = parserWithReducer(parsed.parser, options.reducer);
900
+ return {
901
+ decisionId: decisionId(
902
+ "run-route",
903
+ options.outputId,
904
+ "reducer",
905
+ options.reducer.result.name,
906
+ options.reducer.result.version,
907
+ ),
908
+ routingStatus: "partial",
909
+ reason: `Reducer ${options.reducer.result.name}@${options.reducer.result.version} selected for successful run output (${statusText}); raw output was vaulted before deterministic reduction (${parserTextFor(parser)}).`,
910
+ summary: options.reducer.result.visibleText,
911
+ importantLines,
912
+ parser,
913
+ reducer: runReducerMetadata(options.outputId, options.reducer, options.reducerRecord),
914
+ ...(options.reducerRecord?.lineage !== undefined ? { lineage: options.reducerRecord.lineage } : {}),
915
+ recovery: commandReducerRecoveryHint(options.outputId, options.reducerRecord?.outputId),
916
+ };
861
917
  }
862
918
  function routeFilteredOutput(options, parsed, statusText) {
863
- const defaultText = routedCommandText(options);
864
- const filtered = applyRunOutputFilters({
865
- filters: options.filters,
866
- defaultStream: defaultText.stream,
867
- stdout: options.stdout,
868
- stderr: options.stderr,
869
- combined: options.combined,
870
- fallbackImportantLines: parsed.importantLines,
871
- preserveFallbackFailureEvidence: options.executionStatus !== "success",
872
- caps: {
873
- maxLines: options.thresholds.largeOutputLines,
874
- maxExcerptBytes: options.thresholds.largeOutputBytes,
875
- maxLineBytes: options.thresholds.largeOutputBytes,
876
- },
877
- });
878
- const parser = parserWithEvidence(parsed.parser, filtered.evidence);
879
- const fallbackText = filtered.metadata.fallbackPreservedFailureEvidence
880
- ? " No filtered lines matched, so parsed failure evidence was preserved instead of hiding the failure."
881
- : "";
882
- const selectedText = `${filtered.metadata.selectedLines}/${filtered.metadata.sourceLines} line(s) selected`;
883
- return {
884
- decisionId: decisionId("run-route", options.outputId, "filtered", filtered.description, parser.name),
885
- routingStatus: filtered.evidence.compressed ? "partial" : "routed",
886
- reason: `Run output was vaulted before declarative filters were applied (${statusText}; filters: ${filtered.description}; ${parserTextFor(parser)}).${fallbackText}`,
887
- summary: `${parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`} Filtered routed evidence: ${selectedText} from ${filtered.stream}.`,
888
- importantLines: filtered.evidence.importantLines,
889
- parser: {
890
- ...parser,
891
- counts: {
892
- ...(parser.counts ?? {}),
893
- filterSourceLines: filtered.metadata.sourceLines,
894
- filterSelectedLines: filtered.metadata.selectedLines,
895
- },
896
- },
897
- filters: filtered.metadata,
898
- };
919
+ const defaultText = routedCommandText(options);
920
+ const filtered = applyRunOutputFilters({
921
+ filters: options.filters,
922
+ defaultStream: defaultText.stream,
923
+ stdout: options.stdout,
924
+ stderr: options.stderr,
925
+ combined: options.combined,
926
+ fallbackImportantLines: parsed.importantLines,
927
+ preserveFallbackFailureEvidence: options.executionStatus !== "success",
928
+ caps: {
929
+ maxLines: options.thresholds.largeOutputLines,
930
+ maxExcerptBytes: options.thresholds.largeOutputBytes,
931
+ maxLineBytes: options.thresholds.largeOutputBytes,
932
+ },
933
+ });
934
+ const parser = parserWithEvidence(parsed.parser, filtered.evidence);
935
+ const fallbackText = filtered.metadata.fallbackPreservedFailureEvidence
936
+ ? " No filtered lines matched, so parsed failure evidence was preserved instead of hiding the failure."
937
+ : "";
938
+ const selectedText = `${filtered.metadata.selectedLines}/${filtered.metadata.sourceLines} line(s) selected`;
939
+ return {
940
+ decisionId: decisionId("run-route", options.outputId, "filtered", filtered.description, parser.name),
941
+ routingStatus: filtered.evidence.compressed ? "partial" : "routed",
942
+ reason: `Run output was vaulted before declarative filters were applied (${statusText}; filters: ${filtered.description}; ${parserTextFor(parser)}).${fallbackText}`,
943
+ summary: `${parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`} Filtered routed evidence: ${selectedText} from ${filtered.stream}.`,
944
+ importantLines: filtered.evidence.importantLines,
945
+ parser: {
946
+ ...parser,
947
+ counts: {
948
+ ...(parser.counts ?? {}),
949
+ filterSourceLines: filtered.metadata.sourceLines,
950
+ filterSelectedLines: filtered.metadata.selectedLines,
951
+ },
952
+ },
953
+ filters: filtered.metadata,
954
+ };
899
955
  }
900
956
  async function routeScriptFilteredOutput(options) {
901
- const { routeOptions, rawRecord, scriptFilter } = options;
902
- const baseRouting = routeCommandOutput(routeOptions);
903
- const operation = {
904
- kind: "script",
905
- language: scriptFilter.language,
906
- code: scriptFilter.code,
907
- };
908
- if (scriptFilter.label !== undefined) {
909
- operation.label = scriptFilter.label;
910
- }
911
- const transformOptions = {
912
- sessionId: options.sessionId,
913
- sources: runScriptFilterSources(rawRecord.outputId),
914
- operation,
915
- preserve: routeOptions.preserve,
916
- thresholds: routeOptions.thresholds,
917
- scriptSandboxAdapters: options.scriptSandboxAdapters,
957
+ const { routeOptions, rawRecord, scriptFilter } = options;
958
+ const baseRouting = routeCommandOutput(routeOptions);
959
+ const operation = {
960
+ kind: "script",
961
+ language: scriptFilter.language,
962
+ code: scriptFilter.code,
963
+ };
964
+ if (scriptFilter.label !== undefined) {
965
+ operation.label = scriptFilter.label;
966
+ }
967
+ const transformOptions = {
968
+ sessionId: options.sessionId,
969
+ sources: runScriptFilterSources(rawRecord.outputId),
970
+ operation,
971
+ preserve: routeOptions.preserve,
972
+ thresholds: routeOptions.thresholds,
973
+ scriptSandboxAdapters: options.scriptSandboxAdapters,
974
+ };
975
+ if (options.scriptTransform !== undefined) {
976
+ Object.assign(transformOptions, { scriptTransform: options.scriptTransform });
977
+ }
978
+ if (options.vaultRoot !== undefined) {
979
+ Object.assign(transformOptions, { vaultRoot: options.vaultRoot });
980
+ }
981
+ if (options.vaultRetention !== undefined) {
982
+ Object.assign(transformOptions, { vaultRetention: options.vaultRetention });
983
+ }
984
+ if (scriptFilter.limits !== undefined) {
985
+ Object.assign(transformOptions, { limits: scriptFilter.limits });
986
+ }
987
+ const scriptResult = await freeflowTransform(transformOptions);
988
+ const metadata = runScriptFilterMetadata(scriptFilter, scriptResult, rawRecord.outputId);
989
+ if (isSuccessfulScriptFilterResult(scriptResult)) {
990
+ const importantLines = evidencePacketsAsImportantLines(scriptResult.evidence);
991
+ const parser = {
992
+ name: `script-filter:${scriptFilter.language}`,
993
+ confidence: 1,
994
+ fidelity: "exact",
995
+ compressed: scriptResult.routing.status === "partial",
996
+ counts: {
997
+ scriptEvidencePackets: scriptResult.evidence?.length ?? 0,
998
+ },
918
999
  };
919
- if (options.scriptTransform !== undefined) {
920
- Object.assign(transformOptions, { scriptTransform: options.scriptTransform });
921
- }
922
- if (options.vaultRoot !== undefined) {
923
- Object.assign(transformOptions, { vaultRoot: options.vaultRoot });
924
- }
925
- if (options.vaultRetention !== undefined) {
926
- Object.assign(transformOptions, { vaultRetention: options.vaultRetention });
927
- }
928
- if (scriptFilter.limits !== undefined) {
929
- Object.assign(transformOptions, { limits: scriptFilter.limits });
930
- }
931
- const scriptResult = await freeflowTransform(transformOptions);
932
- const metadata = runScriptFilterMetadata(scriptFilter, scriptResult, rawRecord.outputId);
933
- if (isSuccessfulScriptFilterResult(scriptResult)) {
934
- const importantLines = evidencePacketsAsImportantLines(scriptResult.evidence);
935
- const parser = {
936
- name: `script-filter:${scriptFilter.language}`,
937
- confidence: 1,
938
- fidelity: "exact",
939
- compressed: scriptResult.routing.status === "partial",
940
- counts: {
941
- scriptEvidencePackets: scriptResult.evidence?.length ?? 0,
942
- },
943
- };
944
- return {
945
- decisionId: decisionId("run-route", rawRecord.outputId, "script-filter", scriptResult.outputId, scriptFilter.language),
946
- routingStatus: scriptResult.routing.status,
947
- reason: `Run output was vaulted as outputId=${rawRecord.outputId} before a sandboxed ${scriptFilter.language} script filter ran over captured stdout/stderr/combined. ${scriptResult.routing.reason}`,
948
- summary: `${baseRouting.summary} Script filter completed; transformed outputId=${scriptResult.outputId}.`,
949
- importantLines,
950
- parser,
951
- ...(baseRouting.filters !== undefined ? { filters: baseRouting.filters } : {}),
952
- scriptFilter: metadata,
953
- ...(scriptResult.lineage !== undefined ? { lineage: scriptResult.lineage } : {}),
954
- ...(scriptResult.evidence !== undefined ? { evidence: scriptResult.evidence } : {}),
955
- recovery: commandScriptFilterRecoveryHint(rawRecord.outputId, scriptResult.outputId),
956
- };
957
- }
958
- const failureMessage = scriptResult.failure?.message ?? scriptResult.routing.reason;
959
1000
  return {
960
- ...baseRouting,
961
- decisionId: decisionId("run-route", rawRecord.outputId, "script-filter-failed", scriptFilter.language, failureMessage),
962
- routingStatus: baseRouting.routingStatus === "failed" ? "failed" : "partial",
963
- reason: `Run producer executed and raw output was vaulted as outputId=${rawRecord.outputId}, but the sandboxed ${scriptFilter.language} script filter did not produce transformed output: ${failureMessage} Base run evidence was returned instead.`,
964
- summary: `${baseRouting.summary} Script filter did not produce transformed output: ${failureMessage}`,
965
- parser: {
966
- ...baseRouting.parser,
967
- counts: {
968
- ...(baseRouting.parser.counts ?? {}),
969
- scriptFilterFailures: 1,
970
- },
971
- },
972
- scriptFilter: metadata,
973
- ...(scriptResult.failure !== undefined ? { failure: scriptResult.failure } : {}),
974
- ...(scriptResult.transformExecution !== undefined ? { transformExecution: scriptResult.transformExecution } : {}),
975
- ...(scriptResult.lineage !== undefined ? { lineage: scriptResult.lineage } : {}),
976
- recovery: commandScriptFilterRecoveryHint(rawRecord.outputId),
1001
+ decisionId: decisionId(
1002
+ "run-route",
1003
+ rawRecord.outputId,
1004
+ "script-filter",
1005
+ scriptResult.outputId,
1006
+ scriptFilter.language,
1007
+ ),
1008
+ routingStatus: scriptResult.routing.status,
1009
+ reason: `Run output was vaulted as outputId=${rawRecord.outputId} before a sandboxed ${scriptFilter.language} script filter ran over captured stdout/stderr/combined. ${scriptResult.routing.reason}`,
1010
+ summary: `${baseRouting.summary} Script filter completed; transformed outputId=${scriptResult.outputId}.`,
1011
+ importantLines,
1012
+ parser,
1013
+ ...(baseRouting.filters !== undefined ? { filters: baseRouting.filters } : {}),
1014
+ scriptFilter: metadata,
1015
+ ...(scriptResult.lineage !== undefined ? { lineage: scriptResult.lineage } : {}),
1016
+ ...(scriptResult.evidence !== undefined ? { evidence: scriptResult.evidence } : {}),
1017
+ recovery: commandScriptFilterRecoveryHint(rawRecord.outputId, scriptResult.outputId),
977
1018
  };
1019
+ }
1020
+ const failureMessage = scriptResult.failure?.message ?? scriptResult.routing.reason;
1021
+ return {
1022
+ ...baseRouting,
1023
+ decisionId: decisionId(
1024
+ "run-route",
1025
+ rawRecord.outputId,
1026
+ "script-filter-failed",
1027
+ scriptFilter.language,
1028
+ failureMessage,
1029
+ ),
1030
+ routingStatus: baseRouting.routingStatus === "failed" ? "failed" : "partial",
1031
+ reason: `Run producer executed and raw output was vaulted as outputId=${rawRecord.outputId}, but the sandboxed ${scriptFilter.language} script filter did not produce transformed output: ${failureMessage} Base run evidence was returned instead.`,
1032
+ summary: `${baseRouting.summary} Script filter did not produce transformed output: ${failureMessage}`,
1033
+ parser: {
1034
+ ...baseRouting.parser,
1035
+ counts: {
1036
+ ...(baseRouting.parser.counts ?? {}),
1037
+ scriptFilterFailures: 1,
1038
+ },
1039
+ },
1040
+ scriptFilter: metadata,
1041
+ ...(scriptResult.failure !== undefined ? { failure: scriptResult.failure } : {}),
1042
+ ...(scriptResult.transformExecution !== undefined ? { transformExecution: scriptResult.transformExecution } : {}),
1043
+ ...(scriptResult.lineage !== undefined ? { lineage: scriptResult.lineage } : {}),
1044
+ recovery: commandScriptFilterRecoveryHint(rawRecord.outputId),
1045
+ };
978
1046
  }
979
1047
  function routeFullOutput(options, parsed, outputBytes, outputLines, statusText) {
980
- const full = selectFullOutputLines(options);
981
- const parser = parserWithEvidence(parsed.parser, full);
982
- const routedStatus = full.fidelity === "exact" ? "routed" : "partial";
983
- const capText = `${options.thresholds.largeOutputBytes} byte full-context cap`;
984
- const reason = full.fidelity === "exact"
985
- ? `preserve=full returned exact run output within the ${capText} after ${commandStorageReason(options.storage)} (${statusText}; ${parserTextFor(parser)}).`
986
- : `preserve=full output exceeded the bounded context policy (${outputBytes} bytes, ${outputLines} lines); a bounded preview was returned with raw vault recovery (${statusText}; ${parserTextFor(parser)}).`;
987
- return {
988
- decisionId: decisionId("run-route", options.outputId, "preserve-full", full.fidelity, parsed.parser.name),
989
- routingStatus: routedStatus,
990
- reason,
991
- summary: parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`,
992
- importantLines: full.importantLines,
993
- parser,
994
- };
1048
+ const full = selectFullOutputLines(options);
1049
+ const parser = parserWithEvidence(parsed.parser, full);
1050
+ const routedStatus = full.fidelity === "exact" ? "routed" : "partial";
1051
+ const capText = `${options.thresholds.largeOutputBytes} byte full-context cap`;
1052
+ const reason =
1053
+ full.fidelity === "exact"
1054
+ ? `preserve=full returned exact run output within the ${capText} after ${commandStorageReason(options.storage)} (${statusText}; ${parserTextFor(parser)}).`
1055
+ : `preserve=full output exceeded the bounded context policy (${outputBytes} bytes, ${outputLines} lines); a bounded preview was returned with raw vault recovery (${statusText}; ${parserTextFor(parser)}).`;
1056
+ return {
1057
+ decisionId: decisionId("run-route", options.outputId, "preserve-full", full.fidelity, parsed.parser.name),
1058
+ routingStatus: routedStatus,
1059
+ reason,
1060
+ summary: parsed.summary ?? `Command ${options.executionStatus} with exitCode=${options.exitCode}.`,
1061
+ importantLines: full.importantLines,
1062
+ parser,
1063
+ };
995
1064
  }
996
1065
  function selectNearRawSuccessfulLines(options) {
997
- const { stream, text } = routedCommandText(options);
998
- return assembleTextEvidence({
999
- stream,
1000
- text,
1001
- caps: {
1002
- maxLines: options.thresholds.largeOutputLines,
1003
- maxExcerptBytes: options.thresholds.largeOutputBytes,
1004
- maxLineBytes: options.thresholds.largeOutputBytes,
1005
- },
1006
- });
1066
+ const { stream, text } = routedCommandText(options);
1067
+ return assembleTextEvidence({
1068
+ stream,
1069
+ text,
1070
+ caps: {
1071
+ maxLines: options.thresholds.largeOutputLines,
1072
+ maxExcerptBytes: options.thresholds.largeOutputBytes,
1073
+ maxLineBytes: options.thresholds.largeOutputBytes,
1074
+ },
1075
+ });
1007
1076
  }
1008
1077
  function selectFullOutputLines(options) {
1009
- const { stream, text } = routedCommandText(options);
1010
- return assembleTextEvidence({
1011
- stream,
1012
- text,
1013
- caps: {
1014
- maxLines: Number.MAX_SAFE_INTEGER,
1015
- maxExcerptBytes: options.thresholds.largeOutputBytes,
1016
- maxLineBytes: options.thresholds.largeOutputBytes,
1017
- },
1018
- });
1078
+ const { stream, text } = routedCommandText(options);
1079
+ return assembleTextEvidence({
1080
+ stream,
1081
+ text,
1082
+ caps: {
1083
+ maxLines: Number.MAX_SAFE_INTEGER,
1084
+ maxExcerptBytes: options.thresholds.largeOutputBytes,
1085
+ maxLineBytes: options.thresholds.largeOutputBytes,
1086
+ },
1087
+ });
1019
1088
  }
1020
1089
  function routedCommandText(options) {
1021
- if (options.stdout.length > 0 && options.stderr.length === 0) {
1022
- return { stream: "stdout", text: options.stdout };
1023
- }
1024
- if (options.stderr.length > 0 && options.stdout.length === 0) {
1025
- return { stream: "stderr", text: options.stderr };
1026
- }
1027
- return { stream: "combined", text: options.combined };
1090
+ if (options.stdout.length > 0 && options.stderr.length === 0) {
1091
+ return { stream: "stdout", text: options.stdout };
1092
+ }
1093
+ if (options.stderr.length > 0 && options.stdout.length === 0) {
1094
+ return { stream: "stderr", text: options.stderr };
1095
+ }
1096
+ return { stream: "combined", text: options.combined };
1028
1097
  }
1029
1098
  function runScriptFilterSources(outputId) {
1030
- return [
1031
- { kind: "vault", outputId, stream: "stdout", alias: "stdout" },
1032
- { kind: "vault", outputId, stream: "stderr", alias: "stderr" },
1033
- { kind: "vault", outputId, stream: "combined", alias: "combined" },
1034
- ];
1099
+ return [
1100
+ { kind: "vault", outputId, stream: "stdout", alias: "stdout" },
1101
+ { kind: "vault", outputId, stream: "stderr", alias: "stderr" },
1102
+ { kind: "vault", outputId, stream: "combined", alias: "combined" },
1103
+ ];
1035
1104
  }
1036
1105
  function isSuccessfulScriptFilterResult(result) {
1037
- return result.toolStatus === "ok" && result.failure === undefined && typeof result.outputId === "string" && result.outputId.length > 0;
1106
+ return (
1107
+ result.toolStatus === "ok" &&
1108
+ result.failure === undefined &&
1109
+ typeof result.outputId === "string" &&
1110
+ result.outputId.length > 0
1111
+ );
1038
1112
  }
1039
1113
  function runScriptFilterMetadata(input, result, rawOutputId) {
1040
- const metadata = {
1041
- status: isSuccessfulScriptFilterResult(result) ? "success" : result.transformExecution?.status ?? "failed",
1042
- language: input.language,
1043
- sourceAliases: ["stdout", "stderr", "combined"],
1044
- rawOutputId,
1045
- };
1046
- if (input.label !== undefined) {
1047
- metadata.label = input.label;
1048
- }
1049
- if ("operation" in result && result.operation !== undefined) {
1050
- metadata.operation = result.operation;
1051
- }
1052
- if (result.outputId !== undefined) {
1053
- metadata.outputId = result.outputId;
1054
- }
1055
- if (result.recordId !== undefined) {
1056
- metadata.recordId = result.recordId;
1057
- }
1058
- if (result.persistence !== undefined) {
1059
- metadata.persistence = result.persistence;
1060
- }
1061
- if (result.lineage !== undefined) {
1062
- metadata.lineage = result.lineage;
1063
- }
1064
- if (result.failure !== undefined) {
1065
- metadata.failure = result.failure;
1066
- }
1067
- if (result.transformExecution !== undefined) {
1068
- metadata.transformExecution = result.transformExecution;
1069
- }
1070
- if ("summary" in result && result.summary !== undefined) {
1071
- metadata.summary = result.summary;
1072
- }
1073
- return metadata;
1114
+ const metadata = {
1115
+ status: isSuccessfulScriptFilterResult(result) ? "success" : (result.transformExecution?.status ?? "failed"),
1116
+ language: input.language,
1117
+ sourceAliases: ["stdout", "stderr", "combined"],
1118
+ rawOutputId,
1119
+ };
1120
+ if (input.label !== undefined) {
1121
+ metadata.label = input.label;
1122
+ }
1123
+ if ("operation" in result && result.operation !== undefined) {
1124
+ metadata.operation = result.operation;
1125
+ }
1126
+ if (result.outputId !== undefined) {
1127
+ metadata.outputId = result.outputId;
1128
+ }
1129
+ if (result.recordId !== undefined) {
1130
+ metadata.recordId = result.recordId;
1131
+ }
1132
+ if (result.persistence !== undefined) {
1133
+ metadata.persistence = result.persistence;
1134
+ }
1135
+ if (result.lineage !== undefined) {
1136
+ metadata.lineage = result.lineage;
1137
+ }
1138
+ if (result.failure !== undefined) {
1139
+ metadata.failure = result.failure;
1140
+ }
1141
+ if (result.transformExecution !== undefined) {
1142
+ metadata.transformExecution = result.transformExecution;
1143
+ }
1144
+ if ("summary" in result && result.summary !== undefined) {
1145
+ metadata.summary = result.summary;
1146
+ }
1147
+ return metadata;
1074
1148
  }
1075
1149
  function evidencePacketsAsImportantLines(evidence) {
1076
- if (!Array.isArray(evidence)) {
1077
- return [];
1078
- }
1079
- return evidence
1080
- .filter((packet) => typeof packet.excerpt === "string" && typeof packet.lines === "string")
1081
- .map((packet) => ({
1082
- stream: "combined",
1083
- lines: packet.lines,
1084
- excerpt: packet.excerpt,
1150
+ if (!Array.isArray(evidence)) {
1151
+ return [];
1152
+ }
1153
+ return evidence
1154
+ .filter((packet) => typeof packet.excerpt === "string" && typeof packet.lines === "string")
1155
+ .map((packet) => ({
1156
+ stream: "combined",
1157
+ lines: packet.lines,
1158
+ excerpt: packet.excerpt,
1085
1159
  }));
1086
1160
  }
1087
1161
  function storeReducerOutput(options) {
1088
- const operation = `run-reducer:${options.reducer.result.name}@${options.reducer.result.version}`;
1089
- return storeTextOutput(options.vault, {
1090
- sessionId: options.sessionId,
1091
- raw: options.reducer.result.visibleText,
1092
- sourceKind: "transform",
1093
- decisionIds: [decisionId("run-reducer", options.rawRecord.outputId, options.reducer.result.name, options.reducer.result.version)],
1094
- producer: { kind: "transform", name: "freeflow_run reducer" },
1095
- lineage: {
1096
- sourceRecordIds: [options.rawRecord.recordId],
1097
- sourceOutputIds: [options.rawRecord.outputId],
1098
- operation,
1099
- operationHash: hash(JSON.stringify({ operation, sourceOutputId: options.rawRecord.outputId, facts: options.reducer.result.facts })),
1100
- },
1101
- });
1162
+ const operation = `run-reducer:${options.reducer.result.name}@${options.reducer.result.version}`;
1163
+ return storeTextOutput(options.vault, {
1164
+ sessionId: options.sessionId,
1165
+ raw: options.reducer.result.visibleText,
1166
+ sourceKind: "transform",
1167
+ decisionIds: [
1168
+ decisionId(
1169
+ "run-reducer",
1170
+ options.rawRecord.outputId,
1171
+ options.reducer.result.name,
1172
+ options.reducer.result.version,
1173
+ ),
1174
+ ],
1175
+ producer: { kind: "transform", name: "freeflow_run reducer" },
1176
+ lineage: {
1177
+ sourceRecordIds: [options.rawRecord.recordId],
1178
+ sourceOutputIds: [options.rawRecord.outputId],
1179
+ operation,
1180
+ operationHash: hash(
1181
+ JSON.stringify({ operation, sourceOutputId: options.rawRecord.outputId, facts: options.reducer.result.facts }),
1182
+ ),
1183
+ },
1184
+ });
1102
1185
  }
1103
1186
  function runReducerMetadata(rawOutputId, reducer, reducerRecord) {
1104
- return {
1105
- status: reducerRecord === undefined ? "selected" : "success",
1106
- name: reducer.result.name,
1107
- version: reducer.result.version,
1108
- confidence: reducer.result.confidence,
1109
- rawOutputId,
1110
- summary: reducer.result.visibleText,
1111
- facts: reducer.result.facts,
1112
- ...(reducerRecord !== undefined ? {
1113
- outputId: reducerRecord.outputId,
1114
- recordId: reducerRecord.recordId,
1115
- persistence: reducerRecord.persistence,
1116
- lineage: reducerRecord.lineage,
1117
- } : {}),
1118
- };
1187
+ return {
1188
+ status: reducerRecord === undefined ? "selected" : "success",
1189
+ name: reducer.result.name,
1190
+ version: reducer.result.version,
1191
+ confidence: reducer.result.confidence,
1192
+ rawOutputId,
1193
+ summary: reducer.result.visibleText,
1194
+ facts: reducer.result.facts,
1195
+ ...(reducerRecord !== undefined
1196
+ ? {
1197
+ outputId: reducerRecord.outputId,
1198
+ recordId: reducerRecord.recordId,
1199
+ persistence: reducerRecord.persistence,
1200
+ lineage: reducerRecord.lineage,
1201
+ }
1202
+ : {}),
1203
+ };
1119
1204
  }
1120
1205
  function commandReducerRecoveryHint(rawOutputId, transformedOutputId) {
1121
- if (transformedOutputId) {
1122
- return {
1123
- how: `Raw run output: use freeflow_search with source.kind=vault and outputId=${rawOutputId}. Reducer-transformed output: use freeflow_search with source.kind=vault, outputId=${transformedOutputId}, stream=raw, and an exact lineRange.`,
1124
- outputId: rawOutputId,
1125
- };
1126
- }
1206
+ if (transformedOutputId) {
1127
1207
  return {
1128
- how: `Reducer output was returned in the structured run result. Raw run output remains recoverable with freeflow_search source.kind=vault outputId=${rawOutputId}.`,
1129
- outputId: rawOutputId,
1208
+ how: `Raw run output: use freeflow_search with source.kind=vault and outputId=${rawOutputId}. Reducer-transformed output: use freeflow_search with source.kind=vault, outputId=${transformedOutputId}, stream=raw, and an exact lineRange.`,
1209
+ outputId: rawOutputId,
1130
1210
  };
1211
+ }
1212
+ return {
1213
+ how: `Reducer output was returned in the structured run result. Raw run output remains recoverable with freeflow_search source.kind=vault outputId=${rawOutputId}.`,
1214
+ outputId: rawOutputId,
1215
+ };
1131
1216
  }
1132
1217
  function commandScriptFilterRecoveryHint(rawOutputId, transformedOutputId) {
1133
- if (transformedOutputId) {
1134
- return {
1135
- how: `Raw run output: use freeflow_search with source.kind=vault and outputId=${rawOutputId}. Script-filtered transformed output: use freeflow_search with source.kind=vault, outputId=${transformedOutputId}, stream=raw, and an exact lineRange.`,
1136
- outputId: rawOutputId,
1137
- };
1138
- }
1218
+ if (transformedOutputId) {
1139
1219
  return {
1140
- how: `Script filter did not produce transformed output. Raw run output remains recoverable with freeflow_search source.kind=vault outputId=${rawOutputId}.`,
1141
- outputId: rawOutputId,
1220
+ how: `Raw run output: use freeflow_search with source.kind=vault and outputId=${rawOutputId}. Script-filtered transformed output: use freeflow_search with source.kind=vault, outputId=${transformedOutputId}, stream=raw, and an exact lineRange.`,
1221
+ outputId: rawOutputId,
1142
1222
  };
1223
+ }
1224
+ return {
1225
+ how: `Script filter did not produce transformed output. Raw run output remains recoverable with freeflow_search source.kind=vault outputId=${rawOutputId}.`,
1226
+ outputId: rawOutputId,
1227
+ };
1143
1228
  }
1144
1229
  function normalizeRunScriptFilter(input) {
1145
- if (input === undefined || input === null) {
1146
- return { ok: true };
1147
- }
1148
- if (!isRecord(input)) {
1149
- return { ok: false, path: "$.scriptFilter", message: "freeflow_run scriptFilter must be an object." };
1150
- }
1151
- const operation = { kind: "script" };
1152
- if (input.language !== undefined) {
1153
- operation.language = input.language;
1154
- }
1155
- if (input.code !== undefined) {
1156
- operation.code = input.code;
1157
- }
1158
- if (input.label !== undefined) {
1159
- operation.label = input.label;
1160
- }
1161
- const candidate = {
1162
- sources: runScriptFilterSources("ffout_run_script_filter_validation"),
1163
- operation,
1164
- };
1165
- if (input.limits !== undefined) {
1166
- candidate.limits = input.limits;
1167
- }
1168
- const validation = validateTransformInput(candidate);
1169
- if (!validation.ok) {
1170
- const issue = validation.issues[0] ?? { path: "$.scriptFilter", message: "Invalid script filter." };
1171
- return {
1172
- ok: false,
1173
- path: issue.path.replace(/^\$\.operation/, "$.scriptFilter").replace(/^\$\.limits/, "$.scriptFilter.limits"),
1174
- message: issue.message,
1175
- };
1176
- }
1177
- const scriptFilter = {
1178
- language: input.language,
1179
- code: input.code,
1230
+ if (input === undefined || input === null) {
1231
+ return { ok: true };
1232
+ }
1233
+ if (!isRecord(input)) {
1234
+ return { ok: false, path: "$.scriptFilter", message: "freeflow_run scriptFilter must be an object." };
1235
+ }
1236
+ const operation = { kind: "script" };
1237
+ if (input.language !== undefined) {
1238
+ operation.language = input.language;
1239
+ }
1240
+ if (input.code !== undefined) {
1241
+ operation.code = input.code;
1242
+ }
1243
+ if (input.label !== undefined) {
1244
+ operation.label = input.label;
1245
+ }
1246
+ const candidate = {
1247
+ sources: runScriptFilterSources("ffout_run_script_filter_validation"),
1248
+ operation,
1249
+ };
1250
+ if (input.limits !== undefined) {
1251
+ candidate.limits = input.limits;
1252
+ }
1253
+ const validation = validateTransformInput(candidate);
1254
+ if (!validation.ok) {
1255
+ const issue = validation.issues[0] ?? { path: "$.scriptFilter", message: "Invalid script filter." };
1256
+ return {
1257
+ ok: false,
1258
+ path: issue.path.replace(/^\$\.operation/, "$.scriptFilter").replace(/^\$\.limits/, "$.scriptFilter.limits"),
1259
+ message: issue.message,
1180
1260
  };
1181
- if (input.label !== undefined) {
1182
- scriptFilter.label = input.label;
1183
- }
1184
- if (input.limits !== undefined) {
1185
- scriptFilter.limits = input.limits;
1186
- }
1187
- return { ok: true, scriptFilter };
1261
+ }
1262
+ const scriptFilter = {
1263
+ language: input.language,
1264
+ code: input.code,
1265
+ };
1266
+ if (input.label !== undefined) {
1267
+ scriptFilter.label = input.label;
1268
+ }
1269
+ if (input.limits !== undefined) {
1270
+ scriptFilter.limits = input.limits;
1271
+ }
1272
+ return { ok: true, scriptFilter };
1188
1273
  }
1189
1274
  function isRecord(value) {
1190
- return typeof value === "object" && value !== null && !Array.isArray(value);
1275
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1191
1276
  }
1192
1277
  function parserWithEvidence(parser, evidence) {
1193
- return {
1194
- ...parser,
1195
- fidelity: parser.fidelity === "lossy" || evidence.fidelity === "lossy" ? "lossy" : "exact",
1196
- compressed: evidence.compressed,
1197
- };
1278
+ return {
1279
+ ...parser,
1280
+ fidelity: parser.fidelity === "lossy" || evidence.fidelity === "lossy" ? "lossy" : "exact",
1281
+ compressed: evidence.compressed,
1282
+ };
1198
1283
  }
1199
1284
  function parserTextFor(parser) {
1200
- return `parser=${parser.name} confidence=${parser.confidence.toFixed(2)} fidelity=${parser.fidelity}`;
1285
+ return `parser=${parser.name} confidence=${parser.confidence.toFixed(2)} fidelity=${parser.fidelity}`;
1201
1286
  }
1202
1287
  function combineOutputSections(stdout, stderr) {
1203
- if (stdout.length === 0) {
1204
- return stderr;
1205
- }
1206
- if (stderr.length === 0) {
1207
- return stdout;
1208
- }
1209
- return `[stdout]\n${stdout}\n[stderr]\n${stderr}`;
1288
+ if (stdout.length === 0) {
1289
+ return stderr;
1290
+ }
1291
+ if (stderr.length === 0) {
1292
+ return stdout;
1293
+ }
1294
+ return `[stdout]\n${stdout}\n[stderr]\n${stderr}`;
1210
1295
  }
1211
1296
  function commandText(command) {
1212
- return typeof command === "string" ? command : command.join(" ");
1297
+ return typeof command === "string" ? command : command.join(" ");
1213
1298
  }
1214
1299
  function decisionId(...parts) {
1215
- return `ffdec_${hash(parts.join("\0")).slice(0, 16)}`;
1300
+ return `ffdec_${hash(parts.join("\0")).slice(0, 16)}`;
1216
1301
  }
1217
1302
  function hash(value) {
1218
- return createHash("sha256").update(value).digest("hex");
1303
+ return createHash("sha256").update(value).digest("hex");
1219
1304
  }