failproofai 1.0.7 → 1.0.8

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 (268) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
  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/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
  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/run/route.js +8 -7
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js +9 -7
  34. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/index.html +1 -1
  37. package/.next/standalone/.next/server/app/index.rsc +15 -15
  38. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  40. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js +6 -6
  43. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +11 -10
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page.js +8 -7
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -6
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page.js +7 -6
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +52 -8
  63. package/.next/standalone/.next/server/app/settings/page.js +12 -7
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/{[externals]__1msfs-h._.js → [externals]__19_pzeq._.js} +1 -1
  67. package/.next/standalone/.next/server/chunks/{[externals]__1_bftcl._.js → [externals]__20kzpkf._.js} +1 -1
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ttrwnd._.js +22 -0
  70. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
  71. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
  74. package/.next/standalone/.next/server/chunks/{_1c3k-8x._.js → _1q5i8mb._.js} +2 -2
  75. package/.next/standalone/.next/server/chunks/lib_16xa545._.js +3 -0
  76. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +5 -0
  78. package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +4 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzs._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +4 -0
  83. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02npjtd._.js → [root-of-the-server]__056wjo4._.js} +3 -3
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06pflha._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +22 -0
  87. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0p-5p8u._.js → [root-of-the-server]__0n0xg95._.js} +3 -3
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__013jr2b._.js → [root-of-the-server]__0rwtwpm._.js} +3 -3
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0da85px._.js → [root-of-the-server]__11mayhe._.js} +3 -3
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12e7nhs._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19evfi8._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +4 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0cxe_2_._.js → [root-of-the-server]__1mf3zp6._.js} +3 -3
  100. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ftmoxc._.js → [root-of-the-server]__1pprgri._.js} +3 -3
  101. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1p2otjt._.js → [root-of-the-server]__1q4p5b8._.js} +3 -3
  102. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/ssr/{_166t73i._.js → _0-vcssj._.js} +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +23 -0
  109. package/.next/standalone/.next/server/chunks/ssr/{_1es2j7i._.js → _1gb0ifp._.js} +5 -5
  110. package/.next/standalone/.next/server/chunks/ssr/{_1_qswah._.js → _1q46vxx._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +13 -13
  113. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  116. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  117. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0drixxt._.js → node_modules_next_dist_0w6mzq5._.js} +4 -4
  119. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_18_d8l1._.js +151 -0
  120. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0-q0umm._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/src_hooks_06kzv9d._.js +12 -0
  122. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0g194sy._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +4 -2
  124. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1kx9e0d._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +5 -0
  126. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
  129. package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +3 -0
  130. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  131. package/.next/standalone/.next/server/pages/404.html +1 -1
  132. package/.next/standalone/.next/server/pages/500.html +1 -1
  133. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/server-reference-manifest.json +67 -23
  135. package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +6 -0
  136. package/.next/standalone/.next/static/chunks/0bhidk90e-07f.css +2 -0
  137. package/.next/standalone/.next/static/chunks/{2mdh397ghgnvv.js → 0m-9d6yn9hx4j.js} +1 -1
  138. package/.next/standalone/.next/static/chunks/{0__8a7m868fvf.js → 0wbjy0zo-m7is.js} +1 -1
  139. package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +1 -0
  140. package/.next/standalone/.next/static/chunks/{0o6qlkgubtoex.js → 21uv-uusw329x.js} +1 -1
  141. package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +1 -0
  142. package/.next/standalone/.next/static/chunks/2qdpj67x6ifk_.js +69 -0
  143. package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +1 -0
  144. package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +1 -0
  145. package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +1 -0
  146. package/.next/standalone/.next/static/chunks/{13i7-9is-vhys.js → 3c3qbmosdjl6w.js} +1 -1
  147. package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
  148. package/.next/standalone/app/actions/get-jev-config.ts +604 -0
  149. package/.next/standalone/app/actions/pack-actions.ts +12 -0
  150. package/.next/standalone/app/actions/update-jev-config.ts +569 -0
  151. package/.next/standalone/app/components/jev-notices.tsx +96 -0
  152. package/.next/standalone/app/policies/hooks-client.tsx +14 -3
  153. package/.next/standalone/app/settings/jev-panel.tsx +630 -0
  154. package/.next/standalone/app/settings/page.tsx +20 -1
  155. package/.next/standalone/app/settings/settings-client.tsx +27 -1
  156. package/.next/standalone/app/settings/settings.css +79 -0
  157. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +22 -4
  158. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +14 -1
  159. package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +17 -3
  160. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +3 -0
  161. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +22 -0
  162. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +169 -0
  163. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +1 -1
  164. package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +65 -0
  165. package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +61 -0
  166. package/.next/standalone/package.json +10 -10
  167. package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
  168. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
  169. package/.next/standalone/sdk/typescript/CHANGELOG.md +18 -1
  170. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +0 -274
  171. package/.next/standalone/sdk/typescript/scripts/release.mjs +30 -0
  172. package/.next/standalone/server.js +1 -1
  173. package/README.md +3 -2
  174. package/bin/failproofai.mjs +148 -4
  175. package/dist/cli.mjs +18599 -9478
  176. package/dist/index.js +19 -1
  177. package/dist/worker.mjs +10500 -3773
  178. package/package.json +10 -10
  179. package/pi-extension/index.ts +11 -0
  180. package/scripts/build-policy-pack.mjs +53 -2
  181. package/src/audit/features.ts +3 -2
  182. package/src/hooks/builtin-policies.ts +195 -8
  183. package/src/hooks/cloud-connection.ts +190 -1
  184. package/src/hooks/cloud-enrollment-cli.ts +57 -8
  185. package/src/hooks/cloud-introspect.ts +6 -0
  186. package/src/hooks/cloud-managed-policies.ts +22 -0
  187. package/src/hooks/configure-wizard.ts +26 -6
  188. package/src/hooks/custom-hooks-loader.ts +98 -10
  189. package/src/hooks/custom-hooks-registry.ts +45 -1
  190. package/src/hooks/effective-reviewers.ts +243 -0
  191. package/src/hooks/first-run-gate.ts +5 -0
  192. package/src/hooks/flush-cli.ts +35 -8
  193. package/src/hooks/fp-config.ts +266 -1
  194. package/src/hooks/fp-home.ts +23 -0
  195. package/src/hooks/fp-reset.ts +22 -4
  196. package/src/hooks/handler.ts +303 -7
  197. package/src/hooks/hook-activity-store.ts +118 -6
  198. package/src/hooks/hook-telemetry.ts +41 -0
  199. package/src/hooks/jev-activity.ts +385 -0
  200. package/src/hooks/jev-cli.ts +2172 -0
  201. package/src/hooks/jev-cloud-connection.ts +392 -0
  202. package/src/hooks/loader-utils.ts +6 -0
  203. package/src/hooks/manager.ts +45 -7
  204. package/src/hooks/pack-cli.ts +568 -37
  205. package/src/hooks/pack-failclosed.ts +3 -0
  206. package/src/hooks/pack-manifest.ts +489 -7
  207. package/src/hooks/pack-store.ts +194 -11
  208. package/src/hooks/policy-authority.ts +386 -0
  209. package/src/hooks/policy-catalog.ts +206 -0
  210. package/src/hooks/policy-evaluator.ts +963 -796
  211. package/src/hooks/policy-registry.ts +27 -1
  212. package/src/hooks/policy-reviewability.ts +258 -0
  213. package/src/hooks/policy-types.ts +128 -0
  214. package/src/hooks/semantic/combine.ts +581 -0
  215. package/src/hooks/semantic/compile.ts +176 -0
  216. package/src/hooks/semantic/decide.ts +513 -0
  217. package/src/hooks/semantic/envelope.ts +1255 -0
  218. package/src/hooks/semantic/evaluator.ts +556 -0
  219. package/src/hooks/semantic/facts.ts +387 -0
  220. package/src/hooks/semantic/intent.ts +1190 -0
  221. package/src/hooks/semantic/jev-client.ts +1155 -0
  222. package/src/hooks/semantic/jev-config.ts +1142 -0
  223. package/src/hooks/semantic/jev-review.ts +389 -0
  224. package/src/hooks/semantic/jev-stats.ts +289 -0
  225. package/src/hooks/semantic/jev-throttle.ts +427 -0
  226. package/src/hooks/semantic/pack-policies.ts +294 -0
  227. package/src/hooks/semantic/policies.ts +597 -0
  228. package/src/hooks/semantic/precondition-names.ts +60 -0
  229. package/src/hooks/semantic/preconditions.ts +58 -0
  230. package/src/hooks/semantic/redact.ts +2937 -0
  231. package/src/hooks/semantic/session-root.ts +116 -0
  232. package/src/hooks/semantic/types.ts +162 -0
  233. package/src/hooks/semver-precedence.ts +128 -0
  234. package/src/hooks/tui.ts +4 -0
  235. package/src/hooks/types.ts +1 -1
  236. package/src/hooks/worker-server.ts +121 -27
  237. package/src/index.ts +6 -0
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cuho4x._.js +0 -3
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_r2rbg._.js +0 -24
  240. package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +0 -3
  241. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +0 -4
  242. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +0 -4
  243. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bd3mje._.js +0 -3
  244. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +0 -5
  245. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +0 -3
  246. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +0 -22
  247. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +0 -3
  248. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +0 -5
  249. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +0 -3
  250. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +0 -3
  251. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +0 -3
  252. package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +0 -5
  253. package/.next/standalone/.next/server/chunks/ssr/_0h_douw._.js +0 -3
  254. package/.next/standalone/.next/server/chunks/ssr/_1-i_gzc._.js +0 -23
  255. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +0 -3
  256. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +0 -3
  258. package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +0 -1
  259. package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +0 -6
  260. package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +0 -1
  261. package/.next/standalone/.next/static/chunks/2klitrtzpaoe0.js +0 -1
  262. package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +0 -2
  263. package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +0 -1
  264. package/.next/standalone/.next/static/chunks/3rh5o7e16irrm.js +0 -69
  265. package/.next/standalone/.next/static/chunks/43ufqrz8qo3h-.js +0 -1
  266. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_buildManifest.js +0 -0
  267. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_clientMiddlewareManifest.js +0 -0
  268. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_ssgManifest.js +0 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * The Jev (two-tier evaluator) fields of a hook activity row: their allowed
