@hassangameryt/freeflow 0.3.0 → 0.4.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 (690) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +5 -2
  3. package/.codex-plugin/plugin.json +8 -9
  4. package/README.md +190 -128
  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/command-surface.json +51 -7
  9. package/hooks/freeflow-runtime-context.mjs +264 -136
  10. package/hooks/tests/check-runtime-context-hook.sh +223 -0
  11. package/package.json +23 -24
  12. package/pi-extension/dist/index.js +264 -80
  13. package/pi-extension/dist/integrations/mcp-config.js +29 -0
  14. package/pi-extension/dist/output-router/host-producer-identification.js +232 -0
  15. package/pi-extension/dist/output-router/native-safety-net.js +216 -0
  16. package/pi-extension/dist/output-router/observed-tool-routing.js +122 -0
  17. package/pi-extension/dist/output-router/renderers.js +1023 -0
  18. package/pi-extension/dist/output-router/router-tools.js +554 -0
  19. package/pi-extension/dist/output-router/schemas.js +383 -0
  20. package/pi-extension/dist/output-router/status.js +744 -0
  21. package/pi-extension/dist/output-router/utils.js +502 -0
  22. package/pi-extension/dist/runtime/runtime-context.js +798 -0
  23. package/pi-extension/dist/settings/settings-tui.js +314 -0
  24. package/pi-extension/dist/settings/settings-ui.js +1487 -0
  25. package/pi-extension/freeflow/index.js +1 -0
  26. package/pi-extension/src/index.ts +230 -56
  27. package/pi-extension/src/{host-producer-identification.ts → output-router/host-producer-identification.ts} +37 -7
  28. package/pi-extension/src/{native-safety-net.ts → output-router/native-safety-net.ts} +7 -11
  29. package/pi-extension/src/{observed-tool-routing.ts → output-router/observed-tool-routing.ts} +19 -11
  30. package/pi-extension/src/{renderers.ts → output-router/renderers.ts} +246 -55
  31. package/pi-extension/src/{router-tools.ts → output-router/router-tools.ts} +130 -29
  32. package/pi-extension/src/{schemas.ts → output-router/schemas.ts} +171 -43
  33. package/pi-extension/src/output-router/status.ts +791 -0
  34. package/pi-extension/src/{utils.ts → output-router/utils.ts} +80 -18
  35. package/pi-extension/src/runtime/runtime-context.ts +895 -0
  36. package/pi-extension/src/settings/settings-tui.ts +408 -0
  37. package/pi-extension/src/settings/settings-ui.ts +1730 -0
  38. package/pi-extension/tests/integration/pi-extension.test.js +4018 -0
  39. package/pi-extension/tests/output-router/observed-producers.test.js +132 -0
  40. package/pi-extension/tests/output-router/search.test.js +722 -0
  41. package/pi-extension/tests/settings/settings-tui.test.js +243 -0
  42. package/router/dist/benchmarks/benchmark-harness.d.ts +16 -13
  43. package/router/dist/benchmarks/benchmark-harness.js +62 -62
  44. package/router/dist/benchmarks/benchmarks.d.ts +80 -73
  45. package/router/dist/benchmarks/benchmarks.js +860 -761
  46. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +71 -67
  47. package/router/dist/benchmarks/codex-qa-benchmarks.js +429 -390
  48. package/router/dist/benchmarks/command-benchmarks.d.ts +107 -92
  49. package/router/dist/benchmarks/command-benchmarks.js +616 -571
  50. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +64 -56
  51. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +679 -613
  52. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +103 -95
  53. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +1188 -1103
  54. package/router/dist/benchmarks/context-saving-baseline.d.ts +47 -41
  55. package/router/dist/benchmarks/context-saving-baseline.js +405 -374
  56. package/router/dist/benchmarks/index-benchmarks.d.ts +74 -69
  57. package/router/dist/benchmarks/index-benchmarks.js +761 -661
  58. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +80 -69
  59. package/router/dist/benchmarks/storage-policy-benchmarks.js +549 -469
  60. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +43 -34
  61. package/router/dist/benchmarks/vault-index-benchmarks.js +294 -229
  62. package/router/dist/config/config.d.ts +61 -54
  63. package/router/dist/config/config.js +551 -372
  64. package/router/dist/config/router-contract.d.ts +2 -2
  65. package/router/dist/config/router-contract.js +38 -38
  66. package/router/dist/config/schema.d.ts +19 -10
  67. package/router/dist/config/schema.js +586 -538
  68. package/router/dist/config/types.d.ts +413 -361
  69. package/router/dist/config/types.js +19 -8
  70. package/router/dist/evidence/bounded-evidence.d.ts +26 -26
  71. package/router/dist/evidence/bounded-evidence.js +265 -252
  72. package/router/dist/evidence/evidence-range-selector.d.ts +16 -14
  73. package/router/dist/evidence/evidence-range-selector.js +192 -191
  74. package/router/dist/evidence/evidence-search.d.ts +18 -16
  75. package/router/dist/evidence/evidence-search.js +401 -377
  76. package/router/dist/evidence/evidence.d.ts +17 -17
  77. package/router/dist/evidence/evidence.js +163 -159
  78. package/router/dist/evidence/failure-contracts.d.ts +25 -15
  79. package/router/dist/evidence/failure-contracts.js +132 -126
  80. package/router/dist/evidence/line-ranges.d.ts +17 -15
  81. package/router/dist/evidence/line-ranges.js +18 -18
  82. package/router/dist/experiments/local-index.d.ts +47 -41
  83. package/router/dist/experiments/local-index.js +477 -458
  84. package/router/dist/local/local-traversal.d.ts +18 -0
  85. package/router/dist/local/local-traversal.js +334 -0
  86. package/router/dist/processing/engine.d.ts +94 -70
  87. package/router/dist/processing/engine.js +462 -364
  88. package/router/dist/processing/reducers.d.ts +208 -194
  89. package/router/dist/processing/reducers.js +1434 -1256
  90. package/router/dist/processing/renderers.d.ts +24 -18
  91. package/router/dist/processing/renderers.js +161 -152
  92. package/router/dist/processing/scripts.d.ts +80 -67
  93. package/router/dist/processing/scripts.js +343 -290
  94. package/router/dist/repo/repo-traversal.d.ts +9 -9
  95. package/router/dist/repo/repo-traversal.js +205 -202
  96. package/router/dist/routing/observed-reducers.d.ts +25 -19
  97. package/router/dist/routing/observed-reducers.js +559 -545
  98. package/router/dist/routing/observed-routing.d.ts +23 -14
  99. package/router/dist/routing/observed-routing.js +319 -318
  100. package/router/dist/routing/parsers.d.ts +10 -10
  101. package/router/dist/routing/parsers.js +454 -406
  102. package/router/dist/routing/run-filters.d.ts +45 -41
  103. package/router/dist/routing/run-filters.js +215 -207
  104. package/router/dist/routing/run-reducers.d.ts +45 -26
  105. package/router/dist/routing/run-reducers.js +102 -90
  106. package/router/dist/sandbox/adapter-roots.d.ts +34 -26
  107. package/router/dist/sandbox/adapter-roots.js +43 -41
  108. package/router/dist/sandbox/eryx-python-adapter.d.ts +9 -5
  109. package/router/dist/sandbox/eryx-python-adapter.js +659 -588
  110. package/router/dist/sandbox/jq-wasm-adapter.d.ts +3 -3
  111. package/router/dist/sandbox/jq-wasm-adapter.js +319 -311
  112. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +9 -5
  113. package/router/dist/sandbox/quickjs-wasi-adapter.js +336 -333
  114. package/router/dist/sandbox/script-sandbox.d.ts +105 -84
  115. package/router/dist/sandbox/script-sandbox.js +294 -260
  116. package/router/dist/setup/script-transform-adapters.d.ts +23 -19
  117. package/router/dist/setup/script-transform-adapters.js +223 -204
  118. package/router/dist/tools/batch.d.ts +27 -16
  119. package/router/dist/tools/batch.js +493 -416
  120. package/router/dist/tools/run.d.ts +47 -35
  121. package/router/dist/tools/run.js +1171 -1086
  122. package/router/dist/tools/search.d.ts +53 -31
  123. package/router/dist/tools/search.js +1224 -1065
  124. package/router/dist/transform/engine.d.ts +121 -96
  125. package/router/dist/transform/engine.js +1853 -1736
  126. package/router/dist/vault/vault-index.d.ts +97 -78
  127. package/router/dist/vault/vault-index.js +347 -342
  128. package/router/dist/vault/vault.d.ts +109 -74
  129. package/router/dist/vault/vault.js +528 -533
  130. package/runtime/interaction-contract.md +16 -0
  131. package/skills/bypass/SKILL.md +52 -38
  132. package/skills/commit-work/SKILL.md +54 -46
  133. package/skills/commit-work/references/staging-decisions.md +46 -24
  134. package/skills/decision-gate/SKILL.md +48 -0
  135. package/skills/design-for-depth/SKILL.md +75 -59
  136. package/skills/design-for-depth/references/design-pressure-signals.md +56 -7
  137. package/skills/design-for-depth/references/interface-design-loop.md +156 -0
  138. package/skills/design-for-depth/references/software-design-philosophy.md +32 -3
  139. package/skills/diagnose-failure/SKILL.md +65 -60
  140. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +36 -0
  141. package/skills/diagnose-failure/references/flaky-and-performance.md +30 -18
  142. package/skills/discuss/SKILL.md +121 -0
  143. package/skills/discuss/references/checkpoints.md +66 -0
  144. package/skills/evaluate-skill/SKILL.md +62 -53
  145. package/skills/evaluate-skill/references/definition-schema.md +345 -0
  146. package/skills/evaluate-skill/references/evaluation-design.md +86 -0
  147. package/skills/evaluate-skill/references/execution-and-evidence.md +85 -0
  148. package/skills/evaluate-skill/references/review-and-revision.md +51 -0
  149. package/skills/evaluate-skill/scripts/lib/definitions.mjs +296 -0
  150. package/skills/evaluate-skill/scripts/lib/evidence.mjs +46 -0
  151. package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +60 -0
  152. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +148 -0
  153. package/skills/evaluate-skill/scripts/lib/grade-support.mjs +126 -0
  154. package/skills/evaluate-skill/scripts/lib/grade-workspace.mjs +192 -0
  155. package/skills/evaluate-skill/scripts/lib/grade.mjs +56 -0
  156. package/skills/evaluate-skill/scripts/lib/pi.mjs +489 -0
  157. package/skills/evaluate-skill/scripts/lib/process.mjs +79 -0
  158. package/skills/evaluate-skill/scripts/lib/rpc.mjs +444 -0
  159. package/skills/evaluate-skill/scripts/lib/runner.mjs +346 -0
  160. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +409 -0
  161. package/skills/evaluate-skill/scripts/lib/view.mjs +337 -0
  162. package/skills/evaluate-skill/scripts/pi-guard.mjs +164 -0
  163. package/skills/evaluate-skill/scripts/skill-eval.mjs +101 -0
  164. package/skills/execute-work/SKILL.md +99 -0
  165. package/skills/execute-work/references/code-practices.md +78 -0
  166. package/skills/execute-work/references/execution-loop.md +77 -0
  167. package/skills/finish-branch/SKILL.md +117 -0
  168. package/skills/finish-branch/references/integration-options.md +80 -0
  169. package/skills/handoff/SKILL.md +65 -39
  170. package/skills/handoff/references/templates.md +104 -27
  171. package/skills/launch-work/SKILL.md +116 -0
  172. package/skills/launch-work/references/launch-readiness.md +85 -0
  173. package/skills/migration-work/SKILL.md +115 -0
  174. package/skills/migration-work/references/migration-lifecycle.md +82 -0
  175. package/skills/mode-contract/SKILL.md +50 -52
  176. package/skills/output-router/SKILL.md +21 -17
  177. package/skills/output-router/references/safety-policy.md +1 -1
  178. package/skills/release-work/SKILL.md +118 -0
  179. package/skills/release-work/references/release-evidence.md +78 -0
  180. package/skills/review-artifact/SKILL.md +77 -69
  181. package/skills/review-artifact/references/reviewer-prompt.md +133 -42
  182. package/skills/review-work/SKILL.md +82 -57
  183. package/skills/review-work/references/reviewer-prompt.md +97 -60
  184. package/skills/review-work/references/security-risk-lens.md +67 -0
  185. package/skills/setup-freeflow/SKILL.md +58 -66
  186. package/skills/setup-freeflow/references/activation-contract.md +89 -69
  187. package/skills/setup-freeflow/references/host-setup.md +54 -17
  188. package/skills/setup-freeflow/references/output-router-setup.md +62 -54
  189. package/skills/simplify-code/SKILL.md +80 -0
  190. package/skills/simplify-code/references/simplification-patterns.md +70 -0
  191. package/skills/tdd/SKILL.md +96 -0
  192. package/skills/tdd/references/test-design.md +96 -0
  193. package/skills/track-work/SKILL.md +84 -0
  194. package/skills/track-work/references/working-record-schema.md +378 -0
  195. package/skills/verify-work/SKILL.md +59 -38
  196. package/skills/verify-work/references/browser-runtime-evidence.md +55 -0
  197. package/skills/verify-work/references/integration-evidence.md +51 -0
  198. package/skills/verify-work/references/performance-evidence.md +57 -0
  199. package/skills/workflow/SKILL.md +53 -59
  200. package/skills/workflow/references/domain-skill-composition.md +57 -0
  201. package/skills/workflow/references/workflow-loop.md +92 -0
  202. package/skills/write-plan/SKILL.md +85 -58
  203. package/skills/write-plan/references/plan-shapes.md +132 -46
  204. package/skills/write-skill/SKILL.md +82 -51
  205. package/skills/write-skill/references/activation-boundaries.md +62 -0
  206. package/skills/write-skill/references/agent-first-instructions.md +87 -0
  207. package/skills/write-skill/references/progressive-disclosure.md +63 -0
  208. package/skills/write-skill/scripts/lib/skill-author.mjs +653 -0
  209. package/skills/write-skill/scripts/skill-author.mjs +104 -0
  210. package/skills/write-spec/SKILL.md +65 -54
  211. package/skills/write-spec/references/artifact-standards.md +60 -41
  212. package/skills/write-spec/references/decision-records.md +77 -0
  213. package/skills/write-spec/references/spec-shapes.md +119 -60
  214. package/evals/README.md +0 -32
  215. package/evals/fixtures/copy-conventions.md +0 -31
  216. package/evals/fixtures/output-router/README.md +0 -12
  217. package/evals/fixtures/output-router/failed-command-output.txt +0 -9
  218. package/evals/fixtures/output-router/large-router-manual.md +0 -63
  219. package/evals/fixtures/output-router/native-large-output.txt +0 -40
  220. package/evals/fixtures/output-router/noisy-test-output.txt +0 -30
  221. package/evals/fixtures/output-router/verification-output.txt +0 -8
  222. package/evals/fixtures/tiny-artifact-review-app/README.md +0 -5
  223. package/evals/fixtures/tiny-artifact-review-app/docs/billing-policy.md +0 -10
  224. package/evals/fixtures/tiny-artifact-review-app/docs/specs/billing-webhook-api-draft.md +0 -21
  225. package/evals/fixtures/tiny-artifact-review-app/docs/specs/failed-payment-grace-period.md +0 -24
  226. package/evals/fixtures/tiny-artifact-review-app/docs/specs/immediate-downgrade.md +0 -17
  227. package/evals/fixtures/tiny-artifact-review-app/tests/billing.test.md +0 -8
  228. package/evals/fixtures/tiny-commit-ambiguous-app/.freeflow-eval-setup.sh +0 -15
  229. package/evals/fixtures/tiny-commit-ambiguous-app/README.md +0 -3
  230. package/evals/fixtures/tiny-commit-ambiguous-app/src/billing.ts +0 -5
  231. package/evals/fixtures/tiny-commit-ambiguous-app/src/settings-page.ts +0 -1
  232. package/evals/fixtures/tiny-commit-ambiguous-app/tests/settings.test.md +0 -5
  233. package/evals/fixtures/tiny-commit-app/.freeflow-eval-setup.sh +0 -14
  234. package/evals/fixtures/tiny-commit-app/README.md +0 -3
  235. package/evals/fixtures/tiny-commit-app/docs/specs/settings-title.md +0 -5
  236. package/evals/fixtures/tiny-commit-app/src/billing.ts +0 -5
  237. package/evals/fixtures/tiny-commit-app/src/settings-page.ts +0 -1
  238. package/evals/fixtures/tiny-commit-app/tests/settings.test.md +0 -5
  239. package/evals/fixtures/tiny-commit-everything-app/.freeflow-eval-setup.sh +0 -15
  240. package/evals/fixtures/tiny-commit-everything-app/README.md +0 -3
  241. package/evals/fixtures/tiny-commit-everything-app/docs/specs/settings-title.md +0 -5
  242. package/evals/fixtures/tiny-commit-everything-app/src/billing.ts +0 -5
  243. package/evals/fixtures/tiny-commit-everything-app/src/settings-page.ts +0 -1
  244. package/evals/fixtures/tiny-commit-everything-app/tests/settings.test.md +0 -5
  245. package/evals/fixtures/tiny-commit-staged-app/.freeflow-eval-setup.sh +0 -15
  246. package/evals/fixtures/tiny-commit-staged-app/README.md +0 -3
  247. package/evals/fixtures/tiny-commit-staged-app/docs/specs/settings-title.md +0 -5
  248. package/evals/fixtures/tiny-commit-staged-app/src/billing.ts +0 -5
  249. package/evals/fixtures/tiny-commit-staged-app/src/settings-page.ts +0 -1
  250. package/evals/fixtures/tiny-commit-staged-app/tests/settings.test.md +0 -5
  251. package/evals/fixtures/tiny-commit-staged-mixed-app/.freeflow-eval-setup.sh +0 -15
  252. package/evals/fixtures/tiny-commit-staged-mixed-app/README.md +0 -3
  253. package/evals/fixtures/tiny-commit-staged-mixed-app/docs/billing-policy.md +0 -3
  254. package/evals/fixtures/tiny-commit-staged-mixed-app/docs/release-notes.md +0 -3
  255. package/evals/fixtures/tiny-commit-staged-mixed-app/src/billing.ts +0 -5
  256. package/evals/fixtures/tiny-dashboard-stale-app/README.md +0 -11
  257. package/evals/fixtures/tiny-dashboard-stale-app/src/api-client.ts +0 -13
  258. package/evals/fixtures/tiny-dashboard-stale-app/src/dashboard-data.ts +0 -19
  259. package/evals/fixtures/tiny-dashboard-stale-app/tests/dashboard-data.test.md +0 -9
  260. package/evals/fixtures/tiny-decision-destination-app/README.md +0 -6
  261. package/evals/fixtures/tiny-decision-destination-app/src/risk.ts +0 -8
  262. package/evals/fixtures/tiny-decision-destination-app/tests/risk.test.md +0 -4
  263. package/evals/fixtures/tiny-design-depth-app/README.md +0 -15
  264. package/evals/fixtures/tiny-design-depth-app/src/routes.ts +0 -25
  265. package/evals/fixtures/tiny-design-depth-app/src/sendEmail.ts +0 -3
  266. package/evals/fixtures/tiny-design-depth-app/src/sendSms.ts +0 -3
  267. package/evals/fixtures/tiny-design-depth-app/src/telemetry.ts +0 -3
  268. package/evals/fixtures/tiny-design-depth-app/tests/routes.test.md +0 -12
  269. package/evals/fixtures/tiny-eval-method-app/README.md +0 -8
  270. package/evals/fixtures/tiny-eval-method-app/evals/reports/review-pr-eval-result.md +0 -5
  271. package/evals/fixtures/tiny-eval-method-app/evals/reports/triage-question-failure.md +0 -17
  272. package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.diff +0 -11
  273. package/evals/fixtures/tiny-eval-method-app/evals/runs/review-pr-with-skill-output.md +0 -3
  274. package/evals/fixtures/tiny-eval-method-app/skills/review-pr/SKILL.md +0 -10
  275. package/evals/fixtures/tiny-eval-method-app/skills/triage-question/SKILL.md +0 -10
  276. package/evals/fixtures/tiny-execute-plan-app/README.md +0 -5
  277. package/evals/fixtures/tiny-execute-plan-app/checks/settings-and-billing-check.sh +0 -5
  278. package/evals/fixtures/tiny-execute-plan-app/docs/billing-policy.md +0 -10
  279. package/evals/fixtures/tiny-execute-plan-app/docs/plans/immediate-downgrade-plan.md +0 -11
  280. package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-plan.md +0 -12
  281. package/evals/fixtures/tiny-execute-plan-app/docs/plans/settings-title-with-bad-check.md +0 -15
  282. package/evals/fixtures/tiny-execute-plan-app/docs/plans/unverified-billing-plan.md +0 -9
  283. package/evals/fixtures/tiny-execute-plan-app/docs/specs/failed-payment-grace-period.md +0 -9
  284. package/evals/fixtures/tiny-execute-plan-app/docs/specs/settings-title.md +0 -9
  285. package/evals/fixtures/tiny-execute-plan-app/src/billing.ts +0 -7
  286. package/evals/fixtures/tiny-execute-plan-app/src/settings-page.ts +0 -1
  287. package/evals/fixtures/tiny-execute-plan-app/tests/billing.test.md +0 -7
  288. package/evals/fixtures/tiny-execute-plan-app/tests/settings.test.md +0 -5
  289. package/evals/fixtures/tiny-execute-review-loop-app/README.md +0 -5
  290. package/evals/fixtures/tiny-execute-review-loop-app/docs/billing-policy.md +0 -9
  291. package/evals/fixtures/tiny-execute-review-loop-app/docs/plans/settings-title-plan.md +0 -12
  292. package/evals/fixtures/tiny-execute-review-loop-app/docs/review/previous-agent-summary.md +0 -15
  293. package/evals/fixtures/tiny-execute-review-loop-app/docs/review/review-pass-1-non-pass.md +0 -11
  294. package/evals/fixtures/tiny-execute-review-loop-app/docs/specs/settings-title.md +0 -9
  295. package/evals/fixtures/tiny-execute-review-loop-app/src/billing.ts +0 -7
  296. package/evals/fixtures/tiny-execute-review-loop-app/src/settings-page.ts +0 -1
  297. package/evals/fixtures/tiny-execute-review-loop-app/tests/billing.test.md +0 -7
  298. package/evals/fixtures/tiny-execute-review-loop-app/tests/settings.test.md +0 -5
  299. package/evals/fixtures/tiny-flaky-session-app/README.md +0 -10
  300. package/evals/fixtures/tiny-flaky-session-app/src/session-timeout.ts +0 -13
  301. package/evals/fixtures/tiny-flaky-session-app/tests/session-timeout.test.md +0 -8
  302. package/evals/fixtures/tiny-handoff-app/README.md +0 -5
  303. package/evals/fixtures/tiny-handoff-app/docs/billing-policy.md +0 -10
  304. package/evals/fixtures/tiny-handoff-app/docs/handoffs/old-agent-handoff.md +0 -8
  305. package/evals/fixtures/tiny-handoff-app/docs/plans/billing-retry-plan.md +0 -11
  306. package/evals/fixtures/tiny-handoff-app/src/billing.ts +0 -7
  307. package/evals/fixtures/tiny-handoff-report-app/README.md +0 -3
  308. package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.diff +0 -1
  309. package/evals/fixtures/tiny-handoff-report-app/evals/runs/handoff-3/hof-003/with-skill-output.md +0 -1
  310. package/evals/fixtures/tiny-handoff-report-app/evals/scores/hof-003-score.txt +0 -4
  311. package/evals/fixtures/tiny-plan-app/README.md +0 -5
  312. package/evals/fixtures/tiny-plan-app/docs/billing-policy.md +0 -10
  313. package/evals/fixtures/tiny-plan-app/docs/specs/failed-payment-grace-period.md +0 -25
  314. package/evals/fixtures/tiny-plan-app/src/billing.ts +0 -17
  315. package/evals/fixtures/tiny-plan-app/src/settings-page.ts +0 -1
  316. package/evals/fixtures/tiny-plan-app/tests/billing.test.md +0 -8
  317. package/evals/fixtures/tiny-plan-app/tests/settings.test.md +0 -5
  318. package/evals/fixtures/tiny-plan-strict-api-app/README.md +0 -3
  319. package/evals/fixtures/tiny-plan-strict-api-app/docs/billing-policy.md +0 -5
  320. package/evals/fixtures/tiny-plan-strict-api-app/docs/specs/billing-webhook-api.md +0 -25
  321. package/evals/fixtures/tiny-plan-strict-api-app/src/billing.ts +0 -5
  322. package/evals/fixtures/tiny-plan-strict-api-app/src/webhooks.ts +0 -3
  323. package/evals/fixtures/tiny-plan-strict-api-app/tests/billing-webhook.test.md +0 -8
  324. package/evals/fixtures/tiny-post-setup-invalid-config-app/.freeflow/config.json +0 -3
  325. package/evals/fixtures/tiny-post-setup-invalid-config-app/AGENTS.md +0 -15
  326. package/evals/fixtures/tiny-post-setup-invalid-config-app/README.md +0 -16
  327. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/auth-review.md +0 -15
  328. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/billing-policy.md +0 -10
  329. package/evals/fixtures/tiny-post-setup-invalid-config-app/docs/copy-conventions.md +0 -15
  330. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/auth-middleware.ts +0 -12
  331. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/billing.ts +0 -20
  332. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/login-copy.ts +0 -1
  333. package/evals/fixtures/tiny-post-setup-invalid-config-app/src/settings-page.ts +0 -1
  334. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/auth-middleware.test.md +0 -8
  335. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/billing.test.md +0 -8
  336. package/evals/fixtures/tiny-post-setup-invalid-config-app/tests/copy.test.md +0 -7
  337. package/evals/fixtures/tiny-post-setup-missing-config-app/AGENTS.md +0 -15
  338. package/evals/fixtures/tiny-post-setup-missing-config-app/README.md +0 -16
  339. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/auth-review.md +0 -15
  340. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/billing-policy.md +0 -10
  341. package/evals/fixtures/tiny-post-setup-missing-config-app/docs/copy-conventions.md +0 -15
  342. package/evals/fixtures/tiny-post-setup-missing-config-app/src/auth-middleware.ts +0 -12
  343. package/evals/fixtures/tiny-post-setup-missing-config-app/src/billing.ts +0 -20
  344. package/evals/fixtures/tiny-post-setup-missing-config-app/src/login-copy.ts +0 -1
  345. package/evals/fixtures/tiny-post-setup-missing-config-app/src/settings-page.ts +0 -1
  346. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/auth-middleware.test.md +0 -8
  347. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/billing.test.md +0 -8
  348. package/evals/fixtures/tiny-post-setup-missing-config-app/tests/copy.test.md +0 -7
  349. package/evals/fixtures/tiny-post-setup-source-conflict-app/.freeflow/config.json +0 -3
  350. package/evals/fixtures/tiny-post-setup-source-conflict-app/AGENTS.md +0 -15
  351. package/evals/fixtures/tiny-post-setup-source-conflict-app/README.md +0 -16
  352. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/auth-review.md +0 -15
  353. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/billing-policy.md +0 -10
  354. package/evals/fixtures/tiny-post-setup-source-conflict-app/docs/copy-conventions.md +0 -15
  355. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/auth-middleware.ts +0 -12
  356. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/billing.ts +0 -20
  357. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/login-copy.ts +0 -1
  358. package/evals/fixtures/tiny-post-setup-source-conflict-app/src/settings-page.ts +0 -1
  359. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/auth-middleware.test.md +0 -8
  360. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/billing.test.md +0 -8
  361. package/evals/fixtures/tiny-post-setup-source-conflict-app/tests/copy.test.md +0 -7
  362. package/evals/fixtures/tiny-report-performance-app/README.md +0 -11
  363. package/evals/fixtures/tiny-report-performance-app/docs/performance.md +0 -10
  364. package/evals/fixtures/tiny-report-performance-app/src/report-summary.ts +0 -29
  365. package/evals/fixtures/tiny-report-performance-app/tests/report-performance.test.md +0 -8
  366. package/evals/fixtures/tiny-review-request-app/README.md +0 -3
  367. package/evals/fixtures/tiny-review-request-app/docs/billing-policy.md +0 -5
  368. package/evals/fixtures/tiny-review-request-app/docs/plans/billing-webhook-api.md +0 -19
  369. package/evals/fixtures/tiny-review-request-app/docs/review/previous-agent-summary.md +0 -20
  370. package/evals/fixtures/tiny-review-request-app/docs/specs/billing-webhook-api.md +0 -25
  371. package/evals/fixtures/tiny-review-request-app/src/billing.ts +0 -11
  372. package/evals/fixtures/tiny-review-request-app/src/webhooks.ts +0 -19
  373. package/evals/fixtures/tiny-review-request-app/tests/billing-webhook.test.md +0 -8
  374. package/evals/fixtures/tiny-review-work-app/README.md +0 -5
  375. package/evals/fixtures/tiny-review-work-app/docs/billing-policy.md +0 -9
  376. package/evals/fixtures/tiny-review-work-app/docs/plans/settings-title-plan.md +0 -12
  377. package/evals/fixtures/tiny-review-work-app/docs/review/previous-agent-summary.md +0 -15
  378. package/evals/fixtures/tiny-review-work-app/docs/specs/settings-title.md +0 -9
  379. package/evals/fixtures/tiny-review-work-app/src/billing.ts +0 -7
  380. package/evals/fixtures/tiny-review-work-app/src/settings-page.ts +0 -1
  381. package/evals/fixtures/tiny-review-work-app/tests/billing.test.md +0 -7
  382. package/evals/fixtures/tiny-review-work-app/tests/settings.test.md +0 -5
  383. package/evals/fixtures/tiny-saas-app/README.md +0 -16
  384. package/evals/fixtures/tiny-saas-app/docs/auth-review.md +0 -15
  385. package/evals/fixtures/tiny-saas-app/docs/billing-policy.md +0 -10
  386. package/evals/fixtures/tiny-saas-app/docs/copy-conventions.md +0 -15
  387. package/evals/fixtures/tiny-saas-app/docs/specs/settings-title.md +0 -13
  388. package/evals/fixtures/tiny-saas-app/src/auth-middleware.ts +0 -12
  389. package/evals/fixtures/tiny-saas-app/src/billing.ts +0 -20
  390. package/evals/fixtures/tiny-saas-app/src/login-copy.ts +0 -1
  391. package/evals/fixtures/tiny-saas-app/src/settings-page.ts +0 -1
  392. package/evals/fixtures/tiny-saas-app/tests/auth-middleware.test.md +0 -8
  393. package/evals/fixtures/tiny-saas-app/tests/billing.test.md +0 -8
  394. package/evals/fixtures/tiny-saas-app/tests/copy.test.md +0 -7
  395. package/evals/fixtures/tiny-setup-agents-app/AGENTS.md +0 -6
  396. package/evals/fixtures/tiny-setup-both-app/AGENTS.md +0 -5
  397. package/evals/fixtures/tiny-setup-both-app/CLAUDE.md +0 -5
  398. package/evals/fixtures/tiny-setup-claude-app/CLAUDE.md +0 -6
  399. package/evals/fixtures/tiny-setup-codex-rules-app/.codex/rules/shell.rules +0 -5
  400. package/evals/fixtures/tiny-setup-codex-rules-app/AGENTS.md +0 -6
  401. package/evals/fixtures/tiny-setup-conflict-app/AGENTS.md +0 -6
  402. package/evals/fixtures/tiny-setup-existing-block-app/AGENTS.md +0 -14
  403. package/evals/fixtures/tiny-setup-four-rules-app/CLAUDE.md +0 -6
  404. package/evals/fixtures/tiny-skill-dev-app/README.md +0 -10
  405. package/evals/fixtures/tiny-skill-dev-app/evals/prompts/review-pr-001.txt +0 -8
  406. package/evals/fixtures/tiny-skill-dev-app/evals/reports/review-pr-failure.md +0 -17
  407. package/evals/fixtures/tiny-skill-dev-app/skills/review-pr/SKILL.md +0 -13
  408. package/evals/fixtures/tiny-team-app/README.md +0 -5
  409. package/evals/fixtures/tiny-team-app/docs/product.md +0 -6
  410. package/evals/fixtures/tiny-team-app/src/teams.ts +0 -9
  411. package/evals/fixtures/tiny-team-app/src/users.ts +0 -5
  412. package/evals/fixtures/tiny-team-app/tests/teams.test.md +0 -7
  413. package/evals/fixtures/tiny-verify-app/README.md +0 -5
  414. package/evals/fixtures/tiny-verify-app/src/settings-nav.ts +0 -1
  415. package/evals/fixtures/tiny-verify-app/src/settings-page.ts +0 -1
  416. package/evals/fixtures/tiny-verify-app/tests/settings.test.md +0 -7
  417. package/evals/prompts/aon-001.txt +0 -2
  418. package/evals/prompts/byp-001.txt +0 -2
  419. package/evals/prompts/byp-002.txt +0 -2
  420. package/evals/prompts/cap-001.txt +0 -3
  421. package/evals/prompts/cap-002.txt +0 -3
  422. package/evals/prompts/cmd-001.txt +0 -3
  423. package/evals/prompts/cmd-002.txt +0 -3
  424. package/evals/prompts/cmd-003.txt +0 -6
  425. package/evals/prompts/cmd-004.txt +0 -5
  426. package/evals/prompts/cmd-005.txt +0 -5
  427. package/evals/prompts/cmd-006.txt +0 -5
  428. package/evals/prompts/cmd-007.txt +0 -5
  429. package/evals/prompts/cmd-008.txt +0 -5
  430. package/evals/prompts/cmd-009.txt +0 -8
  431. package/evals/prompts/cmd-010.txt +0 -5
  432. package/evals/prompts/cmd-011.txt +0 -5
  433. package/evals/prompts/cmd-012.txt +0 -5
  434. package/evals/prompts/cmd-013.txt +0 -5
  435. package/evals/prompts/cmd-014.txt +0 -7
  436. package/evals/prompts/cmd-015.txt +0 -7
  437. package/evals/prompts/cmd-016.txt +0 -5
  438. package/evals/prompts/cmt-001.txt +0 -1
  439. package/evals/prompts/cmt-002.txt +0 -1
  440. package/evals/prompts/cmt-003.txt +0 -1
  441. package/evals/prompts/cmt-004.txt +0 -1
  442. package/evals/prompts/cmt-005.txt +0 -1
  443. package/evals/prompts/dfd-001.txt +0 -3
  444. package/evals/prompts/dia-001.txt +0 -3
  445. package/evals/prompts/dia-002.txt +0 -3
  446. package/evals/prompts/dia-003.txt +0 -3
  447. package/evals/prompts/dis-001.txt +0 -5
  448. package/evals/prompts/dis-002.txt +0 -5
  449. package/evals/prompts/esk-001.txt +0 -5
  450. package/evals/prompts/esk-002.txt +0 -5
  451. package/evals/prompts/esk-003.txt +0 -5
  452. package/evals/prompts/grc-001.txt +0 -3
  453. package/evals/prompts/hof-001.txt +0 -3
  454. package/evals/prompts/hof-002.txt +0 -1
  455. package/evals/prompts/hof-003.txt +0 -1
  456. package/evals/prompts/hof-004.txt +0 -1
  457. package/evals/prompts/hof-005.txt +0 -1
  458. package/evals/prompts/ivg-001.txt +0 -1
  459. package/evals/prompts/ivg-002.txt +0 -11
  460. package/evals/prompts/ivg-003.txt +0 -1
  461. package/evals/prompts/ivg-004.txt +0 -1
  462. package/evals/prompts/mode-001.txt +0 -3
  463. package/evals/prompts/mode-002.txt +0 -1
  464. package/evals/prompts/mode-003.txt +0 -3
  465. package/evals/prompts/mode-004.txt +0 -3
  466. package/evals/prompts/mode-005.txt +0 -3
  467. package/evals/prompts/mode-006.txt +0 -3
  468. package/evals/prompts/mode-007.txt +0 -3
  469. package/evals/prompts/otr-001.txt +0 -3
  470. package/evals/prompts/otr-002.txt +0 -3
  471. package/evals/prompts/rar-001.txt +0 -5
  472. package/evals/prompts/rar-002.txt +0 -3
  473. package/evals/prompts/rar-003.txt +0 -6
  474. package/evals/prompts/rar-004.txt +0 -15
  475. package/evals/prompts/rar-005.txt +0 -10
  476. package/evals/prompts/rbr-001.txt +0 -3
  477. package/evals/prompts/rbr-002.txt +0 -3
  478. package/evals/prompts/rbr-003.txt +0 -7
  479. package/evals/prompts/rev-001.txt +0 -3
  480. package/evals/prompts/rev-002.txt +0 -5
  481. package/evals/prompts/rev-003.txt +0 -6
  482. package/evals/prompts/rev-004.txt +0 -1
  483. package/evals/prompts/rev-005.txt +0 -15
  484. package/evals/prompts/rev-006.txt +0 -5
  485. package/evals/prompts/stp-001.txt +0 -1
  486. package/evals/prompts/stp-002.txt +0 -1
  487. package/evals/prompts/stp-003.txt +0 -1
  488. package/evals/prompts/stp-004.txt +0 -1
  489. package/evals/prompts/stp-005.txt +0 -1
  490. package/evals/prompts/stp-006.txt +0 -1
  491. package/evals/prompts/stp-007.txt +0 -1
  492. package/evals/prompts/stp-008.txt +0 -1
  493. package/evals/prompts/stp-009.txt +0 -1
  494. package/evals/prompts/stp-010.txt +0 -1
  495. package/evals/prompts/stp-011.txt +0 -1
  496. package/evals/prompts/vfy-003.txt +0 -1
  497. package/evals/prompts/wpl-001.txt +0 -3
  498. package/evals/prompts/wpl-002.txt +0 -5
  499. package/evals/prompts/wpl-003.txt +0 -3
  500. package/evals/prompts/wpl-004.txt +0 -5
  501. package/evals/prompts/wpl-005.txt +0 -1
  502. package/evals/prompts/wrc-001.txt +0 -10
  503. package/evals/prompts/wrc-002.txt +0 -3
  504. package/evals/prompts/wsk-001.txt +0 -6
  505. package/evals/prompts/wsp-001.txt +0 -5
  506. package/evals/prompts/wsp-002.txt +0 -15
  507. package/evals/prompts/wsp-003.txt +0 -3
  508. package/evals/prompts/wsp-004.txt +0 -15
  509. package/evals/prompts/wsp-005.txt +0 -5
  510. package/evals/prompts/wsp-006.txt +0 -12
  511. package/evals/prompts/wsp-007.txt +0 -9
  512. package/evals/prompts/wsp-008.txt +0 -13
  513. package/evals/prompts/xpl-001.txt +0 -1
  514. package/evals/prompts/xpl-002.txt +0 -3
  515. package/evals/prompts/xpl-003.txt +0 -3
  516. package/evals/prompts/xpl-004.txt +0 -3
  517. package/evals/prompts/xpl-005.txt +0 -5
  518. package/evals/prompts/xpl-006.txt +0 -3
  519. package/evals/registries/adversarial-evals.json +0 -39
  520. package/evals/registries/fixture-evals.json +0 -2513
  521. package/evals/registries/handoff-evals.json +0 -74
  522. package/evals/registries/legacy-evals.json +0 -147
  523. package/evals/registries/skill-evidence.json +0 -193
  524. package/evals/registries/verify-work-evals.json +0 -46
  525. package/evals/reports/acceptance/v0.1-acceptance-report.md +0 -130
  526. package/evals/reports/by-command-surface/command-surface-1-report.md +0 -45
  527. package/evals/reports/by-command-surface/command-surface-10-report.md +0 -76
  528. package/evals/reports/by-command-surface/command-surface-11-report.md +0 -77
  529. package/evals/reports/by-command-surface/command-surface-12-report.md +0 -91
  530. package/evals/reports/by-command-surface/command-surface-13-report.md +0 -64
  531. package/evals/reports/by-command-surface/command-surface-14-report.md +0 -66
  532. package/evals/reports/by-command-surface/command-surface-15-report.md +0 -124
  533. package/evals/reports/by-command-surface/command-surface-16-report.md +0 -39
  534. package/evals/reports/by-command-surface/command-surface-2-report.md +0 -80
  535. package/evals/reports/by-command-surface/command-surface-3-report.md +0 -86
  536. package/evals/reports/by-command-surface/command-surface-4-report.md +0 -76
  537. package/evals/reports/by-command-surface/command-surface-5-report.md +0 -80
  538. package/evals/reports/by-command-surface/command-surface-6-report.md +0 -74
  539. package/evals/reports/by-command-surface/command-surface-7-report.md +0 -84
  540. package/evals/reports/by-command-surface/command-surface-8-report.md +0 -79
  541. package/evals/reports/by-command-surface/command-surface-9-report.md +0 -79
  542. package/evals/reports/by-command-surface/command-surface-matrix.md +0 -91
  543. package/evals/reports/by-skill/bypass-1-report.md +0 -124
  544. package/evals/reports/by-skill/capture-decisions-1-report.md +0 -99
  545. package/evals/reports/by-skill/capture-decisions-2-report.md +0 -102
  546. package/evals/reports/by-skill/commit-work-1-report.md +0 -165
  547. package/evals/reports/by-skill/commit-work-2-report.md +0 -109
  548. package/evals/reports/by-skill/design-for-depth-1-report.md +0 -95
  549. package/evals/reports/by-skill/diagnose-failure-1-report.md +0 -91
  550. package/evals/reports/by-skill/diagnose-failure-2-report.md +0 -94
  551. package/evals/reports/by-skill/discover-1-report.md +0 -118
  552. package/evals/reports/by-skill/evaluate-skill-2-report.md +0 -71
  553. package/evals/reports/by-skill/execute-plan-1-report.md +0 -103
  554. package/evals/reports/by-skill/execute-plan-2-report.md +0 -112
  555. package/evals/reports/by-skill/execute-plan-3-report.md +0 -87
  556. package/evals/reports/by-skill/grill-context-1-report.md +0 -103
  557. package/evals/reports/by-skill/handoff-1-report.md +0 -123
  558. package/evals/reports/by-skill/handoff-2-report.md +0 -105
  559. package/evals/reports/by-skill/handoff-3-report.md +0 -100
  560. package/evals/reports/by-skill/handoff-7-report.md +0 -77
  561. package/evals/reports/by-skill/interview-gate-1-report.md +0 -63
  562. package/evals/reports/by-skill/interview-gate-2-report.md +0 -105
  563. package/evals/reports/by-skill/mode-contract-1-report.md +0 -74
  564. package/evals/reports/by-skill/mode-contract-2-report.md +0 -87
  565. package/evals/reports/by-skill/mode-contract-3-report.md +0 -65
  566. package/evals/reports/by-skill/mode-contract-4-report.md +0 -71
  567. package/evals/reports/by-skill/mode-contract-5-report.md +0 -70
  568. package/evals/reports/by-skill/output-router-1-report.md +0 -76
  569. package/evals/reports/by-skill/output-router-2-report.md +0 -65
  570. package/evals/reports/by-skill/research-1-report.md +0 -144
  571. package/evals/reports/by-skill/research-brief-1-report.md +0 -94
  572. package/evals/reports/by-skill/research-brief-2-report.md +0 -75
  573. package/evals/reports/by-skill/review-artifact-1-report.md +0 -91
  574. package/evals/reports/by-skill/review-artifact-2-report.md +0 -79
  575. package/evals/reports/by-skill/review-artifact-3-report.md +0 -120
  576. package/evals/reports/by-skill/review-artifact-4-report.md +0 -89
  577. package/evals/reports/by-skill/review-artifact-5-report.md +0 -66
  578. package/evals/reports/by-skill/review-work-1-report.md +0 -85
  579. package/evals/reports/by-skill/review-work-2-report.md +0 -87
  580. package/evals/reports/by-skill/review-work-3-report.md +0 -104
  581. package/evals/reports/by-skill/review-work-4-report.md +0 -108
  582. package/evals/reports/by-skill/review-work-5-report.md +0 -73
  583. package/evals/reports/by-skill/review-work-6-report.md +0 -66
  584. package/evals/reports/by-skill/setup-freeflow-1-report.md +0 -199
  585. package/evals/reports/by-skill/setup-freeflow-2-report.md +0 -105
  586. package/evals/reports/by-skill/setup-freeflow-3-report.md +0 -105
  587. package/evals/reports/by-skill/setup-freeflow-4-report.md +0 -88
  588. package/evals/reports/by-skill/setup-freeflow-5-report.md +0 -115
  589. package/evals/reports/by-skill/skill-authoring-1-report.md +0 -81
  590. package/evals/reports/by-skill/verify-work-1-report.md +0 -111
  591. package/evals/reports/by-skill/verify-work-2-report.md +0 -120
  592. package/evals/reports/by-skill/workflow-1-report.md +0 -65
  593. package/evals/reports/by-skill/write-plan-1-report.md +0 -123
  594. package/evals/reports/by-skill/write-plan-2-report.md +0 -98
  595. package/evals/reports/by-skill/write-plan-3-report.md +0 -110
  596. package/evals/reports/by-skill/write-spec-1-report.md +0 -88
  597. package/evals/reports/by-skill/write-spec-2-report.md +0 -89
  598. package/evals/reports/by-skill/write-spec-3-report.md +0 -90
  599. package/evals/reports/by-skill/write-spec-4-report.md +0 -167
  600. package/evals/reports/harness/claude-harness-1-report.md +0 -103
  601. package/evals/reports/harness/eval-harness-1-report.md +0 -91
  602. package/evals/reports/iterations/iteration-1-report.md +0 -71
  603. package/evals/reports/iterations/iteration-2-report.md +0 -78
  604. package/evals/reports/iterations/iteration-3-report.md +0 -118
  605. package/evals/reports/iterations/iteration-4-report.md +0 -131
  606. package/evals/reports/iterations/iteration-5-report.md +0 -149
  607. package/evals/reports/iterations/iteration-6-report.md +0 -136
  608. package/evals/reports/runtime/always-on-runtime-1-report.md +0 -107
  609. package/evals/reports/runtime/context-mode-normalized-benchmark-1-report.md +0 -52
  610. package/evals/reports/runtime/context-mode-real-deep-baseline-1-report.md +0 -410
  611. package/evals/reports/runtime/context-mode-real-deep-final-slice-11-report.md +0 -203
  612. package/evals/reports/runtime/context-mode-real-deep-final-slice-11-review.md +0 -51
  613. package/evals/reports/runtime/context-saving-native-tools-baseline-1-report.md +0 -99
  614. package/evals/reports/runtime/eryx-python-compatibility-reprobe-1-report.md +0 -166
  615. package/evals/reports/runtime/eryx-python-proof-spike-1-report.md +0 -96
  616. package/evals/reports/runtime/eryx-python-proof-spike-2-report.md +0 -151
  617. package/evals/reports/runtime/eryx-python-script-derive-execution-1-report.md +0 -233
  618. package/evals/reports/runtime/jq-script-derive-execution-1-report.md +0 -215
  619. package/evals/reports/runtime/jq-wasm-proof-spike-1-report.md +0 -67
  620. package/evals/reports/runtime/output-router-benchmark-1-report.md +0 -81
  621. package/evals/reports/runtime/output-router-capture-derive-provider-eval-1-report.md +0 -35
  622. package/evals/reports/runtime/output-router-codex-large-index-sqlite-adhoc-report.md +0 -150
  623. package/evals/reports/runtime/output-router-codex-qa-benchmark-1-report.md +0 -46
  624. package/evals/reports/runtime/output-router-command-benchmark-1-report.md +0 -62
  625. package/evals/reports/runtime/output-router-index-benchmark-1-report.md +0 -64
  626. package/evals/reports/runtime/output-router-regression-1-report.md +0 -81
  627. package/evals/reports/runtime/output-router-transform-eval-1-report.md +0 -28
  628. package/evals/reports/runtime/pi-observed-routing-eval-1-report.md +0 -44
  629. package/evals/reports/runtime/quickjs-script-derive-execution-1-report.md +0 -159
  630. package/evals/reports/runtime/quickjs-wasi-proof-spike-1-report.md +0 -55
  631. package/evals/reports/runtime/render-format-row-protocol-1-report.md +0 -58
  632. package/evals/reports/runtime/script-sandbox-adapter-selection-review-1-report.md +0 -84
  633. package/evals/reports/runtime/script-sandbox-probe-resource-hardening-1-report.md +0 -51
  634. package/evals/reports/runtime/storage-policy-benchmark-1-report.md +0 -176
  635. package/evals/reports/runtime/vault-index-storage-spike-1-report.md +0 -39
  636. package/evals/reports/runtime/workflow-context-hook-1-report.md +0 -82
  637. package/evals/runbooks/adversarial-eval-runbook.md +0 -28
  638. package/evals/runbooks/fixture-eval-runbook.md +0 -137
  639. package/evals/runbooks/handoff-eval-runbook.md +0 -22
  640. package/evals/runbooks/verify-work-eval-runbook.md +0 -27
  641. package/evals/scripts/audit-command-surface.sh +0 -160
  642. package/evals/scripts/check-activation-contract.sh +0 -121
  643. package/evals/scripts/check-runtime-context-hook.sh +0 -183
  644. package/evals/scripts/grade-fixture-eval.sh +0 -446
  645. package/evals/scripts/run-claude-fixture-eval.sh +0 -26
  646. package/evals/scripts/run-codex-fixture-eval.sh +0 -26
  647. package/evals/scripts/run-eryx-python-proof-spike.js +0 -559
  648. package/evals/scripts/run-fixture-eval-by-id.sh +0 -23
  649. package/evals/scripts/run-fixture-eval.sh +0 -464
  650. package/evals/scripts/run-jq-wasm-proof-spike.js +0 -299
  651. package/evals/scripts/run-output-router-transform-eval.js +0 -115
  652. package/evals/scripts/run-pi-observed-routing-eval.js +0 -478
  653. package/evals/scripts/run-quickjs-wasi-proof-spike.js +0 -339
  654. package/evals/scripts/skill-evidence.sh +0 -316
  655. package/evals/scripts/validate-release-metadata.sh +0 -486
  656. package/evals/suites/v0.1-acceptance-suite.md +0 -131
  657. package/pi-extension/dist/host-producer-identification.js +0 -186
  658. package/pi-extension/dist/mcp-config.js +0 -30
  659. package/pi-extension/dist/native-safety-net.js +0 -209
  660. package/pi-extension/dist/observed-tool-routing.js +0 -114
  661. package/pi-extension/dist/renderers.js +0 -835
  662. package/pi-extension/dist/router-tools.js +0 -438
  663. package/pi-extension/dist/runtime-context.js +0 -288
  664. package/pi-extension/dist/schemas.js +0 -254
  665. package/pi-extension/dist/status.js +0 -449
  666. package/pi-extension/dist/utils.js +0 -467
  667. package/pi-extension/src/runtime-context.ts +0 -347
  668. package/pi-extension/src/status.ts +0 -505
  669. package/plugin-docs/README.md +0 -40
  670. package/plugin-docs/adr/0001-three-modes.md +0 -27
  671. package/plugin-docs/adr/0002-evals-before-hooks.md +0 -17
  672. package/plugin-docs/adr/0003-release-boundary.md +0 -21
  673. package/plugin-docs/adr/0004-discover-replaces-shallow-discovery-skills.md +0 -26
  674. package/plugin-docs/adr/README.md +0 -10
  675. package/plugin-docs/architecture.md +0 -89
  676. package/plugin-docs/output-router.md +0 -396
  677. package/plugin-docs/release-evidence.md +0 -77
  678. package/plugin-docs/skills.md +0 -44
  679. package/plugin-docs/workflow.md +0 -57
  680. package/skills/diagnose-failure/references/feedback-loop-catalog.md +0 -25
  681. package/skills/discover/ARTIFACT-DESTINATIONS.md +0 -58
  682. package/skills/discover/CHECKPOINTS.md +0 -74
  683. package/skills/discover/SKILL.md +0 -173
  684. package/skills/evaluate-skill/references/eval-patterns.md +0 -41
  685. package/skills/evaluate-skill/references/grading-priority.md +0 -33
  686. package/skills/execute-plan/SKILL.md +0 -133
  687. package/skills/execute-plan/references/execution-map.md +0 -122
  688. package/skills/interview-gate/SKILL.md +0 -90
  689. package/skills/workflow/references/workflow-map.md +0 -104
  690. /package/pi-extension/src/{mcp-config.ts → integrations/mcp-config.ts} +0 -0
