failproofai 1.0.11 → 1.0.12-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +23 -23
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  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 +2 -2
  8. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  13. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js +3 -3
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.rsc +3 -3
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/invite/route.js +5 -6
  26. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route.js +24 -24
  28. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/audit/status/route.js +2 -2
  30. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +4 -5
  32. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +6 -7
  34. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/logout/route.js +6 -7
  36. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/auth/status/route.js +5 -6
  38. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +2 -2
  40. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  42. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  43. package/.next/standalone/.next/server/app/audit/page.js +4 -4
  44. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/index.html +1 -1
  47. package/.next/standalone/.next/server/app/index.rsc +3 -3
  48. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  49. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  50. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  51. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  52. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  53. package/.next/standalone/.next/server/app/page.js +2 -2
  54. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  57. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  58. package/.next/standalone/.next/server/app/policies/page.js +7 -7
  59. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  62. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  63. package/.next/standalone/.next/server/app/project/[name]/page.js +7 -7
  64. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  67. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  68. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  69. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +8 -8
  70. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  73. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  74. package/.next/standalone/.next/server/app/projects/page.js +3 -3
  75. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +3 -3
  78. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  79. package/.next/standalone/.next/server/app/settings/page.js +10 -10
  80. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/chunks/{[externals]__0qkp92tjfvw8r._.js → [externals]__0vt9i6fqinjne._.js} +1 -1
  83. package/.next/standalone/.next/server/chunks/[externals]__1x24dzcbbq6-g._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02vous7mpi2xm._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03i5o4a840guz._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__a_je8fsn65._.js +3 -0
  87. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_hsnj_a2mvl_._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1izwqj_ij_9x_._.js → [root-of-the-server]__0f_4g-vazrvxv._.js} +1 -1
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-oi4gdtmlo5._.js +3 -0
  90. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0swiyzbmvja2d._.js → [root-of-the-server]__0t9ufnv5hi2hq._.js} +5 -5
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wg9dk8x8bnau._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12kq3x-h7t7i1._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a5zkndjwlc13._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1r7kbfkiw2xmu._.js → [root-of-the-server]__1aaw59g-5uty7._.js} +12 -12
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hqpg6vgmfexv._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/_09dz7xva4ce_2._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/_0hf5q4xzyg40j._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/_0tovk6q0miud6._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/_0trp3ycqv17cl._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/_19011-u44143j._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/_1ek68lnh2daur._.js +1 -1
  102. package/.next/standalone/.next/server/chunks/_1vslkoe35wok6._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/{_1ixl-kxq_ctsa._.js → _1y590mjzpkbos._.js} +2 -2
  104. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4vkpxxu7._.js +1 -1
  105. package/.next/standalone/.next/server/chunks/src_hooks_0_em82s16zfym._.js +5 -0
  106. package/.next/standalone/.next/server/chunks/src_hooks_builtin-policies_ts_1yq5ybgx1v98e._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3h94wnn._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/src_hooks_daemon-client_ts_0il_yu1zc0291._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn_4twyh._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01j58mdcdw0vn._.js +3 -0
  111. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0588st-tpiuia._.js +3 -0
  112. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08ch3staq3ejw._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_a8z2ldp2v3n._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0vcyntk4snf0f._.js → [root-of-the-server]__0b78b0j8iyv6l._.js} +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bigvy9xmv2ka._.js +1 -1
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ffu2-38y03ic._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g8b0kyorya-t._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h86bl2qf0k_o._.js +1 -1
  119. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1_xbg2kx30wp-._.js → [root-of-the-server]__0naevg4bcoh54._.js} +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pia5h3p8re4c._.js +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__075uro8t92s0_._.js → [root-of-the-server]__0pwj2h2efe5f-._.js} +3 -3
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zn1d4blhd3bu._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-ey9fgesfbc0._.js +1 -1
  124. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15usvs-ms-0hf._.js +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16gb3_92zvk5x._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17r4zrwanhp6r._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1avi2kypusyb_._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1lnfv02ucky7m._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mc9-zlnh656_._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1r7drlqli-ado._.js +1 -1
  131. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1s2-ck3k3rsoo._.js +3 -0
  132. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1l1qgu5mfapkh._.js → [root-of-the-server]__1vx7o8ukefudh._.js} +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
  134. package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
  135. package/.next/standalone/.next/server/chunks/ssr/_128ebxr83nk6g._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/_1_ozgifqv1ssi._.js +1 -1
  137. package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifpkowwub._.js → _1a3tubds7s7ow._.js} +10 -9
  138. package/.next/standalone/.next/server/chunks/ssr/_1djqs9i27e4kg._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo5_vm5f.js +2 -2
  140. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9snixb5fd-._.js +1 -1
  141. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47q0xq5w._.js +1 -1
  142. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x33jqb6._.js +1 -1
  143. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpcz0uxur._.js +1 -1
  144. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h47jmhhd._.js +1 -1
  145. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_1f_ymmaonkksc.js → node_modules_html-to-image_es_index_1i8oid1gc7s1f.js} +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/package_json_[json]_cjs_013tntikdft59._.js +1 -1
  147. package/.next/standalone/.next/server/chunks/ssr/src_hooks_06kzv9ddabn3_._.js +1 -1
  148. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0agdmptetetdt._.js +5 -0
  149. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0mdwgjisv4fub._.js +5 -0
  150. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4l1tzrm._.js +1 -1
  151. package/.next/standalone/.next/server/chunks/ssr/src_hooks_daemon-client_ts_0k41_i7jg6ndv._.js +1 -1
  152. package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me658zqmh_._.js +1 -1
  153. package/.next/standalone/.next/server/middleware-build-manifest.js +23 -23
  154. package/.next/standalone/.next/server/middleware.js +2 -2
  155. package/.next/standalone/.next/server/pages/404.html +1 -1
  156. package/.next/standalone/.next/server/pages/500.html +1 -1
  157. package/.next/standalone/.next/server/preview-props.json +3 -3
  158. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
  160. package/.next/standalone/.next/static/chunks/{0frxv4_m-m2u5.js → 063al_q720fkj.js} +1 -1
  161. package/.next/standalone/.next/static/chunks/0_zfad4co-t2z.js +1 -0
  162. package/.next/standalone/.next/static/chunks/0jutamwqz8pg5.js +1 -0
  163. package/.next/standalone/.next/static/chunks/114hbolvrv94e.js +1 -0
  164. package/.next/standalone/.next/static/chunks/{37stoe-_yd852.js → 18433qz-8njv3.js} +1 -1
  165. package/.next/standalone/.next/static/chunks/{1kwj8uqxuv85t.js → 1b32-afqacaen.js} +1 -1
  166. package/.next/standalone/.next/static/chunks/{44a7k2_62qc-9.js → 1p-hsi58i-6h0.js} +2 -2
  167. package/.next/standalone/.next/static/chunks/{302llgh97ce6w.js → 2-tf6_7u623kd.js} +1 -1
  168. package/.next/standalone/.next/static/chunks/{1_c0dc7zqj1n7.js → 24w3x2da9sk49.js} +1 -1
  169. package/.next/standalone/.next/static/chunks/2tjfp9dirxnku.js +1 -0
  170. package/.next/standalone/.next/static/chunks/{16z6_d7sp61jm.js → 3-pku9qwv1yfu.js} +1 -1
  171. package/.next/standalone/.next/static/chunks/{15rm15u5a6dua.js → 42e8zab314654.js} +1 -1
  172. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +41 -0
  173. package/.next/standalone/fp-cloud-cli/README.md +42 -1
  174. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +117 -12
  175. package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +285 -19
  176. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +84 -18
  177. package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +170 -6
  178. package/.next/standalone/fp-cloud-cli/fp_cli/models.py +89 -6
  179. package/.next/standalone/fp-cloud-cli/fp_cli/output.py +259 -21
  180. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +8 -5
  181. package/.next/standalone/fp-cloud-cli/skill/SKILL.md +2 -2
  182. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +17 -9
  183. package/.next/standalone/fp-cloud-cli/tests/test_cloud_jev.py +692 -0
  184. package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +46 -0
  185. package/.next/standalone/fp-cloud-cli/tests/test_output.py +23 -0
  186. package/.next/standalone/fp-cloud-cli/uv.lock +6 -6
  187. package/.next/standalone/hermes-plugin/README.md +6 -4
  188. package/.next/standalone/hermes-plugin/__init__.py +16 -0
  189. package/.next/standalone/hermes-plugin/client.py +5 -1
  190. package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
  191. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  192. package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/context.js +72 -0
  193. package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/diag.js +84 -0
  194. package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/metrics.js +50 -0
  195. package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/propagation.js +80 -0
  196. package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/trace.js +70 -0
  197. package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js +52 -0
  198. package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js +44 -0
  199. package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js +12 -0
  200. package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/utils.js +41 -0
  201. package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js +27 -0
  202. package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/context.js +52 -0
  203. package/.next/standalone/node_modules/@opentelemetry/api/build/src/context-api.js +16 -0
  204. package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js +47 -0
  205. package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js +73 -0
  206. package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js +34 -0
  207. package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/types.js +33 -0
  208. package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag-api.js +20 -0
  209. package/.next/standalone/node_modules/@opentelemetry/api/build/src/index.js +71 -0
  210. package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/global-utils.js +60 -0
  211. package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/semver.js +111 -0
  212. package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/Metric.js +18 -0
  213. package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js +118 -0
  214. package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js +20 -0
  215. package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics-api.js +17 -0
  216. package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js +23 -0
  217. package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js +36 -0
  218. package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation-api.js +17 -0
  219. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js +58 -0
  220. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js +68 -0
  221. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js +21 -0
  222. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js +46 -0
  223. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js +46 -0
  224. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js +33 -0
  225. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/context-utils.js +71 -0
  226. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js +94 -0
  227. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js +35 -0
  228. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js +16 -0
  229. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js +25 -0
  230. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/span_kind.js +38 -0
  231. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js +66 -0
  232. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/status.js +29 -0
  233. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js +18 -0
  234. package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace-api.js +17 -0
  235. package/.next/standalone/node_modules/@opentelemetry/api/build/src/version.js +10 -0
  236. package/.next/standalone/node_modules/@opentelemetry/api/package.json +96 -0
  237. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  238. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +2 -2
  239. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +2 -2
  240. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +1 -1
  241. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  242. package/.next/standalone/node_modules/next/dist/server/app-render/async-local-storage.js +1 -1
  243. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  244. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  245. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  246. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  247. package/.next/standalone/node_modules/next/dist/server/lib/generate-agent-files.js +3 -3
  248. package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +1 -1
  249. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  250. package/.next/standalone/node_modules/next/dist/server/lib/trace/tracer.js +1 -1
  251. package/.next/standalone/node_modules/next/dist/server/typescript/rules/config.js +2 -2
  252. package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
  253. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  254. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  255. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  256. package/.next/standalone/node_modules/next/package.json +11 -11
  257. package/.next/standalone/package.json +11 -11
  258. package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
  259. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
  260. package/.next/standalone/sdk/python/pyproject.toml +19 -0
  261. package/.next/standalone/sdk/python/uv.lock +520 -301
  262. package/.next/standalone/sdk/typescript/CHANGELOG.md +13 -0
  263. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +4 -13
  264. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +2 -1
  265. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4 -13
  266. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +3 -0
  267. package/.next/standalone/sdk/typescript/package-lock.json +178 -162
  268. package/.next/standalone/sdk/typescript/package.json +1 -1
  269. package/.next/standalone/sdk/typescript/src/version.ts +1 -1
  270. package/.next/standalone/server.js +1 -1
  271. package/bin/failproofai.mjs +17 -1
  272. package/dist/cli.mjs +2866 -1124
  273. package/dist/worker.mjs +1450 -145
  274. package/hermes-plugin/README.md +6 -4
  275. package/hermes-plugin/__init__.py +16 -0
  276. package/hermes-plugin/client.py +5 -1
  277. package/hermes-plugin/plugin.yaml +1 -1
  278. package/package.json +11 -11
  279. package/src/hooks/agent-roster.ts +172 -0
  280. package/src/hooks/agent-targets.ts +60 -0
  281. package/src/hooks/cloud-connection.ts +97 -27
  282. package/src/hooks/cloud-enrollment-cli.ts +7 -4
  283. package/src/hooks/cloud-managed-policies.ts +380 -20
  284. package/src/hooks/cloud-policy-errors.ts +481 -0
  285. package/src/hooks/config-status.ts +1 -1
  286. package/src/hooks/custom-hooks-loader.ts +26 -3
  287. package/src/hooks/daemon-client.ts +9 -4
  288. package/src/hooks/daemon-service.ts +2 -1
  289. package/src/hooks/effective-reviewers.ts +22 -1
  290. package/src/hooks/fp-home.ts +6 -0
  291. package/src/hooks/handler.ts +235 -18
  292. package/src/hooks/health-probe.ts +15 -0
  293. package/src/hooks/integrations.ts +18 -11
  294. package/src/hooks/jev-cli.ts +197 -0
  295. package/src/hooks/jev-cloud-connection.ts +92 -0
  296. package/src/hooks/manager.ts +122 -16
  297. package/src/hooks/pack-failclosed.ts +2 -0
  298. package/src/hooks/pack-manifest.ts +8 -1
  299. package/src/hooks/policy-evaluator.ts +5 -1
  300. package/src/hooks/policy-registry.ts +3 -2
  301. package/src/hooks/policy-reviewability.ts +21 -5
  302. package/src/hooks/semantic/cloud-jev-health.ts +227 -0
  303. package/src/hooks/semantic/cloud-jev.ts +677 -0
  304. package/src/hooks/semantic/jev-client.ts +18 -1
  305. package/src/hooks/semantic/jev-config.ts +173 -3
  306. package/src/hooks/semantic/jev-review.ts +129 -10
  307. package/src/hooks/semantic/pack-policies.ts +2 -1
  308. package/src/hooks/semantic/types.ts +8 -0
  309. package/src/hooks/session-pause-cli.ts +1 -1
  310. package/src/hooks/worker-server.ts +5 -1
  311. package/.next/standalone/.next/server/chunks/[externals]__0hjaw70fchx66._.js +0 -3
  312. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07l68zv0hqdiu._.js +0 -3
  313. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0car70pylmvor._.js +0 -3
  314. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u3i025_setk_._.js +0 -3
  315. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10a2f6s636yc7._.js +0 -3
  316. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qt5u58xrcuk6._.js +0 -3
  317. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_077n_4ip5__fu._.js +0 -3
  318. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mqvvxcn6v0op._.js +0 -3
  319. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0pb7ds5g0vzgn._.js +0 -3
  320. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1gasm5xkeqmm3._.js +0 -3
  321. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1q1heqmkhh8l4._.js +0 -3
  322. package/.next/standalone/.next/server/chunks/src_hooks_1aveq0uhs2t1b._.js +0 -5
  323. package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7cyqlb2._.js +0 -3
  324. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0888k4s6spfmh._.js +0 -3
  325. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_bflu046ep5j._.js +0 -3
  326. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_lbstb5x2t15._.js +0 -3
  327. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0fdwgktjfhedo._.js +0 -3
  328. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s4deza787asx._.js +0 -3
  329. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__18qe-hu0gwqm4._.js +0 -3
  330. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_p_9xe520fex._.js +0 -3
  331. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fmhm8_s9i4re._.js +0 -3
  332. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1g76awtnmimd1._.js +0 -3
  333. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pczevlpk5lxh._.js +0 -3
  334. package/.next/standalone/.next/server/chunks/ssr/_0dc-of_bn0cim._.js +0 -3
  335. package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo55j16x._.js +0 -5
  336. package/.next/standalone/.next/static/chunks/0m-tv1y6ghhtk.js +0 -1
  337. package/.next/standalone/.next/static/chunks/0ol2gj4ntfn56.js +0 -1
  338. package/.next/standalone/.next/static/chunks/3hj5_7i3nw4zj.js +0 -1
  339. package/.next/standalone/.next/static/chunks/3iyoapeoq_hup.js +0 -1
  340. /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_buildManifest.js +0 -0
  341. /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_clientMiddlewareManifest.js +0 -0
  342. /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_ssgManifest.js +0 -0
