failproofai 1.0.3 → 1.0.4-beta.2

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 (251) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +5 -5
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/invite/route_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
  26. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/audit/status/route_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/login-request/route_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/login-verify/route_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  41. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +37 -4
  42. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  43. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/index.html +1 -1
  46. package/.next/standalone/.next/server/app/index.rsc +15 -15
  47. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  48. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  49. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  50. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  52. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  56. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  63. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  64. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  65. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  68. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  69. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  72. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  73. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{[externals]__0-9ti7z._.js → [externals]__1lh7m5d._.js} +1 -1
  76. package/.next/standalone/.next/server/chunks/{[externals]__0u3wrvq._.js → [externals]__1rqkg_y._.js} +1 -1
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1adacul._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/{_1-akg6w._.js → _08w6xzm._.js} +2 -2
  80. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  82. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +4 -4
  83. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +1 -1
  84. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
  85. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
  86. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rgu2r3._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  98. package/.next/standalone/.next/server/chunks/ssr/_0-oij9d._.js +23 -0
  99. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/ssr/_0l2hi_d._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/ssr/_0oq1dh6._.js +3 -0
  102. package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +47 -13
  103. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
  105. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -69
  106. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_rerun-button_tsx_0blihgw._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/ssr/node_modules_13n822a._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -2
  112. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  115. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  116. package/.next/standalone/.next/server/pages/404.html +1 -1
  117. package/.next/standalone/.next/server/pages/500.html +1 -1
  118. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.json +54 -21
  120. package/.next/standalone/.next/static/chunks/010bv1w6j171t.js +1 -0
  121. package/.next/standalone/.next/static/chunks/04r6ch8uf_n8m.js +1 -0
  122. package/.next/standalone/.next/static/chunks/{29-iqnp9v_axt.css → 0o-hh5_turzlz.css} +1 -1
  123. package/.next/standalone/.next/static/chunks/{40nr6ehj4p3cw.css → 0qmsunv04x4na.css} +1 -1
  124. package/.next/standalone/.next/static/chunks/{0ollg-nnu3t3e.js → 0wz8yftk18ts2.js} +1 -1
  125. package/.next/standalone/.next/static/chunks/0zebh1n9jkfbt.js +1 -0
  126. package/.next/standalone/.next/static/chunks/1eyl7fzkmnkf_.js +1 -0
  127. package/.next/standalone/.next/static/chunks/1pb1oztsbwcss.js +1 -0
  128. package/.next/standalone/.next/static/chunks/{1-_zkmnm-jwei.js → 2aquitk72k2op.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/2bi_1y0a_smt7.js +6 -0
  130. package/.next/standalone/.next/static/chunks/{42yfkhekx440s.js → 2ej3b8gk5ittu.js} +1 -1
  131. package/.next/standalone/.next/static/chunks/{354-n7p7labpn.js → 2zafgs90r_leq.js} +1 -1
  132. package/.next/standalone/.next/static/chunks/{2xm5mj1d21b4n.js → 32spub4wqjem-.js} +1 -1
  133. package/.next/standalone/.next/static/chunks/{1a6u7l3giejch.js → 3m4upvybtrexd.js} +1 -1
  134. package/.next/standalone/.next/static/chunks/{2k9f4tyv04809.css → 3uyhmm01g64k4.css} +1 -0
  135. package/.next/standalone/.next/static/chunks/{turbopack-2x-o099q64i8h.js → turbopack-3s3c-u_u_l0u9.js} +1 -1
  136. package/.next/standalone/.opencode/plugins/failproofai.mjs +51 -27
  137. package/.next/standalone/app/actions/get-leaks.ts +100 -0
  138. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +112 -33
  139. package/.next/standalone/app/audit/_components/audit-poster.tsx +29 -10
  140. package/.next/standalone/app/audit/_components/come-back-better-section.tsx +6 -1
  141. package/.next/standalone/app/audit/_components/empty-state.tsx +4 -1
  142. package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +19 -5
  143. package/.next/standalone/app/audit/_components/leak-section.tsx +179 -0
  144. package/.next/standalone/app/audit/_components/share-templates.ts +110 -44
  145. package/.next/standalone/app/audit/audit-styles.css +114 -1
  146. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +26 -3
  147. package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +31 -8
  148. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +1 -0
  149. package/.next/standalone/fp-cloud-cli/pyproject.toml +9 -2
  150. package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +54 -0
  151. package/.next/standalone/fp-cloud-cli/uv.lock +9 -12
  152. package/.next/standalone/lib/auth/api-server-client.ts +28 -0
  153. package/.next/standalone/lib/claude-sessions.ts +101 -27
  154. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  155. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  156. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
  157. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
  158. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +1 -1
  159. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +5 -5
  160. package/.next/standalone/node_modules/next/dist/experimental/testmode/fetch.js +10 -2
  161. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  162. package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeScriptCli.js +2 -2
  163. package/.next/standalone/node_modules/next/dist/lib/verify-typescript-setup.js +3 -1
  164. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  165. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  166. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  167. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  168. package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js +17 -4
  169. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  170. package/.next/standalone/node_modules/next/dist/shared/lib/router/utils/escape-path-delimiters.js +1 -1
  171. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  172. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  173. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  174. package/.next/standalone/node_modules/next/package.json +11 -11
  175. package/.next/standalone/package.json +14 -13
  176. package/.next/standalone/sdk/python/CHANGELOG.md +155 -0
  177. package/.next/standalone/sdk/python/README.md +8 -0
  178. package/.next/standalone/sdk/python/examples/evaluator_worker.py +121 -0
  179. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
  180. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/__init__.py +101 -0
  181. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/__main__.py +49 -0
  182. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/_sandbox_runner.py +63 -0
  183. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/authoring.py +404 -0
  184. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/client.py +299 -0
  185. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/protocol.py +754 -0
  186. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/runtime.py +936 -0
  187. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/source.py +684 -0
  188. package/.next/standalone/sdk/python/tests/fixtures/evaluator_v2/README.md +28 -0
  189. package/.next/standalone/sdk/python/tests/fixtures/evaluator_v2/contract.json +252 -0
  190. package/.next/standalone/sdk/python/tests/test_evaluator_authoring.py +124 -0
  191. package/.next/standalone/sdk/python/tests/test_evaluator_client.py +253 -0
  192. package/.next/standalone/sdk/python/tests/test_evaluator_example.py +35 -0
  193. package/.next/standalone/sdk/python/tests/test_evaluator_http_e2e.py +636 -0
  194. package/.next/standalone/sdk/python/tests/test_evaluator_main.py +47 -0
  195. package/.next/standalone/sdk/python/tests/test_evaluator_protocol.py +246 -0
  196. package/.next/standalone/sdk/python/tests/test_evaluator_review_fixes.py +164 -0
  197. package/.next/standalone/sdk/python/tests/test_evaluator_runtime.py +1103 -0
  198. package/.next/standalone/sdk/python/tests/test_evaluator_source.py +430 -0
  199. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +17 -0
  200. package/.next/standalone/sdk/python/uv.lock +29 -29
  201. package/.next/standalone/server.js +1 -1
  202. package/README.md +13 -58
  203. package/dist/cli.mjs +5368 -8756
  204. package/dist/worker.mjs +539 -312
  205. package/lib/auth/api-server-client.ts +28 -0
  206. package/lib/claude-sessions.ts +101 -27
  207. package/package.json +14 -13
  208. package/pi-extension/index.ts +42 -4
  209. package/scripts/changelog-open.py +115 -0
  210. package/src/audit/cli.ts +134 -0
  211. package/src/audit/desktop-notify.ts +420 -0
  212. package/src/audit/harm-report.ts +101 -0
  213. package/src/audit/index.ts +141 -13
  214. package/src/audit/leak-fingerprint.ts +200 -0
  215. package/src/audit/leak-notice.ts +161 -0
  216. package/src/audit/leak-record.ts +232 -0
  217. package/src/audit/leak-scan.ts +292 -0
  218. package/src/audit/leak-store.ts +217 -0
  219. package/src/audit/macos-notifier.ts +310 -0
  220. package/src/audit/redact-example.ts +266 -14
  221. package/src/audit/report-harm.ts +12 -1
  222. package/src/audit/report.ts +6 -3
  223. package/src/audit/schedule-cli.ts +37 -0
  224. package/src/audit/scoring.ts +49 -0
  225. package/src/audit/types.ts +41 -0
  226. package/src/hooks/builtin-policies.ts +67 -2
  227. package/src/hooks/configure-wizard.ts +20 -0
  228. package/src/hooks/fp-config.ts +71 -11
  229. package/src/hooks/fp-home.ts +27 -0
  230. package/src/hooks/handler.ts +59 -1
  231. package/src/hooks/integrations.ts +47 -13
  232. package/src/hooks/notice.ts +155 -0
  233. package/src/hooks/uninstall-cli.ts +15 -0
  234. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1b5jzxr._.js +0 -3
  235. package/.next/standalone/.next/server/chunks/ssr/_0j6gd_k._.js +0 -23
  236. package/.next/standalone/.next/server/chunks/ssr/_0v8eebd._.js +0 -3
  237. package/.next/standalone/.next/server/chunks/ssr/_1ylae7o._.js +0 -3
  238. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +0 -3
  239. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1ao30b1.js +0 -3
  240. package/.next/standalone/.next/static/chunks/03slu0c8_71y7.js +0 -1
  241. package/.next/standalone/.next/static/chunks/0nm11ysn0153h.js +0 -1
  242. package/.next/standalone/.next/static/chunks/0u64yey446k4f.css +0 -1
  243. package/.next/standalone/.next/static/chunks/1r9676mkvihto.js +0 -1
  244. package/.next/standalone/.next/static/chunks/30pct5s734jua.js +0 -6
  245. package/.next/standalone/.next/static/chunks/3pibxnbhjza7n.js +0 -69
  246. package/.next/standalone/.next/static/chunks/3qfoeqhy5l10x.js +0 -1
  247. package/.next/standalone/.next/static/chunks/3zkg2s2vzxc3d.js +0 -1
  248. package/.next/standalone/.next/static/chunks/41b5ptaocvi_l.js +0 -1
  249. /package/.next/standalone/.next/static/{JBYgkXkA1PS48m9P_hKNw → aKNv4Kmv98Xpwns0Xa-C-}/_buildManifest.js +0 -0
  250. /package/.next/standalone/.next/static/{JBYgkXkA1PS48m9P_hKNw → aKNv4Kmv98Xpwns0Xa-C-}/_clientMiddlewareManifest.js +0 -0
  251. /package/.next/standalone/.next/static/{JBYgkXkA1PS48m9P_hKNw → aKNv4Kmv98Xpwns0Xa-C-}/_ssgManifest.js +0 -0
@@ -83,11 +83,19 @@ function buildResponse(proxyResponse) {
83
83
  headers: new Headers(headers)
84
84
  });