@@ -17,420 +17,449 @@ const ERYX_CHILD_MODE_ARG = "__freeflow_eryx_child__";
17
17
  const ERYX_CHILD_TIMEOUT_FLOOR_MS = 30_000;
18
18
  export const ERYX_ROOT_ENV = "FREEFLOW_ERYX_ROOT";
19
19
  const PREVIEW2_IMPORTS = new Map([
20
- ["@bytecodealliance/preview2-shim/cli", "../../@bytecodealliance/preview2-shim/lib/browser/cli.js"],
21
- ["@bytecodealliance/preview2-shim/clocks", "../../@bytecodealliance/preview2-shim/lib/browser/clocks.js"],
22
- ["@bytecodealliance/preview2-shim/filesystem", "../../@bytecodealliance/preview2-shim/lib/browser/filesystem.js"],
23
- ["@bytecodealliance/preview2-shim/io", "../../@bytecodealliance/preview2-shim/lib/browser/io.js"],
24
- ["@bytecodealliance/preview2-shim/random", "../../@bytecodealliance/preview2-shim/lib/browser/random.js"],
20
+ ["@bytecodealliance/preview2-shim/cli", "../../@bytecodealliance/preview2-shim/lib/browser/cli.js"],
21
+ ["@bytecodealliance/preview2-shim/clocks", "../../@bytecodealliance/preview2-shim/lib/browser/clocks.js"],
22
+ ["@bytecodealliance/preview2-shim/filesystem", "../../@bytecodealliance/preview2-shim/lib/browser/filesystem.js"],
23
+ ["@bytecodealliance/preview2-shim/io", "../../@bytecodealliance/preview2-shim/lib/browser/io.js"],
24
+ ["@bytecodealliance/preview2-shim/random", "../../@bytecodealliance/preview2-shim/lib/browser/random.js"],
25
25
  ]);