@@ -12,6 +12,15 @@
12
12
  * never installed its checks: `jevChecksInstalled` below is the hook path's
13
13
  * gate for starting a review at all.
14
14
  *
15
+ * ## …and a FailproofAI Cloud `both` policy's own Cloud checks
16
+ *
17
+ * A `both` policy's JS half names its own Jev checks, which run on FailproofAI
18
+ * Cloud and never reach this machine (CONTRACT C10). While Cloud's Jev mode
19
+ * asks (`observe`/`enforce`), those names are reviewers too — but only as
20
+ * `cloud:<policyId>/<name>` (`cloudReviewerName`), which the Cloud review files
21
+ * that policy's own Cloud outcomes under. An installed pack's check of the same
22
+ * name is a different reviewer and can never clear it.
23
+ *
15
24
  * The names come from the MANIFEST, which is already where `authority` and
16
25
  * `reviewedBy` themselves are read from, so this adds no new trust and imports
17
26
  * no semantic module.
@@ -36,11 +45,14 @@
36
45
  */
37
46
  import { readInstalledPacks, type ResolvedPack } from "./pack-manifest";
38
47
  import { NO_REVIEWERS, SEMANTIC_REVIEWER_NAMES } from "./policy-authority";
48
+ import { cloudReviewerNames, readCloudAuthorityInputs, readCloudJevMode } from "./cloud-managed-policies";
49
+ import type { AgentIdentity } from "./agent-targets";
39
50
 
