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
@@ -25,12 +25,42 @@
25
25
  * - **Absent optionals stay absent.** `beta`, `alwaysOn` and `params` are read
26
26
  * with `in` and `undefined` checks; default-filling them changes behaviour and
27
27
  * fails existing tests.
28
+ * - **Every entry states its `authority`,** even though absent already means
29
+ * `hard`: whether Jev may clear a builtin's verdict is a decision to make per
30
+ * policy, not a default to inherit. `reviewable` only where a semantic policy
31
+ * genuinely covers the same concern, named in `reviewedBy`. The table and the
32
+ * reasoning are in `docs/policies/authority.mdx`; `alwaysOn` is hard whatever
33
+ * it says here.
28
34
  *
29
35
  * `params.default` values are handed to policies BY REFERENCE, so this must stay
30
36
  * one module-level const — never a factory minting fresh defaults per call.
31
37
  */
32
38
  import type { PolicyCatalogEntry, PolicyParamsSchema } from "./policy-types";
33
39
 
40
+ /**
41
+ * ── On `authority` and `reviewedBy` in this file ──
42
+ *
43
+ * `reviewable` means Jev may CLEAR this policy's verdict, and only through the
44
+ * semantic checks named here — every one of which must have been asked.
45
+ *
46
+ * Both ways of getting a pairing wrong are silent, and the asymmetry between
47
+ * them is what decides these rows:
48
+ *
49
+ * - a check that is never ASKED never clears, so the block becomes permanent
50
+ * - a check that is asked and does not FIRE answers "no concern", and no
51
+ * concern CLEARS — so naming a check that does not model this policy's
52
+ * shapes does not review the policy, it switches it off for exactly the
53
+ * inputs that check does not understand
54
+ *
55
+ * And an `instruct`-mode check can never answer deny. So the test is not "can
56
+ * the named reviewer keep this block" but "is there anything left that can
57
+ * deny": a deny-mode name in the conjunction, or a deny-mode check covering the
58
+ * same concern independently, or a policy that never denied in the first place.
59
+ * `block-work-on-main` fails all three and is hard for that reason.
60
+ *
61
+ * Each row's own comment says which of those applies. The reasoning was worked
62
+ * out policy by policy in FailproofAI/jev-policies' DECISIONS.md.
63
+ */
34
64
  export const POLICY_CATALOG: PolicyCatalogEntry[] = [
35
65
  {
36
66
  name: "sanitize-jwt",
@@ -38,6 +68,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
38
68
  displayTitle: "Redacted JWT tokens from tool output",
39
69
  impact: "Stops the agent from echoing auth tokens it saw in command output.",
40
70
  match: { events: ["PostToolUse"] },
71
+ authority: "hard",
41
72
  defaultEnabled: true,
42
73
  category: "Sanitize",
43
74
  },
@@ -47,6 +78,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
47
78
  displayTitle: "Redacted API keys from tool output",
48
79
  impact: "Catches OpenAI / Anthropic / GitHub / AWS / Stripe / Google keys before the model sees them.",
49
80
  match: { events: ["PostToolUse"] },
81
+ authority: "hard",
50
82
  defaultEnabled: true,
51
83
  category: "Sanitize",
52
84
  params: {
@@ -63,6 +95,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
63
95
  displayTitle: "Redacted database connection strings from tool output",
64
96
  impact: "Strips embedded DB credentials before they reach the model context.",
65
97
  match: { events: ["PostToolUse"] },
98
+ authority: "hard",
66
99
  defaultEnabled: true,
67
100
  category: "Sanitize",
68
101
  },
@@ -72,6 +105,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
72
105
  displayTitle: "Redacted PEM private keys from tool output",
73
106
  impact: "Prevents private key bodies from being echoed into chat context.",
74
107
  match: { events: ["PostToolUse"] },
108
+ authority: "hard",
75
109
  defaultEnabled: true,
76
110
  category: "Sanitize",
77
111
  },
@@ -81,6 +115,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
81
115
  impact: "Strips Authorization: Bearer values before they hit the model.",
82
116
  description: "Stop Claude from reading Authorization Bearer tokens in tool responses",
83
117
  match: { events: ["PostToolUse"] },
118
+ authority: "hard",
84
119
  defaultEnabled: true,