26
26
  const eryxProbeCache = new Map();
27
27
  export async function discoverEryxPythonSandboxAdaptersFromEnv(env = process.env) {
28
- const candidate = await resolveScriptTransformAdapterRoot("python", env);
29
- if (!candidate) {
30
- return [];
31
- }
32
- try {
33
- return [await createEryxPythonSandboxAdapter({ packageRoot: candidate.packageRoot })];
34
- }
35
- catch (error) {
36
- return [unavailableEryxAdapter(`eryx-python adapter could not load from ${candidate.source === "env" ? candidate.envVar : "global adapter cache"}: ${errorMessage(error)}`)];
37
- }
28
+ const candidate = await resolveScriptTransformAdapterRoot("python", env);
29
+ if (!candidate) {
30
+ return [];
31
+ }
32
+ try {
33
+ return [await createEryxPythonSandboxAdapter({ packageRoot: candidate.packageRoot })];
34
+ } catch (error) {
35
+ return [
36
+ unavailableEryxAdapter(
37
+ `eryx-python adapter could not load from ${candidate.source === "env" ? candidate.envVar : "global adapter cache"}: ${errorMessage(error)}`,
38
+ ),
39
+ ];
40
+ }
38
41
  }
39
42
  export async function createEryxPythonSandboxAdapter(options) {
40
- const runtime = await loadEryxRuntime(options.packageRoot);
41
- return {
42
- id: options.id ?? "eryx-python",
43
- version: options.version ?? runtime.packageVersion,
44
- languages: ["python"],
45
- async probe(language, config) {
46
- if (language !== "python") {
47
- return {
48
- status: "unavailable",
49
- reason: `eryx-python supports python, not ${language}.`,
50
- passedProofs: [],
51
- failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
52
- runtime: runtimeInfo(runtime),
53
- };
54
- }
55
- return probeEryxRuntime(runtime, config);
56
- },
57
- async execute(request) {
58
- if (request.language !== "python") {
59
- return {
60
- status: "policy_violation",
61
- stdout: "",
62
- stderr: "",
63
- outputFiles: [],
64
- exitCode: null,
65
- reason: `eryx-python supports python, not ${request.language}.`,
66
- };
67
- }
68
- if (request.network !== "off") {
69
- return {
70
- status: "policy_violation",
71
- stdout: "",
72
- stderr: "",
73
- outputFiles: [],
74
- exitCode: null,
75
- reason: "eryx-python adapter only supports network=off.",
76
- };
77
- }
78
- if (!runtime.jspiAvailable) {
79
- return executeEryxInJspiChild(runtime, request);
80
- }
81
- const inputs = {};
82
- for (const source of request.sources) {
83
- inputs[source.alias] = await readFile(source.path, "utf8");
84
- }
85
- const run = await runEryx(runtime, {
86
- code: pythonPrelude(inputs) + request.code,
87
- timeoutMs: request.limits.timeoutMs,
88
- outputBytes: request.limits.maxOutputBytes,
89
- inputs,
90
- });
91
- return eryxRunToExecutionResult(run);
92
- },
93
- };
43
+ const runtime = await loadEryxRuntime(options.packageRoot);
44
+ return {
45
+ id: options.id ?? "eryx-python",
46
+ version: options.version ?? runtime.packageVersion,
47
+ languages: ["python"],
48
+ async probe(language, config) {
49
+ if (language !== "python") {
50
+ return {
51
+ status: "unavailable",
52
+ reason: `eryx-python supports python, not ${language}.`,
53
+ passedProofs: [],
54
+ failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
55
+ runtime: runtimeInfo(runtime),
56
+ };
57
+ }
58
+ return probeEryxRuntime(runtime, config);
59
+ },
60
+ async execute(request) {
61
+ if (request.language !== "python") {
62
+ return {
63
+ status: "policy_violation",
64
+ stdout: "",
65
+ stderr: "",
66
+ outputFiles: [],
67
+ exitCode: null,
68
+ reason: `eryx-python supports python, not ${request.language}.`,
69
+ };
70
+ }
71
+ if (request.network !== "off") {
72
+ return {
73
+ status: "policy_violation",
74
+ stdout: "",
75
+ stderr: "",
76
+ outputFiles: [],
77
+ exitCode: null,
78
+ reason: "eryx-python adapter only supports network=off.",
79
+ };
80
+ }
81
+ if (!runtime.jspiAvailable) {
82
+ return executeEryxInJspiChild(runtime, request);
83
+ }
84
+ const inputs = {};
85
+ for (const source of request.sources) {
86
+ inputs[source.alias] = await readFile(source.path, "utf8");
87
+ }
88
+ const run = await runEryx(runtime, {
89
+ code: pythonPrelude(inputs) + request.code,
90
+ timeoutMs: request.limits.timeoutMs,
91
+ outputBytes: request.limits.maxOutputBytes,
92
+ inputs,
93
+ });
94
+ return eryxRunToExecutionResult(run);
95
+ },
96
+ };
94
97
  }
