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,386 @@
1
+ /**
2
+ * Policy authority: who has the last word on a policy's deny or instruct once
3
+ * Jev is configured. See {@link PolicyAuthority} for the two values and
4
+ * `docs/policies/authority.mdx` for the builtin table.
5
+ *
6
+ * Every route a policy arrives by — a builtin, the user's own policy file, an
7
+ * installed pack, a cloud assignment — declares its authority somewhere
8
+ * different. This module is the one place those declarations are read and
9
+ * judged, so the rule cannot drift between them:
10
+ *
11
+ * - `hard` is the default and the answer to anything unclear. Absent, a value
12
+ * that is not one of the two, a `reviewedBy` that is empty or malformed or
13
+ * names a check this build does not have, or an `alwaysOn` policy: all hard.
14
+ * - `reviewable` means Jev may clear the policy's verdict — and only through the
15
+ * semantic policies it names, every one of which must have been asked.
16
+ *
17
+ * Nothing here decides anything at evaluation time. It resolves a declaration
18
+ * once, at registration, and `registerPolicy` stores the result, so what sits in
19
+ * the registry is already the effective authority.
20
+ */
21
+ import { existsSync } from "node:fs";
22
+ import { jevConfigFile } from "./fp-home";
23
+ import { hookLogWarn } from "./hook-logger";
24
+ import { effectiveAuthority } from "./policy-types";
25
+ import type { CustomHook, PolicyAuthority, PolicyCatalogEntry } from "./policy-types";
26
+
27
+ /**
28
+ * A declaration as it arrives, before anything has vouched for it. Fields are
29
+ * `unknown` because three of the four sources are files on disk written by
30
+ * somebody else.
31
+ */
32
+ export interface AuthorityDeclaration {
33
+ authority?: unknown;
34
+ reviewedBy?: unknown;
35
+ /** The self-protection guard. Always hard, whatever else it says. */
36
+ alwaysOn?: boolean;
37
+ }
38
+
39
+ /** The shape-valid authority fields a parsed record (a pack entry, a cloud assignment) carries. */
40
+ export interface AuthorityFields {
41
+ authority?: PolicyAuthority;
42
+ reviewedBy?: string[];
43
+ }
44
+
45
+ /** What a registered policy carries: already judged, and honest to its type. */
46
+ export interface ResolvedAuthority {
47
+ authority: PolicyAuthority;
48
+ /** Present exactly when `authority` is `reviewable`. Deduplicated, in declared order. */
49
+ reviewedBy?: string[];
50
+ /**
51
+ * Why a `reviewable` declaration was not honored, for a warning. Absent when
52
+ * nothing asked for `reviewable` — a policy that is simply hard is not news.
53
+ */
54
+ downgraded?: string;
55
+ }
56
+
57
+ /**
58
+ * The names `reviewedBy` may use: the semantic policies in
59
+ * `src/hooks/semantic/policies.ts`. Not the probes (`INJECTION_PROBE`,
60
+ * `SCOPE_PROBE`, the task probes) — those are inputs to Jev's decision, not
61
+ * checks a regex verdict can be cleared by.
62
+ *
63
+ * Written out rather than read off `SEMANTIC_POLICIES`, and pinned to it by
64
+ * `policy-authority.test.ts`. The registry imports this module, so a runtime
65
+ * import of the semantic policies would load all sixteen of Jev's prompts on
66
+ * every hook event of a machine that never configured Jev, and bundle them into
67
+ * every pack artifact that registers a policy.
68
+ */
69
+ export const SEMANTIC_POLICY_NAMES = [
70
+ "destructive-deletion",
71
+ "production-infra-change",
72
+ "git-history-rewrite",
73
+ "push-to-protected-branch",
74
+ "commit-on-protected-branch",
75
+ "secret-exposure",
76
+ "credential-exfiltration",
77
+ "remote-code-execution",
78
+ "privilege-escalation",
79
+ "database-destruction",
80
+ "read-outside-workspace",
81
+ "agent-config-tampering",
82
+ "system-modification",
83
+ "env-secrets-dump",
84
+ "external-destructive-action",
85
+ "external-data-egress",
86
+ ] as const;
87
+
88
+ /**
89
+ * The compiled-in reviewer set, and the DEFAULT rather than the only one.
90
+ *
91
+ * A pack that declares its own `semantic` entries replaces
92
+ * `SEMANTIC_POLICIES` wholesale on the machine that installed it, so the names
93
+ * a `reviewedBy` may use there are the pack's. Callers that know which set is
94
+ * live pass it (`effectiveReviewerNames()` in `effective-reviewers.ts`, which reads
95
+ * the manifest and imports nothing from `semantic/`); everyone else gets this
96
+ * one, which is what a machine with no pack runs.
97
+ */
98
+ export const SEMANTIC_REVIEWER_NAMES: ReadonlySet<string> = new Set(SEMANTIC_POLICY_NAMES);
99
+
100
+ const isName = (n: unknown): n is string => typeof n === "string" && n.length > 0;
101
+
102
+ /**
103
+ * Judge one declaration.
104
+ *
105
+ * Stricter than `effectiveAuthority`, which is the §7 contract and needs only
106
+ * one usable name: here EVERY entry must be a semantic policy this build has,
107
+ * and anything else makes the whole declaration hard rather than being dropped.
108
+ * `reviewedBy` is a conjunction, so dropping a name the author wrote — a typo, a
109
+ * stray `7` — would let Jev clear the policy on fewer checks than they asked
110
+ * for. It is also the safe direction for version skew: a pack built against a
111
+ * newer semantic set, installed on an older build, enforces as hard rather than
112
+ * as reviewable-by-less.
113
+ *
114
+ * What this returns is what `registerPolicy` stores, so a registered policy's
115
+ * `reviewedBy` is always clean and the two functions agree on it.
116
+ *
117
+ * @param knownReviewers - the semantic policies that CAN be asked on this
118
+ * machine. Defaults to the compiled-in set, which is what runs until a pack
119
+ * ships its own; see {@link SEMANTIC_REVIEWER_NAMES}. It is a parameter rather
120
+ * than a lookup because this module is imported by the registry, and reading
121
+ * which set is live means reading a file — a cost registration is willing to
122
+ * pay once and this judgement must not pay per call.
123
+ */
124
+ export function resolvePolicyAuthority(
125
+ decl: AuthorityDeclaration | undefined,
126
+ knownReviewers: ReadonlySet<string> = SEMANTIC_REVIEWER_NAMES,
127
+ /** Names left out of `knownReviewers` because packs declare them differently, with those packs. */
128
+ contested?: ReadonlyMap<string, string[]>,
129
+ ): ResolvedAuthority {
130
+ const declaredReviewable = decl?.authority === "reviewable";
131
+ if (!decl || effectiveAuthority(decl) === "hard") {
132
+ if (!declaredReviewable) return { authority: "hard" };
133
+ return { authority: "hard", downgraded: whyHard(decl!) };
134
+ }
135
+ const names = decl.reviewedBy as unknown[];
136
+ if (!names.every(isName)) {
137
+ return { authority: "hard", downgraded: "reviewedBy is not a list of semantic policy names" };
138
+ }
139
+ const unknown = names.filter((n) => !knownReviewers.has(n));
140
+ if (unknown.length > 0) {
141
+ return { authority: "hard", downgraded: `reviewedBy names ${unknown.map((n) => whyUnknown(n, knownReviewers, contested)).join("; ")}` };
142
+ }
143
+ return { authority: "reviewable", reviewedBy: [...new Set(names)] };
144
+ }
145
+
146
+ /**
147
+ * The rule that kept one name out. "Not in this build" is only true of the
148
+ * compiled-in set: a pack's own checks, or a name two packs disagree on, is a
149
+ * different reason, and the author reading it has a different fix.
150
+ */
151
+ function whyUnknown(name: string, known: ReadonlySet<string>, contested?: ReadonlyMap<string, string[]>): string {
152
+ // Quoted with JSON.stringify: a pack's name reaches the hook's stderr, so a
153
+ // control character in it must not reach the terminal raw.
154
+ const quoted = JSON.stringify(name);
155
+ const claimants = contested?.get(name);
156
+ if (claimants) return `${quoted}, which packs ${claimants.join(" and ")} declare differently, so it is asked for neither`;
157
+ if (known === SEMANTIC_REVIEWER_NAMES) return `${quoted}, which is not a semantic policy in this build`;
158
+ const sorted = [...known].sort();
159
+ const listed = sorted.length > 6 ? `${sorted.slice(0, 6).join(", ")} and ${sorted.length - 6} more` : sorted.join(", ");
160
+ return `${quoted}, which is not among the Jev checks it is judged against (${listed})`;
161
+ }
162
+
163
+ function whyHard(decl: AuthorityDeclaration): string {
164
+ if (decl.alwaysOn === true) return "it is alwaysOn, and the self-protection guard is never reviewable";
165
+ if (!Array.isArray(decl.reviewedBy) || decl.reviewedBy.length === 0) {
166
+ return "reviewedBy does not name any semantic policy";
167
+ }
168
+ return "reviewedBy is not a list of semantic policy names";
169
+ }
170
+
171
+ /**
172
+ * The shape-valid authority fields of a serialized policy entry, for parsers.
173
+ *
174
+ * Invalid fields are DROPPED, never thrown on. A pack or cloud deployment that
175
+ * is refused over a typo in an optional field fails closed and denies every
176
+ * tool call its policies cover; dropping the field makes that one policy hard,
177
+ * which is the default the typo would have produced at registration anyway.
178
+ * Names are not checked against the semantic set here — that is a property of
179
+ * the build reading the entry, not of the entry, and is judged at registration.
180
+ */
181
+ export function authorityFieldsOf(raw: Record<string, unknown>): AuthorityFields {
182
+ const out: AuthorityFields = {};
183
+ if (raw.authority === "hard" || raw.authority === "reviewable") out.authority = raw.authority;
184
+ const list = raw.reviewedBy;
185
+ if (Array.isArray(list) && list.length > 0 && list.every(isName)) {
186
+ out.reviewedBy = [...(list as string[])];
187
+ }
188
+ return out;
189
+ }
190
+
191
+ /**
192
+ * Why a declaration cannot be PUBLISHED as written, or `undefined` when it can.
193
+ *
194
+ * For build steps — `scripts/build-policy-pack.mjs` and `failproofai publish`.
195
+ * The loaders drop a malformed field and registration downgrades a refused
196
+ * `reviewable`, both toward hard and both only as a warning, because by then the
197
+ * pack is installed and refusing it would fail it closed. At build time nothing
198
+ * is installed yet, so refusing costs nobody anything, while shipping the
199
+ * declaration would make the policy silently hard on every machine that
200
+ * installs it — a decision its author made, quietly not taking effect.
201
+ *
202
+ * An empty `reviewedBy` on a hard policy is not a problem: it says nothing.
203
+ */
204
+ export function authorityProblem(
205
+ decl: AuthorityDeclaration,
206
+ /**
207
+ * The reviewers the pack being built will SHIP WITH — its own `semantic`
208
+ * entries when it declares any, this build's set otherwise. A pack that
209
+ * carries both halves of the two-tier set names its own checks, and refusing
210
+ * that would make the feature unpublishable by the tool that implements it.
211
+ */
212
+ knownReviewers: ReadonlySet<string> = SEMANTIC_REVIEWER_NAMES,
213
+ ): string | undefined {
214
+ if (decl.authority !== undefined && decl.authority !== "hard" && decl.authority !== "reviewable") {
215
+ const t = typeof decl.authority;
216
+ return `authority must be "hard" or "reviewable", and is ${t === "string" ? JSON.stringify(decl.authority) : `${/^[aeiou]/.test(t) ? "an" : "a"} ${t}`}`;
217
+ }
218
+ if (decl.reviewedBy !== undefined && !(Array.isArray(decl.reviewedBy) && decl.reviewedBy.every(isName))) {
219
+ return "reviewedBy must be a list of semantic policy names";
220
+ }
221
+ const { downgraded } = resolvePolicyAuthority(decl, knownReviewers);
222
+ return downgraded ? `authority "reviewable" was refused — ${downgraded}` : undefined;
223
+ }
224
+
225
+ /**
226
+ * The authority fields a pack MANIFEST should carry for one entry: resolved, as
227
+ * the registry will store them, so the manifest says exactly what takes effect.
228
+ * Throws, naming the entry, on anything {@link authorityProblem} refuses.
229
+ */
230
+ export function manifestAuthority(
231
+ entry: AuthorityDeclaration & { name: string },
232
+ knownReviewers: ReadonlySet<string> = SEMANTIC_REVIEWER_NAMES,
233
+ ): {
234
+ authority: PolicyAuthority;
235
+ reviewedBy?: string[];
236
+ } {
237
+ const problem = authorityProblem(entry, knownReviewers);
238
+ if (problem) throw new Error(`${entry.name}: ${problem}`);
239
+ const { authority, reviewedBy } = resolvePolicyAuthority(entry, knownReviewers);
240
+ return reviewedBy ? { authority, reviewedBy } : { authority };
241
+ }
242
+
243
+ /**
244
+ * One authority for several declarations that land on ONE registration.
245
+ *
246
+ * Artifacts are content-addressed, so two cloud assignments or two packs whose
247
+ * code is byte-identical load as one policy (the collapse in
248
+ * `custom-hooks-loader.ts`). Keeping one of their declarations would let the
249
+ * order of `active.json` or `installed.json` decide — and let one pack's
250
+ * manifest, or one team's assignment, make another's policy reviewable.
251
+ *
252
+ * So it resolves toward HARD, the way the collapse resolves the effect toward
253
+ * enforce: reviewable only when EVERY declaration resolves to reviewable, and
254
+ * then through the UNION of their checks (more checks that must all come back
255
+ * clear is stricter, never weaker).
256
+ *
257
+ * ## What the merged record may carry, and why it is the RESOLUTION
258
+ *
259
+ * Nothing here copies a declaration through. It used to keep the first one that
260
+ * was not reviewable, so that a refused `reviewable` would be reported again at
261
+ * registration — and that was the hole: a declaration is only ever resolved
262
+ * against the reviewer set of whoever is looking, so a `reviewable` naming a
263
+ * PACK's own check resolved to hard here, against the builtin set, and was
264
+ * copied forward verbatim. `registerPolicy` then resolved that same raw
265
+ * declaration against `effectiveReviewerNames()`, which does have the pack's
266
+ * check — and the policy registered reviewable, with a hard peer behind the same
267
+ * artifact overruled by nothing more than which pack was listed first.
268
+ *
269
+ * Two changes close it. The reviewer set is now a PARAMETER, so the merge judges
270
+ * by the same names registration will; and a non-reviewable merge emits
271
+ * `{ authority: "hard" }` — the resolved value — rather than the fields it was
272
+ * asked for. Either alone would have been enough for the case above; both,
273
+ * because the first is an agreement between two callers and the second holds
274
+ * whether or not they agree.
275
+ *
276
+ * The reason a refused declaration carried is not lost: it comes back as
277
+ * `refused`, for the caller to say through {@link refusedAuthorityWarning} at
278
+ * the point where it knows which artifact and which packs are involved.
279
+ *
280
+ * Returns `record` itself when its own fields already say that, and a copy with
281
+ * only the two authority fields replaced otherwise. `overruled` is true when
282
+ * some declaration asked for reviewable, validly, and did not get it.
283
+ *
284
+ * @param knownReviewers - the checks that can be asked on this machine. Callers
285
+ * that merge what will be REGISTERED must pass `effectiveReviewerNames()`;
286
+ * the default is this build's compiled-in set, which is what a machine with no
287
+ * pack runs.
288
+ */
289
+ export function withMergedAuthority<T extends AuthorityFields>(
290
+ record: T,
291
+ declarations: ReadonlyArray<AuthorityFields>,
292
+ knownReviewers: ReadonlySet<string> = SEMANTIC_REVIEWER_NAMES,
293
+ ): { merged: T; overruled: boolean; refused?: string } {
294
+ const resolved = declarations.map((d) => resolvePolicyAuthority(d, knownReviewers));
295
+ const allReviewable = resolved.length > 0 && resolved.every((r) => r.authority === "reviewable");
296
+ // The declaration that decided it is hard. Its own fields are not carried —
297
+ // only whether it said anything at all, because a record that declared
298
+ // nothing is already hard and rewriting it to say so would touch a record the
299
+ // collapse has no business touching.
300
+ const decided = declarations[resolved.findIndex((r) => r.authority !== "reviewable")] ?? {};
301
+ const fields: AuthorityFields = allReviewable
302
+ ? { authority: "reviewable", reviewedBy: [...new Set(resolved.flatMap((r) => r.reviewedBy ?? []))] }
303
+ : decided.authority === undefined
304
+ ? {}
305
+ : { authority: "hard" };
306
+ const overruled = !allReviewable && resolved.some((r) => r.authority === "reviewable");
307
+ const refused = resolved.find((r) => r.downgraded !== undefined)?.downgraded;
308
+ const extra = refused === undefined ? {} : { refused };
309
+ const same =
310
+ record.authority === fields.authority &&
311
+ JSON.stringify(record.reviewedBy) === JSON.stringify(fields.reviewedBy);
312
+ if (same) return { merged: record, overruled, ...extra };
313
+ const { authority: _a, reviewedBy: _r, ...rest } = record;
314
+ return { merged: { ...rest, ...fields } as T, overruled, ...extra };
315
+ }
316
+
317
+ /**
318
+ * The warning for a `reviewable` declaration that was not honored. One
319
+ * phrasing, wherever it is noticed — registration for a policy that reaches it
320
+ * with its declaration intact, and the loader for one the collapse hardened
321
+ * before it got there.
322
+ */
323
+ export function refusedAuthorityWarning(subject: string, reason: string): string {
324
+ return `${subject} asks to be reviewable, but ${reason} — it stays hard`;
325
+ }
326
+
327
+ const warnedAuthority = new Set<string>();
328
+
329
+ /**
330
+ * Say that an authority declaration was not honored — once per process, and
331
+ * only once Jev is configured (a global `jev.json` exists).
332
+ *
333
+ * Without Jev, authority decides nothing, so there is nothing to tell anyone —
334
+ * and a warning is not free: it goes to the hook's stderr, which some CLIs show
335
+ * as the deny text itself, on every event, for every machine that installed a
336
+ * pack built against a newer semantic set. Once per process keeps the daemon's
337
+ * warm worker from repeating it for every tool call. Authors are told at build
338
+ * time as well: `failproofai publish` refuses what this would warn about.
339
+ *
340
+ * Presence of the file rather than a validated load: a machine where someone
341
+ * has started configuring Jev is where the answer to "why does Jev never clear
342
+ * this policy" is wanted, and a stat keeps the semantic modules unloaded.
343
+ */
344
+ export function warnAuthority(message: string): void {
345
+ try {
346
+ if (!existsSync(jevConfigFile())) return;
347
+ } catch {
348
+ return;
349
+ }
350
+ if (warnedAuthority.has(message)) return;
351
+ warnedAuthority.add(message);
352
+ hookLogWarn(message);
353
+ }
354
+
355
+ /**
356
+ * Where a loaded hook's authority is declared, by the route it arrived on.
357
+ *
358
+ * - **Cloud-managed:** the artifact record in the active deployment. A cloud
359
+ * policy's authority is a central decision, so code inside the artifact
360
+ * cannot grant itself `reviewable`.
361
+ * - **Pack:** the pack's own manifest entry for that policy, matched by name —
362
+ * the same place its `params` schema is read from. A pack can only ever
363
+ * describe its own policies this way: its names cannot contain `/`, and they
364
+ * register under `pack/<id>@<version>/`, so no manifest can reach a builtin
365
+ * or another pack's policy. A policy the artifact registers but the manifest
366
+ * does not declare has no entry and is hard. When packs share one artifact,
367
+ * the loader has already merged their entries toward hard
368
+ * ({@link withMergedAuthority}), so no one of them decides for the others.
369
+ * - **The user's own file:** the hook itself.
370
+ */
371
+ export function authorityDeclarationFor(
372
+ hook: Pick<CustomHook, "name" | "authority" | "reviewedBy">,
373
+ source: {
374
+ cloudManaged?: { authority?: unknown; reviewedBy?: unknown };
375
+ pack?: { policies: PolicyCatalogEntry[] };
376
+ },
377
+ ): AuthorityDeclaration {
378
+ if (source.cloudManaged) {
379
+ return { authority: source.cloudManaged.authority, reviewedBy: source.cloudManaged.reviewedBy };
380
+ }
381
+ if (source.pack) {
382
+ const entry = source.pack.policies.find((p) => p.name === hook.name);
383
+ return { authority: entry?.authority, reviewedBy: entry?.reviewedBy };
384
+ }
385
+ return { authority: hook.authority, reviewedBy: hook.reviewedBy };
386
+ }