85
120
  category: "Sanitize",
86
121
  },
@@ -90,6 +125,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
90
125
  impact: "Env vars often contain secrets; blocking `env` / `printenv` keeps them out of the model context.",
91
126
  description: "Prevent commands that read environment variables",
92
127
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
128
+ authority: "reviewable",
129
+ reviewedBy: ["env-secrets-dump", "secret-exposure"],
93
130
  defaultEnabled: true,
94
131
  category: "Environment",
95
132
  },
@@ -99,6 +136,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
99
136
  impact: "`.env` files routinely contain API keys and DB credentials.",
100
137
  description: "Block reading/writing .env files",
101
138
  match: { events: ["PreToolUse"] },
139
+ authority: "reviewable",
140
+ reviewedBy: ["secret-exposure"],
102
141
  defaultEnabled: true,
103
142
  category: "Environment",
104
143
  },
@@ -108,6 +147,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
108
147
  impact: "Stops the agent from peeking at neighboring repos or your home directory.",
109
148
  description: "Block file reads outside the session working directory",
110
149
  match: { events: ["PreToolUse"], toolNames: ["Read", "Glob", "Grep", "Bash"] },
150
+ authority: "reviewable",
151
+ reviewedBy: ["read-outside-workspace"],
111
152
  defaultEnabled: false,
112
153
  category: "Environment",
113
154
  params: {
@@ -126,6 +167,18 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
126
167
  // PermissionRequest is Codex's escalation-approval event; fire the same
127
168
  // sudo guard there so Codex sandbox bypasses are blocked too.
128
169
  match: { events: ["PreToolUse", "PermissionRequest"], toolNames: ["Bash"] },
170
+ // Hard, although `privilege-escalation` is deny-mode and its probe is a strict superset
171
+ // of this matcher — so the pairing would pass the "is there anything left that can
172
+ // deny" test. The reason it stays hard is the OTHER clearing path: that check is
173
+ // `userCanOverride: true`, so a human naming the operation clears it, and this policy
174
+ // is `defaultEnabled: true`. Reviewable would therefore turn "sudo is blocked" into
175
+ // "sudo is blocked unless you asked for it" on every machine with Jev configured.
176
+ // Measured against what that buys: the false-block reduction on the labelled corpus
177
+ // came from `block-read-outside-cwd`, `protect-env-vars` and `block-env-files`, which
178
+ // were already reviewable. Sudo contributed nothing to it, so the trade is a headline
179
+ // guarantee for no measured gain. The nine opt-in policies that ARE reviewable here
180
+ // reach only people who switched them on deliberately.
181
+ authority: "hard",
129
182
  defaultEnabled: true,
130
183
  category: "Dangerous Commands",
131
184
  params: {
@@ -142,6 +195,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
142
195
  impact: "`curl ... | sh` runs unverified remote code on your machine.",
143
196
  description: "Block piping downloads to shell",
144
197
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
198
+ // Hard, for the same reason as `block-sudo` above: the `remote-code-execution` pairing is
199
+ // sound, but the check is overridable by an explicit request and this policy is on by
200
+ // default, so reviewable would mean "piping a download to a shell is blocked unless you
201
+ // asked for it". The substring false positive it has — `grep -rn "curl x | sh"` is
202
+ // denied — is real and is the argument for pairing it; it is also rare enough not to
203
+ // pay for weakening the default.
204
+ authority: "hard",
145
205
  defaultEnabled: true,
146
206
  category: "Dangerous Commands",
147
207
  },
@@ -151,6 +211,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
151
211
  impact: "Catches catastrophic `rm -rf /` and Windows equivalents.",
152
212
  description: "Prevent catastrophic deletions",
153
213
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
214
+ // Reviewable: `destructive-deletion` is deny-mode, and its second probe is this
215
+ // policy's path-depth heuristic done properly — `irreplaceable`'s false criteria
216
+ // (build output, dist/, caches, node_modules, virtualenvs, coverage, temp files) is
217
+ // exactly this heuristic's error term. `rm -rf /` keeps both probes true and stays
218
+ // denied; `rm -rf node_modules` is the false block this pairing exists to remove.
219
+ authority: "reviewable",
220
+ reviewedBy: ["destructive-deletion"],
154
221
  defaultEnabled: false,
155
222
  category: "Dangerous Commands",
156
223
  params: {
@@ -180,6 +247,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
180
247
  },
181
248
  defaultEnabled: true,
182
249
  alwaysOn: true,
250
+ authority: "hard",
183
251
  category: "Dangerous Commands",
184
252
  },
