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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +8 -7
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +9 -7
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +6 -6
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +11 -10
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +8 -7
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -6
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +7 -6
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +52 -8
- package/.next/standalone/.next/server/app/settings/page.js +12 -7
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1msfs-h._.js → [externals]__19_pzeq._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1_bftcl._.js → [externals]__20kzpkf._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ttrwnd._.js +22 -0
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
- package/.next/standalone/.next/server/chunks/{_1c3k-8x._.js → _1q5i8mb._.js} +2 -2
- package/.next/standalone/.next/server/chunks/lib_16xa545._.js +3 -0
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +5 -0
- package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +4 -2
- package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzs._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02npjtd._.js → [root-of-the-server]__056wjo4._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06pflha._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +22 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0p-5p8u._.js → [root-of-the-server]__0n0xg95._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__013jr2b._.js → [root-of-the-server]__0rwtwpm._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0da85px._.js → [root-of-the-server]__11mayhe._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12e7nhs._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19evfi8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0cxe_2_._.js → [root-of-the-server]__1mf3zp6._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ftmoxc._.js → [root-of-the-server]__1pprgri._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1p2otjt._.js → [root-of-the-server]__1q4p5b8._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_166t73i._.js → _0-vcssj._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +23 -0
- package/.next/standalone/.next/server/chunks/ssr/{_1es2j7i._.js → _1gb0ifp._.js} +5 -5
- package/.next/standalone/.next/server/chunks/ssr/{_1_qswah._.js → _1q46vxx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +13 -13
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0drixxt._.js → node_modules_next_dist_0w6mzq5._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_18_d8l1._.js +151 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0-q0umm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_06kzv9d._.js +12 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0g194sy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +4 -2
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1kx9e0d._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +3 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +67 -23
- package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +6 -0
- package/.next/standalone/.next/static/chunks/0bhidk90e-07f.css +2 -0
- package/.next/standalone/.next/static/chunks/{2mdh397ghgnvv.js → 0m-9d6yn9hx4j.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0__8a7m868fvf.js → 0wbjy0zo-m7is.js} +1 -1
- package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +1 -0
- package/.next/standalone/.next/static/chunks/{0o6qlkgubtoex.js → 21uv-uusw329x.js} +1 -1
- package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +1 -0
- package/.next/standalone/.next/static/chunks/2qdpj67x6ifk_.js +69 -0
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +1 -0
- package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +1 -0
- package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +1 -0
- package/.next/standalone/.next/static/chunks/{13i7-9is-vhys.js → 3c3qbmosdjl6w.js} +1 -1
- package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
- package/.next/standalone/app/actions/get-jev-config.ts +604 -0
- package/.next/standalone/app/actions/pack-actions.ts +12 -0
- package/.next/standalone/app/actions/update-jev-config.ts +569 -0
- package/.next/standalone/app/components/jev-notices.tsx +96 -0
- package/.next/standalone/app/policies/hooks-client.tsx +14 -3
- package/.next/standalone/app/settings/jev-panel.tsx +630 -0
- package/.next/standalone/app/settings/page.tsx +20 -1
- package/.next/standalone/app/settings/settings-client.tsx +27 -1
- package/.next/standalone/app/settings/settings.css +79 -0
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +22 -4
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +14 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +17 -3
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +3 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +22 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +169 -0
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +65 -0
- package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +61 -0
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
- package/.next/standalone/sdk/typescript/CHANGELOG.md +18 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +0 -274
- package/.next/standalone/sdk/typescript/scripts/release.mjs +30 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +3 -2
- package/bin/failproofai.mjs +148 -4
- package/dist/cli.mjs +18599 -9478
- package/dist/index.js +19 -1
- package/dist/worker.mjs +10500 -3773
- package/package.json +10 -10
- package/pi-extension/index.ts +11 -0
- package/scripts/build-policy-pack.mjs +53 -2
- package/src/audit/features.ts +3 -2
- package/src/hooks/builtin-policies.ts +195 -8
- package/src/hooks/cloud-connection.ts +190 -1
- package/src/hooks/cloud-enrollment-cli.ts +57 -8
- package/src/hooks/cloud-introspect.ts +6 -0
- package/src/hooks/cloud-managed-policies.ts +22 -0
- package/src/hooks/configure-wizard.ts +26 -6
- package/src/hooks/custom-hooks-loader.ts +98 -10
- package/src/hooks/custom-hooks-registry.ts +45 -1
- package/src/hooks/effective-reviewers.ts +243 -0
- package/src/hooks/first-run-gate.ts +5 -0
- package/src/hooks/flush-cli.ts +35 -8
- package/src/hooks/fp-config.ts +266 -1
- package/src/hooks/fp-home.ts +23 -0
- package/src/hooks/fp-reset.ts +22 -4
- package/src/hooks/handler.ts +303 -7
- package/src/hooks/hook-activity-store.ts +118 -6
- package/src/hooks/hook-telemetry.ts +41 -0
- package/src/hooks/jev-activity.ts +385 -0
- package/src/hooks/jev-cli.ts +2172 -0
- package/src/hooks/jev-cloud-connection.ts +392 -0
- package/src/hooks/loader-utils.ts +6 -0
- package/src/hooks/manager.ts +45 -7
- package/src/hooks/pack-cli.ts +568 -37
- package/src/hooks/pack-failclosed.ts +3 -0
- package/src/hooks/pack-manifest.ts +489 -7
- package/src/hooks/pack-store.ts +194 -11
- package/src/hooks/policy-authority.ts +386 -0
- package/src/hooks/policy-catalog.ts +206 -0
- package/src/hooks/policy-evaluator.ts +963 -796
- package/src/hooks/policy-registry.ts +27 -1
- package/src/hooks/policy-reviewability.ts +258 -0
- package/src/hooks/policy-types.ts +128 -0
- package/src/hooks/semantic/combine.ts +581 -0
- package/src/hooks/semantic/compile.ts +176 -0
- package/src/hooks/semantic/decide.ts +513 -0
- package/src/hooks/semantic/envelope.ts +1255 -0
- package/src/hooks/semantic/evaluator.ts +556 -0
- package/src/hooks/semantic/facts.ts +387 -0
- package/src/hooks/semantic/intent.ts +1190 -0
- package/src/hooks/semantic/jev-client.ts +1155 -0
- package/src/hooks/semantic/jev-config.ts +1142 -0
- package/src/hooks/semantic/jev-review.ts +389 -0
- package/src/hooks/semantic/jev-stats.ts +289 -0
- package/src/hooks/semantic/jev-throttle.ts +427 -0
- package/src/hooks/semantic/pack-policies.ts +294 -0
- package/src/hooks/semantic/policies.ts +597 -0
- package/src/hooks/semantic/precondition-names.ts +60 -0
- package/src/hooks/semantic/preconditions.ts +58 -0
- package/src/hooks/semantic/redact.ts +2937 -0
- package/src/hooks/semantic/session-root.ts +116 -0
- package/src/hooks/semantic/types.ts +162 -0
- package/src/hooks/semver-precedence.ts +128 -0
- package/src/hooks/tui.ts +4 -0
- package/src/hooks/types.ts +1 -1
- package/src/hooks/worker-server.ts +121 -27
- package/src/index.ts +6 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cuho4x._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_r2rbg._.js +0 -24
- package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bd3mje._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/_0h_douw._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1-i_gzc._.js +0 -23
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +0 -3
- package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +0 -1
- package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +0 -6
- package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +0 -1
- package/.next/standalone/.next/static/chunks/2klitrtzpaoe0.js +0 -1
- package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +0 -2
- package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +0 -1
- package/.next/standalone/.next/static/chunks/3rh5o7e16irrm.js +0 -69
- package/.next/standalone/.next/static/chunks/43ufqrz8qo3h-.js +0 -1
- /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_clientMiddlewareManifest.js +0 -0
- /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
|
},
|