40
51
  let cached: ReadonlySet<string> | null = null;
41
52
  let cachedContested: ReadonlyMap<string, string[]> = new Map();
42
53
  /** The agent the current registration pass is for; see {@link forgetEffectiveReviewerNames}. */
43
54
  let reviewerCli: string | undefined;
55
+ let reviewerAgent: AgentIdentity | null = null;
44
56
 
45
57
  /**
46
58
  * The packs whose Jev checks take part for `cli`, filtered the way the regex
@@ -180,6 +192,14 @@ export function effectiveReviewerNames(): ReadonlySet<string> {
180
192
  } catch {
181
193
  // See above: an unreadable manifest declares no checks.
182
194
  }
195
+ try {
196
+ // Both reads answer "nothing" for a file they cannot use; guarded anyway,
197
+ // because a throw here would cost the registration pass — every policy.
198
+ const cloud = cloudReviewerNames(readCloudAuthorityInputs(reviewerAgent), readCloudJevMode());
199
+ if (cloud.length > 0) names = new Set([...names, ...cloud]);
200
+ } catch {
201
+ // No Cloud reviewers: every `both` policy stays hard.
202
+ }
183
203
  cached = names;
184
204
  return names;
185
205
  }
@@ -244,7 +264,8 @@ export function reviewerNamesFor(
244
264
  * runs before it registers anything — so a pack installed under a long-lived
245
265
  * warm worker is picked up on the next event rather than at the next restart.
246
266
  */
