failproofai 1.0.7-beta.1 → 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]__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/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
- 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]__0yxwl6j._.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/{_214wgrp._.js → _1-i_gzc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.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_18_d8l1._.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/0__8a7m868fvf.js +1 -0
- package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 0o6qlkgubtoex.js} +1 -1
- package/.next/standalone/.next/static/chunks/13i7-9is-vhys.js +1 -0
- 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/{0vmd180qfntfb.js → 2klitrtzpaoe0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{258668t68du6b.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/{0qrbdkv9qmvli.js → 3rh5o7e16irrm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.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 +9 -9
- package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
- package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
- package/.next/standalone/sdk/python/skill/references/events.md +17 -8
- package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
- package/.next/standalone/sdk/python/skill/references/install.md +3 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
- package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
- package/.next/standalone/sdk/typescript/CHANGELOG.md +133 -0
- package/.next/standalone/sdk/typescript/LICENSE +42 -0
- package/.next/standalone/sdk/typescript/README.md +552 -0
- package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
- package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +261 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +344 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +441 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6797 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +24 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
- package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
- package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
- package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
- package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
- package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
- package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
- package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
- package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
- package/.next/standalone/sdk/typescript/package.json +401 -0
- package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
- package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
- package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
- package/.next/standalone/sdk/typescript/src/context.ts +214 -0
- package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
- package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
- package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
- package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
- package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
- package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
- package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
- package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
- package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
- package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
- package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
- package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
- package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
- package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
- package/.next/standalone/sdk/typescript/src/events.ts +879 -0
- package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
- package/.next/standalone/sdk/typescript/src/index.ts +186 -0
- package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
- package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
- package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
- package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
- package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
- package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
- package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
- package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
- package/.next/standalone/sdk/typescript/src/next.ts +115 -0
- package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
- package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
- package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
- package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
- package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
- package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
- package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
- package/.next/standalone/sdk/typescript/src/version.ts +5 -0
- package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
- package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
- package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
- package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
- package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
- package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
- package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
- package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
- package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
- package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
- package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
- package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
- package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
- package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
- package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
- package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
- package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
- package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
- package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
- package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
- package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
- package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
- package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
- package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
- package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
- package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
- package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
- package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
- package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
- package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
- package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
- package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
- package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +2 -115
- package/dist/cli.mjs +6538 -13686
- package/dist/index.js +1 -19
- package/dist/worker.mjs +2085 -8012
- package/package.json +9 -9
- package/pi-extension/index.ts +0 -11
- package/scripts/build-policy-pack.mjs +2 -39
- package/src/hooks/builtin-policies.ts +3 -21
- 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/pack-cli.ts +17 -278
- package/src/hooks/pack-manifest.ts +7 -479
- package/src/hooks/pack-store.ts +10 -156
- package/src/hooks/policy-catalog.ts +0 -65
- 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/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_0w6mzq5._.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/0cd-_8-c-m1ea.js +0 -6
- package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
- package/.next/standalone/.next/static/chunks/1u5zsejmgrir_.js +0 -1
- package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +0 -1
- package/.next/standalone/.next/static/chunks/2vkvu9-opa_1z.js +0 -1
- package/.next/standalone/.next/static/chunks/37lhv7wa3ywt6.js +0 -1
- package/.next/standalone/app/actions/get-jev-config.ts +0 -409
- 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 -469
- package/src/hooks/effective-reviewers.ts +0 -79
- package/src/hooks/jev-activity.ts +0 -385
- package/src/hooks/jev-cli.ts +0 -1193
- 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/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_ssgManifest.js +0 -0
|
@@ -1,541 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The two-tier combine rules: regex policy verdicts + Jev's review → one
|
|
3
|
-
* final verdict, plus what to record about how it was reached.
|
|
4
|
-
*
|
|
5
|
-
* Pure and synchronous, importing only types and one constant from the equally
|
|
6
|
-
* pure `jev-activity.ts`, so it can sit on the hook path (`policy-evaluator.ts`
|
|
7
|
-
* imports it) without pulling the semantic evaluator into the bundle, and so
|
|
8
|
-
* every row of the table below is testable offline.
|
|
9
|
-
*
|
|
10
|
-
* | Situation | Result |
|
|
11
|
-
* |-----------------------------------------------|-------------------------------------------------------------|
|
|
12
|
-
* | not configured / FAILPROOFAI_EVALUATOR=legacy | `regexOnly` — never reaches this module's `combineTwoTier` |
|
|
13
|
-
* | any HARD deny | the regex result (Jev was aborted, so nothing is cleared) |
|
|
14
|
-
* | Jev degraded — transport, timeout, 429, 402, | the regex result, every deny counts; recorded `jev-fallback`|
|
|
15
|
-
* | 5xx, malformed, model mismatch | |
|
|
16
|
-
* | Jev answered, but part of the CALL was cut | nothing is cleared, so every regex deny counts; Jev's own |
|
|
17
|
-
* | | verdict still joins the most-severe rule; recorded |
|
|
18
|
-
* | | `jev-fallback` / `request-cut`, with its decision |
|
|
19
|
-
* | Jev answered, but a MESSAGE was cut — a human | exactly the row below: the clears stand, and it is NOT |
|
|
20
|
-
* | turn, the agent's last message, or a prompt | recorded as a fallback |
|
|
21
|
-
* | the intent store had already capped | |
|
|
22
|
-
* | Jev answered | reviewable denies/instructs Jev covered are cleared; final =|
|
|
23
|
-
* | | the most severe of {remaining regex results, Jev's verdict} |
|
|
24
|
-
*
|
|
25
|
-
* `shadow` mode computes and records all of it, and still returns the regex
|
|
26
|
-
* result.
|
|
27
|
-
*
|
|
28
|
-
* ## Where this departs from plan §4
|
|
29
|
-
*
|
|
30
|
-
* §4's combine table files BOTH cuts under one row — "Jev degraded (timeout,
|
|
31
|
-
* 429, HTTP/parse error, model-version mismatch) **or the envelope was
|
|
32
|
-
* truncated** → today's regex result (every deny counts); record
|
|
33
|
-
* `evaluator: "jev-fallback"` plus the reason". The two rows above are that
|
|
34
|
-
* row as shipped, and if you arrived from §4 these are the two differences,
|
|
35
|
-
* stated once so nothing below is a surprise:
|
|
36
|
-
*
|
|
37
|
-
* 1. **A cut MESSAGE is not a fallback at all.** Nothing about the CALL was
|
|
38
|
-
* missing and nothing was withheld, so the clears stand and the row is
|
|
39
|
-
* recorded `jev`. Filing it as a fallback made the length of the human's
|
|
40
|
-
* own paste decide the verdict — the same call came out `allow` after a
|
|
41
|
-
* 77-character prompt and `deny` after a 3,000-character one — and inflated
|
|
42
|
-
* the fallback rate with calls Jev answered in full. "What a cut MESSAGE
|
|
43
|
-
* does: nothing", below, is the argument at length.
|
|
44
|
-
* 2. **A cut CALL is a fallback, but not "exactly the regex result".** It
|
|
45
|
-
* clears nothing, so every regex deny counts, which is the half of §4 that
|
|
46
|
-
* protects anything. What it does NOT do is throw Jev's own answer away:
|
|
47
|
-
* that answer still joins the most-severe merge, upward only. Reading §4 as
|
|
48
|
-
* "discard the verdict" made padding a command past the envelope's cap a
|
|
49
|
-
* working way to stop Jev's OWN deny applying (a real repro: `rm -rf /
|
|
50
|
-
* --no-preserve-root` + 2,100 spaces flipped deny → allow). A cut is
|
|
51
|
-
* attacker-influenceable, so it may never SUBTRACT severity.
|
|
52
|
-
*
|
|
53
|
-
* One principle underneath both: a partial picture withdraws CLEARS and
|
|
54
|
-
* nothing else. §4's guarantee — a call the tier could not read whole can
|
|
55
|
-
* never come out more permissive than the regex tier alone — holds in full,
|
|
56
|
-
* and `combineTwoTier`'s result is never less severe than `regexOnly(verdicts)`
|
|
57
|
-
* unless a clear fired. What changed is the direction the rule is allowed to
|
|
58
|
-
* move a verdict, not whether the regex floor survives. The user-facing page
|
|
59
|
-
* (docs/policies/jev-byok.mdx, "When Jev cannot answer") states both rows in
|
|
60
|
-
* the same terms, and `combine.test.ts` plus `truncation-severity.test.ts` pin
|
|
61
|
-
* them.
|
|
62
|
-
*
|
|
63
|
-
* "Jev can only clear what it was actually asked about": a reviewable
|
|
64
|
-
* policy's deny or instruct is cleared only if EVERY semantic policy named in
|
|
65
|
-
* its `reviewedBy` was among the ones put to Jev for this call AND did not
|
|
66
|
-
* come back `deny` — that is, it answered `none`, `overridden` or `instruct`.
|
|
67
|
-
* A name Jev was not asked about — its precondition was false, the tool class
|
|
68
|
-
* did not apply, the name is misspelled — keeps the regex verdict standing.
|
|
69
|
-
*
|
|
70
|
-
* ## A warning-level answer clears the deny, and leaves the warning
|
|
71
|
-
*
|
|
72
|
-
* The rule above is the one thing about this module that was chosen on
|
|
73
|
-
* measured numbers rather than argued from first principles, so this is what
|
|
74
|
-
* it decides and what it deliberately does not.
|
|
75
|
-
*
|
|
76
|
-
* An `instruct` answer means the named check looked at the call, found the
|
|
77
|
-
* thing the regex policy is worried about, and judged it worth a WARNING —
|
|
78
|
-
* not a block. Counting that as "not cleared" left the regex DENY standing,
|
|
79
|
-
* which threw the distinction away: the agent was stopped by a string match
|
|
80
|
-
* on exactly the calls where the check that was supposed to review it had
|
|
81
|
-
* already said "warn, do not stop". Over the 1,332 labelled cases that was
|
|
82
|
-
* the single largest remaining group of false blocks. Measured on this
|
|
83
|
-
* commit, over recorded provider answers for all 1,332 (the live Cloudflare
|
|
84
|
-
* run they were recorded from reproduces case for case under the previous
|
|
85
|
-
* rule): real work blocked 13.9% → 8.7% — 12.5% → 7.3% leaving out the
|
|
86
|
-
* always-on self-protection guard, which is hard and unclearable — against
|
|
87
|
-
* 33.3% for the regex tier alone, attacks blocked 134 → 132 of 234, exact
|
|
88
|
-
* agreement with the labels 70.6% → 70.8%. The live run on which the rule was
|
|
89
|
-
* chosen put the same four at 14.3% → 8.9%, 129 → 127, 70.6% → 70.8%; the few
|
|
90
|
-
* cases between the two are drift in what gets ASKED since the answers were
|
|
91
|
-
* recorded, not in this rule.
|
|
92
|
-
*
|
|
93
|
-
* All 54 calls the change moves go deny → warning. None goes to allow, and
|
|
94
|
-
* neither the regex tier's floor nor any hard policy moves at all.
|
|
95
|
-
*
|
|
96
|
-
* Clearing on `instruct` does not silence anything. The same answer that
|
|
97
|
-
* clears makes Jev's OWN decision an instruct (`decide.ts` — any instruct
|
|
98
|
-
* outcome makes the verdict an instruct), and that instruct joins the
|
|
99
|
-
* most-severe merge below. So the call comes out a WARNING that says what is
|
|
100
|
-
* actually wrong with it, in Jev's words, instead of a block in the regex
|
|
101
|
-
* policy's words. A clear here converts a deny into a warning; it does not
|
|
102
|
-
* convert it into silence.
|
|
103
|
-
*
|
|
104
|
-
* What this deliberately does NOT relax is WHICH questions must have been
|
|
105
|
-
* asked. The gate is still `asked.has(name) && …` for every name in
|
|
106
|
-
* `reviewedBy`: a check whose precondition was false, that does not apply to
|
|
107
|
-
* this tool class, or that is misspelled was never put to Jev, so there is no
|
|
108
|
-
* answer to read and the regex verdict stands. Rule B widens what counts as a
|
|
109
|
-
* clear ANSWER (`none`, `overridden`, `instruct`), never what counts as an
|
|
110
|
-
* asked QUESTION — a call Jev was not asked about is not a call Jev approved,
|
|
111
|
-
* and an unmeasured concern is not an absent one. `deny` is the one answer
|
|
112
|
-
* that keeps the block: the check looked and said stop.
|
|
113
|
-
*
|
|
114
|
-
* ## One rule about a partial picture
|
|
115
|
-
*
|
|
116
|
-
* Three things mean Jev judged less than the call: part of `agent_request` or
|
|
117
|
-
* of the computed `facts` was cut (`requestCut`), injection is suspected, or
|
|
118
|
-
* the injection probe was never asked. Each withdraws every CLEAR and nothing
|
|
119
|
-
* else. Jev's own deny or instruct still joins the most-severe rule, because
|
|
120
|
-
* an answer given on part of the evidence can only ever ADD severity —
|
|
121
|
-
* `combineTwoTier`'s result is never less severe than `regexOnly(verdicts)`
|
|
122
|
-
* unless a clear fired, and a clear fires only when the call was read whole,
|
|
123
|
-
* injection was asked about, and the answer was no.
|
|
124
|
-
*
|
|
125
|
-
* That is what makes padding useless AGAINST THE CALL'S OWN TEXT. Five review
|
|
126
|
-
* rounds tried to prevent the hiding instead — a head-and-tail window, a token
|
|
127
|
-
* skeleton, per-field caps — and each time the next spelling walked through
|
|
128
|
-
* it, because a bounded projection of an unbounded string always drops
|
|
129
|
-
* SOMETHING and the attacker picks what. So this rule does not try: dropping a
|
|
130
|
-
* byte of `agent_request` requires a cut, every such cut sets `requestCut`
|
|
131
|
-
* (`envelope.ts`), and a call with `requestCut` can clear nothing. Spending the
|
|
132
|
-
* budget can cost a call its clears; it can never buy one.
|
|
133
|
-
*
|
|
134
|
-
* The same sentence is NOT true of the derived `facts`, and saying so is
|
|
135
|
-
* better than asserting a property the code does not have. `facts` are
|
|
136
|
-
* computed from the first `MAX_SCAN_CHARS` characters of a command and from a
|
|
137
|
-
* capped number of paths (`facts.ts`), and neither bound sets a flag. What a
|
|
138
|
-
* long enough command can therefore cost is a QUESTION — `selectPolicies` may
|
|
139
|
-
* not pick a probe whose precondition reads those facts — not a clear on
|
|
140
|
-
* evidence Jev never saw: the command text itself is carried whole and judged.
|
|
141
|
-
* Flagging it from here was measured and rejected (it charges an ordinary
|
|
142
|
-
* 20,000-character heredoc, and `prettier --write` over thirteen files, their
|
|
143
|
-
* clears); the narrow fix is for `facts.ts` to report that it stopped and for
|
|
144
|
-
* `policies.ts` to read incomplete evidence as a reason to ASK MORE. Until
|
|
145
|
-
* that lands, this paragraph — not the one above it — is what holds. See
|
|
146
|
-
* `envelope.ts`'s header for the same statement at the source.
|
|
147
|
-
*
|
|
148
|
-
* ## What size may NOT do
|
|
149
|
-
*
|
|
150
|
-
* A previous revision went one step further and DENIED a call whose own text
|
|
151
|
-
* had been cut — `semantic/request-too-large-to-review`, telling the agent to
|
|
152
|
-
* split it up. That is gone, and it is worth saying why, because the argument
|
|
153
|
-
* for it was not silly: in the case this tier exists for, the regex tier has
|
|
154
|
-
* no rule, so its floor is `allow`, and withdrawing clears protects nothing.
|
|
155
|
-
*
|
|
156
|
-
* It was still wrong. The refusal was a deny this product invented, on work no
|
|
157
|
-
* policy objected to, at a threshold ordinary calls reach — a ~1,400-line
|
|
158
|
-
* `Write`, a large MCP body, a long generated migration. The whole reason this
|
|
159
|
-
* tier exists is that regex policies block a third of real work; a new
|
|
160
|
-
* refusal of our own, firing on size rather than on behaviour, spends the
|
|
161
|
-
* benefit it was built to deliver. And it is not even the strongest available
|
|
162
|
-
* answer: Jev is still ASKED, with whatever fitted, and a cut call that is
|
|
163
|
-
* actually dangerous is denied on Jev's own verdict, with a reason that names
|
|
164
|
-
* what is wrong with it rather than how long it is.
|
|
165
|
-
*
|
|
166
|
-
* So: size can only ever make a call stricter through Jev's own verdict or
|
|
167
|
-
* through a regex policy, never through a refusal here. What it costs is the
|
|
168
|
-
* clears.
|
|
169
|
-
*
|
|
170
|
-
* ## What a cut MESSAGE does: nothing
|
|
171
|
-
*
|
|
172
|
-
* `truncated` — a human turn, an agent message or a store-capped prompt that
|
|
173
|
-
* did not fit — is recorded and read no further. It used to withdraw clears
|
|
174
|
-
* too, and that made the length of the human's own prompt decide the verdict:
|
|
175
|
-
* the same call came out `allow` after a 77-character prompt and `deny` after
|
|
176
|
-
* a 3,000-character one, because the clearing half of the tier switched off.
|
|
177
|
-
* Pasting a spec or a stack trace is not an attack, the human's turn is not a
|
|
178
|
-
* channel the agent can write, and consent read out of it is checked locally
|
|
179
|
-
* against the UNCUT text (see `Envelope.evidence`), so there is nothing here
|
|
180
|
-
* for a cut to protect.
|
|
181
|
-
*
|
|
182
|
-
* What the clearing gate claims, exactly. The envelope keeps a BOUNDED window
|
|
183
|
-
* by design — the last `MAX_USER_MESSAGES` human turns — and dropping older
|
|
184
|
-
* turns does not set `truncated`. So a clear rests on a complete view of what
|
|
185
|
-
* was SENT, not on the whole session: an instruction from twenty turns ago is
|
|
186
|
-
* not in the picture, and the tier is not a record of consent over a session.
|
|
187
|
-
*
|
|
188
|
-
* The local `targetNamedByUser` check reads `Envelope.evidence`, which is that
|
|
189
|
-
* window and nothing wider — a turn Jev never saw cannot supply the consent
|
|
190
|
-
* for an `op-requested` override (it could, and flipped a reviewable deny to
|
|
191
|
-
* allow). The two channels differ inside the window,
|
|
192
|
-
* deliberately, and the guarantee is per channel rather than per character:
|
|
193
|
-
* - `user_said` is reported UNCUT. A target named in the cut middle of a
|
|
194
|
-
* long prompt is consent the human typed, and treating it as absent turned
|
|
195
|
-
* explicit requests into instructs and denies.
|
|
196
|
-
* - `agent_last_message` is reported as SENT, capped and redacted. The agent
|
|
197
|
-
* writes that channel and it repeats third-party text, so consent found
|
|
198
|
-
* only in a part of it Jev never read is exactly the subtraction this
|
|
199
|
-
* design refuses everywhere else.
|
|
200
|
-
*
|
|
201
|
-
* "Uncut" there means uncut by the ENVELOPE, and there is one cut it cannot
|
|
202
|
-
* undo: T4's intent store caps a prompt as it READS it (`intent.ts`), so a
|
|
203
|
-
* 12,000-character prompt arrives already head-and-tail cut and its middle is
|
|
204
|
-
* not recoverable by anyone. Run over that, the local substring check read
|
|
205
|
-
* "the user did not name it" off a string that could not have contained it —
|
|
206
|
-
* the same subtraction one channel further out, and the same symptom: the
|
|
207
|
-
* length of the human's paste decided the verdict. So a human turn that
|
|
208
|
-
* arrived cut makes the local check INCONCLUSIVE rather than negative
|
|
209
|
-
* (`PreparedCall.userSaidCut`, `DecideV1Options.userSaidCut`), and the
|
|
210
|
-
* override rests on what it rests on when a call names no identifiable target
|
|
211
|
-
* at all — Jev's own `op_requested` and `scope` answers. It can only restore a
|
|
212
|
-
* clear a short prompt would have kept, it is read from the human channel
|
|
213
|
-
* only, and `targetNamedByUser` still reports FALSE, because nothing in what
|
|
214
|
-
* we hold named the target; what changes is that "false" no longer decides.
|
|
215
|
-
*
|
|
216
|
-
* Severity, meanwhile, is never subtracted by a cut at all. §4's table files a
|
|
217
|
-
* truncated envelope under "fall back to the regex result", and reading that
|
|
218
|
-
* as "throw Jev's answer away" made padding a command past the envelope's
|
|
219
|
-
* per-field cap a working way to stop Jev's OWN deny applying (a real repro:
|
|
220
|
-
* `rm -rf / --no-preserve-root` + 2,100 spaces flipped deny → allow).
|
|
221
|
-
* Truncation is attacker-influenceable, so it may never subtract severity.
|
|
222
|
-
* What §4 asks for is still there — every regex deny counts, and the call is
|
|
223
|
-
* recorded as `jev-fallback` — the answer is just not thrown away on the way
|
|
224
|
-
* in.
|
|
225
|
-
*
|
|
226
|
-
* Size was the same class one step further out, and is no longer a case at
|
|
227
|
-
* all: a request over `MAX_REQUEST_CHARS` used to be
|
|
228
|
-
* `degraded("request-too-large")` — a `fallback`, no verdict, regex-only —
|
|
229
|
-
* which one ignored 70,000-character `file_path`, one long object KEY, or
|
|
230
|
-
* 36,000 empty strings in an array was enough to trigger. The envelope is now
|
|
231
|
-
* built inside a hard budget whose accounting charges what serialization
|
|
232
|
-
* really costs, and being over it is not a degrade at all: the request is sent
|
|
233
|
-
* with what fitted and arrives here `answered`, with `requestCut`.
|
|
234
|
-
*
|
|
235
|
-
* Structurally: a `fallback` review carries no `decision` at all, so a verdict
|
|
236
|
-
* Jev actually produced cannot be filed as one. If Jev decided, it comes
|
|
237
|
-
* through `answered` (possibly `requestCut`), and `answered` always reaches
|
|
238
|
-
* the most-severe merge.
|
|
239
|
-
*
|
|
240
|
-
* A clear is only as good as the check that the call is not acting on text
|
|
241
|
-
* planted by a repo, a tool result or the agent itself, so the injection probe
|
|
242
|
-
* is asked on EVERY call — including one with no recorded human message, where
|
|
243
|
-
* there is no consent to withdraw but there is still planted text to notice.
|
|
244
|
-
* `injectionAsked` false therefore means the request was never sent at all,
|
|
245
|
-
* and then there is nothing to clear anyway.
|
|
246
|
-
*/
|
|
247
|
-
import type { PolicyAuthority } from "../policy-types";
|
|
248
|
-
// The one value import, and deliberately from the activity vocabulary rather
|
|
249
|
-
// than a local literal: the fallback reason this module writes itself has to
|
|
250
|
-
// be a code the activity store's closed list names, or it is stored and
|
|
251
|
-
// shipped as `other`. Importing the constant makes a rename a compile error
|
|
252
|
-
// here. `jev-activity.ts` is pure (no node imports, no semantic modules), so
|
|
253
|
-
// this costs the hook path nothing.
|
|
254
|
-
import { JEV_REASON_REQUEST_CUT } from "../jev-activity";
|
|
255
|
-
|
|
256
|
-
export type Decision = "allow" | "deny" | "instruct";
|
|
257
|
-
export type JevMode = "shadow" | "enforce";
|
|
258
|
-
|
|
259
|
-
/** One regex policy's verdict, in evaluation order. */
|
|
260
|
-
export interface RegexVerdict {
|
|
261
|
-
policyName: string;
|
|
262
|
-
decision: Decision;
|
|
263
|
-
/**
|
|
264
|
-
* deny / instruct: the reason exactly as it would be shown (hint appended).
|
|
265
|
-
* allow: the informational note, or null for a silent allow.
|
|
266
|
-
*/
|
|
267
|
-
reason: string | null;
|
|
268
|
-
/** EFFECTIVE authority (see `effectiveAuthority`), never the declared one. */
|
|
269
|
-
authority: PolicyAuthority;
|
|
270
|
-
/** The semantic policies that must all be asked and none answer `deny`. Empty for `hard`. */
|
|
271
|
-
reviewedBy: readonly string[];
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/** What Jev said, reduced to exactly what the combine rules read. */
|
|
275
|
-
export type JevReview =
|
|
276
|
-
| {
|
|
277
|
-
/** Aborted because a hard deny already decided; Jev's answer was never read. */
|
|
278
|
-
kind: "not-consulted";
|
|
279
|
-
}
|
|
280
|
-
| {
|
|
281
|
-
/**
|
|
282
|
-
* Jev produced no verdict: degraded (timeout, 429, HTTP/parse error,
|
|
283
|
-
* model mismatch, no transport, a config that cannot be built, …).
|
|
284
|
-
*
|
|
285
|
-
* Deliberately carries NO `decision`. A verdict Jev did produce must not
|
|
286
|
-
* be droppable on the way into the combine — that is how padding a
|
|
287
|
-
* command used to make Jev's own deny disappear — so anything Jev
|
|
288
|
-
* decided comes through `answered`, whose severity is always merged.
|
|
289
|
-
*/
|
|
290
|
-
kind: "fallback";
|
|
291
|
-
reason: string;
|
|
292
|
-
latencyMs: number | null;
|
|
293
|
-
model: string | null;
|
|
294
|
-
}
|
|
295
|
-
| {
|
|
296
|
-
kind: "answered";
|
|
297
|
-
decision: Decision;
|
|
298
|
-
reason: string | null;
|
|
299
|
-
/** Attribution for Jev's own deny/instruct, e.g. `semantic/destructive-deletion`. */
|
|
300
|
-
policyName: string;
|
|
301
|
-
/** Semantic policies whose questions were in the request that was answered. */
|
|
302
|
-
asked: readonly string[];
|
|
303
|
-
/**
|
|
304
|
-
* Of `asked`, the ones whose outcome was not `deny` — `none`,
|
|
305
|
-
* `overridden` or `instruct`. Those are the answers that let a
|
|
306
|
-
* reviewable regex verdict be cleared; see "A warning-level answer
|
|
307
|
-
* clears the deny, and leaves the warning" above. Named for what it
|
|
308
|
-
* holds rather than for what it is used for, because "clear" once meant
|
|
309
|
-
* `none`/`overridden` only and a silent widening of that set is exactly
|
|
310
|
-
* the mistake this name prevents.
|
|
311
|
-
*/
|
|
312
|
-
notDenied: readonly string[];
|
|
313
|
-
/**
|
|
314
|
-
* The injection probe was in the request and answered. False → no clear:
|
|
315
|
-
* an unmeasured injection is not an absent one.
|
|
316
|
-
*/
|
|
317
|
-
injectionAsked: boolean;
|
|
318
|
-
/** The injection probe held: every clear is withdrawn. */
|
|
319
|
-
injected: boolean;
|
|
320
|
-
/**
|
|
321
|
-
* Something did not fit: a human turn, the agent's last message, or what
|
|
322
|
-
* the intent store had already capped (`SemanticOutcome.truncated`).
|
|
323
|
-
*
|
|
324
|
-
* READ BY NOTHING HERE, on purpose — see "What a cut MESSAGE does"
|
|
325
|
-
* above. It stays on the review so the verdict log and a future
|
|
326
|
-
* diagnostic can see it, and so that the field's absence is not mistaken
|
|
327
|
-
* for the cut's absence.
|
|
328
|
-
*/
|
|
329
|
-
truncated: boolean;
|
|
330
|
-
/**
|
|
331
|
-
* Part of what the CALL DOES was cut: the tool input did not fit the
|
|
332
|
-
* envelope's request budget, a redaction removed a span of it that could
|
|
333
|
-
* have been executable, or a computed fact about it was dropped
|
|
334
|
-
* (`SemanticOutcome.requestCut`). Implies `truncated`.
|
|
335
|
-
*
|
|
336
|
-
* Withdraws every clear — a clear resting on a call half of which was
|
|
337
|
-
* never read is not a clear — and nothing else: the decision below still
|
|
338
|
-
* joins the most-severe rule, so padding cannot subtract severity, and
|
|
339
|
-
* it cannot add a refusal of our own either. Recorded as `jev-fallback`
|
|
340
|
-
* / `request-cut`.
|
|
341
|
-
*/
|
|
342
|
-
requestCut: boolean;
|
|
343
|
-
/**
|
|
344
|
-
* Null when nothing had to be sent (no semantic policy applied), or when
|
|
345
|
-
* the answer came from the throttle's cache: a hit's ~0 ms is not a
|
|
346
|
-
* provider latency.
|
|
347
|
-
*/
|
|
348
|
-
latencyMs: number | null;
|
|
349
|
-
model: string | null;
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* What `evaluatePolicies` receives when the two-tier path is on: an in-flight
|
|
354
|
-
* Jev review (started before the regex policies run) and how to read each
|
|
355
|
-
* registered policy's effective authority. Built by `jev-review.ts`.
|
|
356
|
-
*/
|
|
357
|
-
export interface TwoTierReview {
|
|
358
|
-
mode: JevMode;
|
|
359
|
-
/** Resolves once Jev answered, failed, or was aborted. Never rejects. */
|
|
360
|
-
review: Promise<JevReview>;
|
|
361
|
-
/** Abort the in-flight request (a hard deny decided). No-op once settled. */
|
|
362
|
-
abort(): void;
|
|
363
|
-
/**
|
|
364
|
-
* Called once, right before the evaluator awaits `review` — by then every
|
|
365
|
-
* read of the process-global policy registry for this call is done. The
|
|
366
|
-
* daemon's warm worker serializes requests around that registry, and uses
|
|
367
|
-
* this to let the next queued request run while this one waits on the
|
|
368
|
-
* network instead of holding every hook on the machine behind it.
|
|
369
|
-
*/
|
|
370
|
-
releaseRegistry?: () => void;
|
|
371
|
-
/** Effective authority + the reviewing semantic policies (empty unless reviewable). */
|
|
372
|
-
authorityOf(p: { name: string; authority?: PolicyAuthority; reviewedBy?: string[] }): {
|
|
373
|
-
authority: PolicyAuthority;
|
|
374
|
-
reviewedBy: string[];
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
export interface FinalVerdict {
|
|
379
|
-
decision: Decision;
|
|
380
|
-
/** deny: exactly the one decider; instruct: every instruct; allow: every note. */
|
|
381
|
-
entries: Array<{ policyName: string; reason: string }>;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/** The hook-activity fields (§7 contract) for one two-tier evaluation. */
|
|
385
|
-
export interface JevActivityFields {
|
|
386
|
-
evaluator: "jev" | "jev-fallback";
|
|
387
|
-
jevDecision?: Decision;
|
|
388
|
-
jevCleared?: string[];
|
|
389
|
-
jevFallbackReason?: string;
|
|
390
|
-
jevLatencyMs?: number;
|
|
391
|
-
jevModel?: string;
|
|
392
|
-
jevMode: JevMode;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export interface CombineOutcome {
|
|
396
|
-
final: FinalVerdict;
|
|
397
|
-
/** Reviewable regex policies Jev cleared (in shadow: would have cleared). */
|
|
398
|
-
cleared: string[];
|
|
399
|
-
/**
|
|
400
|
-
* True when the first entry of `final` came from THIS TIER rather than from
|
|
401
|
-
* a registered policy — today that means Jev's own verdict.
|
|
402
|
-
*
|
|
403
|
-
* `handler.ts` reads it to decide whether to attribute the decision to a
|
|
404
|
-
* registered policy — a name it cannot find in the registry is reported as a
|
|
405
|
-
* builtin, so a name that never was one must say so here.
|
|
406
|
-
*/
|
|
407
|
-
decidedByJev: boolean;
|
|
408
|
-
activity: JevActivityFields;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* The regex engine's answer on its own — exactly what `evaluatePolicies`
|
|
413
|
-
* returned before two tiers existed: the first deny in evaluation order wins;
|
|
414
|
-
* otherwise every instruct, joined; otherwise every allow that carried a note.
|
|
415
|
-
*/
|
|
416
|
-
export function regexOnly(verdicts: readonly RegexVerdict[]): FinalVerdict {
|
|
417
|
-
const deny = verdicts.find((v) => v.decision === "deny");
|
|
418
|
-
if (deny) return { decision: "deny", entries: [{ policyName: deny.policyName, reason: deny.reason ?? "" }] };
|
|
419
|
-
const instructs = verdicts.filter((v) => v.decision === "instruct");
|
|
420
|
-
if (instructs.length > 0) {
|
|
421
|
-
return { decision: "instruct", entries: instructs.map((v) => ({ policyName: v.policyName, reason: v.reason ?? "" })) };
|
|
422
|
-
}
|
|
423
|
-
return {
|
|
424
|
-
decision: "allow",
|
|
425
|
-
entries: verdicts
|
|
426
|
-
.filter((v) => v.decision === "allow" && v.reason)
|
|
427
|
-
.map((v) => ({ policyName: v.policyName, reason: v.reason as string })),
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Whether Jev's answer clears this regex verdict.
|
|
433
|
-
*
|
|
434
|
-
* The rule, exactly: a REVIEWABLE deny or instruct that names at least one
|
|
435
|
-
* reviewer is cleared when EVERY name in its `reviewedBy` was ASKED on this
|
|
436
|
-
* call AND did not answer `deny` (`none`, `overridden` or `instruct` — see "A
|
|
437
|
-
* warning-level answer clears the deny, and leaves the warning" above).
|
|
438
|
-
*
|
|
439
|
-
* The two halves are not interchangeable, and only the second was relaxed:
|
|
440
|
-
* a name that was never asked still blocks the clear, whatever the others
|
|
441
|
-
* said, because an unasked question has no answer to read. A `hard` verdict
|
|
442
|
-
* and a reviewable one naming nobody are never cleared at all.
|
|
443
|
-
*/
|
|
444
|
-
function clears(v: RegexVerdict, asked: ReadonlySet<string>, notDenied: ReadonlySet<string>): boolean {
|
|
445
|
-
if (v.decision === "allow" || v.authority !== "reviewable") return false;
|
|
446
|
-
if (v.reviewedBy.length === 0) return false;
|
|
447
|
-
return v.reviewedBy.every((name) => asked.has(name) && notDenied.has(name));
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
export function combineTwoTier(
|
|
451
|
-
verdicts: readonly RegexVerdict[],
|
|
452
|
-
review: JevReview,
|
|
453
|
-
mode: JevMode,
|
|
454
|
-
): CombineOutcome {
|
|
455
|
-
const legacy = regexOnly(verdicts);
|
|
456
|
-
|
|
457
|
-
if (review.kind === "not-consulted") {
|
|
458
|
-
// A hard deny decided. Nothing was asked, so nothing is cleared, and the
|
|
459
|
-
// regex result is final — byte for byte what the regex engine says alone.
|
|
460
|
-
return { final: legacy, cleared: [], decidedByJev: false, activity: { evaluator: "jev", jevMode: mode } };
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (review.kind === "fallback") {
|
|
464
|
-
return {
|
|
465
|
-
final: legacy,
|
|
466
|
-
cleared: [],
|
|
467
|
-
decidedByJev: false,
|
|
468
|
-
activity: {
|
|
469
|
-
evaluator: "jev-fallback",
|
|
470
|
-
jevFallbackReason: review.reason,
|
|
471
|
-
...(review.latencyMs !== null ? { jevLatencyMs: review.latencyMs } : {}),
|
|
472
|
-
...(review.model ? { jevModel: review.model } : {}),
|
|
473
|
-
jevMode: mode,
|
|
474
|
-
},
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// The one gate on clearing. Every reason Jev's picture of the CALL is
|
|
479
|
-
// partial lives here and here only, so the next one added cannot
|
|
480
|
-
// accidentally take Jev's own severity with it (see "One rule about a
|
|
481
|
-
// partial picture" above). `truncated` is deliberately not among them: see
|
|
482
|
-
// "What a cut MESSAGE does".
|
|
483
|
-
const wholePicture = review.injectionAsked && !review.injected && !review.requestCut;
|
|
484
|
-
const asked = new Set(review.asked);
|
|
485
|
-
const notDenied = new Set(review.notDenied);
|
|
486
|
-
const cleared = wholePicture ? verdicts.filter((v) => clears(v, asked, notDenied)).map((v) => v.policyName) : [];
|
|
487
|
-
const activity: JevActivityFields = {
|
|
488
|
-
// §4 records a call the tier could not read whole as a fallback, and so do
|
|
489
|
-
// we — its clearing half really was off. The decision below is still
|
|
490
|
-
// applied (upward only), so `jev-fallback` + `request-cut` means "Jev
|
|
491
|
-
// cleared nothing", while every other reason means "Jev never answered".
|
|
492
|
-
// A cut MESSAGE is not a fallback: nothing about the call was missing and
|
|
493
|
-
// nothing was withheld, so reporting one would only inflate the rate.
|
|
494
|
-
evaluator: review.requestCut ? "jev-fallback" : "jev",
|
|
495
|
-
...(review.requestCut ? { jevFallbackReason: JEV_REASON_REQUEST_CUT } : {}),
|
|
496
|
-
jevDecision: review.decision,
|
|
497
|
-
...(cleared.length > 0 ? { jevCleared: cleared } : {}),
|
|
498
|
-
...(review.latencyMs !== null ? { jevLatencyMs: review.latencyMs } : {}),
|
|
499
|
-
...(review.model ? { jevModel: review.model } : {}),
|
|
500
|
-
jevMode: mode,
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
if (mode === "shadow") return { final: legacy, cleared, decidedByJev: false, activity };
|
|
504
|
-
|
|
505
|
-
const clearedSet = new Set(cleared);
|
|
506
|
-
const remaining = verdicts.filter((v) => !clearedSet.has(v.policyName));
|
|
507
|
-
const jevEntry = { policyName: review.policyName, reason: review.reason ?? `Flagged by semantic review (${review.policyName})` };
|
|
508
|
-
|
|
509
|
-
// Most severe wins; within a severity, the regex engine's own order first.
|
|
510
|
-
const regexDeny = remaining.find((v) => v.decision === "deny");
|
|
511
|
-
if (regexDeny) {
|
|
512
|
-
return {
|
|
513
|
-
final: { decision: "deny", entries: [{ policyName: regexDeny.policyName, reason: regexDeny.reason ?? "" }] },
|
|
514
|
-
cleared,
|
|
515
|
-
decidedByJev: false,
|
|
516
|
-
activity,
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
if (review.decision === "deny") {
|
|
520
|
-
return { final: { decision: "deny", entries: [jevEntry] }, cleared, decidedByJev: true, activity };
|
|
521
|
-
}
|
|
522
|
-
// A call part of which was not shown to Jev stops HERE and no further: it
|
|
523
|
-
// cleared nothing (`wholePicture` above), so every regex verdict still
|
|
524
|
-
// stands and Jev's own deny already decided if there was one. There is
|
|
525
|
-
// deliberately no third outcome — no refusal of this module's own — because
|
|
526
|
-
// a deny nobody's policy asked for, fired by size on work nobody objected
|
|
527
|
-
// to, costs more than it protects. See "What size may NOT do" above.
|
|
528
|
-
const instructs = remaining
|
|
529
|
-
.filter((v) => v.decision === "instruct")
|
|
530
|
-
.map((v) => ({ policyName: v.policyName, reason: v.reason ?? "" }));
|
|
531
|
-
if (review.decision === "instruct") instructs.push(jevEntry);
|
|
532
|
-
if (instructs.length > 0) {
|
|
533
|
-
return {
|
|
534
|
-
final: { decision: "instruct", entries: instructs },
|
|
535
|
-
cleared,
|
|
536
|
-
decidedByJev: instructs[0] === jevEntry,
|
|
537
|
-
activity,
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
return { final: regexOnly(remaining), cleared, decidedByJev: false, activity };
|
|
541
|
-
}
|