85
85
  }
86
+ function passthroughFetch(originalFetch, request) {
87
+ // Mark the request so the ClientRequest interception in `httpget.ts` sends it
88
+ // to the real server instead of intercepting it again. @mswjs/interceptors
89
+ // intercepts at the TCP level, so an unmarked passthrough would re-enter the
90
+ // interception listener from within itself, recursing indefinitely.
91
+ request.headers.set('next-test-internal', '1');
92
+ return originalFetch(request);
93
+ }
86
94
  async function handleFetch(originalFetch, request) {
87
95
  const testInfo = (0, _context.getTestReqInfo)(request, reader);
88
96
  if (!testInfo) {
89
97
  // Passthrough non-test requests.
90
- return originalFetch(request);
98
+ return passthroughFetch(originalFetch, request);
91
99
  }
92
100
  const { testData, proxyPort } = testInfo;
93
101
  const proxyRequest = await buildProxyRequest(testData, request);
@@ -118,7 +126,7 @@ async function handleFetch(originalFetch, request) {
118
126
  const { api } = proxyResponse;
119
127
  switch(api){
120
128
  case 'continue':
121
- return originalFetch(request);
129
+ return passthroughFetch(originalFetch, request);
122
130
  case 'abort':
123
131
  case 'unhandled':
124
132
  throw Object.defineProperty(new Error(`Proxy request aborted [${request.method} ${request.url}]`), "__NEXT_ERROR_CODE", {
@@ -72,7 +72,7 @@ async function fetchPkgInfo(pkg) {
72
72
  });
73
73
  }
74
74
  const data = await res.json();
75
- const versionData = data.versions["16.3.2"];
75
+ const versionData = data.versions["16.3.4"];
76
76
  return {
77
77
  os: versionData.os,
78
78
  cpu: versionData.cpu,
@@ -100,7 +100,7 @@ async function patchIncorrectLockfile(dir) {
100
100
  const expectedSwcPkgs = Object.keys(_packagejson.optionalDependencies || {}).filter((pkg)=>pkg.startsWith('@next/swc-'));
101
101
  const patchDependency = (pkg, pkgData)=>{
102
102
  lockfileParsed.dependencies[pkg] = {
103
- version: "16.3.2",
103
+ version: "16.3.4",
104
104
  resolved: pkgData.tarball,
105
105
  integrity: pkgData.integrity,
106
106
  optional: true
@@ -108,7 +108,7 @@ async function patchIncorrectLockfile(dir) {
108
108
  };
109
109
  const patchPackage = (pkg, pkgData)=>{
110
110
  lockfileParsed.packages[pkg] = {
111
- version: "16.3.2",
111
+ version: "16.3.4",
112
112
  resolved: pkgData.tarball,
113
113
  integrity: pkgData.integrity,
114
114
  cpu: pkgData.cpu,
@@ -44,7 +44,7 @@ function _interop_require_default(obj) {
44
44
  };
45
45
  }
46
46
  function getTypeScriptPackageInfo(baseDir) {
47
- var _packageJson_bin;
47
+ var _packageJson_bin, _Object_entries_find;
48
48
  let packageJsonPath;
49
49
  try {
50
50
  packageJsonPath = (0, _resolvefrom.resolveFrom)(baseDir, 'typescript/package.json');
@@ -54,7 +54,7 @@ function getTypeScriptPackageInfo(baseDir) {
54
54
  const packageJson = JSON.parse((0, _nodefs.readFileSync)(packageJsonPath, 'utf8'));
55
55
  const packageDir = _nodepath.default.dirname(packageJsonPath);
56
56
  const apiPath = _nodepath.default.join(packageDir, 'lib', 'typescript.js');
57
- const tscBin = typeof packageJson.bin === 'string' ? packageJson.bin : (_packageJson_bin = packageJson.bin) == null ? void 0 : _packageJson_bin.tsc;
57
+ const tscBin = typeof packageJson.bin === 'string' ? packageJson.bin : ((_packageJson_bin = packageJson.bin) == null ? void 0 : _packageJson_bin.tsc) ?? ((_Object_entries_find = Object.entries(packageJson.bin ?? {}).find(([name])=>/^tsc\d+$/.test(name))) == null ? void 0 : _Object_entries_find[1]);
58
58
  const tscBinPath = tscBin ? _nodepath.default.resolve(packageDir, tscBin) : undefined;
59
59
  let tscPath = tscBinPath;
60
60
  if (tscBinPath && (0, _nodefs.existsSync)(tscBinPath) && packageJson.type === 'module' && _nodepath.default.extname(tscBinPath) === '') {
@@ -86,7 +86,9 @@ const typescriptApiPackage = {
86
86
  exportsRestrict: true
87
87
  };
88
88
  const typescriptCliPackage = {
89
- file: 'typescript/bin/tsc',
89
+ // The CLI path is resolved from the package's bin metadata after this initial
90
+ // package-presence check, since aliased TypeScript packages may rename it.
91
+ file: 'typescript/package.json',
90
92
  pkg: 'typescript',
91
93
  exportsRestrict: true
92
94
  };
@@ -1305,7 +1305,7 @@ async function applyModifyConfig(config, phase, silent, dir) {
1305
1305
  }
1306
1306
  config = await adapterMod.modifyConfig(config, {
1307
1307
  phase,
1308
- nextVersion: "16.3.2",
1308
+ nextVersion: "16.3.4",
1309
1309
  projectDir: dir
1310
1310
  });
1311
1311
  }
@@ -302,7 +302,7 @@ async function createHotReloaderTurbopack(opts, serverFields, distDir, resetFetc
302
302
  }
303
303
  const hasRewrites = opts.fsChecker.rewrites.afterFiles.length > 0 || opts.fsChecker.rewrites.beforeFiles.length > 0 || opts.fsChecker.rewrites.fallback.length > 0;
304
304
  const hotReloaderSpan = (0, _trace.trace)('hot-reloader', undefined, {
305
- version: "16.3.2"
305
+ version: "16.3.4"
306
306
  });
307
307
  // Ensure the hotReloaderSpan is flushed immediately as it's the parentSpan for all processing
308
308
  // of the current `next dev` invocation.
@@ -362,7 +362,7 @@ async function createHotReloaderTurbopack(opts, serverFields, distDir, resetFetc
362
362
  writeRoutesHashesManifest: false,
363
363
  currentNodeJsVersion,
364
364
  isPersistentCachingEnabled: (0, _utils2.isFileSystemCacheEnabledForDev)(opts.nextConfig),
365
- nextVersion: "16.3.2",
365
+ nextVersion: "16.3.4",
366
366
  serverHmr: serverFastRefresh
367
367
  }, {
368
368
  turbopackMemoryEviction: opts.nextConfig.experimental.turbopackMemoryEvictionMode,
@@ -234,7 +234,7 @@ class HotReloaderWebpack {
234
234
  this.previewProps = previewProps;
235
235
  this.rewrites = rewrites;
236
236
  this.hotReloaderSpan = (0, _trace.trace)('hot-reloader', undefined, {
237
- version: "16.3.2"
237
+ version: "16.3.4"
238
238
  });
239
239
  // Ensure the hotReloaderSpan is flushed immediately as it's the parentSpan for all processing
240
240
  // of the current `next dev` invocation.
@@ -79,7 +79,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
79
79
  }
80
80
  function logStartInfo({ networkUrl, appUrl, envInfo, logBundler }) {
81
81
  const versionSuffix = logBundler ? ` (${(0, _bundler.bundlerName)((0, _bundler.getBundlerFromEnv)())})` : '';
82
- _log.bootstrap(`${(0, _picocolors.bold)((0, _picocolors.purple)(`${_log.prefixes.ready} Next.js ${"16.3.2"}`))}${versionSuffix}`);
82
+ _log.bootstrap(`${(0, _picocolors.bold)((0, _picocolors.purple)(`${_log.prefixes.ready} Next.js ${"16.3.4"}`))}${versionSuffix}`);
83
83
  if (appUrl) {
84
84
  _log.bootstrap(`- Local: ${appUrl}`);
85
85
  }
@@ -310,18 +310,22 @@ class FileSystemCache {
310
310
  // Wait for all FS operations to complete.
311
311
  await writer.wait();
312
312
  }
313
- getFilePath(pathname, kind) {
313
+ getFilePath(key, kind) {
314
+ let rootDir;
314
315
  switch(kind){
315
316
  case _responsecache.IncrementalCacheKind.FETCH:
316
317
  // we store in .next/cache/fetch-cache so it can be persisted
317
318
  // across deploys
318
- return _path.default.join(this.serverDistDir, '..', 'cache', 'fetch-cache', pathname);
319
+ rootDir = _path.default.join(this.serverDistDir, '..', 'cache', 'fetch-cache');
320
+ break;
319
321
  case _responsecache.IncrementalCacheKind.PAGES:
320
- return _path.default.join(this.serverDistDir, 'pages', pathname);
322
+ rootDir = _path.default.join(this.serverDistDir, 'pages');
323
+ break;
321
324
  case _responsecache.IncrementalCacheKind.IMAGE:
322
325
  case _responsecache.IncrementalCacheKind.APP_PAGE:
323
326
  case _responsecache.IncrementalCacheKind.APP_ROUTE:
324
- return _path.default.join(this.serverDistDir, 'app', pathname);
327
+ rootDir = _path.default.join(this.serverDistDir, 'app');
328
+ break;
325
329
  default:
326
330
  throw Object.defineProperty(new Error(`Unexpected file path kind: ${kind}`), "__NEXT_ERROR_CODE", {
327
331
  value: "E479",
@@ -329,6 +333,15 @@ class FileSystemCache {
329
333
  configurable: true
330
334
  });
331
335
  }
336
+ const filePath = _path.default.join(rootDir, key);
337
+ if (!(filePath.startsWith(rootDir + _path.default.sep) || filePath === rootDir)) {
338
+ throw Object.defineProperty(new Error(`Invalid file path: ${filePath}`), "__NEXT_ERROR_CODE", {
339
+ value: "E1468",
340
+ enumerable: false,
341
+ configurable: true
342
+ });
343
+ }
344
+ return filePath;
332
345
  }
333
346
  }
334
347
 
@@ -177,7 +177,7 @@ async function getRequestHandlers({ dir, port, isDev, onDevServerCleanup, server
177
177
  async function startServer(serverOptions) {
178
178
  const { dir, isDev, hostname, minimalMode, allowRetry, keepAliveTimeout, selfSignedCertificate, serverFastRefresh } = serverOptions;
179
179
  let { port } = serverOptions;
180
- process.title = `next-server (v${"16.3.2"})`;
180
+ process.title = `next-server (v${"16.3.4"})`;
181
181
  let handlersReady = ()=>{};
182
182
  let handlersError = ()=>{};
183
183
  let handlersPromise = new Promise((resolve, reject)=>{
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "default", {
10
10
  }
11
11
  });
12
12
  function escapePathDelimiters(segment, escapeEncoded) {
13
- return segment.replace(new RegExp(`([/#?]${escapeEncoded ? '|%(2f|23|3f|5c)' : ''})`, 'gi'), (char)=>encodeURIComponent(char));
13
+ return segment.replace(new RegExp(`([/#?\\\\]${escapeEncoded ? '|%(2f|23|3f|5c)' : ''})`, 'gi'), (char)=>encodeURIComponent(char));
14
14
  }
15
15
 
16
16
  //# sourceMappingURL=escape-path-delimiters.js.map
@@ -82,7 +82,7 @@ async function getAnonymousMeta() {
82
82
  isWsl: _iswsl.default,
83
83
  isCI: _ciinfo.isCI,
84
84
  ciName: _ciinfo.isCI && _ciinfo.name || null,
85
- nextVersion: "16.3.2",
85
+ nextVersion: "16.3.4",
86
86
  agentName: await (0, _agentname.getAgentName)()
87
87
  };
88
88
  return traits;
@@ -38,7 +38,7 @@ async function eventSwcLoadFailure(event) {
38
38
  telemetry.record({
39
39
  eventName: EVENT_PLUGIN_PRESENT,
40
40
  payload: {
41
- nextVersion: "16.3.2",
41
+ nextVersion: "16.3.4",
42
42
  glibcVersion,
43
43
  installedSwcPackages,
44
44
  arch: process.arch,
@@ -12,12 +12,12 @@ const EVENT_VERSION = 'NEXT_CLI_SESSION_STARTED';
12
12
  function eventCliSession(nextConfig, event) {
13
13
  var _nextConfig_experimental, _nextConfig_experimental_staleTimes, _nextConfig_experimental_staleTimes1, _nextConfig_reactCompiler, _nextConfig_reactCompiler1;
14
14
  // This should be an invariant, if it fails our build tooling is broken.
15
- if (typeof "16.3.2" !== 'string') {
15
+ if (typeof "16.3.4" !== 'string') {
16
16
  return [];
17
17
  }
18
18
  const { images, i18n } = nextConfig || {};
19
19
  const payload = {
20
- nextVersion: "16.3.2",
20
+ nextVersion: "16.3.4",
21
21
  nodeVersion: process.version,
22
22
  cliCommand: event.cliCommand,
23
23
  isSrcDir: event.isSrcDir,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next",
3
- "version": "16.3.2",
3
+ "version": "16.3.4",
4
4
  "description": "The React Framework",
5
5
  "main": "./dist/server/next.js",
6
6
  "license": "MIT",
@@ -81,7 +81,7 @@
81
81
  "next": "./dist/bin/next"
82
82
  },
83
83
  "dependencies": {
84
- "@next/env": "16.3.2",
84
+ "@next/env": "16.3.4",
85
85
  "@swc/helpers": "0.5.23",
86
86
  "baseline-browser-mapping": "^2.9.19",
87
87
  "caniuse-lite": "^1.0.30001579",
@@ -111,15 +111,15 @@
111
111
  }
112
112
  },
113
113
  "optionalDependencies": {
114
- "sharp": "^0.35.3",
115
- "@next/swc-darwin-arm64": "16.3.2",
116
- "@next/swc-darwin-x64": "16.3.2",
117
- "@next/swc-linux-arm64-gnu": "16.3.2",
118
- "@next/swc-linux-arm64-musl": "16.3.2",
119
- "@next/swc-linux-x64-gnu": "16.3.2",
120
- "@next/swc-linux-x64-musl": "16.3.2",
121
- "@next/swc-win32-arm64-msvc": "16.3.2",
122
- "@next/swc-win32-x64-msvc": "16.3.2"
114
+ "sharp": "^0.35.4",
115
+ "@next/swc-darwin-arm64": "16.3.4",
116
+ "@next/swc-darwin-x64": "16.3.4",
117
+ "@next/swc-linux-arm64-gnu": "16.3.4",
118
+ "@next/swc-linux-arm64-musl": "16.3.4",
119
+ "@next/swc-linux-x64-gnu": "16.3.4",
120
+ "@next/swc-linux-x64-musl": "16.3.4",
121
+ "@next/swc-win32-arm64-msvc": "16.3.4",
122
+ "@next/swc-win32-x64-msvc": "16.3.4"
123
123
  },
124
124
  "keywords": [
125
125
  "react",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "1.0.3",
3
+ "version": "1.0.4-beta.2",
4
4
  "description": "Observability and enforcement for AI agent harnesses. 39 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
5
5
  "bin": {
6
6
  "failproofai": "./dist/cli.mjs",
@@ -80,14 +80,14 @@
80
80
  "access": "public"
81
81
  },
82
82
  "devDependencies": {
83
- "@anthropic-ai/sdk": "^0.120.0",
83
+ "@anthropic-ai/sdk": "^0.123.0",
84
84
  "@mdx-js/mdx": "^3.1.1",
85
85
  "@tailwindcss/postcss": "^4.3.1",
86
86
  "@tanstack/react-virtual": "^3.14.10",
87
87
  "@testing-library/jest-dom": "^7.0.0",
88
88
  "@testing-library/react": "^16.3.2",
89
89
  "@testing-library/user-event": "^14.6.5",
90
- "@types/node": "26.2.0",
90
+ "@types/node": "26.4.1",
91
91
  "@types/react": "19.2.18",
92
92
  "@types/react-dom": "^19.2.3",
93
93
  "@vitejs/plugin-react": "^6.1.0",
@@ -102,7 +102,7 @@
102
102
  "tailwind-merge": "^3.4.0",
103
103
  "tailwindcss": "^4.3.1",
104
104
  "typescript": "6.0.3",
105
- "vitest": "^4.1.11"
105
+ "vitest": "^5.0.0"
106
106
  },
107
107
  "dependencies": {
108
108
  "html-to-image": "^1.11.13",
@@ -117,18 +117,19 @@
117
117
  "vite": "8.0.16",
118
118
  "undici": "7.29.0",
119
119
  "brace-expansion": "5.0.9",
120
- "sharp": "0.35.0"
120
+ "sharp": "0.35.0",
121
+ "browserslist": "4.28.8"
121
122
  },
122
123
  "optionalDependencies": {
123
- "@failproofai/failproofaid-linux-x64": "1.0.3",
124
- "@failproofai/failproofaid-linux-arm64": "1.0.3",
125
- "@failproofai/failproofaid-darwin-x64": "1.0.3",
126
- "@failproofai/failproofaid-darwin-arm64": "1.0.3"
124
+ "@failproofai/failproofaid-linux-x64": "1.0.4-beta.2",
125
+ "@failproofai/failproofaid-linux-arm64": "1.0.4-beta.2",
126
+ "@failproofai/failproofaid-darwin-x64": "1.0.4-beta.2",
127
+ "@failproofai/failproofaid-darwin-arm64": "1.0.4-beta.2"
127
128
  },
128
129
  "failproofaidBinaries": {
129
- "linux-x64": "2a4164e88792f2cd8616868eb63a52011e110b8b13643e1082ad3af982730226",
130
- "linux-arm64": "c995f896183ba54b596535687b94bfd52efaa56736a36016d2de987bccdaa810",
131
- "darwin-x64": "a56c871ce0d460683a2e57cb6eed2f91a329c2f03889612fef62191fcb57868a",
132
- "darwin-arm64": "dab3246a917dc32869dfb36b5b682beaa87330c8cd2797027c9b9adc4084ceab"
130
+ "linux-x64": "3039575242ff240c68a79c4ebd4e0e35e865da99c6d8a46d1a17b2d7962cb47b",
131
+ "linux-arm64": "02fe993dca0faccb528c48472ca1d637274c562992ba7da1bc8d439103dbcc13",
132
+ "darwin-x64": "2be5a422007a773253611f24f2ad9e2a301f075392ed7bc2dc0f6354d3186696",
133
+ "darwin-arm64": "5882a4acd7317289346934290ac8277ca79edadb009e284c9fc0b23b74d321d7"
133
134
  }
134
135
  }
@@ -9,6 +9,13 @@ in `failproofai_sdk/_version.py` becomes that release's GitHub Release body. A
9
9
  release whose section is missing or empty is refused before anything is built —
10
10
  see `scripts/changelog-section.py`.
11
11
 
12
+ ## 0.0.1b3 — 2026-09-08
13
+
14
+ Open for the next release. `0.0.1b2` published on 2026-09-08 and the `bump` job
15
+ moved the version here automatically; nothing has landed against `0.0.1b3` yet.
16
+ Add entries as changes merge — this section becomes the GitHub Release body when
17
+ it ships.
18
+
12
19
  ## 0.0.1b2 — 2026-08-25
13
20
 
14
21
  Open for the next release. `0.0.1b1` published on 2026-08-24 and the `bump` job
@@ -16,6 +23,154 @@ moved the version here automatically; nothing has landed against `0.0.1b2` yet.
16
23
  Add entries as changes merge — this section becomes the GitHub Release body when
17
24
  it ships.
18
25
 
26
+ - Retire the old inbound evaluator boundary and add evaluator authoring plus the
27
+ outbound-only v2 worker runtime under the lazy `failproofai_sdk.evaluator`
28
+ namespace.
29
+ - Harden the managed-evaluator source sandbox against a class of escapes an
30
+ adversarial review found: `str.format`/`format_map` C-level field traversal,
31
+ generator/frame introspection (`gi_frame.f_globals`) that reached the eval
32
+ globals and could poison a process-shared namespace across evaluations, and
33
+ `type.mro()` type-object reach. Attribute access is now **default-deny** (an
34
+ allowlist of the transcript data surface plus pure string/collection methods,
35
+ so every current and future introspection attribute is rejected), each eval
36
+ runs with **fresh per-call globals**, and a result whose text embeds a runtime
37
+ object repr (`<... at 0x...>`, a heap-pointer/ASLR disclosure that falls out of
38
+ any bound method's repr) is rejected at the output boundary. `enumerate` and
39
+ bare generator expressions are no longer permitted — both were gratuitous
40
+ pointer-repr sources; use `range(len(...))` and list/set/dict comprehensions.
41
+ - Report **why** a server-authored definition was rejected. Every failure
42
+ collapsed to `evaluation raised <TypeName>`, so a hosted definition that can
43
+ never run reported only `evaluation raised UnsafeEvaluatorSource` — on every
44
+ session, forever, with nothing telling the author what was wrong. It matters
45
+ because the server accepts any source passing its size and key checks and does
46
+ not validate the sandbox's single-expression grammar, so a structurally
47
+ unrunnable definition is published successfully and then fails silently.
48
+ `UnsafeEvaluatorSource` now carries its detail (`evaluator_source must be one
49
+ expression`), bounded to `MAX_ERROR_MESSAGE_BYTES`. Deliberately narrower than
50
+ the generic handler, which still reports the type name only: this exception is
51
+ raised by our own validator before any customer source executes and describes
52
+ the source's shape, so it embeds no transcript content.
53
+ - Scrub the sandbox child's environment. `subprocess.Popen` inherited
54
+ `os.environ`, so the process executing untrusted server-authored source ran
55
+ with `FAILPROOFAI_EVALUATOR_TOKEN` in its environment — on the managed pod,
56
+ the cross-tenant credential. Defence in depth rather than a live escape (the
57
+ AST allowlist and empty `__builtins__` already stop a managed expression
58
+ reaching `os.environ`): a future gap there can no longer be escalated into
59
+ credential theft. Only what the interpreter needs is forwarded, `PYTHONPATH`
60
+ included.
61
+ - Contain a poison managed definition to its own run: source is now compiled
62
+ lazily inside the per-run executor, so a definition the sandbox rejects
63
+ dead-letters as one bounded `failed`/`eval_error` run instead of crashing the
64
+ assignment task and forcing it to be reclaimed until its attempt budget runs
65
+ out.
66
+ - Run managed (server-authored) evaluations in a **killable fork+exec'd
67
+ subprocess** with hard `RLIMIT_CPU` + `RLIMIT_AS` + a parent wall-clock kill —
68
+ so a compute/memory bomb in a hosted definition (`sum(range(10**20))`) can no
69
+ longer exhaust the worker (SEC-001). Cancelling an in-process thread does not
70
+ stop it; a fresh subprocess the kernel bounds and the parent terminates does. A
71
+ plain `os.fork()` would deadlock — the worker is multi-threaded (asyncio loop,
72
+ executor, writer) and forking one hangs the child on an inherited lock — so the
73
+ sandbox execs a fresh `python -m ..._sandbox_runner` that sets its own limits;
74
+ the transcript crosses in via `to_wire`, only the result crosses back. The
75
+ effective budget is **clamped to a hard ceiling** (`MAX_SANDBOX_TIMEOUT_SECONDS`,
76
+ 60s) so a large server-provided `timeout_seconds` cannot remove the bound.
77
+ Managed conditions, which previously ran with no timeout at all, are sandboxed
78
+ the same way. The result crossing back is **bounded on both sides** — the child
79
+ validates it (`result_items`, the 25-result limit) and refuses to serialize
80
+ anything over 1 MiB, and the parent reads at most that before killing the child
81
+ — so an oversized result (`metrics={str(x): 1 for x in range(100000)}`) cannot
82
+ OOM the worker either. The per-sandbox address space is capped (512 MiB) and the number of concurrent sandbox processes is bounded (a semaphore), so the AGGREGATE memory is bounded independent of the worker's `max_concurrency` — a fleet of concurrent runs can't OOM the host. Fails **closed** (`EvaluationSandboxUnavailable`) if the
83
+ sandbox cannot be spawned or the transcript cannot be serialized. Defense in depth at
84
+ compile time: reject `**` with a large/non-constant exponent and cap total AST
85
+ size. A managed condition the sandbox rejects now dead-letters as
86
+ `condition_error` instead of stranding the assignment. Only server-authored
87
+ source is isolated this way; customer evaluators still run in-process.
88
+ - Require `execution_mode` on the wire instead of coercing a falsy/missing value
89
+ to `local` — a malformed value silently ran a `python` definition down the
90
+ customer path (or vice-versa); it is now a hard protocol error.
91
+ - Count the sandbox-slot wait against the execution timeout (SEC-001). `_run_sandboxed`
92
+ acquired the `MAX_CONCURRENT_SANDBOXES` slot with an UNBOUNDED wait and only started
93
+ its wall-clock deadline afterward — so a run queued behind busy slots could, after the
94
+ runtime's `asyncio.wait_for` already reported it timed out (that cancels only the
95
+ awaiter, not the executor thread), still acquire a slot and launch a sandbox; 28
96
+ threads could pile up behind 4 long sandboxes and starve the worker (conditions have
97
+ no runtime-level wait at all). One wall-clock deadline now covers BOTH the slot wait
98
+ and execution: the slot is acquired with the remaining budget, and on timeout the run
99
+ raises `EvaluationTimeout` **without spawning a child**. Regression test: more
100
+ concurrent compute bombs than slots all resolve within ~one budget, not N serialized
101
+ budgets.
102
+ - A managed (`python`) definition's applicability is now governed by the SERVER's
103
+ `condition_source`, never a colliding local condition (COR-001). `process_assignment`
104
+ keyed the local-definition lookup on `(eval_key, eval_version)` alone and selected
105
+ `local.condition` whenever a local definition with that key existed — so a managed
106
+ definition whose server condition was false could be forced to run anyway if the
107
+ worker had also registered a local definition under the same key whose condition was
108
+ true, executing server-managed source against the operator's intent. Condition
109
+ selection now branches on `execution_mode`, mirroring the evaluator branch: `LOCAL`
110
+ uses `local.condition`, `PYTHON` compiles and runs the server's `condition_source`
111
+ regardless of any key collision. Regression test: identical local+managed keys, local
112
+ condition true and managed false, asserts the definition is skipped and no managed run
113
+ is submitted.
114
+ - Recognize the server's `incomplete_plan` terminal error (API-001). The server rejects a
115
+ plan that fails to cover every snapshotted definition with `422 incomplete_plan`; that
116
+ code is now in the SDK's `ERROR_SPECS` mirror and the shared `contract.json` fixture
117
+ (byte-identical with the server's), so a worker no longer treats a valid server-defined
118
+ failure as an unrecognized error. The fixture-equality test covers it.
119
+ - Close a heap-address disclosure bypass in the managed-source sandbox
120
+ (adversarial-audit SEC). The output-boundary guard that rejects a `<obj at 0xADDR>`
121
+ repr in a result field was anchored on the literal `<`, so an allow-listed
122
+ `str(payload.get).replace("<", "")` — or an f-string / `%`-format of a bare bound
123
+ method — kept the live heap address while stripping the match, leaking an
124
+ ASLR/memory-layout primitive of the sandbox process into a persisted result. The fix
125
+ moves the defense to compile time: a bound method (the only reachable value with a
126
+ pointer repr — the transcript and result types are all frozen, pointer-free
127
+ dataclasses) may now only be **called**, never referenced as a bare value, so no
128
+ reachable value can carry a pointer repr through `str()`, an f-string, or `%`. The
129
+ output-boundary scan is kept and broadened (no longer requires the leading `<`) as
130
+ defense in depth. Legitimate evaluations — which call methods and read data
131
+ attributes — are unaffected; regression tests cover the `.replace("<","")`, f-string,
132
+ and `%` bypasses and confirm called-method/data-attribute stringification still works.
133
+ - Switch the worker from long-polling to **normal (short) polling**, matching the
134
+ cadence of our other cloud surfaces. `claim` no longer sends `wait_seconds` and
135
+ the server returns immediately; when a claim comes back empty the worker sleeps
136
+ the server-advertised `poll_interval_seconds` (from the register response,
137
+ default 10 s) before polling again, instead of holding a request open for up to
138
+ 25 s. Removes the `claim_wait_seconds` config knob and the
139
+ `request_timeout_seconds > claim_wait_seconds` constraint; the poll cadence is
140
+ now tuned centrally by the server, not per worker.
141
+ - Bound the pre-plan condition phase by the assignment lease (hermes advisory).
142
+ Conditions were evaluated serially with no lease awareness before the plan was
143
+ created, and a managed condition could run its full sandbox budget — so a few
144
+ near-budget conditions could burn the whole lease before the plan request and
145
+ the server would fence the plan as `lease_lost`, reclaiming the assignment in a
146
+ loop instead of submitting a result. Each condition is now capped to the lease
147
+ time remaining before a plan-submission margin (using `lease_expires_at` when it
148
+ is in the future, else the negotiated lease duration), and once that budget is
149
+ gone the remaining conditions are skipped as `lease_exhausted` rather than run.
150
+ Local conditions, which previously had no timeout at all, are bounded the same
151
+ way. The complete fix — renewing the lease *during* the condition phase — needs
152
+ a server-side pre-plan heartbeat and is tracked separately.
153
+ - Make a timed-out **synchronous** evaluator observable and stop it starving the
154
+ worker (hermes advisory). A synchronous evaluator that overruns its timeout runs
155
+ in the executor thread and cannot be cancelled (CPython cannot interrupt a
156
+ running thread), so its thread was permanently lost; with the pool sized to the
157
+ concurrency limit, one such orphan on a single-slot worker silently stopped all
158
+ further local evaluation. The eval executor now carries headroom over the
159
+ semaphore so an orphaned thread does not immediately starve live capacity — the
160
+ semaphore stays the real concurrency bound — and each orphan increments
161
+ `sync_evaluations_orphaned` and logs a warning naming the evaluator, so a hung
162
+ one is findable. This is a finite cushion, not a cure for a permanently-blocked
163
+ evaluator; prefer `async def` evaluators (cooperatively cancellable) or managed
164
+ `python` evaluators (subprocess-isolated, hard-killed) for long or untrusted work.
165
+ - Let a managed source's list/set/dict comprehension read `session` on CPython
166
+ 3.10/3.11 (hermes COR-001). The sandbox eval put `session` in the eval *locals*,
167
+ but a comprehension runs in its own scope and resolves a free name like
168
+ `session` from *globals* — so on 3.10 (a supported version) an allowed source
169
+ such as `all([session.event_count > 0 for i in range(1)])` raised `NameError`.
170
+ `session` now goes in a fresh per-call globals mapping and both eval paths use
171
+ empty locals, which keeps isolation and works across 3.10–3.14. Regression test
172
+ runs on the whole version matrix.
173
+
19
174
  ## 0.0.1b1 — 2026-08-24
20
175
 
21
176
  The first release under this name. Everything below describes the package as it
@@ -10,6 +10,14 @@ the platform.
10
10
  - **Dependencies:** none. Standard library only, so installing it constrains
11
11
  nothing else in your environment.
12
12
 
13
+ ## Evaluator v2 status
14
+
15
+ The legacy inbound `agenteye-evaluator` package has been retired; do not build new
16
+ evaluator services against its server-push HTTP contract. Evaluator v2 authoring
17
+ and its customer-hosted, outbound-only worker runtime live under the lazy
18
+ `failproofai_sdk.evaluator` namespace. Importing the top-level tracing SDK does not
19
+ import or start the evaluator runtime.
20
+
13
21
  ## Installation
14
22
 
15
23
  ```bash