95
98
  function unavailableEryxAdapter(reason) {
96
- return {
97
- id: "eryx-python",
98
- version: "unavailable",
99
- languages: ["python"],
100
- async probe() {
101
- return {
102
- status: "unavailable",
103
- reason,
104
- passedProofs: [],
105
- failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
106
- };
107
- },
108
- async execute() {
109
- return {
110
- status: "policy_violation",
111
- stdout: "",
112
- stderr: "",
113
- outputFiles: [],
114
- exitCode: null,
115
- reason,
116
- };
117
- },
118
- };
99
+ return {
100
+ id: "eryx-python",
101
+ version: "unavailable",
102
+ languages: ["python"],
103
+ async probe() {
104
+ return {
105
+ status: "unavailable",
106
+ reason,
107
+ passedProofs: [],
108
+ failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
109
+ };
110
+ },
111
+ async execute() {
112
+ return {
113
+ status: "policy_violation",
114
+ stdout: "",
115
+ stderr: "",
116
+ outputFiles: [],
117
+ exitCode: null,
118
+ reason,
119
+ };
120
+ },
121
+ };
119
122
  }
120
123
  async function loadEryxRuntime(packageRoot) {
121
- const resolvedRoot = resolve(packageRoot);
122
- const packageJson = JSON.parse(await readFile(join(resolvedRoot, "package.json"), "utf8"));
123
- const preview2ShimRoot = resolve(resolvedRoot, "..", "..", "@bytecodealliance", "preview2-shim");
124
- const preview2ShimJson = JSON.parse(await readFile(join(preview2ShimRoot, "package.json"), "utf8"));
125
- const runtimeHash = await hashEryxRuntime(resolvedRoot, preview2ShimRoot);
126
- return {
127
- packageName: String(packageJson.name ?? "@bsull/eryx"),
128
- packageVersion: String(packageJson.version ?? "unknown"),
129
- packageRoot: resolvedRoot,
130
- preview2ShimRoot,
131
- preview2ShimVersion: String(preview2ShimJson.version ?? "unknown"),
132
- runtimeHash,
133
- jspiAvailable: nodeJspiAvailable(),
134
- };
124
+ const resolvedRoot = resolve(packageRoot);
125
+ const packageJson = JSON.parse(await readFile(join(resolvedRoot, "package.json"), "utf8"));
126
+ const preview2ShimRoot = resolve(resolvedRoot, "..", "..", "@bytecodealliance", "preview2-shim");
127
+ const preview2ShimJson = JSON.parse(await readFile(join(preview2ShimRoot, "package.json"), "utf8"));
128
+ const runtimeHash = await hashEryxRuntime(resolvedRoot, preview2ShimRoot);
129
+ return {
130
+ packageName: String(packageJson.name ?? "@bsull/eryx"),
131
+ packageVersion: String(packageJson.version ?? "unknown"),
132
+ packageRoot: resolvedRoot,
133
+ preview2ShimRoot,
134
+ preview2ShimVersion: String(preview2ShimJson.version ?? "unknown"),
135
+ runtimeHash,
136
+ jspiAvailable: nodeJspiAvailable(),
137
+ };
135
138
  }
