failproofai 1.0.7-beta.2 → 1.0.7
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 +4 -4
- 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 +7 -8
- 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 +5 -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 -13
- 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 +7 -8
- 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 +7 -7
- 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 +6 -7
- 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 +8 -41
- package/.next/standalone/.next/server/app/settings/page.js +9 -12
- 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]__1j-zsg5._.js → [externals]__1_bftcl._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__19_pzeq._.js → [externals]__1msfs-h._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l3yhx4._.js +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1bf34x4._.js → [root-of-the-server]__1_r2rbg._.js} +7 -5
- 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/{_1q5i8mb._.js → _1c3k-8x._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +2 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0l44ual._.js → [root-of-the-server]__0bd3mje._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1mf3zp6._.js → [root-of-the-server]__0cxe_2_._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +22 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1w_5l7t._.js → _0h_douw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1mel6y1._.js → _1-i_gzc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_1v-jvrv._.js → _166t73i._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1q46vxx._.js → _1_qswah._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifp._.js → _1es2j7i._.js} +5 -5
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +3 -0
- 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 +2 -2
- 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_settings-client_tsx_20lq-mq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +10 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.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/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 +23 -56
- package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +1 -0
- package/.next/standalone/.next/static/chunks/{129ag2bw93bdh.js → 0__8a7m868fvf.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3ugmd_7dyn0id.js → 0o6qlkgubtoex.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0fqd7m_u81mi5.js → 13i7-9is-vhys.js} +1 -1
- package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +6 -0
- package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +1 -0
- package/.next/standalone/.next/static/chunks/{2_pltstd8-xgs.js → 2klitrtzpaoe0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3brze37td_wnc.js → 2mdh397ghgnvv.js} +1 -1
- package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +2 -0
- package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +1 -0
- package/.next/standalone/.next/static/chunks/3rh5o7e16irrm.js +69 -0
- package/.next/standalone/.next/static/chunks/{1qd741hzlmjbo.js → 43ufqrz8qo3h-.js} +1 -1
- package/.next/standalone/SECURITY.md +53 -0
- package/.next/standalone/app/actions/pack-actions.ts +0 -12
- package/.next/standalone/app/policies/hooks-client.tsx +0 -9
- package/.next/standalone/app/settings/page.tsx +1 -20
- package/.next/standalone/app/settings/settings-client.tsx +1 -27
- package/.next/standalone/app/settings/settings.css +0 -79
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/typescript/CHANGELOG.md +15 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +10 -30
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +3 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +4 -16
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +3 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +13 -132
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +4 -142
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +1396 -1016
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +9 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +2 -2
- package/bin/failproofai.mjs +2 -115
- package/dist/cli.mjs +6543 -13872
- package/dist/index.js +1 -19
- package/dist/worker.mjs +2022 -8055
- package/package.json +10 -10
- package/pi-extension/index.ts +0 -11
- package/scripts/build-policy-pack.mjs +2 -53
- package/src/audit/features.ts +2 -3
- package/src/hooks/builtin-policies.ts +8 -177
- package/src/hooks/cloud-enrollment-cli.ts +1 -1
- package/src/hooks/cloud-managed-policies.ts +0 -22
- package/src/hooks/custom-hooks-loader.ts +7 -45
- package/src/hooks/custom-hooks-registry.ts +1 -45
- package/src/hooks/first-run-gate.ts +0 -5
- package/src/hooks/fp-home.ts +0 -23
- package/src/hooks/handler.ts +6 -265
- package/src/hooks/hook-activity-store.ts +1 -105
- package/src/hooks/hook-telemetry.ts +0 -41
- package/src/hooks/loader-utils.ts +0 -6
- package/src/hooks/manager.ts +1 -1
- package/src/hooks/pack-cli.ts +19 -412
- package/src/hooks/pack-manifest.ts +7 -479
- package/src/hooks/pack-store.ts +11 -157
- package/src/hooks/policy-catalog.ts +0 -204
- package/src/hooks/policy-evaluator.ts +796 -940
- package/src/hooks/policy-registry.ts +0 -25
- package/src/hooks/policy-types.ts +0 -126
- package/src/hooks/types.ts +1 -1
- package/src/hooks/worker-server.ts +26 -119
- package/src/index.ts +0 -6
- package/.next/standalone/.next/server/chunks/src_hooks_01frwmb._.js +0 -5
- package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qxnccm._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0soxz2z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1feuvhb._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_18_d8l1._.js +0 -151
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_095a_79._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_18k8rl0._.js +0 -12
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +0 -3
- package/.next/standalone/.next/static/chunks/043j99m8ykg__.css +0 -2
- package/.next/standalone/.next/static/chunks/2c8j9l6j_b1ci.js +0 -1
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +0 -1
- package/.next/standalone/.next/static/chunks/3-k569wzcli8q.js +0 -1
- package/.next/standalone/.next/static/chunks/3otmypm6j_xfo.js +0 -6
- package/.next/standalone/.next/static/chunks/3yxro_r2_o9ad.js +0 -69
- package/.next/standalone/PROBE-FOLLOWUP.md +0 -186
- package/.next/standalone/app/actions/get-jev-config.ts +0 -424
- package/.next/standalone/app/actions/update-jev-config.ts +0 -420
- package/.next/standalone/app/components/jev-notices.tsx +0 -96
- package/.next/standalone/app/settings/jev-panel.tsx +0 -473
- package/src/hooks/effective-reviewers.ts +0 -79
- package/src/hooks/jev-activity.ts +0 -385
- package/src/hooks/jev-cli.ts +0 -1249
- package/src/hooks/policy-authority.ts +0 -333
- package/src/hooks/policy-reviewability.ts +0 -229
- package/src/hooks/semantic/combine.ts +0 -541
- package/src/hooks/semantic/compile.ts +0 -176
- package/src/hooks/semantic/decide.ts +0 -392
- package/src/hooks/semantic/envelope.ts +0 -1296
- package/src/hooks/semantic/evaluator.ts +0 -547
- package/src/hooks/semantic/facts.ts +0 -292
- package/src/hooks/semantic/intent.ts +0 -1190
- package/src/hooks/semantic/jev-client.ts +0 -643
- package/src/hooks/semantic/jev-config.ts +0 -594
- package/src/hooks/semantic/jev-review.ts +0 -374
- package/src/hooks/semantic/jev-stats.ts +0 -289
- package/src/hooks/semantic/jev-throttle.ts +0 -421
- package/src/hooks/semantic/pack-policies.ts +0 -251
- package/src/hooks/semantic/policies.ts +0 -596
- package/src/hooks/semantic/precondition-names.ts +0 -60
- package/src/hooks/semantic/preconditions.ts +0 -58
- package/src/hooks/semantic/redact.ts +0 -2910
- package/src/hooks/semantic/types.ts +0 -145
- package/src/hooks/semver-precedence.ts +0 -128
- /package/.next/standalone/.next/static/{gbEOjBgZAxF2UIUwZVHNu → PgeWCHmyVbjRznv2VO7KF}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{gbEOjBgZAxF2UIUwZVHNu → PgeWCHmyVbjRznv2VO7KF}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{gbEOjBgZAxF2UIUwZVHNu → PgeWCHmyVbjRznv2VO7KF}/_ssgManifest.js +0 -0
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { HookEventType } from "./types";
|
|
9
9
|
import type { PolicyFunction, PolicyMatcher, PolicyParamsSchema, RegisteredPolicy } from "./policy-types";
|
|
10
|
-
import { effectiveReviewerNames, forgetEffectiveReviewerNames } from "./effective-reviewers";
|
|
11
|
-
import { resolvePolicyAuthority, type AuthorityDeclaration } from "./policy-authority";
|
|
12
10
|
|
|
13
11
|
const REGISTRY_KEY = "__FAILPROOFAI_POLICY_REGISTRY__";
|
|
14
12
|
const INDEX_CACHE_KEY = "__FAILPROOFAI_POLICY_INDEX_CACHE__";
|
|
@@ -60,34 +58,15 @@ export function registerPolicy(
|
|
|
60
58
|
match: PolicyMatcher,
|
|
61
59
|
priority: number = 0,
|
|
62
60
|
params?: PolicyParamsSchema,
|
|
63
|
-
/**
|
|
64
|
-
* The policy's authority declaration, as its source wrote it. Judged HERE,
|
|
65
|
-
* so the registry only ever holds an effective value: `reviewable` with a
|
|
66
|
-
* clean `reviewedBy`, or `hard`. See `resolvePolicyAuthority`.
|
|
67
|
-
*
|
|
68
|
-
* Absent means the caller declared nothing, and the entry then carries no
|
|
69
|
-
* authority field at all — which `effectiveAuthority` reads as hard.
|
|
70
|
-
*/
|
|
71
|
-
meta?: AuthorityDeclaration,
|
|
72
61
|
): void {
|
|
73
62
|
const canonical = normalizePolicyName(name);
|
|
74
63
|
const registry = getRegistry();
|
|
75
64
|
const idx = registry.findIndex((p) => p.name === canonical);
|
|
76
|
-
// Judged against the reviewers this MACHINE can ask, not against the ones this
|
|
77
|
-
// build compiled in. A pack that ships its own `semantic` set replaces the
|
|
78
|
-
// compiled one, so its policies name checks that exist here and nowhere in
|
|
79
|
-
// `SEMANTIC_POLICY_NAMES` — and judging them by the builtin list would
|
|
80
|
-
// downgrade the whole rewritten set to `hard` while reporting nothing but a
|
|
81
|
-
// warning. `effectiveReviewerNames` reads the manifest — already where a
|
|
82
|
-
// pack's `reviewedBy` itself comes from — once per registration pass.
|
|
83
|
-
const authority = meta ? resolvePolicyAuthority(meta, effectiveReviewerNames()) : undefined;
|
|
84
65
|
const entry: RegisteredPolicy = {
|
|
85
66
|
name: canonical, description, fn, match, priority,
|
|
86
67
|
// Absent stays absent: `evaluatePolicies` distinguishes "declares a schema"
|
|
87
68
|
// from "declares none", and a spread `params: undefined` is neither.
|
|
88
69
|
...(params ? { params } : {}),
|
|
89
|
-
...(authority ? { authority: authority.authority } : {}),
|
|
90
|
-
...(authority?.reviewedBy ? { reviewedBy: authority.reviewedBy } : {}),
|
|
91
70
|
};
|
|
92
71
|
if (idx >= 0) {
|
|
93
72
|
registry[idx] = entry;
|
|
@@ -131,10 +110,6 @@ export function clearPolicies(): void {
|
|
|
131
110
|
const g = globalThis as GlobalWithRegistry;
|
|
132
111
|
g[REGISTRY_KEY] = [];
|
|
133
112
|
setIndexCache(null);
|
|
134
|
-
// The reviewer set describes the policies that are about to be registered, so
|
|
135
|
-
// it is rebuilt with them. Dropping it here is also what keeps one read per
|
|
136
|
-
// evaluation instead of one per policy.
|
|
137
|
-
forgetEffectiveReviewerNames();
|
|
138
113
|
}
|
|
139
114
|
|
|
140
115
|
/**
|
|
@@ -43,52 +43,6 @@ export interface RegisteredPolicy {
|
|
|
43
43
|
* the user's OWN configured `policyParams` for it, not merely the defaults.
|
|
44
44
|
*/
|
|
45
45
|
params?: PolicyParamsSchema;
|
|
46
|
-
/** Whether Jev may clear this policy's deny/instruct; see {@link effectiveAuthority}. */
|
|
47
|
-
authority?: PolicyAuthority;
|
|
48
|
-
/**
|
|
49
|
-
* The semantic policies (`src/hooks/semantic/policies.ts`) that must all be
|
|
50
|
-
* asked, and none of which may answer `deny`, before Jev clears this policy.
|
|
51
|
-
*/
|
|
52
|
-
reviewedBy?: string[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Who has the last word on a policy's deny or instruct when Jev is configured.
|
|
57
|
-
*
|
|
58
|
-
* - `hard`: final. Jev can never clear it.
|
|
59
|
-
* - `reviewable`: Jev may clear it, but only through the semantic policies
|
|
60
|
-
* named in `reviewedBy`, and only when every one of them was actually asked
|
|
61
|
-
* and none of them answered `deny` — a `none`, `overridden` or `instruct`
|
|
62
|
-
* answer clears it (`combine.ts`, "A warning-level answer clears the deny").
|
|
63
|
-
* A named check that was NOT asked always keeps the verdict standing.
|
|
64
|
-
*/
|
|
65
|
-
export type PolicyAuthority = "hard" | "reviewable";
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The authority a policy actually has. `reviewable` only when it is declared
|
|
69
|
-
* `reviewable`, names at least one semantic policy in `reviewedBy`, and is not
|
|
70
|
-
* `alwaysOn`. Anything else — absent, invalid, an empty `reviewedBy`, the
|
|
71
|
-
* self-protection guard — is `hard`, so an unknown custom, cloud or third-party
|
|
72
|
-
* policy can never be weakened by Jev.
|
|
73
|
-
*
|
|
74
|
-
* This is the §7 contract every task builds against, and it is deliberately
|
|
75
|
-
* the looser of two rules: one usable name is enough here. REGISTRATION is
|
|
76
|
-
* stricter — `resolvePolicyAuthority` in `policy-authority.ts` makes the whole
|
|
77
|
-
* declaration hard if any entry is malformed or is not a semantic policy this
|
|
78
|
-
* build has, and that is what `registerPolicy` stores. So a registered policy's
|
|
79
|
-
* `reviewedBy` is already clean, and the two rules agree on everything that
|
|
80
|
-
* reaches the registry.
|
|
81
|
-
*/
|
|
82
|
-
export function effectiveAuthority(p: {
|
|
83
|
-
authority?: unknown;
|
|
84
|
-
reviewedBy?: unknown;
|
|
85
|
-
alwaysOn?: boolean;
|
|
86
|
-
}): PolicyAuthority {
|
|
87
|
-
if (p.alwaysOn === true) return "hard";
|
|
88
|
-
if (p.authority !== "reviewable") return "hard";
|
|
89
|
-
if (!Array.isArray(p.reviewedBy)) return "hard";
|
|
90
|
-
const named = p.reviewedBy.filter((n) => typeof n === "string" && n.length > 0);
|
|
91
|
-
return named.length > 0 ? "reviewable" : "hard";
|
|
92
46
|
}
|
|
93
47
|
|
|
94
48
|
export interface PolicyParamsSchema {
|
|
@@ -135,10 +89,6 @@ export interface BuiltinPolicyDefinition {
|
|
|
135
89
|
* secondary line in the audit report. e.g. "Could leak code from neighboring
|
|
136
90
|
* repos to the model." */
|
|
137
91
|
impact?: string;
|
|
138
|
-
/** See {@link PolicyAuthority}. Absent means `hard`. */
|
|
139
|
-
authority?: PolicyAuthority;
|
|
140
|
-
/** See {@link RegisteredPolicy.reviewedBy}. */
|
|
141
|
-
reviewedBy?: string[];
|
|
142
92
|
}
|
|
143
93
|
|
|
144
94
|
export interface CustomHook {
|
|
@@ -148,82 +98,6 @@ export interface CustomHook {
|
|
|
148
98
|
events?: HookEventType[];
|
|
149
99
|
};
|
|
150
100
|
fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
|
|
151
|
-
/**
|
|
152
|
-
* See {@link PolicyAuthority}. Absent means `hard`.
|
|
153
|
-
*
|
|
154
|
-
* Honored for the user's own local policy files (explicit paths and
|
|
155
|
-
* `.failproofai/policies/`). For a pack policy the pack's MANIFEST decides,
|
|
156
|
-
* and for a cloud-managed one the cloud ARTIFACT record does — the same split
|
|
157
|
-
* as `params`, so the declaration a user reviewed in a listing is the one
|
|
158
|
-
* that takes effect.
|
|
159
|
-
*/
|
|
160
|
-
authority?: PolicyAuthority;
|
|
161
|
-
/** See {@link RegisteredPolicy.reviewedBy}. */
|
|
162
|
-
reviewedBy?: string[];
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* The tool classes a semantic policy may be asked about.
|
|
167
|
-
*
|
|
168
|
-
* A structural copy of `ToolClass` in `src/hooks/semantic/types.ts`, and
|
|
169
|
-
* deliberately not an import of it. This module is the public API's type
|
|
170
|
-
* surface — every custom policy file and every pack entry imports it — and the
|
|
171
|
-
* semantic modules must stay off the import graph of a machine with no
|
|
172
|
-
* `jev.json` (see `precondition-names.ts` for what that costs when it slips).
|
|
173
|
-
* A type import would be erased, but the two lists still have to agree, so
|
|
174
|
-
* `__tests__/hooks/semantic/pack-semantic-registry.test.ts` pins them.
|
|
175
|
-
*/
|
|
176
|
-
export type SemanticToolClass = "shell" | "write" | "read" | "network" | "other";
|
|
177
|
-
|
|
178
|
-
/** One yes/no question in a semantic policy, as a pack declares it. */
|
|
179
|
-
export interface SemanticProbeDeclaration {
|
|
180
|
-
/** Lowercase slug, unique within the policy. The answer map is keyed `<policy>.<id>`. */
|
|
181
|
-
id: string;
|
|
182
|
-
instructions: string;
|
|
183
|
-
criteria?: { true: string; false: string };
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* A semantic (Jev) policy as its author DECLARES it — a question set, not code.
|
|
188
|
-
*
|
|
189
|
-
* The compiled-in equivalent is `SemanticPolicy` in `semantic/types.ts`, and
|
|
190
|
-
* the one difference is the whole reason both exist: there, `precondition` is a
|
|
191
|
-
* function over the computed facts; here it is the NAME of one, because a
|
|
192
|
-
* declaration has to survive a trip through a JSON manifest and because a
|
|
193
|
-
* downloaded artifact must not hand this process an expression to evaluate on
|
|
194
|
-
* every tool call. `semantic/preconditions.ts` binds the name to its predicate.
|
|
195
|
-
*
|
|
196
|
-
* There is no `fn` and no `match`: a semantic policy never executes locally and
|
|
197
|
-
* is never selected by event or tool name — `appliesTo` and `precondition`
|
|
198
|
-
* decide what it is asked about, and Jev answers it. That is also why it is
|
|
199
|
-
* registered through `semanticPolicies`, its own namespace, rather than as a
|
|
200
|
-
* variant of `customPolicies.add`.
|
|
201
|
-
*/
|
|
202
|
-
export interface SemanticPolicyDeclaration {
|
|
203
|
-
/** Short slug. Reported as `semantic/<name>`, and what a `reviewedBy` names. */
|
|
204
|
-
name: string;
|
|
205
|
-
/** Past-tense phrase for what was caught, e.g. "Deleted something irreplaceable". */
|
|
206
|
-
title: string;
|
|
207
|
-
appliesTo: SemanticToolClass[];
|
|
208
|
-
/** `deny` blocks on strong evidence and warns on moderate; `instruct` only ever warns. */
|
|
209
|
-
mode: "deny" | "instruct";
|
|
210
|
-
/**
|
|
211
|
-
* Whether the human's own explicit request may clear this policy.
|
|
212
|
-
*
|
|
213
|
-
* Required, with no default anywhere in the stack. It is the field that
|
|
214
|
-
* decides whether a prompt injection can talk its way past the policy, and a
|
|
215
|
-
* default for it would be a security decision made by absence — the author
|
|
216
|
-
* would never learn which way it went.
|
|
217
|
-
*/
|
|
218
|
-
userCanOverride: boolean;
|
|
219
|
-
/** A name from `PACK_PRECONDITION_NAMES`. Absent, or `"always"`, means no precondition. */
|
|
220
|
-
precondition?: string;
|
|
221
|
-
/** Every probe must hold for the policy to fire (conjunction). 1–6 of them. */
|
|
222
|
-
probes: SemanticProbeDeclaration[];
|
|
223
|
-
/** If this holds, the policy does not fire — the documented exceptions. */
|
|
224
|
-
exempt?: SemanticProbeDeclaration;
|
|
225
|
-
/** Shown to the agent when the policy fires. */
|
|
226
|
-
guidance: string;
|
|
227
101
|
}
|
|
228
102
|
|
|
229
103
|
export interface LlmConfig {
|
package/src/hooks/types.ts
CHANGED
|
@@ -1059,7 +1059,7 @@ export type HookEventType = (typeof HOOK_EVENT_TYPES)[number];
|
|
|
1059
1059
|
*
|
|
1060
1060
|
* It stays in `HOOK_EVENT_TYPES` because that list is the canonical set a
|
|
1061
1061
|
* policy may subscribe to; this one governs what we write into settings.json.
|
|
1062
|
-
* No builtin matches it (all
|
|
1062
|
+
* No builtin matches it (all 39 match only PreToolUse / PostToolUse /
|
|
1063
1063
|
* PermissionRequest / Stop), so nothing is lost by not registering.
|
|
1064
1064
|
*/
|
|
1065
1065
|
export const CLAUDE_INSTALL_EVENT_TYPES = HOOK_EVENT_TYPES.filter(
|
|
@@ -17,10 +17,7 @@
|
|
|
17
17
|
* evaluations could have request B's `clearPolicies()` wipe request A's
|
|
18
18
|
* in-flight registration. Serializing keeps the existing registry code
|
|
19
19
|
* correct with zero changes; a worker_threads/process pool is a valid
|
|
20
|
-
* future enhancement if this becomes a real throughput bottleneck.
|
|
21
|
-
* exception is the network wait of a two-tier (Jev) review, which happens
|
|
22
|
-
* after the registry is no longer read and so does not hold the queue (see
|
|
23
|
-
* `enqueue`).
|
|
20
|
+
* future enhancement if this becomes a real throughput bottleneck.
|
|
24
21
|
*/
|
|
25
22
|
import { createConnection, createServer, type Server, type Socket } from "node:net";
|
|
26
23
|
import { existsSync, unlinkSync } from "node:fs";
|
|
@@ -100,115 +97,37 @@ const TASK_DEADLINE_MS = 60_000;
|
|
|
100
97
|
* worker whose `try_wait()` reports it gone), which costs one cold start and
|
|
101
98
|
* denies the in-flight requests — the same fail-closed outcome they were headed
|
|
102
99
|
* for anyway, but recovered on the next call instead of never.
|
|
103
|
-
*
|
|
104
|
-
* A task may hand its place in the chain back early by calling `release`:
|
|
105
|
-
* the next request starts while the task finishes on its own. Only the
|
|
106
|
-
* two-tier (Jev) path does, at the point it stops reading the registry and
|
|
107
|
-
* starts waiting on Jev's network answer (`EvaluateHookEventOptions.
|
|
108
|
-
* releaseRegistry`). Without that, every hook on the machine — PostToolUse,
|
|
109
|
-
* UserPromptSubmit, other agents' calls — would queue behind each gated call's
|
|
110
|
-
* round trip, and a slow or unreachable provider would push the calls at the
|
|
111
|
-
* back of the queue past the client's 30 s budget into fail-closed denies.
|
|
112
|
-
* A released task no longer holds the registry, so the deadline it was running
|
|
113
|
-
* under — the one that protects the QUEUE — has done its job. It gets a fresh
|
|
114
|
-
* one of its own instead of none: it is still running, its connection's later
|
|
115
|
-
* replies still queue behind it (see `handleConnection`), and a task that has
|
|
116
|
-
* not settled a minute after handing the queue back is wedged on something
|
|
117
|
-
* that is not going to finish. Its Jev wait is bounded by the configured
|
|
118
|
-
* timeout, so nothing on the intended path comes close.
|
|
119
|
-
*
|
|
120
|
-
* Released tasks therefore run concurrently with each other and with the
|
|
121
|
-
* queue: two gated calls can be waiting on Jev at once (T5's throttle shares
|
|
122
|
-
* one cache and token bucket across them, and does not merge identical
|
|
123
|
-
* in-flight requests). Replies on one connection still leave in request order
|
|
124
|
-
* (see `handleConnection`).
|
|
125
100
|
*/
|
|
126
101
|
const WEDGED_EXIT_CODE = 75;
|
|
127
|
-
/**
|
|
128
|
-
* A released task's own deadline, counted from the moment it handed the queue
|
|
129
|
-
* back. Its Jev wait is bounded by the configured timeout (at most 10 s, plus
|
|
130
|
-
* the review's own backstop), so only a task stuck on something else ever
|
|
131
|
-
* reaches this.
|
|
132
|
-
*/
|
|
133
|
-
const RELEASED_TASK_DEADLINE_MS = 60_000;
|
|
134
|
-
|
|
135
|
-
/** What a wedged task costs: this worker, so the supervisor respawns a clean one. */
|
|
136
|
-
function exitWedged(ms: number, released: boolean): void {
|
|
137
|
-
hookLogWarn(
|
|
138
|
-
`worker: a ${released ? "released " : ""}request did not settle within ${ms}ms; ` +
|
|
139
|
-
`exiting so the supervisor can respawn a clean worker`,
|
|
140
|
-
);
|
|
141
|
-
process.exit(WEDGED_EXIT_CODE);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export interface QueuedTaskOptions {
|
|
145
|
-
taskMs?: number;
|
|
146
|
-
releasedMs?: number;
|
|
147
|
-
onWedged?: (ms: number, released: boolean) => void;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Runs one queued task under a wedge deadline, calling `settle` when the next
|
|
152
|
-
* task may start — because this one finished, or because it handed its place
|
|
153
|
-
* back early with the `release` it is given. A released task keeps running
|
|
154
|
-
* under a deadline of its own (see `RELEASED_TASK_DEADLINE_MS`); dropping the
|
|
155
|
-
* deadline at that point would have made every wedge past the release
|
|
156
|
-
* invisible.
|
|
157
|
-
*
|
|
158
|
-
* Exported for the deadlines' own tests: they are a minute long and expiry
|
|
159
|
-
* exits the process, so a test passes its own values and its own `onWedged`.
|
|
160
|
-
*/
|
|
161
|
-
export function runQueuedTask(task: (release: () => void) => Promise<void>, settle: () => void, opts: QueuedTaskOptions = {}): void {
|
|
162
|
-
const onWedged = opts.onWedged ?? exitWedged;
|
|
163
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
164
|
-
let finished = false;
|
|
165
|
-
let started = false;
|
|
166
|
-
const arm = (ms: number, released: boolean) => {
|
|
167
|
-
clearTimeout(timer);
|
|
168
|
-
timer = setTimeout(() => onWedged(ms, released), ms);
|
|
169
|
-
// Never let the deadline itself hold the event loop open.
|
|
170
|
-
timer.unref?.();
|
|
171
|
-
};
|
|
172
|
-
/** The next task starts once, whether this one released first or just finished. */
|
|
173
|
-
const startNext = () => {
|
|
174
|
-
if (started) return;
|
|
175
|
-
started = true;
|
|
176
|
-
settle();
|
|
177
|
-
};
|
|
178
|
-
const finish = () => {
|
|
179
|
-
finished = true;
|
|
180
|
-
clearTimeout(timer);
|
|
181
|
-
startNext();
|
|
182
|
-
};
|
|
183
|
-
const release = () => {
|
|
184
|
-
if (finished) return;
|
|
185
|
-
arm(opts.releasedMs ?? RELEASED_TASK_DEADLINE_MS, true);
|
|
186
|
-
startNext();
|
|
187
|
-
};
|
|
188
|
-
arm(opts.taskMs ?? TASK_DEADLINE_MS, false);
|
|
189
|
-
void task(release).then(finish, finish);
|
|
190
|
-
}
|
|
191
102
|
|
|
192
103
|
let processingChain: Promise<void> = Promise.resolve();
|
|
193
|
-
function enqueue(task: (
|
|
194
|
-
processingChain = processingChain
|
|
104
|
+
function enqueue(task: () => Promise<void>): void {
|
|
105
|
+
processingChain = processingChain
|
|
106
|
+
.then(
|
|
107
|
+
() =>
|
|
108
|
+
new Promise<void>((settle) => {
|
|
109
|
+
const timer = setTimeout(() => {
|
|
110
|
+
hookLogWarn(
|
|
111
|
+
`worker: a request did not settle within ${TASK_DEADLINE_MS}ms; ` +
|
|
112
|
+
`exiting so the supervisor can respawn a clean worker`,
|
|
113
|
+
);
|
|
114
|
+
process.exit(WEDGED_EXIT_CODE);
|
|
115
|
+
}, TASK_DEADLINE_MS);
|
|
116
|
+
// Never let the deadline itself hold the event loop open.
|
|
117
|
+
timer.unref?.();
|
|
118
|
+
const done = () => {
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
settle();
|
|
121
|
+
};
|
|
122
|
+
void task().then(done, done);
|
|
123
|
+
}),
|
|
124
|
+
)
|
|
125
|
+
.catch(() => {});
|
|
195
126
|
}
|
|
196
127
|
|
|
197
128
|
function handleConnection(socket: Socket, shutdown: () => void): void {
|
|
198
129
|
let recvBuf = Buffer.alloc(0);
|
|
199
130
|
let declaredLen: number | null = null;
|
|
200
|
-
/**
|
|
201
|
-
* Hook replies leave in the order their requests arrived on this
|
|
202
|
-
* connection. The wire carries no request id, so a client that pipelines
|
|
203
|
-
* several requests on one connection can match replies only by order — which
|
|
204
|
-
* the strictly serialized queue used to guarantee by itself. A two-tier task
|
|
205
|
-
* that releases the queue early (see `enqueue`) can finish after a request
|
|
206
|
-
* that arrived behind it, so each reply waits for every earlier one on its
|
|
207
|
-
* connection. The Rust supervisor opens one connection per request, so today
|
|
208
|
-
* this never delays anything; it keeps the ordering true for any client that
|
|
209
|
-
* does pipeline.
|
|
210
|
-
*/
|
|
211
|
-
let replies: Promise<void> = Promise.resolve();
|
|
212
131
|
|
|
213
132
|
socket.on("data", (chunk: Buffer) => {
|
|
214
133
|
recvBuf = Buffer.concat([recvBuf, chunk]);
|
|
@@ -259,27 +178,15 @@ function handleConnection(socket: Socket, shutdown: () => void): void {
|
|
|
259
178
|
}
|
|
260
179
|
const request = message;
|
|
261
180
|
|
|
262
|
-
|
|
263
|
-
const reply = new Promise<Buffer>((resolveReply) => {
|
|
264
|
-
deliver = resolveReply;
|
|
265
|
-
});
|
|
266
|
-
replies = replies
|
|
267
|
-
.then(() => reply)
|
|
268
|
-
.then((frame) => {
|
|
269
|
-
socket.write(frame);
|
|
270
|
-
})
|
|
271
|
-
.catch(() => {});
|
|
272
|
-
|
|
273
|
-
enqueue(async (release) => {
|
|
181
|
+
enqueue(async () => {
|
|
274
182
|
try {
|
|
275
183
|
const result = await evaluateHookEvent(request.hookEvent, request.cli, request.stdin, {
|
|
276
184
|
awaitTelemetryFlush: false,
|
|
277
185
|
// Normalised here so no consumer has to know the wire spells
|
|
278
186
|
// "absent" as null.
|
|
279
187
|
fallbackCwd: request.cwd ?? undefined,
|
|
280
|
-
releaseRegistry: release,
|
|
281
188
|
});
|
|
282
|
-
|
|
189
|
+
socket.write(
|
|
283
190
|
encodeFrame({
|
|
284
191
|
type: "hookResult",
|
|
285
192
|
exitCode: result.exitCode,
|
|
@@ -291,7 +198,7 @@ function handleConnection(socket: Socket, shutdown: () => void): void {
|
|
|
291
198
|
} catch (err) {
|
|
292
199
|
const msg = err instanceof Error ? err.message : String(err);
|
|
293
200
|
hookLogWarn(`worker: evaluateHookEvent threw: ${msg}`);
|
|
294
|
-
|
|
201
|
+
socket.write(encodeFrame({ type: "error", message: msg }));
|
|
295
202
|
}
|
|
296
203
|
});
|
|
297
204
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export {
|
|
8
8
|
customPolicies,
|
|
9
|
-
semanticPolicies,
|
|
10
9
|
getCustomHooks,
|
|
11
|
-
getSemanticRegistrations,
|
|
12
10
|
clearCustomHooks,
|
|
13
11
|
} from "./hooks/custom-hooks-registry";
|
|
14
12
|
export { allow, deny, instruct } from "./hooks/policy-helpers";
|
|
@@ -18,8 +16,4 @@ export type {
|
|
|
18
16
|
CustomHook,
|
|
19
17
|
PolicyDecision,
|
|
20
18
|
PolicyFunction,
|
|
21
|
-
PolicyAuthority,
|
|
22
|
-
SemanticPolicyDeclaration,
|
|
23
|
-
SemanticProbeDeclaration,
|
|
24
|
-
SemanticToolClass,
|
|
25
19
|
} from "./hooks/policy-types";
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
module.exports=[97348,e=>{"use strict";var i=e.i(2157),t=e.i(50227),r=e.i(79857);let o={info:0,warn:1,error:2},n=(0,r.logsDir)(),a=!1,s="warn",l=!1,c=n;function d(e){return!function(){if(a)return;a=!0;let e=(process.env.FAILPROOFAI_LOG_LEVEL??"").toLowerCase();("info"===e||"warn"===e||"error"===e)&&(s=e);let i=(process.env.FAILPROOFAI_HOOK_LOG_FILE??"").trim();i&&(l=!0,"1"!==i&&"true"!==i&&(c=i))}(),o[e]>=o[s]}function u(e,i){process.stderr.write(`[failproofai:hook] ${e} ${i}
|
|
2
|
-
`)}function y(e,r){if(l)try{(0,i.existsSync)(c)||(0,i.mkdirSync)(c,{recursive:!0});let o=(0,t.join)(c,"hooks.log");try{if((0,i.statSync)(o).size>=524288){let e=`hooks-${Date.now()}.log`;(0,i.renameSync)(o,(0,t.join)(c,e))}}catch{}let n=new Date().toISOString(),a=`[${n}] ${e} ${r}
|
|
3
|
-
`;(0,i.appendFileSync)(o,a,"utf-8")}catch{}}e.s(["hookLogError",0,function(e){d("error")&&(u("ERROR",e),y("ERROR",e))},"hookLogInfo",0,function(e){d("info")&&(u("INFO",e),y("INFO",e))},"hookLogWarn",0,function(e){d("warn")&&(u("WARN",e),y("WARN",e))}])},73136,49335,e=>{"use strict";var i=e.i(2157),t=e.i(50227),r=e.i(60526),o=e.i(97348),n=e.i(79857);function a(e){if(!(0,i.existsSync)(e))return{};try{let t=(0,i.readFileSync)(e,"utf8");return JSON.parse(t)}catch(i){return(0,o.hookLogWarn)(`failed to parse config at ${e}: ${i instanceof Error?i.message:String(i)}`),{}}}e.s(["readMergedHooksConfig",0,function(e){let o=function(e){let o=(0,r.homedir)(),n=(0,t.resolve)(e);for(;n!==o;){let e=(0,t.resolve)(n,".failproofai");try{if((0,i.statSync)(e).isDirectory())return n}catch{}let r=(0,t.dirname)(n);if(r===n)break;n=r}return(0,t.resolve)(e)}(e??process.cwd()),s=(0,t.resolve)(o,".failproofai","policies-config.json"),l=(0,t.resolve)(o,".failproofai","policies-config.local.json"),c=(0,n.globalPolicyConfigFile)(),d=a(s),u=a(l),y=a(c),f=new Set([...d.enabledPolicies??[],...u.enabledPolicies??[],...y.enabledPolicies??[]]),h={};for(let e of[d,u,y])if(e.policyParams)for(let[i,t]of Object.entries(e.policyParams))i in h||(h[i]=t);let p=[d,u,y].map(e=>void 0!==e.customPoliciesPaths?e.customPoliciesPaths:void 0!==e.customPoliciesPath?[e.customPoliciesPath]:void 0).find(e=>void 0!==e),v=new Set([...d.disabledCustomPolicies??[],...u.disabledCustomPolicies??[],...y.disabledCustomPolicies??[]]),m=d.customPoliciesEnabled??u.customPoliciesEnabled??y.customPoliciesEnabled,g=d.llm??u.llm??y.llm;return{enabledPolicies:[...f],...Object.keys(h).length>0?{policyParams:h}:{},...void 0!==p?{customPoliciesPaths:p}:{},...v.size?{disabledCustomPolicies:[...v]}:{},...void 0!==m?{customPoliciesEnabled:m}:{},...void 0!==g?{llm:g}:{}}}],73136);var s=e.i(24214),l=e.i(28067),c=e.i(17694);let d=l.POSTHOG_API_KEY,u=new Set;async function y(e,i,t){let r=JSON.stringify({api_key:process.env.FAILPROOFAI_POSTHOG_KEY??d,event:i,distinct_id:e,properties:{...t,$lib:"failproofai-hooks",failproofai_version:s.version,product:l.POSTHOG_PRODUCT}});try{await fetch(process.env.FAILPROOFAI_POSTHOG_HOST?`${process.env.FAILPROOFAI_POSTHOG_HOST}/capture/`:"https://us.i.posthog.com/capture/",{method:"POST",headers:{"Content-Type":"application/json"},body:r,signal:AbortSignal.timeout(5e3)})}catch{}}async function f(e,i,t){if(!(0,c.isTelemetryEnabled)())return;let r=y(e,i,t);u.add(r),r.finally(()=>u.delete(r)),await r}e.s(["trackHookEvent",0,f],49335)},99891,e=>{"use strict";e.i(2157),e.i(79857),e.i(97348);let i=new Set(["destructive-deletion","production-infra-change","git-history-rewrite","push-to-protected-branch","commit-on-protected-branch","secret-exposure","credential-exfiltration","remote-code-execution","privilege-escalation","database-destruction","read-outside-workspace","agent-config-tampering","system-modification","env-secrets-dump","external-destructive-action","external-data-egress"]),t=e=>"string"==typeof e&&e.length>0;e.s(["SEMANTIC_REVIEWER_NAMES",0,i,"authorityFieldsOf",0,function(e){let i={};("hard"===e.authority||"reviewable"===e.authority)&&(i.authority=e.authority);let r=e.reviewedBy;return Array.isArray(r)&&r.length>0&&r.every(t)&&(i.reviewedBy=[...r]),i},"resolvePolicyAuthority",0,function(e,r=i){let o=e?.authority==="reviewable";if(!e||"hard"==(!0!==e.alwaysOn&&"reviewable"===e.authority&&Array.isArray(e.reviewedBy)&&e.reviewedBy.filter(e=>"string"==typeof e&&e.length>0).length>0?"reviewable":"hard")){var n;return o?{authority:"hard",downgraded:!0===(n=e).alwaysOn?"it is alwaysOn, and the self-protection guard is never reviewable":Array.isArray(n.reviewedBy)&&0!==n.reviewedBy.length?"reviewedBy is not a list of semantic policy names":"reviewedBy does not name any semantic policy"}:{authority:"hard"}}let a=e.reviewedBy;if(!a.every(t))return{authority:"hard",downgraded:"reviewedBy is not a list of semantic policy names"};let s=a.filter(e=>!r.has(e));return s.length>0?{authority:"hard",downgraded:`reviewedBy names ${s.map(e=>JSON.stringify(e)).join(", ")}, which ${1===s.length?"is not a semantic policy":"are not semantic policies"} in this build`}:{authority:"reviewable",reviewedBy:[...new Set(a)]}}],99891)}];
|
|
4
|
-
|
|
5
|
-
//# sourceMappingURL=src_hooks_01frwmb._.js.map
|