247
- export function forgetEffectiveReviewerNames(cli?: string): void {
267
+ export function forgetEffectiveReviewerNames(cli?: string, agent: AgentIdentity | null = null): void {
248
268
  cached = null;
249
269
  reviewerCli = cli;
270
+ reviewerAgent = agent;
250
271
  }
@@ -165,6 +165,9 @@ export const credentialsFile = (home?: string) => atHome(home, "credentials.json
165
165
  */
166
166
  export const jevConfigFile = (home?: string) => atHome(home, "jev.json");
167
167
 
168
+ /** Owner-only inventory maintained by failproofaid. Paths stay on this machine. */
169
+ export const agentRosterFile = (home?: string) => atHome(home, "agents", "roster.json");
170
+
168
171
  // ── Daemon binaries ──────────────────────────────────────────────────────────
169
172
 
170
173
  export const binDir = (home?: string) => atHome(home, "bin");
@@ -656,6 +659,9 @@ export const HOME_CLASSES: readonly { path: (home?: string) => string; class: Da
656
659
  // history the user was already told about. Kept OUT of `auditSessionFile`
657
660
  // precisely so both survive a sign-out.
658
661
  { path: auditMachineFile, class: "identity" },
662
+ // Profile IDs are stable across restarts and renames. A reset that deleted
663
+ // this file would make Cloud's exact-profile assignments match nobody.
664
+ { path: agentRosterFile, class: "identity" },
659
665
 
660
666
  // ── May be dropped: rebuilt on demand ──
661
667
  // NOTE: `auditDir` itself is deliberately absent. Layout 4 made it MIXED — it
@@ -37,7 +37,7 @@ import type { TwoTierReview } from "./semantic/combine";
37
37
  import type { JevActivityFields } from "./semantic/combine";
38
38
  import type { JevConfig } from "./semantic/jev-config";
39
39
  import { clearPolicies, registerPolicy, getPoliciesForEvent } from "./policy-registry";
40
- import { loadAllCustomHooks } from "./custom-hooks-loader";
40
+ import { loadAllCustomHooks, type LoadAllResult } from "./custom-hooks-loader";
41
41
  import { contestedReviewerNames, effectiveReviewerNames, jevChecksInstalled } from "./effective-reviewers";
42
42
  import {
43
43
  authorityDeclarationFor,
@@ -56,13 +56,34 @@ import { resolveTranscriptPath } from "./resolve-transcript-path";
56
56
  import { getInstanceId } from "../../lib/telemetry-id";
57
57
  import { hookLogInfo, hookLogWarn } from "./hook-logger";
58
58
  import { readStdinPayload } from "./read-stdin";
59
- import { readActiveCloudManagedPolicies, type CloudManagedPolicyArtifact } from "./cloud-managed-policies";
59
+ import {
60
+ cloudJevAsks,
61
+ withCloudAuthority,
62
+ readActiveCloudManagedPolicies,
63
+ readCloudJevMode,
64
+ readCloudJevState,
65
+ readCloudAgentScopeRequired,
66
+ type CloudManagedPolicyArtifact,
67
+ type CloudPolicyError,
68
+ } from "./cloud-managed-policies";
69
+ import {
70
+ cloudPolicyErrorsPath,
71
+ collectCloudPolicyErrors,
72
+ installedPackIds,
73
+ jevBudgetPath,
74
+ readJevBudgetDrops,
75
+ writeCloudPolicyErrors,
76
+ recordCloudLoadChecked,
77
+ } from "./cloud-policy-errors";
60
78
  import { hasInstalledRegexPacks, readInstalledPacks, type PackError, type ResolvedPack } from "./pack-manifest";
61
79
  import { missingGuards, packFailureReason, combinedGuardMatch, guardsCover } from "./pack-failclosed";
62
80
  import { readActivePause, type ActivePause } from "./session-pause";
63
81
  import { jevConfigFile } from "./fp-home";
64
82
  import { layoutWarningForHook } from "./fp-reset";
65
83
  import { noteUntracedAgent } from "./untraced-note";
84
+ import { isHealthProbe } from "./health-probe";
85
+ import { readRuntimeAgentIdentity, runtimeAgentSettingsPath } from "./agent-roster";
86
+ import type { AgentIdentity } from "./agent-targets";
66
87
 
67
88
  /**
68
89
  * Canonicalize an event name to PascalCase. Codex sends snake_case event names
@@ -169,6 +190,8 @@ export interface EvaluateHookEventOptions {
169
190
  * written for.
170
191
  */
171
192
  fallbackCwd?: string;
193
+ /** Config selected by the hook process (may differ from the worker's env). */
194
+ agentSettingsPath?: string;
172
195
  /**
173
196
  * The warm worker's hook into its request queue. Called at most once, and
174
197
  * only on the two-tier path, at the point this evaluation stops reading the
@@ -222,10 +245,20 @@ async function runObserved(
222
245
  // package ships none: until `failproofai policies add FailproofAI/jev-policies`
223
246
  // (or another pack declaring `semantic` checks) Jev is inert — no request, no
224
247
  // intent capture — whether the config is BYOK or FailproofAI Cloud's;
248
+ //
249
+ // …or, in place of the first two, FailproofAI Cloud sets this machine's Jev
250
+ // mode to `observe`/`enforce` (`active.json` `jevMode`, CONTRACT C10): then
251
+ // EVERY gated call goes to FailproofAI Cloud on the Cloud Jev credential —
252
+ // `jev.json` is not used — because the checks Cloud deployed to this machine
253
+ // live there and this machine cannot know which apply. Cloud's `off` switches
254
+ // Jev off whatever `jev.json` says. The remaining conditions hold either way:
225
255
  // - `FAILPROOFAI_EVALUATOR` is not `legacy` (see "Turning Jev off" below);
226
- // - this is not the fail-closed `forceDecision` path and no session pause is
256
+ // - this is not the fail-closed `forceDecision` path, and no session pause is
227
257
  // active — a pause suspends local policy, and Jev must not become a way to
228
- // evaluate what the pause switched off;
258
+ // evaluate what the pause switched off. FailproofAI Cloud's checks are the
259
+ // exception, as Cloud JS assignments are: under a Cloud mode that asks, a
260
+ // paused session's calls still go to Cloud, with no installed pack's check
261
+ // in them;
229
262
  // - the event is a gate (`PreToolUse` / `PermissionRequest`) for a named tool
230
263
  // that the AGENT requested (see `isHumanAuthoredGate`).
231
264
  //
@@ -266,6 +299,14 @@ function jevForcedOff(opts: EvaluateHookEventOptions | undefined): boolean {
266
299
  return process.env.FAILPROOFAI_EVALUATOR === "legacy" || !!opts?.forceDecision;
267
300
  }
268
301
 
302
+ /** How a Cloud-mode review reaches FailproofAI Cloud (`semantic/cloud-jev.ts`). */
303
+ interface CloudJevRoute {
304
+ machineId: string;
305
+ deployment: number | null;
306
+ mode: "observe" | "enforce";
307
+ agent: AgentIdentity | null;
308
+ }
309
+
269
310
  /**
270
311
  * The BYOK config (with the build's default mode, D2), or null (Jev off). A
271
312
  * config that cannot be read is off, never a failure. Logged at info, like
@@ -283,8 +324,31 @@ function jevForcedOff(opts: EvaluateHookEventOptions | undefined): boolean {
283
324
  * unreadable directory above it and a path that is not a file are all null
284
325
  * there too.
285
326
  */
286
- async function readJevConfig(): Promise<{ config: JevConfig; defaultMode: TwoTierReview["mode"] } | null> {
327
+ async function readJevConfig(agent?: AgentIdentity | null): Promise<{
328
+ config: JevConfig;
329
+ defaultMode: TwoTierReview["mode"];
330
+ /** Set when FailproofAI Cloud's mode asks: the review goes to Cloud. */
331
+ cloud?: CloudJevRoute;
332
+ } | null> {
287
333
  try {
334
+ // FailproofAI Cloud's mode, when its deployment sets one, decides (CONTRACT
335
+ // C10.2): `off` is no Jev at all, whatever `jev.json` says; `observe` or
336
+ // `enforce` runs Jev on FailproofAI Cloud with the Cloud Jev credential —
337
+ // never `jev.json`'s provider — or not at all, when this machine cannot
338
+ // (`loadJevConfigForCloudMode` says why, for `errors.json`). Read off
339
+ // `active.json`, which is small and read on this path already.
340
+ const cloud = readCloudJevState();
341
+ if (cloud.jevMode === "off") return null;
342
+ if (cloudJevAsks(cloud.jevMode)) {
343
+ const { loadJevConfigForCloudMode, DEFAULT_JEV_MODE } = await import("./semantic/jev-config");
344
+ const resolved = loadJevConfigForCloudMode(cloud.jevMode);
345
+ if (!resolved.config || !resolved.machineId) return null;
346
+ return {
347
+ config: resolved.config,
348
+ defaultMode: DEFAULT_JEV_MODE,
349
+ cloud: { machineId: resolved.machineId, deployment: cloud.deployment, mode: cloud.jevMode, agent: agent ?? null },
350
+ };
351
+ }
288
352
  if (!existsSync(jevConfigFile())) return null;
289
353
  const { loadJevConfig, DEFAULT_JEV_MODE } = await import("./semantic/jev-config");
290
354
  const config = loadJevConfig();
@@ -300,6 +364,90 @@ async function readJevConfig(): Promise<{ config: JevConfig; defaultMode: TwoTie
300
364
  }
301
365
  }
302
366
 
367
+ /**
368
+ * Where a Jev decision's check came from, as activity-row fields. A FailproofAI
369
+ * Cloud check's outcome arrives with `origin.cloudPolicyId`/`cloudVersion`,
370
+ * carried pack-shaped through the review (`cloud:<id>` / `<version>`, see
371
+ * `semantic/cloud-jev.ts`), and is filed here under the Cloud attribution pair
372
+ * a Cloud JS policy's decision uses — so the Cloud policy page counts it
373
+ * against the policy that was deployed.
374
+ */
375
+ function jevAttribution(
376
+ origin: { packId: string; packVersion?: string } | undefined,
377
+ ): { packId?: string; packVersion?: string; cloudPolicyId?: string; cloudVersion?: number } {
378
+ if (!origin) return {};
379
+ if (origin.packId.startsWith("cloud:")) {
380
+ const version = Number(origin.packVersion);
381
+ return {
382
+ cloudPolicyId: origin.packId.slice("cloud:".length),
383
+ ...(Number.isSafeInteger(version) ? { cloudVersion: version } : {}),
384
+ };
385
+ }
386
+ return origin;
387
+ }
388
+
389
+ /**
390
+ * Compute and write `cloud-policies/errors.json` for this machine's Cloud
391
+ * deployment. A no-op off a Cloud-managed machine (`writeCloudPolicyErrors`
392
+ * skips without an `active.json`) and when nothing changed. Never throws.
393
+ */
394
+ async function recordCloudPolicyErrors(input: {
395
+ manifestError: string | null;
396
+ jsPolicies: CloudManagedPolicyArtifact[];
397
+ jsFailures: LoadAllResult["cloudFailures"] | undefined;
398
+ agentScopeUnresolved?: boolean;
399
+ }): Promise<void> {
400
+ try {
401
+ const jev = readCloudJevState();
402
+ const managed = input.manifestError !== null || input.jsPolicies.length > 0 || jev.jevMode !== null ||
403
+ jev.errors.length > 0 || input.agentScopeUnresolved === true;
404
+ // An unmanaged machine never reads further. A managed machine whose
405
+ // deployment just emptied still writes, so a stale report is cleared.
406
+ if (!managed && !existsSync(cloudPolicyErrorsPath())) return;
407
+ // Only while Cloud's mode ASKS (CONTRACT C10.2): why this machine cannot
408
+ // send its calls (`transcripts_disabled`, `jev_unconfigured…`), and the
409
+ // installed packs' checks Cloud dropped for the question budget under this
410
+ // deployment. The config answer is kept by its module until an input
411
+ // changes, so the second ask of a gate event reads no file.
412
+ let jevProblem: string | null = null;
413
+ let budgetDrops: CloudPolicyError[] = [];
414
+ let health: CloudPolicyError[] = [];
415
+ if (cloudJevAsks(jev.jevMode)) {
416
+ const { loadJevConfigForCloudMode } = await import("./semantic/jev-config");
417
+ const resolved = loadJevConfigForCloudMode(jev.jevMode);
418
+ jevProblem = resolved.problem;
419
+ if (resolved.machineId) {
420
+ // A drop of a pack uninstalled since is not reported (review m2);
421
+ // `installed.json` is read only when there is a record to filter.
422
+ budgetDrops = existsSync(jevBudgetPath())
423
+ ? readJevBudgetDrops({ machineId: resolved.machineId, deployment: jev.deployment, jevMode: jev.jevMode }, installedPackIds())
424
+ : [];
425
+ }
426
+ // Rate-limited or unavailable FailproofAI Cloud Jev, as this process has seen it (review M3).
427
+ const { cloudJevHealthErrors } = await import("./semantic/cloud-jev-health");
428
+ health = cloudJevHealthErrors();
429
+ }
430
+ writeCloudPolicyErrors(
431
+ collectCloudPolicyErrors({
432
+ manifestError: input.manifestError,
433
+ jsPolicies: input.jsPolicies,
434
+ jsFailures: input.jsFailures,
435
+ jev,
436
+ jevProblem,
437
+ budgetDrops,
438
+ health,
439
+ agentScopeUnresolved: input.agentScopeUnresolved,
440
+ }),
441
+ );
442
+ // After the report: what this hook load-checked (N4). A failure is in
443
+ // errors.json first, so the listing never sees a checked policy without
444
+ // its error.
445
+ if (input.jsPolicies.length > 0) recordCloudLoadChecked(input.jsPolicies[0].deployment, input.jsPolicies);
446
+ } catch (err) {
447
+ hookLogInfo(`could not record Cloud policy errors: ${err instanceof Error ? err.message : String(err)}`);
448
+ }
449
+ }
450
+
303
451
  /**
304
452
  * Start Jev's review of this call — before the regex policies run, so the two
305
453
  * proceed in parallel — or return null for the regex-only path.
@@ -311,15 +459,27 @@ async function startTwoTier(
311
459
  cli: IntegrationType,
312
460
  opts: EvaluateHookEventOptions | undefined,
313
461
  activePause: ActivePause | null,
462
+ agent: AgentIdentity | null,
314
463
  ): Promise<TwoTierReview | null> {
315
464
  if (!JEV_GATE_EVENTS.has(canonicalEventType)) return null;
316
465
  if (isHumanAuthoredGate(session.rawHookEventName, cli)) return null;
317
466
  if (typeof parsed.tool_name !== "string" || parsed.tool_name.length === 0) return null;
318
- if (jevForcedOff(opts) || activePause) return null;
319
- // Read off the reviewer set registration just cached, so it is free.
320
- if (!jevChecksInstalled()) return null;
321
- const loaded = await readJevConfig();
467
+ if (jevForcedOff(opts)) return null;
468
+ // Read off the reviewer set registration just cached, so it is free. Under a
469
+ // Cloud mode that asks, every gated call goes to Cloud whether or not an
470
+ // installed pack declares a check: the Cloud checks are Cloud's to select.
471
+ const cloudAsks = cloudJevAsks(readCloudJevMode());
472
+ // A session pause suspends LOCAL policy only: installed packs' Jev checks
473
+ // with it, FailproofAI Cloud's Jev checks never — the same exemption Cloud
474
+ // JS assignments get below, for the same reason (a locally-issued command
475
+ // must not switch off what the org assigned centrally).
476
+ if (activePause && !cloudAsks) return null;
477
+ if (!cloudAsks && !jevChecksInstalled()) return null;
478
+ const loaded = await readJevConfig(agent);
322
479
  if (!loaded) return null;
480
+ // Paused, and the config is not Cloud's after all (read in between): the
481
+ // local path has nothing left to ask.
482
+ if (activePause && !loaded.cloud) return null;
323
483
  const cfg = loaded.config;
324
484
  try {
325
485
  const { startJevReview } = await import("./semantic/jev-review");
@@ -331,6 +491,9 @@ async function startTwoTier(
331
491
  permissionMode: session.permissionMode,
332
492
  sessionId: session.sessionId,
333
493
  cli,
494
+ ...(loaded.cloud ? { cloud: loaded.cloud } : {}),
495
+ // Cloud's checks are still asked; the installed packs' are not.
496
+ ...(activePause ? { localPaused: true } : {}),
334
497
  });
335
498
  } catch (err) {
336
499
  // Configured but unable to start: that is a fallback, and it is recorded
@@ -405,7 +568,9 @@ async function captureJevIntent(
405
568
  ): Promise<void> {
406
569
  if (canonicalEventType !== "UserPromptSubmit" || jevForcedOff(opts)) return;
407
570
  try {
408
- if (!jevChecksInstalled()) return;
571
+ // Same gate as `startTwoTier`: a Cloud mode that asks needs what the human
572
+ // typed whatever the installed packs declare.
573
+ if (!cloudJevAsks(readCloudJevMode()) && !jevChecksInstalled()) return;
409
574
  if (!(await readJevConfig())) return;
410
575
  if (decision === "deny") {
411
576
  const { ENFORCEMENT_CAPABILITY } = await import("./enforcement-capability");
@@ -464,6 +629,12 @@ export async function evaluateHookEvent(
464
629
  }
465
630
  }
466
631
 
632
+ // The daemon health probe: proof the worker answers, not an agent event.
633
+ // Answered before anything records scope errors or activity (B3).
634
+ if (isHealthProbe(eventType, parsed)) {
635
+ return { exitCode: 0, stdout: "", stderr: "" };
636
+ }
637
+
467
638
  normalizeCliPayload(cli, parsed);
468
639
 
469
640
  // Canonicalize event name (Codex sends snake_case; internals expect PascalCase)
@@ -508,6 +679,9 @@ export async function evaluateHookEvent(
508
679
  rawHookEventName: eventType,
509
680
  cli,
510
681
  };
682
+ const runtimeAgent = readRuntimeAgentIdentity(
683
+ cli, opts?.agentSettingsPath ?? runtimeAgentSettingsPath(cli, session.cwd),
684
+ );
511
685
 
512
686
  let config: HooksConfig;
513
687
  let customHooksList: CustomHook[] = [];
@@ -554,7 +728,7 @@ export async function evaluateHookEvent(
554
728
  } else {
555
729
  // Load enabled policies (merge across project/local/global scopes)
556
730
  config = readMergedHooksConfig(session.cwd);
557
- clearPolicies(cli);
731
+ clearPolicies(cli, runtimeAgent);
558
732
 
559
733
  // A session pause suspends LOCAL policy only, for a bounded time. Cloud
560
734
  // assignments are exempt below for the same reason `disabledCustomPolicies`
@@ -616,10 +790,13 @@ export async function evaluateHookEvent(
616
790
  // than the status quo, which already failed open on five of the twelve —
617
791
  // just accidentally, and without saying so.
618
792
  let cloudManagedPolicies: CloudManagedPolicyArtifact[] = [];
793
+ /** Why the Cloud JS half did not load at all, for `errors.json`. */
794
+ let cloudManifestError: string | null = null;
619
795
  try {
620
- cloudManagedPolicies = readActiveCloudManagedPolicies();
796
+ cloudManagedPolicies = readActiveCloudManagedPolicies(runtimeAgent);
621
797
  } catch (err) {
622
798
  const msg = err instanceof Error ? err.message : String(err);
799
+ cloudManifestError = msg;
623
800
  hookLogWarn(
624
801
  `[failproofai] cloud-managed policies could NOT be loaded and are not being enforced: ${msg}. ` +
625
802
  `Local policies are unaffected. Run \`failproofai config --status\` to check this machine's enrolment.`,
@@ -633,7 +810,9 @@ export async function evaluateHookEvent(
633
810
  // policy decided this event: "what was deployed here at the time" is a
634
811
  // separate question from "what decided", and only the former can tell a
635
812
  // rollout that changed nothing from one that never reached the machine.
636
- cloudDeployment = cloudManagedPolicies[0]?.deployment;
813
+ // A machine whose deployment carries only a Jev mode has no JS policy to
814
+ // read it off.
815
+ cloudDeployment = cloudManagedPolicies[0]?.deployment ?? readCloudJevState().deployment ?? undefined;
637
816
  // Installed packs. `readInstalledPacks` never throws: a bad manifest or a
638
817
  // tampered artifact yields zero packs and a recorded reason, which is
639
818
  // sound ONLY because the builtins still ship compiled in and keep
@@ -661,11 +840,22 @@ export async function evaluateHookEvent(
661
840
  ...installedPacks.map((pack) => pack.path),
662
841
  ];
663
842
 
843
+ // A FailproofAI Cloud policy's `reviewedBy` names ITS OWN Cloud Jev
844
+ // checks, which run on FailproofAI Cloud (CONTRACT C10.5). Each is
845
+ // translated here to `cloud:<id>/<name>` — a reviewer only that policy's
846
+ // own Cloud outcomes can satisfy, never an installed pack's check of the
847
+ // same name (C9.4) — and only while Cloud's Jev mode asks. An `observe`
848
+ // assignment, or no mode that asks, is hard, without a warning: that is
849
+ // the org's choice, not a broken policy. Before the loader, so two
850
+ // assignments sharing one artifact merge names that still say whose.
851
+ const cloudJevMode = readCloudJevMode();
852
+ const cloudForLoading = cloudManagedPolicies.map((policy) => withCloudAuthority(policy, cloudJevMode));
853
+
664
854
  // Load and register custom hooks (layer 2, after builtins)
665
855
  const loadResult = await loadAllCustomHooks(allExplicitPaths, {
666
856
  sessionCwd: session.cwd,
667
857
  customPoliciesEnabled: config.customPoliciesEnabled,
668
- ...(cloudManagedPolicies.length > 0 ? { cloudManagedPolicies } : {}),
858
+ ...(cloudForLoading.length > 0 ? { cloudManagedPolicies: cloudForLoading } : {}),
669
859
  ...(installedPacks.length > 0 ? { packs: installedPacks } : {}),
670
860
  });
671
861
  customHooksList = loadResult.hooks;
@@ -812,6 +1002,7 @@ export async function evaluateHookEvent(
812
1002
  // for the user's own files; anything unclear registers as hard. Said
813
1003
  // aloud when a `reviewable` claim is refused and Jev is configured, so
814
1004
  // an author is not left wondering why Jev never clears it.
1005
+ // A Cloud record's authority was translated before loading (above).
815
1006
  const authority = authorityDeclarationFor(hook, { cloudManaged, pack });
816
1007
  // Against the same set `registerPolicy` judges it by, or this warning
817
1008
  // describes a different machine than the registry does: a pack that
@@ -835,6 +1026,17 @@ export async function evaluateHookEvent(
835
1026
  );
836
1027
  }
837
1028
 
1029
+ // What this machine could not load from its FailproofAI Cloud deployment,
1030
+ // for the daemon to report on its next poll. Only on a managed machine,
1031
+ // written only when it changes, and never able to cost this event its
1032
+ // answer (see `cloud-policy-errors.ts`).
1033
+ await recordCloudPolicyErrors({
1034
+ manifestError: cloudManifestError,
1035
+ jsPolicies: cloudManagedPolicies,
1036
+ jsFailures: loadResult.cloudFailures,
1037
+ agentScopeUnresolved: runtimeAgent === null && readCloudAgentScopeRequired(),
1038
+ });
1039
+
838
1040
  // Fail closed on enforcement this machine was told it had and does not.
839
1041
  //
840
1042
  // Additive, and deliberately NOT a clearPolicies() the way the
@@ -924,7 +1126,7 @@ export async function evaluateHookEvent(
924
1126
  // starts HERE, before any regex policy runs, and evaluatePolicies combines
925
1127
  // the two (see semantic/combine.ts). Otherwise this is null and the call
926
1128
  // below is exactly the regex-only evaluation it always was.
927
- const twoTier = await startTwoTier(canonicalEventType, parsed, session, cli, opts, activePause);
1129
+ const twoTier = await startTwoTier(canonicalEventType, parsed, session, cli, opts, activePause, runtimeAgent);
928
1130
  // On the two-tier path the registry is read for the activity row BEFORE
929
1131
  // evaluating, because evaluatePolicies may hand the registry back to the
930
1132
  // warm worker's queue (`releaseRegistry`) while it waits on Jev, and the
@@ -1001,7 +1203,7 @@ export async function evaluateHookEvent(
1001
1203
  // would be false — so it is attributed to Jev itself. Leaving it out
1002
1204
  // instead filed every Jev block under "unattributed" on FailproofAI
1003
1205
  // Cloud's policy page, beside rows written before attribution existed.
1004
- ...(result.policyName && result.twoTier?.decidedByJev ? { policySource: "jev" as const, ...jevOrigin } : {}),
1206
+ ...(result.policyName && result.twoTier?.decidedByJev ? { policySource: "jev" as const, ...jevAttribution(jevOrigin) } : {}),
1005
1207
  ...(result.policyName && !result.twoTier?.decidedByJev
1006
1208
  ? (() => {
1007
1209
  const attribution = policyAttribution.get(result.policyName);
@@ -1016,6 +1218,14 @@ export async function evaluateHookEvent(
1016
1218
  };
1017
1219
  })()
1018
1220
  : {}),
1221
+ // Observe mode, nothing else decided: the Jev check that would have is
1222
+ // named on the row, with its Cloud policy (B12). Before, the row read
1223
+ // policyName/cloudPolicyId null, so "would have" never reached a policy.
1224
+ // No `policySource`: nothing decided this call, and the policy page
1225
+ // counts a source as a decision; `observed` carries the "would have".
1226
+ ...(!result.policyName && observeVerdict
1227
+ ? { policyName: observeVerdict.policyName, ...jevAttribution(result.twoTier?.jevOrigin) }
1228
+ : {}),
1019
1229
  ...(cloudDeployment !== undefined ? { cloudDeployment } : {}),
1020
1230
  // The point of observe mode is this record. Without it the rollout is
1021
1231
  // unmeasurable and the row is indistinguishable from one where the policy
@@ -1116,7 +1326,11 @@ export async function evaluateHookEvent(
1116
1326
  * kept unchanged so nothing about the one-shot (non-daemon) path regresses.
1117
1327
  * Internally now just a thin wrapper around `evaluateHookEvent`.
1118
1328
  */
1119
- export async function handleHookEvent(eventType: string, cli: IntegrationType = "claude"): Promise<number> {
1329
+ export async function handleHookEvent(
1330
+ eventType: string,
1331
+ cli: IntegrationType = "claude",
1332
+ agentSettingsPath?: string,
1333
+ ): Promise<number> {
1120
1334
  const MAX_STDIN_BYTES = 1_048_576; // 1 MB
1121
1335
  const stdinRead = await readStdinPayload(MAX_STDIN_BYTES);
1122
1336
  if (stdinRead.readError) {
@@ -1148,7 +1362,10 @@ export async function handleHookEvent(eventType: string, cli: IntegrationType =
1148
1362
  });
1149
1363
  }
1150
1364
 
1151
- const result = await evaluateHookEvent(eventType, cli, stdinRead.payload);
1365
+ const result = await evaluateHookEvent(
1366
+ eventType, cli, stdinRead.payload,
1367
+ agentSettingsPath === undefined ? undefined : { agentSettingsPath },
1368
+ );
1152
1369
 
1153
1370
  // Say it out loud, once a session, when the collector is holding batches the
1154
1371
  // server definitively refused.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The daemon health probe's marker (`probeDaemon` in `daemon-service.ts`).
3
+ *
4
+ * The probe is a SessionStart sent through the daemon to the warm worker, so a
5
+ * reply proves the whole path answers. It is not an agent's session: the
6
+ * handler answers it before any scope, policy or activity logic, or every
7
+ * probe recorded `agent_scope_unresolved` in `errors.json` (it carries no cwd
8
+ * and no `--agent-scope`) and wrote a fake SessionStart activity row.
9
+ */
10
+ export const HEALTH_PROBE_SOURCE = "failproofai-health-probe";
11
+
12
+ /** Whether a parsed hook payload is the daemon health probe. */
13
+ export function isHealthProbe(eventType: string, parsed: Record<string, unknown>): boolean {
14
+ return eventType === "SessionStart" && parsed.source === HEALTH_PROBE_SOURCE && parsed.session_id === undefined;
15
+ }
@@ -154,6 +154,12 @@ function isMarkedHook(hook: unknown): boolean {
154
154
  return cmd.includes("failproofai") && cmd.includes("--hook");
155
155
  }
156
156
 
157
+ /** A hook names its installing settings scope, avoiding a cwd-based guess
158
+ * when user and project/local hooks both exist for the same integration. */
159
+ function agentScopeSuffix(scope?: HookScope): string {
160
+ return ` --agent-scope ${scope ?? "user"}`;
161
+ }
162
+
157
163
  function stripLegacyVersion(settings: Record<string, unknown>): boolean {
158
164
  if ("version" in settings) {
159
165
  delete settings.version;
@@ -285,7 +291,7 @@ export const claudeCode: Integration = {
285
291
  : `"${binaryPath}" --hook ${eventType}`;
286
292
  return {
287
293
  type: "command",
288
- command,
294
+ command: command + agentScopeSuffix(scope),
289
295
  // Claude reads `timeout` in SECONDS per https://code.claude.com/docs/en/hooks
290
296
  // ("Seconds before canceling. Defaults: 600 for command ...; 60 for agent"),
291
297
  // NOT milliseconds. 60 = 60s; the old 60000 meant ~16.7h. (#482-class unit fix)
@@ -464,7 +470,7 @@ export const codex: Integration = {
464
470
  // Codex reads `timeout` in SECONDS (the field is literally `timeout`,
465
471
  // default 600 per https://developers.openai.com/codex/hooks) — same unit as
466
472
  // Claude/Cursor/Copilot. 60 = 60s.
467
- command,
473
+ command: command + agentScopeSuffix(scope),
468
474
  timeout: 60,
469
475
  [FAILPROOFAI_HOOK_MARKER]: true,
470
476
  };
@@ -644,8 +650,8 @@ export const copilot: Integration = {
644
650
  : `"${binaryPath}" --hook ${eventType} --cli copilot`;
645
651
  return {
646
652
  type: "command",
647
- bash: cmd,
648
- powershell: cmd,
653
+ bash: cmd + agentScopeSuffix(scope),
654
+ powershell: cmd + agentScopeSuffix(scope),
649
655
  timeoutSec: 60,
650
656
  [FAILPROOFAI_HOOK_MARKER]: true,
651
657
  };
@@ -788,7 +794,7 @@ export const cursor: Integration = {
788
794
  // use 30 and 10), NOT milliseconds. 60 = 60s; the old 60000 meant ~16.7h.
789
795
  return {
790
796
  type: "command",
791
- command,
797
+ command: command + agentScopeSuffix(scope),
792
798
  timeout: 60,
793
799
  [FAILPROOFAI_HOOK_MARKER]: true,
794
800
  };
@@ -981,12 +987,13 @@ function canonicalizeToolInput(canonicalToolName, args) {
981
987
 
982
988
  const FAILPROOFAI_BIN = ${escapedBin};
983
989
  const USE_NPX = ${useNpx};
990
+ const AGENT_SCOPE = ${JSON.stringify(scope)};
984
991
 
985
992
  function runFailproofai(eventName, payload, directory) {
986
993
  const cmd = USE_NPX ? "npx" : FAILPROOFAI_BIN;
987
994
  const args = USE_NPX
988
- ? ["-y", "failproofai", "--hook", eventName, "--cli", "opencode"]
989
- : ["--hook", eventName, "--cli", "opencode"];
995
+ ? ["-y", "failproofai", "--hook", eventName, "--cli", "opencode", "--agent-scope", AGENT_SCOPE]
996
+ : ["--hook", eventName, "--cli", "opencode", "--agent-scope", AGENT_SCOPE];
990
997
  const r = spawnSync(cmd, args, {
991
998
  input: JSON.stringify(payload),
992
999
  encoding: "utf8",
@@ -2460,7 +2467,7 @@ export const factory: Integration = {
2460
2467
  : `"${binaryPath}" --hook ${eventType} --cli factory`;
2461
2468
  return {
2462
2469
  type: "command",
2463
- command,
2470
+ command: command + agentScopeSuffix(scope),
2464
2471
  // droid reads `timeout` in SECONDS (verified against droid v0.171.0). 30s.
2465
2472
  timeout: 30,
2466
2473
  [FAILPROOFAI_HOOK_MARKER]: true,
@@ -2593,7 +2600,7 @@ export const devin: Integration = {
2593
2600
  : `"${binaryPath}" --hook ${eventType} --cli devin`;
2594
2601
  return {
2595
2602
  type: "command",
2596
- command,
2603
+ command: command + agentScopeSuffix(scope),
2597
2604
  // Devin reads `timeout` in SECONDS like Claude. 60 = 60s.
2598
2605
  timeout: 60,
2599
2606
  [FAILPROOFAI_HOOK_MARKER]: true,
@@ -2738,7 +2745,7 @@ export const antigravity: Integration = {
2738
2745
  : `"${binaryPath}" --hook ${eventType} --cli antigravity`;
2739
2746
  return {
2740
2747
  type: "command",
2741
- command,
2748
+ command: command + agentScopeSuffix(scope),
2742
2749
  // Antigravity reads `timeout` in SECONDS (verified agy v1.1.2). 30s.
2743
2750
  timeout: 30,
2744
2751
  [FAILPROOFAI_HOOK_MARKER]: true,
@@ -2926,7 +2933,7 @@ export const goose: Integration = {
2926
2933
  : `"${binaryPath}" --hook ${eventType} --cli goose`;
2927
2934
  // Open Plugins command entry: { type, command } only (Goose applies its own
2928
2935
  // timeout; no marker field — see isGooseFailproofaiHook).
2929
- return { type: "command", command };
2936
+ return { type: "command", command: command + agentScopeSuffix(scope) };
2930
2937
  },
2931
2938
 
2932
2939
  isFailproofaiHook: isGooseFailproofaiHook,