136
139
  async function hashEryxRuntime(packageRoot, preview2ShimRoot) {
137
- const hash = createHash("sha256");
138
- hash.update("eryx-runtime-tree-v1\0");
139
- await hashRuntimeTree(hash, packageRoot, "eryx");
140
- await hashRuntimeTree(hash, preview2ShimRoot, "preview2-shim");
141
- return `sha256_${hash.digest("hex")}`;
140
+ const hash = createHash("sha256");
141
+ hash.update("eryx-runtime-tree-v1\0");
142
+ await hashRuntimeTree(hash, packageRoot, "eryx");
143
+ await hashRuntimeTree(hash, preview2ShimRoot, "preview2-shim");
144
+ return `sha256_${hash.digest("hex")}`;
142
145
  }
143
146
  async function hashRuntimeTree(hash, root, label, relativeDir = ".") {
144
- const dir = join(root, relativeDir);
145
- const entries = await readdir(dir, { withFileTypes: true });
146
- entries.sort((left, right) => left.name.localeCompare(right.name));
147
- for (const entry of entries) {
148
- const relativePath = relativeDir === "." ? entry.name : join(relativeDir, entry.name);
149
- const fullPath = join(root, relativePath);
150
- const stats = await lstat(fullPath);
151
- if (stats.isSymbolicLink()) {
152
- throw new Error(`${label} runtime tree contains unsupported symlink: ${relativePath}`);
153
- }
154
- if (stats.isDirectory()) {
155
- hash.update(`${label}:dir:${relativePath}\0`);
156
- await hashRuntimeTree(hash, root, label, relativePath);
157
- continue;
158
- }
159
- if (!stats.isFile()) {
160
- throw new Error(`${label} runtime tree contains unsupported non-file entry: ${relativePath}`);
161
- }
162
- hash.update(`${label}:file:${relativePath}:${stats.size}\0`);
163
- hash.update(await readFile(fullPath));
164
- }
147
+ const dir = join(root, relativeDir);
148
+ const entries = await readdir(dir, { withFileTypes: true });
149
+ entries.sort((left, right) => left.name.localeCompare(right.name));
150
+ for (const entry of entries) {
151
+ const relativePath = relativeDir === "." ? entry.name : join(relativeDir, entry.name);
152
+ const fullPath = join(root, relativePath);
153
+ const stats = await lstat(fullPath);
154
+ if (stats.isSymbolicLink()) {
155
+ throw new Error(`${label} runtime tree contains unsupported symlink: ${relativePath}`);
156
+ }
157
+ if (stats.isDirectory()) {
158
+ hash.update(`${label}:dir:${relativePath}\0`);
159
+ await hashRuntimeTree(hash, root, label, relativePath);
160
+ continue;
161
+ }
162
+ if (!stats.isFile()) {
163
+ throw new Error(`${label} runtime tree contains unsupported non-file entry: ${relativePath}`);
164
+ }
165
+ hash.update(`${label}:file:${relativePath}:${stats.size}\0`);
166
+ hash.update(await readFile(fullPath));
167
+ }
165
168
  }
166
169
  function nodeJspiAvailable() {
167
- const nodeOptions = process.env.NODE_OPTIONS ?? "";
168
- const flagPresent = process.execArgv.includes("--experimental-wasm-jspi") || nodeOptions.split(/\s+/).includes("--experimental-wasm-jspi");
169
- return flagPresent && typeof WebAssembly.Suspending === "function";
170
+ const nodeOptions = process.env.NODE_OPTIONS ?? "";
171
+ const flagPresent =
172
+ process.execArgv.includes("--experimental-wasm-jspi") ||
173
+ nodeOptions.split(/\s+/).includes("--experimental-wasm-jspi");
174
+ return flagPresent && typeof WebAssembly.Suspending === "function";
170
175
  }
171
176
  function runtimeInfo(runtime) {
172
- return {
173
- name: runtime.packageName,
174
- version: `${runtime.packageVersion}+preview2-shim-${runtime.preview2ShimVersion}`,
175
- };
177
+ return {
178
+ name: runtime.packageName,
179
+ version: `${runtime.packageVersion}+preview2-shim-${runtime.preview2ShimVersion}`,
180
+ };
176
181
  }
177
182
  async function probeEryxRuntime(runtime, config) {
178
- const timeoutMs = Math.min(config.limits.timeoutMs, DEFAULT_PROBE_TIMEOUT_MS);
179
- const outputBytes = Math.min(config.limits.maxOutputBytes, DEFAULT_PROBE_OUTPUT_BYTES);
180
- const currentRuntimeHash = await hashEryxRuntime(runtime.packageRoot, runtime.preview2ShimRoot);
181
- if (currentRuntimeHash !== runtime.runtimeHash) {
182
- return {
183
- status: "unavailable",
184
- reason: "eryx-python explicit package root changed after adapter creation; refusing to reuse stale proof cache.",
185
- passedProofs: [],
186
- failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
187
- runtime: runtimeInfo(runtime),
188
- };
189
- }
190
- const cacheKey = [runtime.packageVersion, runtime.preview2ShimVersion, currentRuntimeHash, runtime.jspiAvailable, timeoutMs, outputBytes, config.network].join(":");
191
- const cached = eryxProbeCache.get(cacheKey);
192
- if (cached) {
193
- return cloneProbeResult(await cached);
194
- }
195
- const probePromise = runEryxProbe(runtime, config, timeoutMs, outputBytes);
196
- eryxProbeCache.set(cacheKey, probePromise);
197
- try {
198
- return cloneProbeResult(await probePromise);
199
- }
200
- catch (error) {
201
- eryxProbeCache.delete(cacheKey);
202
- throw error;
203
- }
183
+ const timeoutMs = Math.min(config.limits.timeoutMs, DEFAULT_PROBE_TIMEOUT_MS);
184
+ const outputBytes = Math.min(config.limits.maxOutputBytes, DEFAULT_PROBE_OUTPUT_BYTES);
185
+ const currentRuntimeHash = await hashEryxRuntime(runtime.packageRoot, runtime.preview2ShimRoot);
186
+ if (currentRuntimeHash !== runtime.runtimeHash) {
187
+ return {
188
+ status: "unavailable",
189
+ reason: "eryx-python explicit package root changed after adapter creation; refusing to reuse stale proof cache.",
190
+ passedProofs: [],
191
+ failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
192
+ runtime: runtimeInfo(runtime),
193
+ };
194
+ }
195
+ const cacheKey = [
196
+ runtime.packageVersion,
197
+ runtime.preview2ShimVersion,
198
+ currentRuntimeHash,
199
+ runtime.jspiAvailable,
200
+ timeoutMs,
201
+ outputBytes,
202
+ config.network,
203
+ ].join(":");
204
+ const cached = eryxProbeCache.get(cacheKey);
205
+ if (cached) {
206
+ return cloneProbeResult(await cached);
207
+ }
208
+ const probePromise = runEryxProbe(runtime, config, timeoutMs, outputBytes);
209
+ eryxProbeCache.set(cacheKey, probePromise);
210
+ try {
211
+ return cloneProbeResult(await probePromise);
212
+ } catch (error) {
213
+ eryxProbeCache.delete(cacheKey);
214
+ throw error;
215
+ }
204
216
  }