185
253
  {
@@ -188,6 +256,12 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
188
256
  impact: "kubectl can change live cluster state — gated unless allow-listed.",
189
257
  description: "Block kubectl commands (Kubernetes cluster mutations)",
190
258
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
259
+ // Reviewable: `production-infra-change` is deny-mode and names kubectl explicitly. This
260
+ // policy denies the whole CLI, read-only subcommands included; the probe's false
261
+ // criteria is the split a regex cannot make — get, list, describe, logs, status,
262
+ // plan, diff, validate, whoami, --dry-run.
263
+ authority: "reviewable",
264
+ reviewedBy: ["production-infra-change"],
191
265
  defaultEnabled: false,
192
266
  category: "Infra Commands",
193
267
  params: {
@@ -204,6 +278,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
204
278
  impact: "Terraform mutates real infrastructure — gated unless allow-listed.",
205
279
  description: "Block terraform and tofu (OpenTofu) commands",
206
280
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
281
+ // Reviewable: same pairing as `block-kubectl`; the probe names terraform and tofu, and
282
+ // clears `terraform plan` and `terraform validate`.
283
+ authority: "reviewable",
284
+ reviewedBy: ["production-infra-change"],
207
285
  defaultEnabled: false,
208
286
  category: "Infra Commands",
209
287
  params: {
@@ -220,6 +298,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
220
298
  impact: "AWS CLI can spend money or break prod — gated.",
221
299
  description: "Block aws CLI commands",
222
300
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
301
+ // Reviewable: same pairing; the probe names aws, and clears `aws sts
302
+ // get-caller-identity` and `aws s3 ls`.
303
+ authority: "reviewable",
304
+ reviewedBy: ["production-infra-change"],
223
305
  defaultEnabled: false,
224
306
  category: "Infra Commands",
225
307
  params: {
@@ -236,6 +318,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
236
318
  impact: "gcloud can spend money or break prod — gated.",
237
319
  description: "Block gcloud (Google Cloud) CLI commands",
238
320
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
321
+ // Reviewable: same pairing; the probe names gcloud, and clears `gcloud auth list` and
322
+ // `gcloud config list`.
323
+ authority: "reviewable",
324
+ reviewedBy: ["production-infra-change"],
239
325
  defaultEnabled: false,
240
326
  category: "Infra Commands",
241
327
  params: {
@@ -252,6 +338,9 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
252
338
  impact: "az can spend money or break prod — gated.",
253
339
  description: "Block az (Azure) CLI commands",
254
340
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
341
+ // Reviewable: same pairing; the probe names az, and clears `az account show`.
342
+ authority: "reviewable",
343
+ reviewedBy: ["production-infra-change"],
255
344
  defaultEnabled: false,
256
345
  category: "Infra Commands",
257
346
  params: {
@@ -268,6 +357,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
268
357
  impact: "Helm releases mutate cluster state — gated.",
269
358
  description: "Block helm commands",
270
359
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
360
+ // Reviewable: same pairing; the probe names helm, and clears `helm list` and
361
+ // `helm status`.
362
+ authority: "reviewable",
363
+ reviewedBy: ["production-infra-change"],
271
364
  defaultEnabled: false,
272
365
  category: "Infra Commands",
273
366
  params: {
@@ -284,6 +377,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
284
377
  impact: "Catches `gh workflow run`, `gh pr merge`, `gh secret set`, etc.",
285
378
  description: "Block gh CLI pipeline-trigger subcommands (workflow run, run rerun/cancel, pr merge, release create/delete, cache delete, secret set/delete)",
286
379
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
380
+ authority: "hard",
287
381
  defaultEnabled: false,
288
382
  category: "Infra Commands",
289
383
  params: {
@@ -300,6 +394,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
300
394
  impact: "Stops the agent from creating `.pem`, `id_rsa`, `credentials.json`, etc.",
301
395
  description: "Block writing secret key files",
302
396
  match: { events: ["PreToolUse"], toolNames: ["Write"] },
397
+ // Reviewable: `secret-exposure` is deny-mode and `write` is in its `appliesTo`, so a
398
+ // real private key still comes back deny. What clears is this matcher's substring
399
+ // problem — `/credentials/` and `id_rsa` unanchored against a whole path, which
400
+ // catches `src/auth/credentials.ts`. `credential-exfiltration` would have been a
401
+ // dead name here: it applies to shell and network, and a file write is neither.
402
+ authority: "reviewable",
403
+ reviewedBy: ["secret-exposure"],
303
404
  defaultEnabled: false,
304
405
  category: "Dangerous Commands",
305
406
  params: {
@@ -316,6 +417,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
316
417
  impact: "Direct pushes to a protected branch bypass review.",
317
418
  description: "Block pushing to main/master",
318
419
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
420
+ authority: "hard",
319
421
  defaultEnabled: true,
320
422
  category: "Git",
321
423
  params: {
@@ -332,6 +434,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
332
434
  impact: "Force-pushes rewrite history and can clobber teammates' work.",
333
435
  description: "Prevent force-pushing to any branch",
334
436
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
437
+ // Reviewable: `git-history-rewrite` is deny-mode and its probe is a superset of this
438
+ // matcher — it counts `--force-with-lease` (which `isForcePushFlag` deliberately
439
+ // treats as safe), a `+refspec`, and a remote-branch delete, and says `git -C dir`
440
+ // and an absolute binary path change nothing. A real force-push stays blocked; what
441
+ // clears is the user asking to force-push their own branch.
442
+ authority: "reviewable",
443
+ reviewedBy: ["git-history-rewrite"],
335
444
  defaultEnabled: false,
336
445
  category: "Git",
337
446
  },
@@ -341,6 +450,22 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
341
450
  impact: "Work should land via PR — direct commits skip review.",
342
451
  description: "Block git commits and merges on main/master branch",
343
452
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
453
+ // Hard, although `commit-on-protected-branch` covers exactly this concern.
454
+ // That check is `mode: "instruct"`, and an instruct-mode reviewer can never
455
+ // answer deny — so the conjunction had one reachable outcome, cleared, and
456
+ // marking this reviewable did not hand the decision to Jev. It switched the
457
+ // policy off on every machine that configured Jev, while the mark said
458
+ // otherwise.
459
+ //
460
+ // The engine has since changed under that argument: a reviewer that FIRES
461
+ // with nobody consenting now keeps the block (`combine.ts`, "A check that
462
+ // fired without consent keeps the floor"), so an instruct-only reviewer is
463
+ // no longer "off". `block-read-outside-cwd`, which also has only an
464
+ // instruct reviewer, stays reviewable on exactly that rule: it clears when
465
+ // the read is requested or the check finds nothing, and keeps the deny on
466
+ // an unrequested read it flags. Making this one reviewable again is a
467
+ // product call nobody has made.
468
+ authority: "hard",
344
469
  defaultEnabled: false,
345
470
  category: "Git",
346
471
  params: {
@@ -357,6 +482,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
357
482
  impact: "Amending after a push rewrites history that others may have pulled.",
358
483
  description: "Warns before amending git commits, which rewrites history",
359
484
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
485
+ authority: "reviewable",
486
+ reviewedBy: ["git-history-rewrite"],
360
487
  defaultEnabled: false,
361
488
  category: "Git",
362
489
  },
@@ -366,8 +493,71 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
366
493
  impact: "Stash deletions are permanent and silent.",
367
494
  description: "Warns before permanently deleting stashed changes",
368
495
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
496
+ authority: "hard",
497
+ defaultEnabled: false,
498
+ category: "Git",
499
+ },
500
+ {
501
+ name: "warn-git-clean",
502
+ displayTitle: "Tried to delete untracked or ignored files with git clean",
503
+ impact: "`git clean -fdx` takes `.env`, local config and unstaged work — git never had a copy of any of it.",
504
+ description: "Warns before git clean deletes untracked directories (-d) or ignored files (-x / -X)",
505
+ match: { events: ["PreToolUse"], toolNames: ["Bash"] },
506
+ // Hard, and deliberately NOT `reviewable` through `destructive-deletion`,
507
+ // although that check is the one whose whole subject is deleting data that
508
+ // cannot be regenerated.
509
+ //
510
+ // Measured on a real machine, through the real hook, with a Jev config
511
+ // present, on `git clean -fdx`:
512
+ //
513
+ // jev: ok decision=allow applied=two-tier 495ms
514
+ // probes: destructive-deletion.destroys=0.94 beyond_task=0.79 task_step=0.78
515
+ //
516
+ // `destroys` came back 0.94 — the check sees the destruction; its own
517
+ // instructions name `git clean -fdx` by example. The policy still did not
518
+ // fire, because evidence is the MIN over a policy's probes and the partner
519
+ // probe `irreplaceable` came back low (it is absent from the probe line,
520
+ // which lists only what answered above the display floor). That is not a
521
+ // tuning accident: `git clean` carries NO path operand, so `facts.paths` is
522
+ // empty (measured — `extractPaths` skips `clean` as not path-like and
523
+ // `-fdx` as a flag), while `irreplaceable` is written to read
524
+ // `facts.paths[].relation` and to answer false for "only regenerable data
525
+ // inside the project: build output, dist/, caches, node_modules, …". With
526
+ // nothing to point at, the false branch is the honest answer to the
527
+ // question as written.
528
+ //
529
+ // A named check that is asked and does not fire answers "no concern", and
530
+ // that CLEARS (`combine.ts`, "A check that fired without consent keeps the
531
+ // floor"). So
532
+ // pairing this policy with `destructive-deletion` would not hand the
533
+ // decision to Jev — it would switch the policy off on every machine that
534
+ // configured Jev, which is exactly the `block-work-on-main` mistake. The
535
+ // test is "is there anything left that can DENY", and no other deny-mode
536
+ // semantic check covers untracked-file deletion, so a clear would leave the
537
+ // concern enforced by nothing. Hard until the probe is recalibrated against
538
+ // the corpus; the proposed wording and why it needs a replay are in
539
+ // `PROBE-FOLLOWUP.md`.
540
+ authority: "hard",
541
+ // Off by default, and `instruct` rather than `deny`, because `git clean
542
+ // -fdx` is a command developers run on purpose and often — it is the
543
+ // standard way to get a genuinely clean tree before a build. A default-on
544
+ // deny would fire on ordinary work, and a guard people switch off protects
545
+ // nothing; every policy in this category except `block-push-master` is
546
+ // default-off for the same reason, and `block-read-outside-cwd` was
547
+ // demoted out of the audit's archetype signal for being exactly this kind
548
+ // of ambient. What IS worth saying every time it is enabled is that the
549
+ // blast radius is wider than the operator usually means, so the policy
550
+ // warns and names what goes.
369
551
  defaultEnabled: false,
370
552
  category: "Git",
553
+ params: {
554
+ destructiveFlags: {
555
+ type: "string[]",
556
+ description:
557
+ "git clean flag letters that make it worth warning about, checked alongside --force. Narrow to ['x','X'] to allow `git clean -fd`, or widen with 'f' to warn on a bare `git clean -f`.",
558
+ default: ["d", "x", "X"],
559
+ },
560
+ } satisfies PolicyParamsSchema,
371
561
  },
372
562
  {
373
563
  name: "warn-all-files-staged",
@@ -375,6 +565,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
375
565
  impact: "Wide stages routinely catch generated files or secrets you didn't intend to commit.",
376
566
  description: "Warns before staging all working tree files with git add -A / . / --all",
377
567
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
568
+ authority: "hard",
378
569
  defaultEnabled: false,
379
570
  category: "Git",
380
571
  },
@@ -384,6 +575,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
384
575
  impact: "Easy way to wipe a table by accident.",
385
576
  description: "Warn before executing destructive SQL (DROP/TRUNCATE/DELETE without WHERE) via database clients",
386
577
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
578
+ authority: "reviewable",
579
+ reviewedBy: ["database-destruction"],
387
580
  defaultEnabled: false,
388
581
  category: "Database",
389
582
  },
@@ -393,6 +586,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
393
586
  impact: "ALTER TABLE operations can lock tables and break readers.",
394
587
  description: "Warns before SQL schema changes (ALTER TABLE with column or rename operations)",
395
588
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
589
+ authority: "hard",
396
590
  defaultEnabled: false,
397
591
  category: "Database",
398
592
  },
@@ -402,6 +596,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
402
596
  impact: "Publishes are irreversible — `npm publish` / `cargo publish` shouldn't happen without intent.",
403
597
  description: "Warn before publishing packages to public registries (npm, PyPI, crates.io, RubyGems, etc.)",
404
598
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
599
+ authority: "hard",
405
600
  defaultEnabled: false,
406
601
  category: "Packages & System",
407
602
  },
@@ -411,6 +606,8 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
411
606
  impact: "`npm i -g`, `cargo install`, `pip --user` pollute your machine outside the project.",
412
607
  description: "Warns before installing packages globally (npm -g, cargo install, etc.)",
413
608
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
609
+ authority: "reviewable",
610
+ reviewedBy: ["system-modification"],
414
611
  defaultEnabled: false,
415
612
  category: "Packages & System",
416
613
  },
@@ -420,6 +617,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
420
617
  impact: "Mixing package managers creates lockfile churn for your team.",
421
618
  description: "Blocks non-preferred package managers and tells Claude to use an allowed one (e.g., uv instead of pip)",
422
619
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
620
+ authority: "hard",
423
621
  defaultEnabled: false,
424
622
  category: "Packages & System",
425
623
  params: {
@@ -441,6 +639,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
441
639
  impact: "Catches accidentally large file writes (logs, binaries, model dumps).",
442
640
  description: "Warn before writing files larger than 1MB (configurable via thresholdKb param)",
443
641
  match: { events: ["PreToolUse"], toolNames: ["Write"] },
642
+ authority: "hard",
444
643
  defaultEnabled: false,
445
644
  category: "Packages & System",
446
645
  params: {
@@ -457,6 +656,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
457
656
  impact: "Catches `nohup` / `&` / `screen` / `tmux` / `disown` patterns that the agent often forgets to clean up.",
458
657
  description: "Warns before starting detached or background processes",
459
658
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
659
+ authority: "hard",
460
660
  defaultEnabled: false,
461
661
  category: "Packages & System",
462
662
  },
@@ -466,6 +666,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
466
666
  impact: "Usually a sign of a stuck loop burning tokens.",
467
667
  description: "Warn when the same tool is called 3+ times with identical parameters",
468
668
  match: { events: ["PreToolUse"] },
669
+ authority: "hard",
469
670
  defaultEnabled: false,
470
671
  category: "AI Behavior",
471
672
  },
@@ -475,6 +676,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
475
676
  impact: "Work not in a commit is invisible to teammates and easy to lose.",
476
677
  description: "Require all changes to be committed before Claude stops",
477
678
  match: { events: ["Stop"] },
679
+ authority: "hard",
478
680
  defaultEnabled: false,
479
681
  category: "Workflow",
480
682
  },
@@ -484,6 +686,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
484
686
  impact: "Local-only commits won't trigger CI or be reviewable.",
485
687
  description: "Require all commits to be pushed to remote before Claude stops",
486
688
  match: { events: ["Stop"] },
689
+ authority: "hard",
487
690
  defaultEnabled: false,
488
691
  category: "Workflow",
489
692
  params: {
@@ -505,6 +708,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
505
708
  impact: "Branches without PRs don't get reviewed.",
506
709
  description: "Require a pull request to exist for the current branch before Claude stops",
507
710
  match: { events: ["Stop"] },
711
+ authority: "hard",
508
712
  defaultEnabled: false,
509
713
  category: "Workflow",
510
714
  params: {
@@ -521,6 +725,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
521
725
  impact: "Conflicting branches can't merge — surface them early.",
522
726
  description: "Require the current branch to merge cleanly with the base branch before Claude stops",
523
727
  match: { events: ["Stop"] },
728
+ authority: "hard",
524
729
  defaultEnabled: false,
525
730
  category: "Workflow",
526
731
  params: {
@@ -537,6 +742,7 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
537
742
  impact: "Failing CI blocks deploy.",
538
743
  description: "Require CI checks to pass on the current HEAD commit before Claude stops (ignores stale runs on prior commits)",
539
744
  match: { events: ["Stop"] },
745
+ authority: "hard",
540
746
  defaultEnabled: false,
541
747
  category: "Workflow",
542
748
  },