3
+ * shapes, the one normaliser every writer and shipper goes through, and a
4
+ * plain-language summary for the dashboard.
5
+ *
6
+ * WHY A NORMALISER AT ALL. These fields leave the machine: the collector ships
7
+ * them to FailproofAI Cloud (`crates/fpai-collect/src/sources/hooks/transform.rs`)
8
+ * and a few ride PostHog (`hook-telemetry.ts`). The rule for everything shipped
9
+ * from a hook row is "decisions and tool names, never file contents", and most
10
+ * of these fields are closed sets that cannot break it. `jevFallbackReason` is
11
+ * the exception: the evaluator's degraded reasons include free text
12
+ * (`prepare: <error message>`, `error: <message>`), and an error message is
13
+ * exactly where a fragment of the judged command or the human's prompt can end
14
+ * up. So a reason is reduced to one of a closed list of CODES before it is
15
+ * stored ({@link JEV_REASON_CODES}), and anything else becomes `other` — even a
16
+ * short kebab-case word, which could be the command's own first word. The Rust
17
+ * side applies the same rule again, for rows written by some other build.
18
+ *
19
+ * WHAT THE VALIDATORS DO NOT COVER. `jevCleared` and `jevModel` are checked for
20
+ * shape only. A cleared name is a registered policy name: no control characters
21
+ * or line breaks, and no whitespace unless it sits under a registered namespace
22
+ * (`custom/`, `pack/`, `cloud/`, `.failproofai-<scope>/`, `failproofai/`),
23
+ * where a user's own hook name may contain spaces. A model id is the alphabet
24
+ * `jev.json` accepts. That keeps a bare sentence, a command line or a prompt
25
+ * out, but a fragment of the right shape — a path, a file name — would pass.
26
+ * Those two fields rely on the writer supplying registered policy names and the
27
+ * provider's model id, which is what the combine rules write.
28
+ *
29
+ * WHAT `evaluator: "jev"` MEANS. The two-tier path ran for this call. It does
30
+ * NOT by itself mean Jev answered. When a hard policy denies, the combine rules
31
+ * abort Jev and record `{ evaluator: "jev", jevMode }`; when no semantic policy
32
+ * applies to the call (TodoWrite, Task, …), no request is sent and they record
33
+ * `{ evaluator: "jev", jevDecision: "allow", jevMode }`. So every reader
34
+ * classifies a row with {@link jevOutcome} — answered, fell back, not consulted
35
+ * or no request — rather than reading `evaluator` alone.
36
+ *
37
+ * Pure on purpose — no node imports — so the client dashboard can use
38
+ * {@link describeJevActivity} without pulling `node:fs` into a browser bundle.
39
+ */
40
+ import type { HookActivityEntry } from "./hook-activity-store";
41
+
42
+ export type JevActivityFields = Pick<
43
+ HookActivityEntry,
44
+ "evaluator" | "jevDecision" | "jevCleared" | "jevFallbackReason" | "jevLatencyMs" | "jevModel" | "jevMode"
45
+ >;
46
+
47
+ /** Every Jev key on an activity row, in the order they are documented. */
48
+ export const JEV_ACTIVITY_KEYS = [
49
+ "evaluator",
50
+ "jevDecision",
51
+ "jevCleared",
52
+ "jevFallbackReason",
53
+ "jevLatencyMs",
54
+ "jevModel",
55
+ "jevMode",
56
+ ] as const satisfies ReadonlyArray<keyof JevActivityFields>;
57
+
58
+ const EVALUATORS = new Set(["jev", "jev-fallback"]);
59
+ const DECISIONS = new Set(["allow", "instruct", "deny"]);
60
+ const MODES = new Set(["shadow", "enforce"]);
61
+
62
+ /**
63
+ * A reason's leading code — lowercase kebab-case — either alone or followed by
64
+ * `:` / `(` and free text: `timeout`, `http-429`, `prepare: <message>`.
65
+ */
66
+ const REASON_HEAD_RE = /^([a-z0-9]+(?:-[a-z0-9]+)*)\s*(?:$|[:(])/;
67
+ const HTTP_CODE_RE = /^http-\d{3}$/;
68
+ export const JEV_REASON_MAX_CHARS = 40;
69
+ /** What a reason that is not a known code is stored as. */
70
+ export const JEV_REASON_OTHER = "other";
71
+
72
+ /**
73
+ * Every fallback reason code a row may carry, besides `http-NNN`. The codes the
74
+ * Jev client, the evaluator, the throttle and the combine rules produce; any
75
+ * other reason is stored as `other`. A code added to a producer must be added
76
+ * here AND to `JEV_REASON_CODES` in the collector's `transform.rs` (a test
77
+ * keeps the two identical), or it ships as `other` — safe, but less useful.
78
+ *
79
+ * WHY A TUPLE AND A TYPE, not just a set. A producer that writes the code as a
80
+ * bare string literal can be renamed without this list hearing about it, and
81
+ * the result is silent: the row still stores, as `other`, and only a reader
82
+ * months later notices the diagnosis is gone. That is exactly what happened to
83
+ * `request-cut` — the combine rules' name for "Jev answered, but was shown
84
+ * only part of the call" — which was renamed from `truncated` after this list
85
+ * was written and spent its whole life being stored as `other`. So the codes
86
+ * a producer writes DIRECTLY are exported from here as constants typed
87
+ * {@link JevReasonCode} (see {@link JEV_REASON_REQUEST_CUT}): the producer
88
+ * imports the constant instead of retyping the string, and a code this list
89
+ * does not name is a compile error rather than a quiet `other`.
90
+ *
91
+ * Codes no producer writes any more (`truncated`, `request-too-large`) stay
92
+ * here on purpose: rows written by an older build still carry them, and this
93
+ * list is also what the collector applies to THOSE rows.
94
+ */
95
+ export const JEV_REASON_CODE_LIST = [
96
+ "aborted",
97
+ "cloudflare-error",
98
+ "cloudflare-incomplete",
99
+ "config",
100
+ "error",
101
+ "malformed",
102
+ "model-mismatch",
103
+ "network",
104
+ "no-api-key",
105
+ "no-transport",
106
+ "other",
107
+ "out-of-credits",
108
+ "prepare-error",
109
+ "provider-refused",
110
+ "rate-limited",
111
+ "request-cut",
112
+ "request-too-large",
113
+ "timeout",
114
+ "truncated",
115
+ "unavailable",
116
+ "upstream-error",
117
+ ] as const;
118
+
119
+ /** One of {@link JEV_REASON_CODE_LIST}. */
120
+ export type JevReasonCode = (typeof JEV_REASON_CODE_LIST)[number];
121
+
122
+ export const JEV_REASON_CODES: ReadonlySet<string> = new Set<string>(JEV_REASON_CODE_LIST);
123
+
124
+ /**
125
+ * "Jev answered, but the request it answered had to be cut to fit the
126
+ * envelope, so it cleared nothing" — the one fallback reason the combine rules
127
+ * write themselves (`semantic/combine.ts`), rather than passing on from the
128
+ * client or the evaluator. It is a value, not a literal, so that renaming the
129
+ * code in {@link JEV_REASON_CODE_LIST} breaks the build at the producer
130
+ * instead of silently storing `other`.
131
+ */
132
+ export const JEV_REASON_REQUEST_CUT: JevReasonCode = "request-cut";
133
+
134
+ /**
135
+ * "The provider would not run the model on this request" — the OTHER thing an
136
+ * HTTP 402 means on these routes, and the one that is not about the operator's
137
+ * balance. The Cloudflare route answers a request whose content it declines
138
+ * with 402 and a `Payment error` category — the same status a real empty
139
+ * account gets — so until that call was split both landed under
140
+ * `out-of-credits`, and `failproofai jev status` told operators to top up
141
+ * accounts that were fine. What can and cannot be told apart from the response
142
+ * is written out in `semantic/jev-client.ts` (`paymentRequiredCode`), which is
143
+ * the only producer; it imports this constant rather than retyping the string,
144
+ * for the reason {@link JEV_REASON_CODE_LIST} gives.
145
+ */
146
+ export const JEV_REASON_PROVIDER_REFUSED: JevReasonCode = "provider-refused";
147
+
148
+ /**
149
+ * Leading words that are renamed on the way in: the evaluator's free-text
150
+ * prefixes, each mapped to its code. `prepare` is the one that differs — the
151
+ * evaluator writes `prepare: <message>`, and the combine rules cut that down
152
+ * to a bare `prepare` — and both are stored as `prepare-error`, so one failure
153
+ * never shows up under two names. `FREE_TEXT_PREFIXES` in the collector's
154
+ * `transform.rs` is the same list; a test keeps the two identical.
155
+ */
156
+ export const JEV_FREE_TEXT_PREFIXES: ReadonlyMap<string, string> = new Map<string, string>([
157
+ ["prepare", "prepare-error"],
158
+ ["error", "error"],
159
+ ["timeout", "timeout"],
160
+ ["network", "network"],
161
+ ["malformed", "malformed"],
162
+ ["truncated", "truncated"],
163
+ ["rate-limited", "rate-limited"],
164
+ ["out-of-credits", "out-of-credits"],
165
+ ["model-mismatch", "model-mismatch"],
166
+ ["request-too-large", "request-too-large"],
167
+ ["config", "config"],
168
+ ]);
169
+
170
+ /**
171
+ * Model ids: `jev-1.13.0`, `typesafe/jev-1.13-20260917`, `~typesafe/jev-latest`,
172
+ * `@cf/typesafe/jev`. Exactly what `jev.json` accepts for `model` (`MODEL_RE`
173
+ * in `semantic/jev-config.ts`), since the recorded model must match the
174
+ * configured one; `is_model_id` in the collector's `transform.rs` is the same.
175
+ */
176
+ export const JEV_MODEL_RE = /^[A-Za-z0-9._:/@~+-]{1,200}$/;
177
+ export const JEV_POLICY_NAME_MAX_CHARS = 200;
178
+ /** Control characters (C0, DEL, C1) and the Unicode line and paragraph separators. */
179
+ const NAME_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;
180
+ /**
181
+ * The namespaces the handler registers a loaded hook under
182
+ * (`${prefix}/${hook.name}`): `custom/`, `pack/<id>@<v>/`, `cloud/<id>@<v>/`,
183
+ * `.failproofai-<scope>/`, plus the builtins' `failproofai/`. The hook's own
184
+ * name after the prefix is whatever its author wrote, spaces included.
185
+ */
186
+ const REGISTERED_NAMESPACE_RE = /^(?:custom|pack|cloud|failproofai|\.failproofai-[A-Za-z0-9_-]{1,32})\//;
187
+ export const JEV_CLEARED_MAX = 64;
188
+
189
+ /**
190
+ * True for a string shaped like a registered policy name: 1–200 characters,
191
+ * no control characters or line breaks, and whitespace only after a registered
192
+ * namespace (`custom/No secrets in logs`). A bare sentence or command line
193
+ * (`curl -d @payroll.csv`) is not a policy name. `is_policy_name` in the
194
+ * collector's `transform.rs` applies the same rule.
195
+ */
196
+ export function isJevPolicyName(s: unknown): s is string {
197
+ if (typeof s !== "string" || s.length === 0 || [...s].length > JEV_POLICY_NAME_MAX_CHARS) return false;
198
+ if (NAME_FORBIDDEN_RE.test(s)) return false;
199
+ return !/\s/.test(s) || REGISTERED_NAMESPACE_RE.test(s);
200
+ }
201
+
202
+ /**
203
+ * Reduce a fallback reason to a known code, or undefined when there is none.
204
+ *
205
+ * - A known code (`timeout`, `http-429`, `model-mismatch`), alone or in front
206
+ * of free text (`prepare: Unexpected token…`, `http-500: upstream said …`):
207
+ * that code, lowercased, renamed through {@link JEV_FREE_TEXT_PREFIXES}.
208
+ * - Anything else: `other`. Never the text — not even a short kebab-case word
209
+ * that merely looks like a code (`curl`, `secret-project`).
210
+ */
211
+ export function normalizeJevFallbackReason(raw: unknown): string | undefined {
212
+ if (typeof raw !== "string") return undefined;
213
+ const s = raw.trim().toLowerCase();
214
+ if (s.length === 0) return undefined;
215
+ const head = REASON_HEAD_RE.exec(s)?.[1];
216
+ if (head === undefined || head.length > JEV_REASON_MAX_CHARS) return JEV_REASON_OTHER;
217
+ if (HTTP_CODE_RE.test(head)) return head;
218
+ const code = JEV_FREE_TEXT_PREFIXES.get(head) ?? head;
219
+ return JEV_REASON_CODES.has(code) ? code : JEV_REASON_OTHER;
220
+ }
221
+
222
+ /**
223
+ * The Jev fields of `entry`, each one valid or absent. Non-Jev keys pass
224
+ * through untouched, and an entry with no Jev keys comes back as the same
225
+ * object — the unconfigured path must not be rewritten on its way to disk.
226
+ *
227
+ * Deliberately field-by-field rather than all-or-nothing: an invalid model id
228
+ * is no reason to lose the fact that Jev fell back.
229
+ */
230
+ export function sanitizeJevActivity<T extends JevActivityFields>(entry: T): T {
231
+ if (!JEV_ACTIVITY_KEYS.some((k) => entry[k] !== undefined)) return entry;
232
+ const out: T = { ...entry };
233
+ const drop = (k: keyof JevActivityFields) => {
234
+ delete out[k];
235
+ };
236
+
237
+ if (!(typeof out.evaluator === "string" && EVALUATORS.has(out.evaluator))) drop("evaluator");
238
+ if (!(typeof out.jevDecision === "string" && DECISIONS.has(out.jevDecision))) drop("jevDecision");
239
+ if (!(typeof out.jevMode === "string" && MODES.has(out.jevMode))) drop("jevMode");
240
+
241
+ if (Array.isArray(out.jevCleared)) {
242
+ const names = [
243
+ ...new Set(out.jevCleared.filter(isJevPolicyName)),
244
+ ].slice(0, JEV_CLEARED_MAX);
245
+ out.jevCleared = names;
246
+ } else {
247
+ drop("jevCleared");
248
+ }
249
+
250
+ const reason = normalizeJevFallbackReason(out.jevFallbackReason);
251
+ if (reason === undefined) drop("jevFallbackReason");
252
+ else out.jevFallbackReason = reason;
253
+
254
+ if (typeof out.jevLatencyMs === "number" && Number.isFinite(out.jevLatencyMs) && out.jevLatencyMs >= 0) {
255
+ out.jevLatencyMs = Math.round(out.jevLatencyMs);
256
+ } else {
257
+ drop("jevLatencyMs");
258
+ }
259
+
260
+ if (typeof out.jevModel === "string" && JEV_MODEL_RE.test(out.jevModel.trim())) out.jevModel = out.jevModel.trim();
261
+ else drop("jevModel");
262
+
263
+ return out;
264
+ }
265
+
266
+ /** True when the row says which evaluator ran, i.e. a Jev config was present for the call. */
267
+ export function hasJevActivity(entry: JevActivityFields): boolean {
268
+ return entry.evaluator === "jev" || entry.evaluator === "jev-fallback";
269
+ }
270
+
271
+ /**
272
+ * What happened to Jev on one call:
273
+ *
274
+ * - `answered`: Jev's answer was read and the combine rules applied it.
275
+ * - `fallback`: Jev was asked and was unavailable, truncated or mismatched, so
276
+ * the regex result stood (`evaluator: "jev-fallback"`).
277
+ * - `not-consulted`: a hard policy denied first, so Jev was aborted and its
278
+ * answer never read. The combine rules record exactly
279
+ * `{ evaluator: "jev", jevMode }` for that.
280
+ * - `no-request`: no semantic policy applies to the call (TodoWrite, Task,
281
+ * Skill, …), so Jev had nothing to ask and no request was sent. The
282
+ * evaluator's answer to an empty question list is always `allow`, and the
283
+ * combine rules record `{ evaluator: "jev", jevDecision: "allow", jevMode }`
284
+ * — a verdict with no latency and no model.
285
+ *
286
+ * Null when Jev was not part of the call (no config, or not a gate).
287
+ *
288
+ * A `jev` row counts as answered when it carries anything only a request
289
+ * produces: a cleared list (even an empty one), a latency, a model id, or a
290
+ * `deny` / `instruct` verdict (the evaluator reaches those only from answers).
291
+ * An `allow` and nothing else is `no-request`; no Jev field at all (or only a
292
+ * verdict this build cannot read) is `not-consulted`. `transform.rs` applies
293
+ * the same rule (`JevOutcome`).
294
+ */
295
+ export type JevOutcome = "answered" | "fallback" | "not-consulted" | "no-request";
296
+
297
+ export function jevOutcome(raw: JevActivityFields): JevOutcome | null {
298
+ return outcomeOf(sanitizeJevActivity(raw));
299
+ }
300
+
301
+ /** {@link jevOutcome} for a row that is already sanitized. */
302
+ function outcomeOf(e: JevActivityFields): JevOutcome | null {
303
+ if (e.evaluator === "jev-fallback") return "fallback";
304
+ if (e.evaluator !== "jev") return null;
305
+ if (e.jevCleared !== undefined || e.jevLatencyMs !== undefined || e.jevModel !== undefined) return "answered";
306
+ if (e.jevDecision === "deny" || e.jevDecision === "instruct") return "answered";
307
+ if (e.jevDecision === "allow") return "no-request";
308
+ return "not-consulted";
309
+ }
310
+
311
+ /**
312
+ * Fallback reasons that mean Jev DID answer and the combine rules set the
313
+ * answer aside: the call was cut to fit the envelope (Jev judged only part of
314
+ * it), or a model other than the configured one answered. `truncated` is the
315
+ * name a build before the rename wrote for the first of those, kept so an old
316
+ * row still reads correctly.
317
+ */
318
+ const ANSWERED_BUT_NOT_APPLIED_REASONS: ReadonlySet<string> = new Set<string>([
319
+ JEV_REASON_REQUEST_CUT,
320
+ "truncated",
321
+ "model-mismatch",
322
+ ]);
323
+
324
+ /**
325
+ * True for a fallback row where Jev answered but its answer was not applied —
326
+ * the row carries Jev's verdict (the combine rules record one only when Jev
327
+ * answered), or its reason is one of {@link ANSWERED_BUT_NOT_APPLIED_REASONS}.
328
+ * Such a row is not "Jev unavailable". Expects a sanitized row.
329
+ */
330
+ export function jevAnsweredButNotApplied(e: JevActivityFields): boolean {
331
+ if (e.evaluator !== "jev-fallback") return false;
332
+ return e.jevDecision !== undefined || ANSWERED_BUT_NOT_APPLIED_REASONS.has(e.jevFallbackReason ?? "");
333
+ }
334
+
335
+ /** What the dashboard says about a call Jev was not consulted on. */
336
+ export const JEV_NOT_CONSULTED_FACT = "Jev not consulted: a hard policy's deny is final";
337
+ /** What the dashboard says about a call no semantic policy applied to. */
338
+ export const JEV_NO_REQUEST_FACT = "Jev not asked: no semantic policy applies to this call";
339
+
340
+ /**
341
+ * What Jev did on one row, as short facts in display order — e.g.
342
+ * `["Jev verdict: allow", "cleared block-env-files", "38 ms", "jev-1.13.0"]` —
343
+ * or null when Jev was not involved. Plain language, no probabilities: those
344
+ * live in the verdict log. Never an empty list: a call Jev was not consulted
345
+ * on says so ({@link JEV_NOT_CONSULTED_FACT}). A fallback where Jev answered
346
+ * but was set aside (truncated, model mismatch) says "Jev's answer not
347
+ * applied" and shows the verdict it gave, not "Jev unavailable".
348
+ */
349
+ export function describeJevActivity(raw: JevActivityFields): string[] | null {
350
+ const e = sanitizeJevActivity(raw);
351
+ const outcome = outcomeOf(e);
352
+ if (outcome === null) return null;
353
+ if (outcome === "not-consulted") return [JEV_NOT_CONSULTED_FACT];
354
+ if (outcome === "no-request") return [JEV_NO_REQUEST_FACT];
355
+ const facts: string[] = [];
356
+
357
+ if (outcome === "fallback") {
358
+ const reason = e.jevFallbackReason ?? "unknown reason";
359
+ if (jevAnsweredButNotApplied(e)) {
360
+ // Jev did answer — the call was cut to fit the envelope, or the wrong
361
+ // model answered — so "unavailable" would be false, and its verdict is
362
+ // exactly what someone reading this row wants to see.
363
+ facts.push(`Jev's answer not applied: ${reason}`);
364
+ if (e.jevDecision) facts.push(`Jev verdict (not applied): ${e.jevDecision}`);
365
+ } else {
366
+ facts.push(`Jev unavailable: ${reason}`);
367
+ }
368
+ facts.push("the regex policies decided alone");
369
+ if (e.jevLatencyMs !== undefined) facts.push(`${e.jevLatencyMs} ms`);
370
+ if (e.jevModel && jevAnsweredButNotApplied(e)) facts.push(e.jevModel);
371
+ return facts;
372
+ }
373
+
374
+ if (e.jevDecision) facts.push(`Jev verdict: ${e.jevDecision}`);
375
+ const cleared = e.jevCleared ?? [];
376
+ if (cleared.length > 0) {
377
+ facts.push(`${e.jevMode === "shadow" ? "would have cleared" : "cleared"} ${cleared.join(", ")}`);
378
+ }
379
+ if (e.jevMode === "shadow") facts.push("shadow mode: the regex result was enforced");
380
+ if (e.jevLatencyMs !== undefined) facts.push(`${e.jevLatencyMs} ms`);
381
+ if (e.jevModel) facts.push(e.jevModel);
382
+ // Answered, but nothing this build can show (a verdict in a shape it cannot read).
383
+ if (facts.length === 0) facts.push("Jev answered");
384
+ return facts;
385
+ }