205
217
  async function runEryxProbe(runtime, config, timeoutMs, outputBytes) {
206
- if (config.network !== "off") {
207
- return {
208
- status: "unavailable",
209
- reason: "eryx-python adapter only supports network=off.",
210
- passedProofs: [],
211
- failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
212
- runtime: runtimeInfo(runtime),
213
- };
214
- }
215
- if (!runtime.jspiAvailable) {
216
- return probeEryxInJspiChild(runtime, config);
217
- }
218
- const previousSecret = process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL;
219
- process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL = SECRET_SENTINEL;
220
- try {
221
- const passedProofs = [];
222
- const failedProofs = [];
223
- const fixtures = scriptSandboxProofFixturesForLanguage("python");
224
- for (const fixture of fixtures) {
225
- const run = await runEryx(runtime, {
226
- code: fixture.program,
227
- timeoutMs,
228
- outputBytes,
229
- });
230
- const assessment = assessEryxProof(fixture.proof, run, timeoutMs, outputBytes);
231
- if (assessment) {
232
- passedProofs.push(fixture.proof);
233
- }
234
- else {
235
- failedProofs.push(fixture.proof);
236
- }
237
- }
238
- const allPassed = SCRIPT_SANDBOX_REQUIRED_PROOFS.every((proof) => passedProofs.includes(proof));
239
- return {
240
- status: allPassed ? "available" : "unavailable",
241
- reason: allPassed ? "eryx-python passed every required Python sandbox proof." : "eryx-python did not pass every required Python sandbox proof.",
242
- passedProofs,
243
- failedProofs,
244
- runtime: runtimeInfo(runtime),
245
- };
218
+ if (config.network !== "off") {
219
+ return {
220
+ status: "unavailable",
221
+ reason: "eryx-python adapter only supports network=off.",
222
+ passedProofs: [],
223
+ failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
224
+ runtime: runtimeInfo(runtime),
225
+ };
226
+ }
227
+ if (!runtime.jspiAvailable) {
228
+ return probeEryxInJspiChild(runtime, config);
229
+ }
230
+ const previousSecret = process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL;
231
+ process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL = SECRET_SENTINEL;
232
+ try {
233
+ const passedProofs = [];
234
+ const failedProofs = [];
235
+ const fixtures = scriptSandboxProofFixturesForLanguage("python");
236
+ for (const fixture of fixtures) {
237
+ const run = await runEryx(runtime, {
238
+ code: fixture.program,
239
+ timeoutMs,
240
+ outputBytes,
241
+ });
242
+ const assessment = assessEryxProof(fixture.proof, run, timeoutMs, outputBytes);
243
+ if (assessment) {
244
+ passedProofs.push(fixture.proof);
245
+ } else {
246
+ failedProofs.push(fixture.proof);
247
+ }
246
248
  }
247
- finally {
248
- if (previousSecret === undefined) {
249
- delete process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL;
250
- }
251
- else {
252
- process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL = previousSecret;
253
- }
249
+ const allPassed = SCRIPT_SANDBOX_REQUIRED_PROOFS.every((proof) => passedProofs.includes(proof));
250
+ return {
251
+ status: allPassed ? "available" : "unavailable",
252
+ reason: allPassed
253
+ ? "eryx-python passed every required Python sandbox proof."
254
+ : "eryx-python did not pass every required Python sandbox proof.",
255
+ passedProofs,
256
+ failedProofs,
257
+ runtime: runtimeInfo(runtime),
258
+ };
259
+ } finally {
260
+ if (previousSecret === undefined) {
261
+ delete process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL;
262
+ } else {
263
+ process.env.FREEFLOW_SANDBOX_SECRET_SENTINEL = previousSecret;
254
264
  }
265
+ }
255
266
  }
256
267
  async function probeEryxInJspiChild(runtime, config) {
257
- try {
258
- const result = await runEryxChildRequest({
259
- kind: "probe",
260
- packageRoot: runtime.packageRoot,
261
- config,
262
- }, childTimeoutMsForProbe(config));
263
- if (isProbeResult(result)) {
264
- return {
265
- ...result,
266
- reason: result.status === "available"
267
- ? `${result.reason} via child Node --experimental-wasm-jspi.`
268
- : result.reason,
269
- };
270
- }
271
- return unavailableProbeResult("eryx-python child probe returned an execution result instead of a probe result.", runtime);
272
- }
273
- catch (error) {
274
- return unavailableProbeResult(`eryx-python child JSPI probe failed: ${errorMessage(error)}`, runtime);
275
- }
268
+ try {
269
+ const result = await runEryxChildRequest(
270
+ {
271
+ kind: "probe",
272
+ packageRoot: runtime.packageRoot,
273
+ config,
274
+ },
275
+ childTimeoutMsForProbe(config),
276
+ );
277
+ if (isProbeResult(result)) {
278
+ return {
279
+ ...result,
280
+ reason:
281
+ result.status === "available" ? `${result.reason} via child Node --experimental-wasm-jspi.` : result.reason,
282
+ };
283
+ }
284
+ return unavailableProbeResult(
285
+ "eryx-python child probe returned an execution result instead of a probe result.",
286
+ runtime,
287
+ );
288
+ } catch (error) {
289
+ return unavailableProbeResult(`eryx-python child JSPI probe failed: ${errorMessage(error)}`, runtime);
290
+ }
276
291
  }
277
292
  async function executeEryxInJspiChild(runtime, request) {
278
- try {
279
- const result = await runEryxChildRequest({
280
- kind: "execute",
281
- packageRoot: runtime.packageRoot,
282
- request,
283
- }, childTimeoutMsForExecution(request));
284
- if (isExecutionResult(result)) {
285
- return result;
286
- }
287
- return {
288
- status: "failed",
289
- stdout: "",
290
- stderr: "eryx-python child execution returned a probe result instead of an execution result.",
291
- outputFiles: [],
292
- exitCode: null,
293
- reason: "Invalid child execution response.",
294
- };
295
- }
296
- catch (error) {
297
- const message = errorMessage(error);
298
- return {
299
- status: "failed",
300
- stdout: "",
301
- stderr: message,
302
- outputFiles: [],
303
- exitCode: null,
304
- reason: `eryx-python child JSPI execution failed: ${message}`,
305
- };
293
+ try {
294
+ const result = await runEryxChildRequest(
295
+ {
296
+ kind: "execute",
297
+ packageRoot: runtime.packageRoot,
298
+ request,
299
+ },
300
+ childTimeoutMsForExecution(request),
301
+ );
302
+ if (isExecutionResult(result)) {
303
+ return result;
306
304
  }
305
+ return {
306
+ status: "failed",
307
+ stdout: "",
308
+ stderr: "eryx-python child execution returned a probe result instead of an execution result.",
309
+ outputFiles: [],
310
+ exitCode: null,
311
+ reason: "Invalid child execution response.",
312
+ };
313
+ } catch (error) {
314
+ const message = errorMessage(error);
315
+ return {
316
+ status: "failed",
317
+ stdout: "",
318
+ stderr: message,
319
+ outputFiles: [],
320
+ exitCode: null,
321
+ reason: `eryx-python child JSPI execution failed: ${message}`,
322
+ };
323
+ }
307
324
  }
308
325
  async function runEryxChildRequest(request, timeoutMs) {
309
- const root = await mkdtemp(join(tmpdir(), "freeflow-eryx-child-"));
310
- const requestPath = join(root, "request.json");
311
- const responsePath = join(root, "response.json");
312
- try {
313
- await writeFile(requestPath, JSON.stringify(request), "utf8");
314
- await runEryxChildProcess(requestPath, responsePath, timeoutMs);
315
- const response = JSON.parse(await readFile(responsePath, "utf8"));
316
- if (!response.ok) {
317
- throw new Error(response.message);
318
- }
319
- return response.result;
320
- }
321
- finally {
322
- await rm(root, { recursive: true, force: true });
323
- }
326
+ const root = await mkdtemp(join(tmpdir(), "freeflow-eryx-child-"));
327
+ const requestPath = join(root, "request.json");
328
+ const responsePath = join(root, "response.json");
329
+ try {
330
+ await writeFile(requestPath, JSON.stringify(request), "utf8");
331
+ await runEryxChildProcess(requestPath, responsePath, timeoutMs);
332
+ const response = JSON.parse(await readFile(responsePath, "utf8"));
333
+ if (!response.ok) {
334
+ throw new Error(response.message);
335
+ }
336
+ return response.result;
337
+ } finally {
338
+ await rm(root, { recursive: true, force: true });
339
+ }
324
340
  }
325
341
  async function runEryxChildProcess(requestPath, responsePath, timeoutMs) {
326
- const nodeBinary = await resolveEryxChildNodeBinary();
327
- const child = spawn(nodeBinary, ["--experimental-wasm-jspi", fileURLToPath(import.meta.url), ERYX_CHILD_MODE_ARG, requestPath, responsePath], {
328
- stdio: ["ignore", "ignore", "pipe"],
329
- env: process.env,
330
- });
331
- let stderr = "";
332
- child.stderr.setEncoding("utf8");
333
- child.stderr.on("data", (chunk) => {
334
- stderr += String(chunk);
342
+ const nodeBinary = await resolveEryxChildNodeBinary();
343
+ const child = spawn(
344
+ nodeBinary,
345
+ ["--experimental-wasm-jspi", fileURLToPath(import.meta.url), ERYX_CHILD_MODE_ARG, requestPath, responsePath],
346
+ {
347
+ stdio: ["ignore", "ignore", "pipe"],
348
+ env: process.env,
349
+ },
350
+ );
351
+ let stderr = "";
352
+ child.stderr.setEncoding("utf8");
353
+ child.stderr.on("data", (chunk) => {
354
+ stderr += String(chunk);
355
+ });
356
+ await new Promise((resolvePromise, reject) => {
357
+ const timer = setTimeout(() => {
358
+ child.kill("SIGKILL");
359
+ reject(new Error(`eryx-python child process timed out after ${timeoutMs}ms.`));
360
+ }, timeoutMs);
361
+ child.on("error", (error) => {
362
+ clearTimeout(timer);
363
+ reject(error);
335
364
  });
336
- await new Promise((resolvePromise, reject) => {
337
- const timer = setTimeout(() => {
338
- child.kill("SIGKILL");
339
- reject(new Error(`eryx-python child process timed out after ${timeoutMs}ms.`));
340
- }, timeoutMs);
341
- child.on("error", (error) => {
342
- clearTimeout(timer);
343
- reject(error);
344
- });
345
- child.on("close", (code) => {
346
- clearTimeout(timer);
347
- if (code === 0) {
348
- resolvePromise();
349
- }
350
- else {
351
- reject(new Error(`eryx-python child process ${nodeBinary} exited with code ${code}. ${stderr.trim()}`));
352
- }
353
- });
365
+ child.on("close", (code) => {
366
+ clearTimeout(timer);
367
+ if (code === 0) {
368
+ resolvePromise();
369
+ } else {
370
+ reject(new Error(`eryx-python child process ${nodeBinary} exited with code ${code}. ${stderr.trim()}`));
371
+ }
354
372
  });
373
+ });
355
374
  }
356
375
  async function resolveEryxChildNodeBinary() {
357
- const configured = defaultScriptTransformNodeBinary();
358
- if (await fileExists(configured)) {
359
- return configured;
360
- }
361
- return process.execPath;
376
+ const configured = defaultScriptTransformNodeBinary();
377
+ if (await fileExists(configured)) {
378
+ return configured;
379
+ }
380
+ return process.execPath;
362
381
  }
363
382
  async function fileExists(path) {
364
- try {
365
- await access(path);
366
- return true;
367
- }
368
- catch {
369
- return false;
370
- }
383
+ try {
384
+ await access(path);
385
+ return true;
386
+ } catch {
387
+ return false;
388
+ }
371
389
  }
372
390
  function childTimeoutMsForProbe(config) {
373
- return Math.max(ERYX_CHILD_TIMEOUT_FLOOR_MS, Math.min(config.limits.timeoutMs, DEFAULT_PROBE_TIMEOUT_MS) * SCRIPT_SANDBOX_REQUIRED_PROOFS.length * 8);
391
+ return Math.max(
392
+ ERYX_CHILD_TIMEOUT_FLOOR_MS,
393
+ Math.min(config.limits.timeoutMs, DEFAULT_PROBE_TIMEOUT_MS) * SCRIPT_SANDBOX_REQUIRED_PROOFS.length * 8,
394
+ );
374
395
  }
375
396
  function childTimeoutMsForExecution(request) {
376
- return Math.max(ERYX_CHILD_TIMEOUT_FLOOR_MS, request.limits.timeoutMs + 5_000);
397
+ return Math.max(ERYX_CHILD_TIMEOUT_FLOOR_MS, request.limits.timeoutMs + 5_000);
377
398
  }
378
399
  function unavailableProbeResult(reason, runtime) {
379
- return {
380
- status: "unavailable",
381
- reason,
382
- passedProofs: [],
383
- failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
384
- runtime: runtimeInfo(runtime),
385
- };
400
+ return {
401
+ status: "unavailable",
402
+ reason,
403
+ passedProofs: [],
404
+ failedProofs: [...SCRIPT_SANDBOX_REQUIRED_PROOFS],
405
+ runtime: runtimeInfo(runtime),
406
+ };
386
407
  }
387
408
  function isProbeResult(value) {
388
- return Array.isArray(value.passedProofs) && Array.isArray(value.failedProofs);
409
+ return Array.isArray(value.passedProofs) && Array.isArray(value.failedProofs);
389
410
  }
390
411
  function isExecutionResult(value) {
391
- return Array.isArray(value.outputFiles);
412
+ return Array.isArray(value.outputFiles);
392
413
  }
393
414
  async function runEryx(runtime, options) {
394
- const start = Date.now();
395
- const patched = await createPatchedPackageTree(runtime);
396
- try {
397
- const eryxEntryUrl = pathToFileURL(join(patched.eryxRoot, "index.js")).href;
398
- return await runEryxWorker({ eryxEntryUrl, code: options.code, timeoutMs: options.timeoutMs, outputBytes: options.outputBytes, startedAt: start });
399
- }
400
- finally {
401
- await rm(patched.root, { recursive: true, force: true });
402
- }
415
+ const start = Date.now();
416
+ const patched = await createPatchedPackageTree(runtime);
417
+ try {
418
+ const eryxEntryUrl = pathToFileURL(join(patched.eryxRoot, "index.js")).href;
419
+ return await runEryxWorker({
420
+ eryxEntryUrl,
421
+ code: options.code,
422
+ timeoutMs: options.timeoutMs,
423
+ outputBytes: options.outputBytes,
424
+ startedAt: start,
425
+ });
426
+ } finally {
427
+ await rm(patched.root, { recursive: true, force: true });
428
+ }
403
429
  }
404
430
  async function createPatchedPackageTree(runtime) {
405
- const root = await mkdtemp(join(tmpdir(), "freeflow-eryx-adapter-"));
406
- const eryxRoot = join(root, "node_modules", "@bsull", "eryx");
407
- const preview2ShimRoot = join(root, "node_modules", "@bytecodealliance", "preview2-shim");
408
- try {
409
- await mkdir(dirname(eryxRoot), { recursive: true });
410
- await mkdir(dirname(preview2ShimRoot), { recursive: true });
411
- await cp(runtime.packageRoot, eryxRoot, { recursive: true, dereference: false });
412
- await cp(runtime.preview2ShimRoot, preview2ShimRoot, { recursive: true, dereference: false });
413
- const copiedRuntimeHash = await hashEryxRuntime(eryxRoot, preview2ShimRoot);
414
- if (copiedRuntimeHash !== runtime.runtimeHash) {
415
- throw new Error("eryx-python explicit package root changed while preparing sandbox copy; refusing to execute unproven runtime files.");
416
- }
417
- for (const file of [join(eryxRoot, "index.js"), join(eryxRoot, "eryx-sandbox.js")]) {
418
- let text = await readFile(file, "utf8");
419
- for (const [from, to] of PREVIEW2_IMPORTS) {
420
- text = text.split(from).join(to);
421
- }
422
- await writeFile(file, text, "utf8");
423
- }
424
- await writeInstrumentedNetworkDenyShim(eryxRoot);
425
- return { root, eryxRoot };
426
- }
427
- catch (error) {
428
- await rm(root, { recursive: true, force: true });
429
- throw error;
431
+ const root = await mkdtemp(join(tmpdir(), "freeflow-eryx-adapter-"));
432
+ const eryxRoot = join(root, "node_modules", "@bsull", "eryx");
433
+ const preview2ShimRoot = join(root, "node_modules", "@bytecodealliance", "preview2-shim");
434
+ try {
435
+ await mkdir(dirname(eryxRoot), { recursive: true });
436
+ await mkdir(dirname(preview2ShimRoot), { recursive: true });
437
+ await cp(runtime.packageRoot, eryxRoot, { recursive: true, dereference: false });
438
+ await cp(runtime.preview2ShimRoot, preview2ShimRoot, { recursive: true, dereference: false });
439
+ const copiedRuntimeHash = await hashEryxRuntime(eryxRoot, preview2ShimRoot);
440
+ if (copiedRuntimeHash !== runtime.runtimeHash) {
441
+ throw new Error(
442
+ "eryx-python explicit package root changed while preparing sandbox copy; refusing to execute unproven runtime files.",
443
+ );
444
+ }
445
+ for (const file of [join(eryxRoot, "index.js"), join(eryxRoot, "eryx-sandbox.js")]) {
446
+ let text = await readFile(file, "utf8");
447
+ for (const [from, to] of PREVIEW2_IMPORTS) {
448
+ text = text.split(from).join(to);
449
+ }
450
+ await writeFile(file, text, "utf8");
430
451
  }
452
+ await writeInstrumentedNetworkDenyShim(eryxRoot);
453
+ return { root, eryxRoot };
454
+ } catch (error) {
455
+ await rm(root, { recursive: true, force: true });
456
+ throw error;
457
+ }
431
458
  }
432
459
  async function writeInstrumentedNetworkDenyShim(eryxRoot) {
433
- await writeFile(join(eryxRoot, "shims", "net.js"), `
460
+ await writeFile(
461
+ join(eryxRoot, "shims", "net.js"),
462
+ `
434
463
  const recordNetworkDeny = (kind, operation) => {
435
464
  globalThis.__freeflowEryxNetworkEvents ??= [];
436
465
  globalThis.__freeflowEryxNetworkEvents.push({ kind, operation, decision: "not-permitted" });
@@ -473,10 +502,12 @@ export const tls = {
473
502
  recordNetworkDeny("tls", "close");
474
503
  },
475
504
  };
476
- `, "utf8");
505
+ `,
506
+ "utf8",
507
+ );
477
508
  }
478
509
  async function runEryxWorker(options) {
479
- const workerSource = `
510
+ const workerSource = `
480
511
  import { parentPort, workerData } from 'node:worker_threads';
481
512
 
482
513
  let stdout = '';
@@ -544,254 +575,294 @@ async function runEryxWorker(options) {
544
575
  finish({ status: 'error', errorName: error?.name ?? 'Error', errorMessage: message, exitCode: 1 });
545
576
  }
546
577
  `;
547
- const worker = new Worker(workerSource, {
548
- eval: true,
549
- type: "module",
550
- workerData: { eryxEntryUrl: options.eryxEntryUrl, code: options.code, outputBytes: options.outputBytes },
551
- stdout: true,
552
- stderr: true,
553
- resourceLimits: {
554
- maxOldGenerationSizeMb: DEFAULT_WORKER_OLD_GENERATION_MB,
555
- maxYoungGenerationSizeMb: DEFAULT_WORKER_YOUNG_GENERATION_MB,
556
- },
557
- });
558
- let externalStdout = "";
559
- let externalStderr = "";
560
- let externalRawStdoutBytes = 0;
561
- let externalRawStderrBytes = 0;
562
- let externalTruncated = false;
563
- const appendExternal = (stream, chunk) => {
564
- const text = String(chunk ?? "");
565
- const bytes = Buffer.byteLength(text, "utf8");
566
- if (stream === "stderr")
567
- externalRawStderrBytes += bytes;
568
- else
569
- externalRawStdoutBytes += bytes;
570
- const currentBytes = Buffer.byteLength(externalStdout, "utf8") + Buffer.byteLength(externalStderr, "utf8");
571
- const remaining = options.outputBytes - currentBytes;
572
- if (remaining <= 0) {
573
- externalTruncated = externalTruncated || bytes > 0;
574
- return;
575
- }
576
- const buffer = Buffer.from(text, "utf8");
577
- const nextText = buffer.byteLength > remaining ? buffer.subarray(0, remaining).toString("utf8") : text;
578
- if (buffer.byteLength > remaining)
579
- externalTruncated = true;
580
- if (stream === "stderr")
581
- externalStderr += nextText;
582
- else
583
- externalStdout += nextText;
578
+ const worker = new Worker(workerSource, {
579
+ eval: true,
580
+ type: "module",
581
+ workerData: { eryxEntryUrl: options.eryxEntryUrl, code: options.code, outputBytes: options.outputBytes },
582
+ stdout: true,
583
+ stderr: true,
584
+ resourceLimits: {
585
+ maxOldGenerationSizeMb: DEFAULT_WORKER_OLD_GENERATION_MB,
586
+ maxYoungGenerationSizeMb: DEFAULT_WORKER_YOUNG_GENERATION_MB,
587
+ },
588
+ });
589
+ let externalStdout = "";
590
+ let externalStderr = "";
591
+ let externalRawStdoutBytes = 0;
592
+ let externalRawStderrBytes = 0;
593
+ let externalTruncated = false;
594
+ const appendExternal = (stream, chunk) => {
595
+ const text = String(chunk ?? "");
596
+ const bytes = Buffer.byteLength(text, "utf8");
597
+ if (stream === "stderr") externalRawStderrBytes += bytes;
598
+ else externalRawStdoutBytes += bytes;
599
+ const currentBytes = Buffer.byteLength(externalStdout, "utf8") + Buffer.byteLength(externalStderr, "utf8");
600
+ const remaining = options.outputBytes - currentBytes;
601
+ if (remaining <= 0) {
602
+ externalTruncated = externalTruncated || bytes > 0;
603
+ return;
604
+ }
605
+ const buffer = Buffer.from(text, "utf8");
606
+ const nextText = buffer.byteLength > remaining ? buffer.subarray(0, remaining).toString("utf8") : text;
607
+ if (buffer.byteLength > remaining) externalTruncated = true;
608
+ if (stream === "stderr") externalStderr += nextText;
609
+ else externalStdout += nextText;
610
+ };
611
+ worker.stdout?.on("data", (chunk) => appendExternal("stdout", chunk));
612
+ worker.stderr?.on("data", (chunk) => appendExternal("stderr", chunk));
613
+ return new Promise((resolve) => {
614
+ let settled = false;
615
+ const finish = (result) => {
616
+ if (settled) return;
617
+ settled = true;
618
+ clearTimeout(timer);
619
+ const merged = mergeWorkerResult(result, {
620
+ externalStdout,
621
+ externalStderr,
622
+ externalRawStdoutBytes,
623
+ externalRawStderrBytes,
624
+ externalTruncated,
625
+ outputBytes: options.outputBytes,
626
+ });
627
+ resolve({ ...merged, durationMs: Date.now() - options.startedAt });
584
628
  };
585
- worker.stdout?.on("data", (chunk) => appendExternal("stdout", chunk));
586
- worker.stderr?.on("data", (chunk) => appendExternal("stderr", chunk));
587
- return new Promise((resolve) => {
588
- let settled = false;
589
- const finish = (result) => {
590
- if (settled)
591
- return;
592
- settled = true;
593
- clearTimeout(timer);
594
- const merged = mergeWorkerResult(result, {
595
- externalStdout,
596
- externalStderr,
597
- externalRawStdoutBytes,
598
- externalRawStderrBytes,
599
- externalTruncated,
600
- outputBytes: options.outputBytes,
601
- });
602
- resolve({ ...merged, durationMs: Date.now() - options.startedAt });
603
- };
604
- const timer = setTimeout(() => {
605
- if (settled)
606
- return;
607
- finish({ status: "timed_out", stdout: "", stderr: "", exitCode: null, rawStdoutBytes: 0, rawStderrBytes: 0, stdoutBytes: 0, stderrBytes: 0, outputBytes: 0, truncated: false, outputFiles: [], networkEvents: [] });
608
- void worker.terminate();
609
- }, options.timeoutMs);
610
- worker.on("message", (message) => finish(message));
611
- worker.on("error", (error) => {
612
- const message = errorMessage(error);
613
- finish({ status: "error", stdout: "", stderr: message, exitCode: null, rawStdoutBytes: 0, rawStderrBytes: Buffer.byteLength(message, "utf8"), truncated: false, outputFiles: [], networkEvents: [], errorName: error.name, errorMessage: message });
614
- });
615
- worker.on("exit", (code) => {
616
- if (!settled && code !== 0) {
617
- finish({ status: "error", stdout: "", stderr: `worker exited with code ${code}`, exitCode: code, rawStdoutBytes: 0, rawStderrBytes: 0, truncated: false, outputFiles: [], networkEvents: [] });
618
- }
629
+ const timer = setTimeout(() => {
630
+ if (settled) return;
631
+ finish({
632
+ status: "timed_out",
633
+ stdout: "",
634
+ stderr: "",
635
+ exitCode: null,
636
+ rawStdoutBytes: 0,
637
+ rawStderrBytes: 0,
638
+ stdoutBytes: 0,
639
+ stderrBytes: 0,
640
+ outputBytes: 0,
641
+ truncated: false,
642
+ outputFiles: [],
643
+ networkEvents: [],
644
+ });
645
+ void worker.terminate();
646
+ }, options.timeoutMs);
647
+ worker.on("message", (message) => finish(message));
648
+ worker.on("error", (error) => {
649
+ const message = errorMessage(error);
650
+ finish({
651
+ status: "error",
652
+ stdout: "",
653
+ stderr: message,
654
+ exitCode: null,
655
+ rawStdoutBytes: 0,
656
+ rawStderrBytes: Buffer.byteLength(message, "utf8"),
657
+ truncated: false,
658
+ outputFiles: [],
659
+ networkEvents: [],
660
+ errorName: error.name,
661
+ errorMessage: message,
662
+ });
663
+ });
664
+ worker.on("exit", (code) => {
665
+ if (!settled && code !== 0) {
666
+ finish({
667
+ status: "error",
668
+ stdout: "",
669
+ stderr: `worker exited with code ${code}`,
670
+ exitCode: code,
671
+ rawStdoutBytes: 0,
672
+ rawStderrBytes: 0,
673
+ truncated: false,
674
+ outputFiles: [],
675
+ networkEvents: [],
619
676
  });
677
+ }
620
678
  });
679
+ });
621
680
  }
622
681
  function mergeWorkerResult(result, external) {
623
- let stdout = "";
624
- let stderr = "";
625
- let truncated = Boolean(result.truncated || external.externalTruncated);
626
- const append = (stream, value) => {
627
- const currentBytes = Buffer.byteLength(stdout, "utf8") + Buffer.byteLength(stderr, "utf8");
628
- const remaining = external.outputBytes - currentBytes;
629
- if (remaining <= 0) {
630
- truncated = truncated || Buffer.byteLength(value, "utf8") > 0;
631
- return;
632
- }
633
- const buffer = Buffer.from(value, "utf8");
634
- const nextText = buffer.byteLength > remaining ? buffer.subarray(0, remaining).toString("utf8") : value;
635
- if (buffer.byteLength > remaining)
636
- truncated = true;
637
- if (stream === "stderr")
638
- stderr += nextText;
639
- else
640
- stdout += nextText;
641
- };
642
- append("stdout", external.externalStdout);
643
- append("stderr", external.externalStderr);
644
- append("stdout", result.stdout ?? "");
645
- append("stderr", result.stderr ?? "");
646
- const rawStdoutBytes = (result.rawStdoutBytes ?? 0) + external.externalRawStdoutBytes;
647
- const rawStderrBytes = (result.rawStderrBytes ?? 0) + external.externalRawStderrBytes;
648
- const merged = {
649
- status: result.status ?? "error",
650
- stdout,
651
- stderr,
652
- rawStdoutBytes,
653
- rawStderrBytes,
654
- stdoutBytes: Buffer.byteLength(stdout, "utf8"),
655
- stderrBytes: Buffer.byteLength(stderr, "utf8"),
656
- outputBytes: Buffer.byteLength(stdout, "utf8") + Buffer.byteLength(stderr, "utf8"),
657
- truncated,
658
- exitCode: result.exitCode ?? null,
659
- durationMs: result.durationMs ?? 0,
660
- outputFiles: result.outputFiles ?? [],
661
- networkEvents: result.networkEvents ?? [],
662
- };
663
- if (result.errorName !== undefined) {
664
- merged.errorName = result.errorName;
665
- }
666
- if (result.errorMessage !== undefined) {
667
- merged.errorMessage = result.errorMessage;
668
- }
669
- return merged;
682
+ let stdout = "";
683
+ let stderr = "";
684
+ let truncated = Boolean(result.truncated || external.externalTruncated);
685
+ const append = (stream, value) => {
686
+ const currentBytes = Buffer.byteLength(stdout, "utf8") + Buffer.byteLength(stderr, "utf8");
687
+ const remaining = external.outputBytes - currentBytes;
688
+ if (remaining <= 0) {
689
+ truncated = truncated || Buffer.byteLength(value, "utf8") > 0;
690
+ return;
691
+ }
692
+ const buffer = Buffer.from(value, "utf8");
693
+ const nextText = buffer.byteLength > remaining ? buffer.subarray(0, remaining).toString("utf8") : value;
694
+ if (buffer.byteLength > remaining) truncated = true;
695
+ if (stream === "stderr") stderr += nextText;
696
+ else stdout += nextText;
697
+ };
698
+ append("stdout", external.externalStdout);
699
+ append("stderr", external.externalStderr);
700
+ append("stdout", result.stdout ?? "");
701
+ append("stderr", result.stderr ?? "");
702
+ const rawStdoutBytes = (result.rawStdoutBytes ?? 0) + external.externalRawStdoutBytes;
703
+ const rawStderrBytes = (result.rawStderrBytes ?? 0) + external.externalRawStderrBytes;
704
+ const merged = {
705
+ status: result.status ?? "error",
706
+ stdout,
707
+ stderr,
708
+ rawStdoutBytes,
709
+ rawStderrBytes,
710
+ stdoutBytes: Buffer.byteLength(stdout, "utf8"),
711
+ stderrBytes: Buffer.byteLength(stderr, "utf8"),
712
+ outputBytes: Buffer.byteLength(stdout, "utf8") + Buffer.byteLength(stderr, "utf8"),
713
+ truncated,
714
+ exitCode: result.exitCode ?? null,
715
+ durationMs: result.durationMs ?? 0,
716
+ outputFiles: result.outputFiles ?? [],
717
+ networkEvents: result.networkEvents ?? [],
718
+ };
719
+ if (result.errorName !== undefined) {
720
+ merged.errorName = result.errorName;
721
+ }
722
+ if (result.errorMessage !== undefined) {
723
+ merged.errorMessage = result.errorMessage;
724
+ }
725
+ return merged;
670
726
  }
671
727
  function eryxRunToExecutionResult(run) {
672
- if (run.status === "timed_out") {
673
- return {
674
- status: "timed_out",
675
- stdout: run.stdout,
676
- stderr: run.stderr,
677
- outputFiles: [],
678
- exitCode: null,
679
- durationMs: run.durationMs,
680
- reason: "Eryx Python execution exceeded timeoutMs.",
681
- };
682
- }
683
- if (run.truncated || run.status === "output_limit_exceeded") {
684
- return {
685
- status: "failed",
686
- stdout: run.stdout,
687
- stderr: run.stderr,
688
- outputFiles: [],
689
- exitCode: run.exitCode,
690
- durationMs: run.durationMs,
691
- reason: "Eryx Python execution exceeded maxOutputBytes.",
692
- };
693
- }
694
- if (run.status === "error") {
695
- return {
696
- status: "failed",
697
- stdout: run.stdout,
698
- stderr: run.stderr || run.errorMessage || "Eryx Python execution failed.",
699
- outputFiles: [],
700
- exitCode: run.exitCode,
701
- durationMs: run.durationMs,
702
- reason: "Eryx Python execution failed.",
703
- };
704
- }
728
+ if (run.status === "timed_out") {
705
729
  return {
706
- status: "success",
707
- stdout: run.stdout,
708
- stderr: run.stderr,
709
- outputFiles: [],
710
- exitCode: 0,
711
- durationMs: run.durationMs,
730
+ status: "timed_out",
731
+ stdout: run.stdout,
732
+ stderr: run.stderr,
733
+ outputFiles: [],
734
+ exitCode: null,
735
+ durationMs: run.durationMs,
736
+ reason: "Eryx Python execution exceeded timeoutMs.",
737
+ };
738
+ }
739
+ if (run.truncated || run.status === "output_limit_exceeded") {
740
+ return {
741
+ status: "failed",
742
+ stdout: run.stdout,
743
+ stderr: run.stderr,
744
+ outputFiles: [],
745
+ exitCode: run.exitCode,
746
+ durationMs: run.durationMs,
747
+ reason: "Eryx Python execution exceeded maxOutputBytes.",
712
748
  };
749
+ }
750
+ if (run.status === "error") {
751
+ return {
752
+ status: "failed",
753
+ stdout: run.stdout,
754
+ stderr: run.stderr || run.errorMessage || "Eryx Python execution failed.",
755
+ outputFiles: [],
756
+ exitCode: run.exitCode,
757
+ durationMs: run.durationMs,
758
+ reason: "Eryx Python execution failed.",
759
+ };
760
+ }
761
+ return {
762
+ status: "success",
763
+ stdout: run.stdout,
764
+ stderr: run.stderr,
765
+ outputFiles: [],
766
+ exitCode: 0,
767
+ durationMs: run.durationMs,
768
+ };
713
769
  }
714
770
  function assessEryxProof(proof, run, timeoutMs, outputBytes) {
715
- const combined = `${run.stdout ?? ""}\n${run.stderr ?? ""}\n${run.errorMessage ?? ""}`;
716
- switch (proof) {
717
- case "env_access_denied":
718
- return !combined.includes(SECRET_SENTINEL) && !combined.includes(HOST_HOME) && !combined.includes("process.env") && !/AWS_|GITHUB_|TOKEN|SECRET/i.test(combined);
719
- case "home_access_denied":
720
- return !combined.includes(HOST_HOME) && !/PRIVATE KEY|FREEFLOW_SANDBOX_SECRET/.test(combined);
721
- case "repo_access_denied":
722
- return !combined.includes("@hassangameryt/freeflow") && !combined.includes("@earendil-works/freeflow") && !combined.includes('"scripts"');
723
- case "vault_access_denied":
724
- return !combined.includes("ffout_") && !combined.includes("ffrec_");
725
- case "network_access_denied":
726
- return run.status !== "success" && networkDeniedByShim(run) && !combined.includes("Example Domain");
727
- case "input_read_only":
728
- return run.status !== "success" && !combined.includes("mutated");
729
- case "output_escape_denied":
730
- return !combined.includes("/etc/passwd") && run.outputFiles.length === 0;
731
- case "stdout_stderr_bounded":
732
- return run.status !== "error" && run.truncated && run.outputBytes <= outputBytes && run.rawStdoutBytes > outputBytes && run.rawStderrBytes > outputBytes;
733
- case "timeout_enforced":
734
- return run.status === "timed_out" && run.durationMs < timeoutMs * 5;
735
- default:
736
- return false;
737
- }
771
+ const combined = `${run.stdout ?? ""}\n${run.stderr ?? ""}\n${run.errorMessage ?? ""}`;
772
+ switch (proof) {
773
+ case "env_access_denied":
774
+ return (
775
+ !combined.includes(SECRET_SENTINEL) &&
776
+ !combined.includes(HOST_HOME) &&
777
+ !combined.includes("process.env") &&
778
+ !/AWS_|GITHUB_|TOKEN|SECRET/i.test(combined)
779
+ );
780
+ case "home_access_denied":
781
+ return !combined.includes(HOST_HOME) && !/PRIVATE KEY|FREEFLOW_SANDBOX_SECRET/.test(combined);
782
+ case "repo_access_denied":
783
+ return (
784
+ !combined.includes("@hassangameryt/freeflow") &&
785
+ !combined.includes("@earendil-works/freeflow") &&
786
+ !combined.includes('"scripts"')
787
+ );
788
+ case "vault_access_denied":
789
+ return !combined.includes("ffout_") && !combined.includes("ffrec_");
790
+ case "network_access_denied":
791
+ return run.status !== "success" && networkDeniedByShim(run) && !combined.includes("Example Domain");
792
+ case "input_read_only":
793
+ return run.status !== "success" && !combined.includes("mutated");
794
+ case "output_escape_denied":
795
+ return !combined.includes("/etc/passwd") && run.outputFiles.length === 0;
796
+ case "stdout_stderr_bounded":
797
+ return (
798
+ run.status !== "error" &&
799
+ run.truncated &&
800
+ run.outputBytes <= outputBytes &&
801
+ run.rawStdoutBytes > outputBytes &&
802
+ run.rawStderrBytes > outputBytes
803
+ );
804
+ case "timeout_enforced":
805
+ return run.status === "timed_out" && run.durationMs < timeoutMs * 5;
806
+ default:
807
+ return false;
808
+ }
738
809
  }
739
810
  function networkDeniedByShim(run) {
740
- return run.networkEvents.some((event) => event?.decision === "not-permitted" && (event?.kind === "tcp" || event?.kind === "tls"));
811
+ return run.networkEvents.some(
812
+ (event) => event?.decision === "not-permitted" && (event?.kind === "tcp" || event?.kind === "tls"),
813
+ );
741
814
  }
742
815
  function pythonPrelude(inputs) {
743
- const encodedInputs = JSON.stringify(inputs).replaceAll("</", "<\\/");
744
- return [
745
- "# Freeflow injected input/output helpers.",
746
- "import json as __freeflow_json",
747
- `__freeflow_sources = __freeflow_json.loads(${JSON.stringify(encodedInputs)})`,
748
- "sources = dict(__freeflow_sources)",
749
- "def read_text(alias):",
750
- " return __freeflow_sources[alias]",
751
- "def write_text(text):",
752
- " print(str(text), end='')",
753
- "",
754
- ].join("\n");
816
+ const encodedInputs = JSON.stringify(inputs).replaceAll("</", "<\\/");
817
+ return [
818
+ "# Freeflow injected input/output helpers.",
819
+ "import json as __freeflow_json",
820
+ `__freeflow_sources = __freeflow_json.loads(${JSON.stringify(encodedInputs)})`,
821
+ "sources = dict(__freeflow_sources)",
822
+ "def read_text(alias):",
823
+ " return __freeflow_sources[alias]",
824
+ "def write_text(text):",
825
+ " print(str(text), end='')",
826
+ "",
827
+ ].join("\n");
755
828
  }
756
829
  function cloneProbeResult(result) {
757
- const cloned = {
758
- ...result,
759
- passedProofs: [...result.passedProofs],
760
- failedProofs: [...result.failedProofs],
761
- };
762
- if (result.runtime !== undefined) {
763
- cloned.runtime = { ...result.runtime };
764
- }
765
- return cloned;
830
+ const cloned = {
831
+ ...result,
832
+ passedProofs: [...result.passedProofs],
833
+ failedProofs: [...result.failedProofs],
834
+ };
835
+ if (result.runtime !== undefined) {
836
+ cloned.runtime = { ...result.runtime };
837
+ }
838
+ return cloned;
766
839
  }
767
840
  async function runEryxChildCli(argv) {
768
- const requestPath = argv[0];
769
- const responsePath = argv[1];
770
- if (!requestPath || !responsePath) {
771
- throw new Error("eryx-python child mode requires request and response paths.");
772
- }
773
- const payload = JSON.parse(await readFile(requestPath, "utf8"));
774
- let response;
775
- try {
776
- const adapter = await createEryxPythonSandboxAdapter({ packageRoot: payload.packageRoot });
777
- if (payload.kind === "probe") {
778
- response = { ok: true, result: await adapter.probe("python", payload.config) };
779
- }
780
- else {
781
- response = { ok: true, result: await adapter.execute(payload.request) };
782
- }
783
- }
784
- catch (error) {
785
- response = { ok: false, message: errorMessage(error) };
786
- }
787
- await writeFile(responsePath, JSON.stringify(response), "utf8");
841
+ const requestPath = argv[0];
842
+ const responsePath = argv[1];
843
+ if (!requestPath || !responsePath) {
844
+ throw new Error("eryx-python child mode requires request and response paths.");
845
+ }
846
+ const payload = JSON.parse(await readFile(requestPath, "utf8"));
847
+ let response;
848
+ try {
849
+ const adapter = await createEryxPythonSandboxAdapter({ packageRoot: payload.packageRoot });
850
+ if (payload.kind === "probe") {
851
+ response = { ok: true, result: await adapter.probe("python", payload.config) };
852
+ } else {
853
+ response = { ok: true, result: await adapter.execute(payload.request) };
854
+ }
855
+ } catch (error) {
856
+ response = { ok: false, message: errorMessage(error) };
857
+ }
858
+ await writeFile(responsePath, JSON.stringify(response), "utf8");
788
859
  }
789
860
  function errorMessage(error) {
790
- return error instanceof Error ? error.message : String(error);
861
+ return error instanceof Error ? error.message : String(error);
791
862
  }
792
863
  if (process.argv[2] === ERYX_CHILD_MODE_ARG) {
793
- runEryxChildCli(process.argv.slice(3)).catch((error) => {
794
- console.error(errorMessage(error));
795
- process.exit(1);
796
- });
864
+ runEryxChildCli(process.argv.slice(3)).catch((error) => {
865
+ console.error(errorMessage(error));
866
+ process.exit(1);
867
+ });
797
868
  }