failproofai 1.0.12-beta.1 → 1.0.12
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.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 +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- 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.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 +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- 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.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.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 +3 -3
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- 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 +2 -2
- 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.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.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.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 -8
- 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/_0tovk6q0miud6._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3ycqv17cl._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68lnh2daur._.js +2 -2
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4vkpxxu7._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0_em82s16zfym._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08ch3staq3ejw._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bigvy9xmv2ka._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h86bl2qf0k_o._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pia5h3p8re4c._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-ey9fgesfbc0._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15usvs-ms-0hf._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__167mipqmjprq5._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16gb3_92zvk5x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1avi2kypusyb_._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1r7drlqli-ado._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0b78b0j8iyv6l._.js → [root-of-the-server]__1vofkb2oq7p7e._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1a3tubds7s7ow._.js → _0ouu886szh6yj._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1d98fyfrcaqhy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1djqs9i27e4kg._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo5_vm5f.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9snixb5fd-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47q0xq5w._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x33jqb6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpcz0uxur._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h47jmhhd._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_1i8oid1gc7s1f.js → node_modules_html-to-image_es_index_0tqc05n832v7a.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/package_json_[json]_cjs_013tntikdft59._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0agdmptetetdt._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0mdwgjisv4fub._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589gp4p60j._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me658zqmh_._.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/preview-props.json +3 -3
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
- package/.next/standalone/.next/static/chunks/{1b32-afqacaen.js → 0el9n3h9_zp5m.js} +1 -1
- package/.next/standalone/.next/static/chunks/0k7g_8x3o6gd-.js +1 -0
- package/.next/standalone/.next/static/chunks/{42e8zab314654.js → 0umzct31duk5g.js} +1 -1
- package/.next/standalone/.next/static/chunks/{24w3x2da9sk49.js → 0wobqgosirs8p.js} +1 -1
- package/.next/standalone/.next/static/chunks/12rug3jilwqzs.js +1 -0
- package/.next/standalone/.next/static/chunks/{2-tf6_7u623kd.js → 1kduj74-715jh.js} +1 -1
- package/.next/standalone/.next/static/chunks/2701amhrbsbot.js +1 -0
- package/.next/standalone/.next/static/chunks/{18433qz-8njv3.js → 27cavoc8paelg.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0_zfad4co-t2z.js → 2ve23a7keupjw.js} +1 -1
- package/.next/standalone/.next/static/chunks/3bv6xaoitjpnh.js +6 -0
- package/.next/standalone/app/actions/update-jev-config.ts +5 -3
- package/.next/standalone/app/settings/jev-panel.tsx +1 -1
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +28 -18
- package/.next/standalone/fp-cloud-cli/README.md +127 -9
- package/.next/standalone/fp-cloud-cli/fp_cli/app.py +15 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +199 -34
- package/.next/standalone/fp-cloud-cli/fp_cli/cloud_output.py +523 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_cloud.py +45 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +3 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/account_cmds.py +171 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +80 -7
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +23 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +2 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/contracts_cmds.py +67 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/dashboards_cmds.py +159 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/evaluators_cmds.py +380 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +14 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +12 -216
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +82 -6
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +4 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +17 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +143 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +70 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sentiment_cmds.py +49 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +95 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +2 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +21 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +14 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +7 -53
- package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +3 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/evaluator_spec.py +266 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +189 -152
- package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +21 -24
- package/.next/standalone/fp-cloud-cli/skill/SKILL.md +124 -23
- package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +2 -1
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +173 -22
- package/.next/standalone/fp-cloud-cli/tests/fake_cloud_smoke.py +312 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_account.py +125 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_agent.py +253 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_human_views.py +287 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_jev.py +32 -197
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_observability.py +116 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_transport.py +141 -0
- package/.next/standalone/fp-cloud-cli/tests/test_commands.py +3 -3
- package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +3 -3
- package/.next/standalone/fp-cloud-cli/tests/test_evaluator_authoring.py +449 -0
- package/.next/standalone/fp-cloud-cli/tests/test_facets.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +15 -0
- package/.next/standalone/fp-cloud-cli/tests/test_operator.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +37 -37
- package/.next/standalone/fp-cloud-cli/tests/test_round4_behaviour.py +144 -0
- package/.next/standalone/fp-cloud-cli/tests/test_screen_language.py +80 -0
- package/.next/standalone/fp-cloud-cli/tests/test_session_reevaluate.py +33 -0
- package/.next/standalone/fp-cloud-cli/tests/test_staging_parity.py +198 -0
- package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +1 -1
- package/.next/standalone/hermes-plugin/__init__.py +11 -0
- package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
- package/.next/standalone/package.json +11 -10
- package/.next/standalone/sdk/python/uv.lock +31 -8
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +68 -176
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +2 -2
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +98 -115
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +3 -3
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +149 -171
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +2 -2
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +25 -25
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +10 -10
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +1760 -638
- package/dist/worker.mjs +426 -76
- package/hermes-plugin/__init__.py +11 -0
- package/hermes-plugin/plugin.yaml +1 -1
- package/package.json +11 -10
- package/src/audit/open-browser.ts +24 -7
- package/src/hooks/agent-roster.ts +9 -1
- package/src/hooks/agent-skill.ts +206 -0
- package/src/hooks/cloud-connection.ts +27 -51
- package/src/hooks/cloud-introspect.ts +5 -2
- package/src/hooks/cloud-login.ts +248 -0
- package/src/hooks/cloud-managed-policies.ts +54 -4
- package/src/hooks/codex-system-hooks.ts +10 -4
- package/src/hooks/config-status.ts +9 -3
- package/src/hooks/configure-wizard.ts +356 -32
- package/src/hooks/delivery-health.ts +47 -2
- package/src/hooks/effective-reviewers.ts +14 -0
- package/src/hooks/fp-config.ts +19 -0
- package/src/hooks/fp-home.ts +1 -1
- package/src/hooks/handler.ts +43 -5
- package/src/hooks/hook-activity-store.ts +7 -1
- package/src/hooks/integrations.ts +18 -3
- package/src/hooks/jev-activity.ts +117 -1
- package/src/hooks/jev-cli.ts +7 -9
- package/src/hooks/manager.ts +80 -46
- package/src/hooks/policy-evaluator.ts +17 -0
- package/src/hooks/policy-reviewability.ts +4 -2
- package/src/hooks/semantic/cloud-jev.ts +219 -28
- package/src/hooks/semantic/combine.ts +26 -1
- package/src/hooks/semantic/intent.ts +127 -24
- package/src/hooks/semantic/jev-client.ts +1 -1
- package/src/hooks/semantic/jev-config.ts +6 -27
- package/src/hooks/semantic/jev-review.ts +111 -4
- package/src/hooks/tui.ts +280 -0
- package/src/hooks/uninstall-cli.ts +12 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0588st-tpiuia._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_128ebxr83nk6g._.js +0 -3
- package/.next/standalone/.next/static/chunks/0jutamwqz8pg5.js +0 -1
- package/.next/standalone/.next/static/chunks/114hbolvrv94e.js +0 -1
- package/.next/standalone/.next/static/chunks/1p-hsi58i-6h0.js +0 -6
- package/.next/standalone/.next/static/chunks/3-pku9qwv1yfu.js +0 -1
- /package/.next/standalone/.next/static/{xq8UgF5yFxty1VWxY2hyn → D7LY1YSrw96ZxKSpxxrFw}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{xq8UgF5yFxty1VWxY2hyn → D7LY1YSrw96ZxKSpxxrFw}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{xq8UgF5yFxty1VWxY2hyn → D7LY1YSrw96ZxKSpxxrFw}/_ssgManifest.js +0 -0
package/dist/worker.mjs
CHANGED
|
@@ -1166,7 +1166,7 @@ function instruct(reason) {
|
|
|
1166
1166
|
}
|
|
1167
1167
|
|
|
1168
1168
|
// package.json
|
|
1169
|
-
var version = "1.0.12
|
|
1169
|
+
var version = "1.0.12";
|
|
1170
1170
|
var init_package = () => {};
|
|
1171
1171
|
|
|
1172
1172
|
// src/hooks/agent-targets.ts
|
|
@@ -1474,6 +1474,40 @@ function readCloudJevState() {
|
|
|
1474
1474
|
const deployment = Number.isSafeInteger(active.deployment) ? active.deployment : null;
|
|
1475
1475
|
return { jevMode, deployment, errors };
|
|
1476
1476
|
}
|
|
1477
|
+
function readCloudJevAssignments() {
|
|
1478
|
+
try {
|
|
1479
|
+
const active = readActiveRaw();
|
|
1480
|
+
if (!active || !Array.isArray(active.jevPolicies))
|
|
1481
|
+
return null;
|
|
1482
|
+
const schema = active.schemaVersion;
|
|
1483
|
+
const out = [];
|
|
1484
|
+
for (const raw of active.jevPolicies) {
|
|
1485
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
1486
|
+
return null;
|
|
1487
|
+
const entry = raw;
|
|
1488
|
+
if (typeof entry.id !== "string" || !POLICY_ID_RE.test(entry.id))
|
|
1489
|
+
return null;
|
|
1490
|
+
if (!Number.isSafeInteger(entry.version) || entry.version < 0)
|
|
1491
|
+
return null;
|
|
1492
|
+
if (entry.effect !== undefined && entry.effect !== "enforce" && entry.effect !== "observe")
|
|
1493
|
+
return null;
|
|
1494
|
+
const targets = parseAgentTargets(entry.agentTargets, schema);
|
|
1495
|
+
out.push({
|
|
1496
|
+
id: entry.id,
|
|
1497
|
+
version: entry.version,
|
|
1498
|
+
effect: entry.effect === "observe" ? "observe" : "enforce",
|
|
1499
|
+
...targets ? { agentTargets: targets } : {}
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
return out;
|
|
1503
|
+
} catch {
|
|
1504
|
+
return null;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
function cloudJevAssignmentsFor(agent) {
|
|
1508
|
+
const all = readCloudJevAssignments();
|
|
1509
|
+
return all === null ? null : all.filter((a) => agentTargetsMatch(a.agentTargets, agent));
|
|
1510
|
+
}
|
|
1477
1511
|
function cloudReviewerName(policyId, name) {
|
|
1478
1512
|
return `cloud:${policyId}/${name}`;
|
|
1479
1513
|
}
|
|
@@ -2104,9 +2138,11 @@ function effectiveReviewerNames() {
|
|
|
2104
2138
|
return cached;
|
|
2105
2139
|
let names = NO_REVIEWERS;
|
|
2106
2140
|
cachedContested = new Map;
|
|
2141
|
+
cachedPackChecks = false;
|
|
2107
2142
|
try {
|
|
2108
2143
|
const packs = jevPacks(readInstalledPacks().packs, reviewerCli);
|
|
2109
2144
|
names = reviewerNamesFor(packs);
|
|
2145
|
+
cachedPackChecks = names.size > 0;
|
|
2110
2146
|
cachedContested = contestedSemanticNames(packs);
|
|
2111
2147
|
} catch {}
|
|
2112
2148
|
try {
|
|
@@ -2124,6 +2160,10 @@ function contestedReviewerNames() {
|
|
|
2124
2160
|
function jevChecksInstalled() {
|
|
2125
2161
|
return effectiveReviewerNames().size > 0;
|
|
2126
2162
|
}
|
|
2163
|
+
function packJevChecksInstalled() {
|
|
2164
|
+
effectiveReviewerNames();
|
|
2165
|
+
return cachedPackChecks;
|
|
2166
|
+
}
|
|
2127
2167
|
function reviewerNamesFor(packs) {
|
|
2128
2168
|
const contested = contestedSemanticNames(packs);
|
|
2129
2169
|
const declared = packs.flatMap((p) => (p.semantic ?? []).filter((s) => !isReservedClaim(p, s.name)).map((s) => s.name)).filter((name) => !contested.has(name));
|
|
@@ -2136,7 +2176,7 @@ function forgetEffectiveReviewerNames(cli, agent = null) {
|
|
|
2136
2176
|
reviewerCli = cli;
|
|
2137
2177
|
reviewerAgent = agent;
|
|
2138
2178
|
}
|
|
2139
|
-
var cached = null, cachedContested, reviewerCli, reviewerAgent = null;
|
|
2179
|
+
var cached = null, cachedPackChecks = false, cachedContested, reviewerCli, reviewerAgent = null;
|
|
2140
2180
|
var init_effective_reviewers = __esm(() => {
|
|
2141
2181
|
init_pack_manifest();
|
|
2142
2182
|
init_policy_authority();
|
|
@@ -4362,6 +4402,57 @@ function normalizeJevFallbackReason(raw) {
|
|
|
4362
4402
|
const code = JEV_FREE_TEXT_PREFIXES.get(head) ?? head;
|
|
4363
4403
|
return JEV_REASON_CODES.has(code) ? code : JEV_REASON_OTHER;
|
|
4364
4404
|
}
|
|
4405
|
+
function sanitizeCheck(raw) {
|
|
4406
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
4407
|
+
return null;
|
|
4408
|
+
const r = raw;
|
|
4409
|
+
if (typeof r.check !== "string" || !JEV_CHECK_NAME_RE.test(r.check))
|
|
4410
|
+
return null;
|
|
4411
|
+
if (typeof r.verdict !== "string" || !CHECK_VERDICT_SET.has(r.verdict))
|
|
4412
|
+
return null;
|
|
4413
|
+
if (typeof r.why !== "string" || !CHECK_WHY_SET.has(r.why))
|
|
4414
|
+
return null;
|
|
4415
|
+
if (!isP(r.p))
|
|
4416
|
+
return null;
|
|
4417
|
+
const out = {
|
|
4418
|
+
check: r.check,
|
|
4419
|
+
verdict: r.verdict,
|
|
4420
|
+
why: r.why,
|
|
4421
|
+
p: round2(r.p)
|
|
4422
|
+
};
|
|
4423
|
+
if (typeof r.policy === "string" && isJevPolicyName(r.policy) && !/\s/.test(r.policy) && /^(?:cloud|pack)\//.test(r.policy)) {
|
|
4424
|
+
out.policy = r.policy;
|
|
4425
|
+
}
|
|
4426
|
+
if (isP(r.exempt))
|
|
4427
|
+
out.exempt = round2(r.exempt);
|
|
4428
|
+
if (r.watched === true)
|
|
4429
|
+
out.watched = true;
|
|
4430
|
+
if (r.probes && typeof r.probes === "object" && !Array.isArray(r.probes)) {
|
|
4431
|
+
const probes = {};
|
|
4432
|
+
for (const [id, v] of Object.entries(r.probes)) {
|
|
4433
|
+
if (Object.keys(probes).length >= JEV_CHECK_PROBES_MAX)
|
|
4434
|
+
break;
|
|
4435
|
+
if (JEV_PROBE_ID_RE.test(id) && isP(v))
|
|
4436
|
+
probes[id] = round2(v);
|
|
4437
|
+
}
|
|
4438
|
+
if (Object.keys(probes).length > 0)
|
|
4439
|
+
out.probes = probes;
|
|
4440
|
+
}
|
|
4441
|
+
return out;
|
|
4442
|
+
}
|
|
4443
|
+
function sanitizeJevChecks(raw) {
|
|
4444
|
+
if (!Array.isArray(raw))
|
|
4445
|
+
return;
|
|
4446
|
+
const out = [];
|
|
4447
|
+
for (const item of raw) {
|
|
4448
|
+
if (out.length >= JEV_CHECKS_MAX)
|
|
4449
|
+
break;
|
|
4450
|
+
const rec = sanitizeCheck(item);
|
|
4451
|
+
if (rec)
|
|
4452
|
+
out.push(rec);
|
|
4453
|
+
}
|
|
4454
|
+
return raw.length > 0 && out.length === 0 ? undefined : out;
|
|
4455
|
+
}
|
|
4365
4456
|
function sanitizeJevActivity(entry) {
|
|
4366
4457
|
if (!JEV_ACTIVITY_KEYS.some((k) => entry[k] !== undefined))
|
|
4367
4458
|
return entry;
|
|
@@ -4400,6 +4491,11 @@ function sanitizeJevActivity(entry) {
|
|
|
4400
4491
|
out.jevModel = out.jevModel.trim();
|
|
4401
4492
|
else
|
|
4402
4493
|
drop("jevModel");
|
|
4494
|
+
const checks = out.evaluator === "jev" ? sanitizeJevChecks(out.jevChecks) : undefined;
|
|
4495
|
+
if (checks === undefined)
|
|
4496
|
+
drop("jevChecks");
|
|
4497
|
+
else
|
|
4498
|
+
out.jevChecks = checks;
|
|
4403
4499
|
return out;
|
|
4404
4500
|
}
|
|
4405
4501
|
function jevOutcome(raw) {
|
|
@@ -4410,6 +4506,8 @@ function outcomeOf(e) {
|
|
|
4410
4506
|
return "fallback";
|
|
4411
4507
|
if (e.evaluator !== "jev")
|
|
4412
4508
|
return null;
|
|
4509
|
+
if (Array.isArray(e.jevChecks) && e.jevChecks.length === 0)
|
|
4510
|
+
return "no-request";
|
|
4413
4511
|
if (e.jevCleared !== undefined || e.jevLatencyMs !== undefined || e.jevModel !== undefined)
|
|
4414
4512
|
return "answered";
|
|
4415
4513
|
if (e.jevDecision === "deny" || e.jevDecision === "instruct")
|
|
@@ -4418,7 +4516,7 @@ function outcomeOf(e) {
|
|
|
4418
4516
|
return "no-request";
|
|
4419
4517
|
return "not-consulted";
|
|
4420
4518
|
}
|
|
4421
|
-
var JEV_ACTIVITY_KEYS, EVALUATORS, DECISIONS, MODES, REASON_HEAD_RE, HTTP_CODE_RE, JEV_REASON_MAX_CHARS = 40, JEV_REASON_OTHER = "other", JEV_REASON_CODE_LIST, JEV_REASON_CODES, JEV_REASON_REQUEST_CUT = "request-cut", JEV_REASON_PROVIDER_REFUSED = "provider-refused", JEV_FREE_TEXT_PREFIXES, JEV_MODEL_RE, JEV_POLICY_NAME_MAX_CHARS = 200, NAME_FORBIDDEN_RE, REGISTERED_NAMESPACE_RE, JEV_CLEARED_MAX = 64, ANSWERED_BUT_NOT_APPLIED_REASONS;
|
|
4519
|
+
var JEV_ACTIVITY_KEYS, EVALUATORS, DECISIONS, MODES, REASON_HEAD_RE, HTTP_CODE_RE, JEV_REASON_MAX_CHARS = 40, JEV_REASON_OTHER = "other", JEV_REASON_CODE_LIST, JEV_REASON_CODES, JEV_REASON_REQUEST_CUT = "request-cut", JEV_REASON_PROVIDER_REFUSED = "provider-refused", JEV_FREE_TEXT_PREFIXES, JEV_MODEL_RE, JEV_POLICY_NAME_MAX_CHARS = 200, NAME_FORBIDDEN_RE, REGISTERED_NAMESPACE_RE, JEV_CLEARED_MAX = 64, JEV_CHECK_VERDICTS, JEV_CHECK_WHY, JEV_CHECKS_MAX = 32, JEV_CHECK_PROBES_MAX = 8, JEV_CHECK_NAME_RE, JEV_PROBE_ID_RE, CHECK_VERDICT_SET, CHECK_WHY_SET, isP = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 1, round2 = (v) => Math.round(v * 100) / 100, ANSWERED_BUT_NOT_APPLIED_REASONS;
|
|
4422
4520
|
var init_jev_activity = __esm(() => {
|
|
4423
4521
|
JEV_ACTIVITY_KEYS = [
|
|
4424
4522
|
"evaluator",
|
|
@@ -4427,7 +4525,8 @@ var init_jev_activity = __esm(() => {
|
|
|
4427
4525
|
"jevFallbackReason",
|
|
4428
4526
|
"jevLatencyMs",
|
|
4429
4527
|
"jevModel",
|
|
4430
|
-
"jevMode"
|
|
4528
|
+
"jevMode",
|
|
4529
|
+
"jevChecks"
|
|
4431
4530
|
];
|
|
4432
4531
|
EVALUATORS = new Set(["jev", "jev-fallback"]);
|
|
4433
4532
|
DECISIONS = new Set(["allow", "instruct", "deny"]);
|
|
@@ -4474,6 +4573,22 @@ var init_jev_activity = __esm(() => {
|
|
|
4474
4573
|
JEV_MODEL_RE = /^[A-Za-z0-9._:/@~+-]{1,200}$/;
|
|
4475
4574
|
NAME_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;
|
|
4476
4575
|
REGISTERED_NAMESPACE_RE = /^(?:custom|pack|cloud|failproofai|\.failproofai-[A-Za-z0-9_-]{1,32})\//;
|
|
4576
|
+
JEV_CHECK_VERDICTS = ["none", "deny", "instruct", "overridden"];
|
|
4577
|
+
JEV_CHECK_WHY = [
|
|
4578
|
+
"not-detected",
|
|
4579
|
+
"exempt",
|
|
4580
|
+
"fired",
|
|
4581
|
+
"injection",
|
|
4582
|
+
"user-asked",
|
|
4583
|
+
"op-requested",
|
|
4584
|
+
"task-step",
|
|
4585
|
+
"downgraded",
|
|
4586
|
+
"scan-incomplete"
|
|
4587
|
+
];
|
|
4588
|
+
JEV_CHECK_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
4589
|
+
JEV_PROBE_ID_RE = /^[a-z][a-z0-9_]{0,31}$/;
|
|
4590
|
+
CHECK_VERDICT_SET = new Set(JEV_CHECK_VERDICTS);
|
|
4591
|
+
CHECK_WHY_SET = new Set(JEV_CHECK_WHY);
|
|
4477
4592
|
ANSWERED_BUT_NOT_APPLIED_REASONS = new Set([
|
|
4478
4593
|
JEV_REASON_REQUEST_CUT,
|
|
4479
4594
|
"truncated",
|
|
@@ -4534,7 +4649,8 @@ function combineTwoTier(verdicts, review, mode) {
|
|
|
4534
4649
|
...cleared.length > 0 && RANK[enforced.final.decision] < RANK[legacy.decision] ? { jevCleared: cleared } : {},
|
|
4535
4650
|
...review.latencyMs !== null ? { jevLatencyMs: review.latencyMs } : {},
|
|
4536
4651
|
...review.model ? { jevModel: review.model } : {},
|
|
4537
|
-
jevMode: mode
|
|
4652
|
+
jevMode: mode,
|
|
4653
|
+
...review.checks ? { jevChecks: [...review.checks] } : {}
|
|
4538
4654
|
};
|
|
4539
4655
|
if (mode === "observe") {
|
|
4540
4656
|
const observeVerdict = review.decision === "deny" || review.decision === "instruct" ? {
|
|
@@ -5201,6 +5317,12 @@ async function evaluatePolicies(eventType, payload, session, config, twoTier) {
|
|
|
5201
5317
|
twoTier.releaseRegistry?.();
|
|
5202
5318
|
review = await twoTier.review;
|
|
5203
5319
|
}
|
|
5320
|
+
if (review.kind === "answered" && review.asked.length === 0 && review.decision === "allow" && !review.observedAsked?.length) {
|
|
5321
|
+
return formatVerdict(eventType, session, toolName, regexOnly(collected.verdicts));
|
|
5322
|
+
}
|
|
5323
|
+
if (review.kind === "not-consulted" && twoTier.cloud) {
|
|
5324
|
+
return formatVerdict(eventType, session, toolName, regexOnly(collected.verdicts));
|
|
5325
|
+
}
|
|
5204
5326
|
const combined = combineTwoTier(collected.verdicts, review, twoTier.mode);
|
|
5205
5327
|
if (combined.cleared.length > 0) {
|
|
5206
5328
|
hookLogInfo(`jev ${twoTier.mode === "observe" ? "would clear" : "cleared"}: ${combined.cleared.join(", ")}`);
|
|
@@ -5214,7 +5336,8 @@ async function evaluatePolicies(eventType, payload, session, config, twoTier) {
|
|
|
5214
5336
|
activity: combined.activity,
|
|
5215
5337
|
decidedByJev: combined.decidedByJev,
|
|
5216
5338
|
...(combined.decidedByJev || combined.observeVerdict) && review.kind === "answered" && review.origin ? { jevOrigin: review.origin } : {},
|
|
5217
|
-
...combined.observeVerdict ? { observeVerdict: combined.observeVerdict } : {}
|
|
5339
|
+
...combined.observeVerdict ? { observeVerdict: combined.observeVerdict } : {},
|
|
5340
|
+
...review.kind === "answered" && review.observedCloud?.length ? { observedCloud: review.observedCloud } : {}
|
|
5218
5341
|
}
|
|
5219
5342
|
};
|
|
5220
5343
|
}
|
|
@@ -12092,7 +12215,13 @@ function runtimeAgentSettingsPath(cli, cwd, userHome = homedir21(), hookScope) {
|
|
|
12092
12215
|
if (config?.trim())
|
|
12093
12216
|
return resolve15(config);
|
|
12094
12217
|
const state = process.env.OPENCLAW_STATE_DIR || process.env.OPENCLAW_HOME;
|
|
12095
|
-
|
|
12218
|
+
if (state?.trim())
|
|
12219
|
+
return resolve15(state, "openclaw.json");
|
|
12220
|
+
const profile = process.env.OPENCLAW_PROFILE?.trim();
|
|
12221
|
+
if (profile && profile !== "default" && /^[A-Za-z0-9._-]{1,80}$/.test(profile) && !profile.startsWith(".")) {
|
|
12222
|
+
return resolve15(userHome, `.openclaw-${profile}`, "openclaw.json");
|
|
12223
|
+
}
|
|
12224
|
+
return resolve15(userHome, ".openclaw", "openclaw.json");
|
|
12096
12225
|
}
|
|
12097
12226
|
const relative = USER_SETTINGS[cli];
|
|
12098
12227
|
if (!relative)
|
|
@@ -12246,13 +12375,6 @@ function validateBaseUrl(raw) {
|
|
|
12246
12375
|
url.pathname = url.pathname.replace(/\/+$/, "") || "/";
|
|
12247
12376
|
return { ok: true, value: url.toString() };
|
|
12248
12377
|
}
|
|
12249
|
-
function isPlainHttp(url) {
|
|
12250
|
-
try {
|
|
12251
|
-
return new URL(url).protocol === "http:";
|
|
12252
|
-
} catch {
|
|
12253
|
-
return false;
|
|
12254
|
-
}
|
|
12255
|
-
}
|
|
12256
12378
|
function originOf(raw) {
|
|
12257
12379
|
try {
|
|
12258
12380
|
const url = new URL(raw);
|
|
@@ -12387,12 +12509,6 @@ function validateJevConfig(raw, envKey, cloud) {
|
|
|
12387
12509
|
return { ok: false, problem: 'mode must be "off", "observe" or "enforce"' };
|
|
12388
12510
|
cfg.mode = mode;
|
|
12389
12511
|
}
|
|
12390
|
-
if (cfg.baseUrl !== undefined && isPlainHttp(cfg.baseUrl) && cfg.mode === "enforce") {
|
|
12391
|
-
return {
|
|
12392
|
-
ok: false,
|
|
12393
|
-
problem: "plain http (to localhost) is accepted only with mode observe: in enforce mode Jev's answers can clear a deny, " + "and while the local proxy is down any process on this machine could take its port and answer. " + (cfg.provider === JEV_CLOUD_PROVIDER ? "Reconnect to an https FailproofAI Cloud URL (failproofai config --token <key> --url https://…), or keep mode observe" : "Use https, or mode observe")
|
|
12394
|
-
};
|
|
12395
|
-
}
|
|
12396
12512
|
return { ok: true, value: cfg };
|
|
12397
12513
|
}
|
|
12398
12514
|
function validateLoadedJevConfig(cfg) {
|
|
@@ -15590,6 +15706,7 @@ __export(exports_intent, {
|
|
|
15590
15706
|
cleanHumanTurn: () => cleanHumanTurn,
|
|
15591
15707
|
cleanUserSaid: () => cleanUserSaid,
|
|
15592
15708
|
humanMessageText: () => humanMessageText,
|
|
15709
|
+
intentProfileKey: () => intentProfileKey,
|
|
15593
15710
|
lastAgentMessage: () => lastAgentMessage,
|
|
15594
15711
|
looseIntentStoreDir: () => looseIntentStoreDir,
|
|
15595
15712
|
pruneExpiredSessions: () => pruneExpiredSessions,
|
|
@@ -15609,13 +15726,27 @@ import {
|
|
|
15609
15726
|
writeFileSync as writeFileSync8
|
|
15610
15727
|
} from "node:fs";
|
|
15611
15728
|
import { dirname as dirname10, resolve as resolve17 } from "node:path";
|
|
15729
|
+
function intentProfileKey(profile) {
|
|
15730
|
+
if (validAgentIdentity(profile.agent))
|
|
15731
|
+
return `${profile.agent.integration}.${profile.agent.instanceId}`;
|
|
15732
|
+
return isKnownCli(profile.cli) ? profile.cli : null;
|
|
15733
|
+
}
|
|
15734
|
+
function storeSlot(sessionId, profile) {
|
|
15735
|
+
if (profile === undefined)
|
|
15736
|
+
return { dir: sessionsDir(), file: resolve17(sessionsDir(), `${sessionId}.json`) };
|
|
15737
|
+
const key = intentProfileKey(profile);
|
|
15738
|
+
if (key === null || !PROFILE_DIR_RE.test(key))
|
|
15739
|
+
return null;
|
|
15740
|
+
const dir = resolve17(sessionsDir(), key);
|
|
15741
|
+
return { dir, file: resolve17(dir, `${sessionId}.json`) };
|
|
15742
|
+
}
|
|
15612
15743
|
function modesAreMeaningful2() {
|
|
15613
15744
|
return process.platform !== "win32";
|
|
15614
15745
|
}
|
|
15615
|
-
function storeDirChain() {
|
|
15746
|
+
function storeDirChain(innermost = sessionsDir()) {
|
|
15616
15747
|
const home = resolve17(failproofaiHome());
|
|
15617
15748
|
const chain = [];
|
|
15618
|
-
let dir =
|
|
15749
|
+
let dir = innermost;
|
|
15619
15750
|
for (let i = 0;i < 8; i++) {
|
|
15620
15751
|
chain.push(dir);
|
|
15621
15752
|
if (dir === home)
|
|
@@ -15627,10 +15758,10 @@ function storeDirChain() {
|
|
|
15627
15758
|
}
|
|
15628
15759
|
return chain;
|
|
15629
15760
|
}
|
|
15630
|
-
function looseIntentStoreDir() {
|
|
15761
|
+
function looseIntentStoreDir(innermost) {
|
|
15631
15762
|
if (!modesAreMeaningful2())
|
|
15632
15763
|
return null;
|
|
15633
|
-
for (const dir of storeDirChain()) {
|
|
15764
|
+
for (const dir of storeDirChain(innermost)) {
|
|
15634
15765
|
let mode;
|
|
15635
15766
|
try {
|
|
15636
15767
|
mode = statSync20(dir).mode & 511;
|
|
@@ -15649,23 +15780,22 @@ function looseIntentStoreDir() {
|
|
|
15649
15780
|
}
|
|
15650
15781
|
return null;
|
|
15651
15782
|
}
|
|
15652
|
-
function readIntentFile(
|
|
15783
|
+
function readIntentFile(slot) {
|
|
15653
15784
|
try {
|
|
15654
|
-
const parsed = JSON.parse(readFileSync19(
|
|
15785
|
+
const parsed = JSON.parse(readFileSync19(slot.file, "utf8"));
|
|
15655
15786
|
return Array.isArray(parsed?.prompts) ? parsed : { prompts: [] };
|
|
15656
15787
|
} catch {
|
|
15657
15788
|
return { prompts: [] };
|
|
15658
15789
|
}
|
|
15659
15790
|
}
|
|
15660
|
-
function appendPrompt(
|
|
15791
|
+
function appendPrompt(slot, entry) {
|
|
15661
15792
|
try {
|
|
15662
|
-
const file = readIntentFile(
|
|
15793
|
+
const file = readIntentFile(slot);
|
|
15663
15794
|
const last = file.prompts[file.prompts.length - 1];
|
|
15664
15795
|
const kept = last && last.text === entry.text ? file.prompts.slice(0, -1) : file.prompts;
|
|
15665
15796
|
file.prompts = [...kept, entry].slice(-MAX_RECORDED_PROMPTS);
|
|
15666
|
-
|
|
15667
|
-
|
|
15668
|
-
const target = intentFile(sessionId);
|
|
15797
|
+
mkdirSync9(slot.dir, { recursive: true, mode: 448 });
|
|
15798
|
+
const target = slot.file;
|
|
15669
15799
|
const isNew = !fileExists2(target);
|
|
15670
15800
|
const tmp = `${target}.${process.pid}.tmp`;
|
|
15671
15801
|
writeFileSync8(tmp, JSON.stringify(file), { mode: 384 });
|
|
@@ -15686,9 +15816,24 @@ function fileExists2(path) {
|
|
|
15686
15816
|
}
|
|
15687
15817
|
}
|
|
15688
15818
|
function pruneExpiredSessions(now = Date.now()) {
|
|
15819
|
+
const root = sessionsDir();
|
|
15820
|
+
let removed = pruneDir(root, now);
|
|
15821
|
+
try {
|
|
15822
|
+
for (const name of readdirSync13(root)) {
|
|
15823
|
+
if (!PROFILE_DIR_RE.test(name))
|
|
15824
|
+
continue;
|
|
15825
|
+
const dir = resolve17(root, name);
|
|
15826
|
+
try {
|
|
15827
|
+
if (statSync20(dir).isDirectory())
|
|
15828
|
+
removed += pruneDir(dir, now);
|
|
15829
|
+
} catch {}
|
|
15830
|
+
}
|
|
15831
|
+
} catch {}
|
|
15832
|
+
return removed;
|
|
15833
|
+
}
|
|
15834
|
+
function pruneDir(dir, now) {
|
|
15689
15835
|
let removed = 0;
|
|
15690
15836
|
try {
|
|
15691
|
-
const dir = sessionsDir();
|
|
15692
15837
|
for (const name of readdirSync13(dir)) {
|
|
15693
15838
|
if (!SESSION_FILE_RE3.test(name))
|
|
15694
15839
|
continue;
|
|
@@ -15704,23 +15849,29 @@ function pruneExpiredSessions(now = Date.now()) {
|
|
|
15704
15849
|
} catch {}
|
|
15705
15850
|
return removed;
|
|
15706
15851
|
}
|
|
15707
|
-
function recordPrompt(sessionId, prompt, agent, now) {
|
|
15852
|
+
function recordPrompt(sessionId, profile, prompt, agent, now) {
|
|
15708
15853
|
if (!SESSION_ID_RE2.test(sessionId))
|
|
15709
15854
|
return false;
|
|
15710
15855
|
if (prompt.trim().length === 0)
|
|
15711
15856
|
return false;
|
|
15857
|
+
const slot = storeSlot(sessionId, profile);
|
|
15858
|
+
if (!slot)
|
|
15859
|
+
return false;
|
|
15712
15860
|
try {
|
|
15713
|
-
return appendPrompt(
|
|
15861
|
+
return appendPrompt(slot, { at: now, text: storable(prompt.trim()), agent: agent === null ? null : storable(agent) });
|
|
15714
15862
|
} catch {
|
|
15715
15863
|
return false;
|
|
15716
15864
|
}
|
|
15717
15865
|
}
|
|
15718
|
-
function livePrompts(sessionId, now) {
|
|
15866
|
+
function livePrompts(sessionId, now, profile) {
|
|
15719
15867
|
if (!sessionId || !SESSION_ID_RE2.test(sessionId))
|
|
15720
15868
|
return [];
|
|
15721
|
-
|
|
15869
|
+
const slot = storeSlot(sessionId, profile);
|
|
15870
|
+
if (!slot)
|
|
15871
|
+
return [];
|
|
15872
|
+
if (looseIntentStoreDir(slot.dir) !== null)
|
|
15722
15873
|
return [];
|
|
15723
|
-
return readIntentFile(
|
|
15874
|
+
return readIntentFile(slot).prompts.filter((p) => typeof p?.text === "string" && typeof p.at === "number" && now - p.at <= INTENT_MAX_AGE_MS && p.at - now <= MAX_CLOCK_SKEW_MS);
|
|
15724
15875
|
}
|
|
15725
15876
|
function replaceTagBlocks(text, tag, replace, attributes = false) {
|
|
15726
15877
|
const open = attributes ? `<${tag}` : `<${tag}>`;
|
|
@@ -16067,16 +16218,16 @@ function captureIntent(ev, now = Date.now()) {
|
|
|
16067
16218
|
const cleaned = cleanHumanTurn(raw);
|
|
16068
16219
|
if (cleaned === null)
|
|
16069
16220
|
return;
|
|
16070
|
-
recordPrompt(sessionId, cleaned, lastAgentMessage(ev.transcriptPath), now);
|
|
16221
|
+
recordPrompt(sessionId, ev.profile, cleaned, lastAgentMessage(ev.transcriptPath), now);
|
|
16071
16222
|
} catch {}
|
|
16072
16223
|
}
|
|
16073
|
-
function readIntent(sessionId, now = Date.now()) {
|
|
16074
|
-
const prompts = livePrompts(sessionId, now);
|
|
16224
|
+
function readIntent(sessionId, now = Date.now(), profile) {
|
|
16225
|
+
const prompts = livePrompts(sessionId, now, profile);
|
|
16075
16226
|
const latest = prompts[prompts.length - 1];
|
|
16076
16227
|
const agent = latest && typeof latest.agent === "string" && latest.agent.length > 0 ? latest.agent : null;
|
|
16077
16228
|
return { userSaid: prompts.map((p) => p.text), agentLastMessage: agent };
|
|
16078
16229
|
}
|
|
16079
|
-
var MAX_RECORDED_PROMPTS = 5, INTENT_MAX_AGE_MS, MAX_CLOCK_SKEW_MS, SESSION_ID_RE2, sessionsDir = () => resolve17(semanticDir(), "sessions"),
|
|
16230
|
+
var MAX_RECORDED_PROMPTS = 5, INTENT_MAX_AGE_MS, MAX_CLOCK_SKEW_MS, SESSION_ID_RE2, sessionsDir = () => resolve17(semanticDir(), "sessions"), PROFILE_DIR_RE, DIR_WRITABLE_BY_OTHERS3 = 18, SESSION_FILE_RE3, NON_HUMAN_PREFIXES, CONTINUATION_PREFIX = "This session is being continued from a previous conversation", IDE_MACHINE_OPENERS, IDE_AMBIGUOUS_OPENERS, IDE_REQUEST_HEADINGS, obj = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : undefined, CLAUDE_MACHINE_SOURCES, claudeMachineTurn = (payload) => typeof payload.source === "string" && CLAUDE_MACHINE_SOURCES.has(payload.source), piMachineTurn = (payload) => payload.input_source === "extension" || payload.source === "extension", openclawMachineRun = (payload) => {
|
|
16080
16231
|
const meta = obj(payload.openclaw);
|
|
16081
16232
|
if (!meta)
|
|
16082
16233
|
return false;
|
|
@@ -16092,9 +16243,11 @@ var MAX_RECORDED_PROMPTS = 5, INTENT_MAX_AGE_MS, MAX_CLOCK_SKEW_MS, SESSION_ID_R
|
|
|
16092
16243
|
var init_intent = __esm(() => {
|
|
16093
16244
|
init_fp_home();
|
|
16094
16245
|
init_envelope();
|
|
16246
|
+
init_agent_targets();
|
|
16095
16247
|
INTENT_MAX_AGE_MS = 6 * 60 * 60 * 1000;
|
|
16096
16248
|
MAX_CLOCK_SKEW_MS = 5 * 60 * 1000;
|
|
16097
16249
|
SESSION_ID_RE2 = /^[A-Za-z0-9._-]{1,128}$/;
|
|
16250
|
+
PROFILE_DIR_RE = /^[a-z]+(?:\.agt_[0-9a-f]{16,32})?$/;
|
|
16098
16251
|
SESSION_FILE_RE3 = /^[A-Za-z0-9._-]{1,128}\.json(?:\.\d+\.tmp)?$/;
|
|
16099
16252
|
NON_HUMAN_PREFIXES = [
|
|
16100
16253
|
"<local-command-caveat>",
|
|
@@ -17004,7 +17157,11 @@ function parseOutcome(raw, i) {
|
|
|
17004
17157
|
if (!origin || typeof origin !== "object" || typeof origin.cloudPolicyId !== "string" || !POLICY_ID_RE2.test(origin.cloudPolicyId) || !Number.isSafeInteger(origin.cloudVersion) || origin.cloudVersion < 0) {
|
|
17005
17158
|
malformed(`outcome ${i} has no Cloud origin`);
|
|
17006
17159
|
}
|
|
17007
|
-
|
|
17160
|
+
if (o.effect !== undefined && o.effect !== "enforce" && o.effect !== "observe")
|
|
17161
|
+
malformed(`outcome ${i} has an unknown effect`);
|
|
17162
|
+
if (o.reason !== undefined && o.reason !== null && typeof o.reason !== "string")
|
|
17163
|
+
malformed(`outcome ${i} reason is not text`);
|
|
17164
|
+
const outcome = {
|
|
17008
17165
|
policy: o.policy,
|
|
17009
17166
|
mode: o.mode,
|
|
17010
17167
|
...typeof o.userCanOverride === "boolean" ? { userCanOverride: o.userCanOverride } : {},
|
|
@@ -17018,41 +17175,103 @@ function parseOutcome(raw, i) {
|
|
|
17018
17175
|
...o.intent !== undefined ? { intent: o.intent } : {},
|
|
17019
17176
|
...o.targetScanIncomplete === true ? { targetScanIncomplete: true } : {}
|
|
17020
17177
|
};
|
|
17178
|
+
return {
|
|
17179
|
+
outcome,
|
|
17180
|
+
cloudPolicyId: origin.cloudPolicyId,
|
|
17181
|
+
cloudVersion: origin.cloudVersion,
|
|
17182
|
+
observe: o.effect === "observe",
|
|
17183
|
+
reason: typeof o.reason === "string" ? capReason(o.reason) : null
|
|
17184
|
+
};
|
|
17021
17185
|
}
|
|
17022
|
-
function
|
|
17023
|
-
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
const
|
|
17186
|
+
function capReason(reason) {
|
|
17187
|
+
return reason.length > MAX_CLOUD_REASON_CHARS ? `${reason.slice(0, MAX_CLOUD_REASON_CHARS - 1)}…` : reason;
|
|
17188
|
+
}
|
|
17189
|
+
function observedChecks(parsed, watched = null) {
|
|
17190
|
+
const firing = watched?.parsed.filter((p) => p.outcome.verdict === "deny" || p.outcome.verdict === "instruct") ?? [];
|
|
17191
|
+
const watchedReason = firing.length === 1 && typeof watched?.v.reason === "string" ? capReason(watched.v.reason) : null;
|
|
17192
|
+
const byPolicy = new Map;
|
|
17193
|
+
for (const p of parsed) {
|
|
17194
|
+
const verdict = p.outcome.verdict;
|
|
17195
|
+
if (verdict !== "deny" && verdict !== "instruct")
|
|
17196
|
+
continue;
|
|
17197
|
+
const prev = byPolicy.get(p.cloudPolicyId);
|
|
17198
|
+
if (prev && SEVERITY[prev.decision] >= SEVERITY[verdict])
|
|
17199
|
+
continue;
|
|
17200
|
+
byPolicy.set(p.cloudPolicyId, {
|
|
17201
|
+
cloudPolicyId: p.cloudPolicyId,
|
|
17202
|
+
cloudVersion: p.cloudVersion,
|
|
17203
|
+
check: p.outcome.policy,
|
|
17204
|
+
decision: verdict,
|
|
17205
|
+
reason: p.reason ?? (firing[0] === p ? watchedReason : null) ?? `Flagged by semantic review (semantic/${p.outcome.policy})`
|
|
17206
|
+
});
|
|
17207
|
+
}
|
|
17208
|
+
return [...byPolicy.values()];
|
|
17209
|
+
}
|
|
17210
|
+
function parseVerdictBlock(rawVerdict, rawAsked, what) {
|
|
17211
|
+
const v = rawVerdict;
|
|
17027
17212
|
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
17028
|
-
malformed(
|
|
17213
|
+
malformed(`no ${what}`);
|
|
17029
17214
|
if (typeof v.decision !== "string" || !DECISIONS2.has(v.decision))
|
|
17030
|
-
malformed(
|
|
17215
|
+
malformed(`${what} has no decision`);
|
|
17031
17216
|
if (v.reason !== null && v.reason !== undefined && typeof v.reason !== "string")
|
|
17032
|
-
malformed(
|
|
17217
|
+
malformed(`${what} reason is not text`);
|
|
17033
17218
|
if (!Array.isArray(v.outcomes) || v.outcomes.length > MAX_LIST)
|
|
17034
|
-
malformed(
|
|
17219
|
+
malformed(`${what} has no outcomes list`);
|
|
17035
17220
|
if (v.beyondTask !== undefined && typeof v.beyondTask !== "boolean")
|
|
17036
|
-
malformed(
|
|
17037
|
-
const
|
|
17038
|
-
const asked = names(
|
|
17221
|
+
malformed(`${what} beyondTask is not a flag`);
|
|
17222
|
+
const parsed = v.outcomes.map(parseOutcome);
|
|
17223
|
+
const asked = names(rawAsked, `${what} asked`);
|
|
17039
17224
|
const askedSet = new Set(asked);
|
|
17040
17225
|
const seen = new Set;
|
|
17041
|
-
|
|
17226
|
+
parsed.forEach(({ outcome: o }, i) => {
|
|
17042
17227
|
if (!askedSet.has(o.policy))
|
|
17043
|
-
malformed(
|
|
17228
|
+
malformed(`${what} outcome ${i} answers ${JSON.stringify(o.policy)}, which Cloud did not ask`);
|
|
17044
17229
|
const key = `${o.origin?.packId ?? ""}\x00${o.policy}`;
|
|
17045
17230
|
if (seen.has(key))
|
|
17046
|
-
malformed(
|
|
17231
|
+
malformed(`${what} outcome ${i} answers ${JSON.stringify(o.policy)} twice`);
|
|
17047
17232
|
seen.add(key);
|
|
17048
17233
|
});
|
|
17049
|
-
|
|
17234
|
+
return { v, parsed, asked };
|
|
17235
|
+
}
|
|
17236
|
+
function parseCloudReply(raw, observedPolicies = []) {
|
|
17237
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
17238
|
+
malformed("no cloud block");
|
|
17239
|
+
const block = raw;
|
|
17240
|
+
const { v, parsed, asked } = parseVerdictBlock(block.verdict, block.asked, "verdict");
|
|
17241
|
+
let watched = null;
|
|
17242
|
+
if (block.observed !== undefined && block.observed !== null) {
|
|
17243
|
+
const o = block.observed;
|
|
17244
|
+
if (typeof o !== "object" || Array.isArray(o))
|
|
17245
|
+
malformed("observed is not an object");
|
|
17246
|
+
watched = parseVerdictBlock(o.verdict, o.asked, "observed verdict");
|
|
17247
|
+
if (watched.parsed.some((p) => p.outcome.verdict === "deny") && watched.v.decision !== "deny") {
|
|
17248
|
+
malformed("an observed check denied but its verdict does not");
|
|
17249
|
+
}
|
|
17250
|
+
}
|
|
17251
|
+
const observeIds = new Set(observedPolicies);
|
|
17252
|
+
const isObserved = (p) => p.observe || observeIds.has(p.cloudPolicyId);
|
|
17253
|
+
const enforced = parsed.filter((p) => !isObserved(p)).map((p) => p.outcome);
|
|
17254
|
+
const observedHere = parsed.filter(isObserved);
|
|
17255
|
+
const observed = [...observedHere, ...watched?.parsed ?? []];
|
|
17256
|
+
if (enforced.some((o) => o.verdict === "deny") && v.decision !== "deny")
|
|
17050
17257
|
malformed("a check denied but the verdict does not");
|
|
17258
|
+
const cloudReason = typeof v.reason === "string" ? capReason(v.reason) : null;
|
|
17259
|
+
let decision = v.decision;
|
|
17260
|
+
let reason = cloudReason;
|
|
17261
|
+
if (observedHere.length > 0) {
|
|
17262
|
+
const own = enforced.some((o) => o.verdict === "deny") ? "deny" : enforced.some((o) => o.verdict === "instruct") || v.beyondTask === true ? "instruct" : "allow";
|
|
17263
|
+
const capped = RANK2[own] <= RANK2[decision] ? own : decision;
|
|
17264
|
+
if (capped !== decision)
|
|
17265
|
+
reason = null;
|
|
17266
|
+
decision = capped;
|
|
17267
|
+
}
|
|
17051
17268
|
return {
|
|
17269
|
+
observed: observedChecks(observed, watched),
|
|
17270
|
+
observedAsked: [...observedHere.map((p) => p.outcome.policy), ...watched?.asked ?? []],
|
|
17052
17271
|
verdict: {
|
|
17053
|
-
decision
|
|
17054
|
-
reason
|
|
17055
|
-
outcomes,
|
|
17272
|
+
decision,
|
|
17273
|
+
reason,
|
|
17274
|
+
outcomes: enforced,
|
|
17056
17275
|
injectionSuspected: nullableProbability(v.injectionSuspected, "injectionSuspected"),
|
|
17057
17276
|
scopeWithinRequest: nullableProbability(v.scopeWithinRequest, "scopeWithinRequest"),
|
|
17058
17277
|
beyondTask: v.beyondTask === true
|
|
@@ -17062,6 +17281,29 @@ function parseCloudReply(raw) {
|
|
|
17062
17281
|
droppedCloud: names(block.droppedCloud, "droppedCloud")
|
|
17063
17282
|
};
|
|
17064
17283
|
}
|
|
17284
|
+
function parseObservedOutcomes(raw) {
|
|
17285
|
+
try {
|
|
17286
|
+
const block = raw?.observed;
|
|
17287
|
+
if (!block || typeof block !== "object" || Array.isArray(block))
|
|
17288
|
+
return [];
|
|
17289
|
+
const asked = new Set(names(block.asked, "observed.asked"));
|
|
17290
|
+
const outcomes = block.verdict?.outcomes ?? [];
|
|
17291
|
+
if (!Array.isArray(outcomes) || outcomes.length > MAX_LIST)
|
|
17292
|
+
return [];
|
|
17293
|
+
const seen = new Set;
|
|
17294
|
+
const out = [];
|
|
17295
|
+
outcomes.forEach((o, i) => {
|
|
17296
|
+
const parsed = parseOutcome(o, i).outcome;
|
|
17297
|
+
if (!asked.has(parsed.policy) || seen.has(parsed.policy))
|
|
17298
|
+
return;
|
|
17299
|
+
seen.add(parsed.policy);
|
|
17300
|
+
out.push(parsed);
|
|
17301
|
+
});
|
|
17302
|
+
return out;
|
|
17303
|
+
} catch {
|
|
17304
|
+
return [];
|
|
17305
|
+
}
|
|
17306
|
+
}
|
|
17065
17307
|
function joinLines(reasons) {
|
|
17066
17308
|
const lines = [];
|
|
17067
17309
|
for (const reason of reasons) {
|
|
@@ -17108,6 +17350,22 @@ function expectedQuestions(request, prepared, dropped) {
|
|
|
17108
17350
|
}));
|
|
17109
17351
|
return { ...request, questions };
|
|
17110
17352
|
}
|
|
17353
|
+
function cloudCheckAnswers(response, asked) {
|
|
17354
|
+
const out = {};
|
|
17355
|
+
if (asked.length === 0)
|
|
17356
|
+
return out;
|
|
17357
|
+
const names = new Set(asked);
|
|
17358
|
+
const answers = response.answers && typeof response.answers === "object" ? response.answers : {};
|
|
17359
|
+
for (const [id, a] of Object.entries(answers)) {
|
|
17360
|
+
const dot = id.lastIndexOf(".");
|
|
17361
|
+
if (dot <= 0 || !names.has(id.slice(0, dot)) || !QUESTION_PART_RE.test(id.slice(dot + 1)))
|
|
17362
|
+
continue;
|
|
17363
|
+
const p = a?.noul;
|
|
17364
|
+
if (isProbability(p))
|
|
17365
|
+
out[id] = p;
|
|
17366
|
+
}
|
|
17367
|
+
return out;
|
|
17368
|
+
}
|
|
17111
17369
|
function presentAnswers(response) {
|
|
17112
17370
|
const out = {};
|
|
17113
17371
|
const answers = response.answers && typeof response.answers === "object" ? response.answers : {};
|
|
@@ -17136,7 +17394,7 @@ async function evaluateCloudSemantic(input, opts) {
|
|
|
17136
17394
|
model: opts.model ?? DEFAULT_JEV_MODEL,
|
|
17137
17395
|
modelVerified: true,
|
|
17138
17396
|
via: "none",
|
|
17139
|
-
cloud: { asked: [], droppedLocal: [], droppedCloud: [] }
|
|
17397
|
+
cloud: { asked: [], droppedLocal: [], droppedCloud: [], answers: {}, observed: [], observedAsked: [], observedOutcomes: [] }
|
|
17140
17398
|
};
|
|
17141
17399
|
}
|
|
17142
17400
|
let prepared;
|
|
@@ -17177,11 +17435,13 @@ async function evaluateCloudSemantic(input, opts) {
|
|
|
17177
17435
|
const timeout = AbortSignal.timeout(opts.timeoutMs ?? envNumber2("FAILPROOFAI_JEV_TIMEOUT_MS", DEFAULT_JEV_TIMEOUT_MS));
|
|
17178
17436
|
const signal = opts.signal ? AbortSignal.any([timeout, opts.signal]) : timeout;
|
|
17179
17437
|
const response = await transport(request, signal);
|
|
17180
|
-
const reply = parseCloudReply(response.cloud);
|
|
17438
|
+
const reply = parseCloudReply(response.cloud, opts.observedPolicies);
|
|
17439
|
+
const observedAsked = new Set(reply.observedAsked);
|
|
17440
|
+
const observedOutcomes = parseObservedOutcomes(response.cloud).filter((o) => observedAsked.has(o.policy));
|
|
17181
17441
|
const own = new Map(prepared.selected.map((p) => [p.name, p]));
|
|
17182
17442
|
const dropped = new Set(reply.droppedLocal.filter((name) => own.has(name)));
|
|
17183
17443
|
const kept = prepared.selected.filter((p) => !dropped.has(p.name));
|
|
17184
|
-
const shortCircuit = kept.length === 0 && reply.asked.length === 0 && reply.verdict.outcomes.length === 0;
|
|
17444
|
+
const shortCircuit = kept.length === 0 && reply.asked.length === 0 && reply.verdict.outcomes.length === 0 && reply.observedAsked.length === 0;
|
|
17185
17445
|
const answers = shortCircuit ? presentAnswers(response) : readAnswers(expectedQuestions(request, prepared, dropped), response);
|
|
17186
17446
|
const local = prepared.intent === "v1" ? decideV1(kept, answers, input.toolInput, prepared.userSaid, prepared.agentLastMessage, {
|
|
17187
17447
|
...opts.v1,
|
|
@@ -17203,7 +17463,11 @@ async function evaluateCloudSemantic(input, opts) {
|
|
|
17203
17463
|
cloud: {
|
|
17204
17464
|
asked: reply.asked,
|
|
17205
17465
|
droppedLocal: [...dropped].map((name) => ({ name, packId: own.get(name)?.origin?.packId ?? null })),
|
|
17206
|
-
droppedCloud: reply.droppedCloud
|
|
17466
|
+
droppedCloud: reply.droppedCloud,
|
|
17467
|
+
answers: cloudCheckAnswers(response, [...reply.asked, ...reply.observedAsked]),
|
|
17468
|
+
observed: reply.observed,
|
|
17469
|
+
observedAsked: reply.observedAsked,
|
|
17470
|
+
observedOutcomes
|
|
17207
17471
|
}
|
|
17208
17472
|
};
|
|
17209
17473
|
} catch (err) {
|
|
@@ -17216,7 +17480,7 @@ async function evaluateCloudSemantic(input, opts) {
|
|
|
17216
17480
|
return degraded(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
17217
17481
|
}
|
|
17218
17482
|
}
|
|
17219
|
-
var CLOUD_BLOCK_VERSION = 1, MAX_TARGET_SCAN_CHARS = 64000, MAX_CLOUD_BLOCK_BYTES = 240000, blockBytes = (block) => Buffer.byteLength(JSON.stringify(block), "utf8"), REDACTED_TARGET_WORD = "\x00redacted", MAX_SECRET_SCAN_CHARS, REDACTION_MARKER, REDACTED_SAID = "\x00", POLICY_ID_RE2, MAX_NAME_CHARS = 256, MAX_LIST = 4096, MAX_CLOUD_REASON_CHARS = 8192, isProbability = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 1, isName2 = (v) => typeof v === "string" && v.length > 0 && v.length <= MAX_NAME_CHARS, DECISIONS2, VERDICTS, INTENTS, RANK2, EMPTY_ALLOW;
|
|
17483
|
+
var CLOUD_BLOCK_VERSION = 1, MAX_TARGET_SCAN_CHARS = 64000, MAX_CLOUD_BLOCK_BYTES = 240000, blockBytes = (block) => Buffer.byteLength(JSON.stringify(block), "utf8"), REDACTED_TARGET_WORD = "\x00redacted", MAX_SECRET_SCAN_CHARS, REDACTION_MARKER, REDACTED_SAID = "\x00", POLICY_ID_RE2, MAX_NAME_CHARS = 256, MAX_LIST = 4096, MAX_CLOUD_REASON_CHARS = 8192, isProbability = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 1, isName2 = (v) => typeof v === "string" && v.length > 0 && v.length <= MAX_NAME_CHARS, DECISIONS2, VERDICTS, INTENTS, SEVERITY, RANK2, EMPTY_ALLOW, QUESTION_PART_RE;
|
|
17220
17484
|
var init_cloud_jev = __esm(() => {
|
|
17221
17485
|
init_compile();
|
|
17222
17486
|
init_decide();
|
|
@@ -17232,6 +17496,7 @@ var init_cloud_jev = __esm(() => {
|
|
|
17232
17496
|
DECISIONS2 = new Set(["allow", "deny", "instruct"]);
|
|
17233
17497
|
VERDICTS = new Set(["deny", "instruct", "overridden", "none"]);
|
|
17234
17498
|
INTENTS = new Set(["op-requested", "task-step", "downgraded-task-step"]);
|
|
17499
|
+
SEVERITY = { instruct: 1, deny: 2 };
|
|
17235
17500
|
RANK2 = { allow: 0, instruct: 1, deny: 2 };
|
|
17236
17501
|
EMPTY_ALLOW = {
|
|
17237
17502
|
decision: "allow",
|
|
@@ -17241,6 +17506,7 @@ var init_cloud_jev = __esm(() => {
|
|
|
17241
17506
|
scopeWithinRequest: null,
|
|
17242
17507
|
beyondTask: false
|
|
17243
17508
|
};
|
|
17509
|
+
QUESTION_PART_RE = /^[a-z][a-z0-9_]{0,31}$/;
|
|
17244
17510
|
});
|
|
17245
17511
|
|
|
17246
17512
|
// src/hooks/semantic/jev-throttle.ts
|
|
@@ -17576,6 +17842,55 @@ function fallbackCode(reason) {
|
|
|
17576
17842
|
const code = reason.split(":")[0].trim();
|
|
17577
17843
|
return /^[a-z0-9][a-z0-9-]{0,63}$/.test(code) ? code : "error";
|
|
17578
17844
|
}
|
|
17845
|
+
function checkWhy(o) {
|
|
17846
|
+
switch (o.verdict) {
|
|
17847
|
+
case "none":
|
|
17848
|
+
return o.evidence < DEFAULT_THRESHOLDS_V1.fire ? "not-detected" : "exempt";
|
|
17849
|
+
case "overridden":
|
|
17850
|
+
return o.intent === "op-requested" ? "op-requested" : o.intent === "task-step" ? "task-step" : "user-asked";
|
|
17851
|
+
case "deny":
|
|
17852
|
+
return o.escalatedByInjection ? "injection" : "fired";
|
|
17853
|
+
default:
|
|
17854
|
+
if (o.intent === "downgraded-task-step")
|
|
17855
|
+
return "downgraded";
|
|
17856
|
+
return o.targetScanIncomplete ? "scan-incomplete" : "fired";
|
|
17857
|
+
}
|
|
17858
|
+
}
|
|
17859
|
+
function checkPolicy(o) {
|
|
17860
|
+
const packId = o.origin?.packId;
|
|
17861
|
+
if (!packId)
|
|
17862
|
+
return;
|
|
17863
|
+
const at = o.origin?.packVersion ? `@${o.origin.packVersion}` : "";
|
|
17864
|
+
return packId.startsWith("cloud:") ? `cloud/${packId.slice("cloud:".length)}${at}` : `pack/${packId}${at}`;
|
|
17865
|
+
}
|
|
17866
|
+
function checkRecords(outcomes, answers, watched = []) {
|
|
17867
|
+
const all = [...outcomes.map((o) => ({ o, watched: false })), ...watched.map((o) => ({ o, watched: true }))];
|
|
17868
|
+
return all.slice(0, JEV_CHECKS_MAX).map(({ o, watched: isWatched }) => {
|
|
17869
|
+
const probes = {};
|
|
17870
|
+
const prefix = `${o.policy}.`;
|
|
17871
|
+
for (const [id, p] of Object.entries(answers)) {
|
|
17872
|
+
if (Object.keys(probes).length >= JEV_CHECK_PROBES_MAX)
|
|
17873
|
+
break;
|
|
17874
|
+
if (!id.startsWith(prefix))
|
|
17875
|
+
continue;
|
|
17876
|
+
const part = id.slice(prefix.length);
|
|
17877
|
+
if (part === "exempt" || part === "user_asked" || !JEV_PROBE_ID_RE.test(part))
|
|
17878
|
+
continue;
|
|
17879
|
+
probes[part] = round2(p);
|
|
17880
|
+
}
|
|
17881
|
+
const policy = checkPolicy(o);
|
|
17882
|
+
return {
|
|
17883
|
+
check: o.policy,
|
|
17884
|
+
...policy ? { policy } : {},
|
|
17885
|
+
verdict: o.verdict,
|
|
17886
|
+
why: checkWhy(o),
|
|
17887
|
+
p: round2(o.evidence),
|
|
17888
|
+
...o.exempt !== null ? { exempt: round2(o.exempt) } : {},
|
|
17889
|
+
...Object.keys(probes).length > 0 ? { probes } : {},
|
|
17890
|
+
...isWatched ? { watched: true } : {}
|
|
17891
|
+
};
|
|
17892
|
+
});
|
|
17893
|
+
}
|
|
17579
17894
|
function toReview(outcome, cached = false) {
|
|
17580
17895
|
if (outcome.status === "degraded") {
|
|
17581
17896
|
return { kind: "fallback", reason: fallbackCode(outcome.reason), latencyMs: outcome.latencyMs, model: null };
|
|
@@ -17584,15 +17899,19 @@ function toReview(outcome, cached = false) {
|
|
|
17584
17899
|
const latencyMs = sent && !cached ? outcome.latencyMs : null;
|
|
17585
17900
|
const model = sent ? outcome.model : null;
|
|
17586
17901
|
const outcomes = outcome.verdict.outcomes;
|
|
17587
|
-
const
|
|
17902
|
+
const cloudSummary = "cloud" in outcome ? outcome.cloud : null;
|
|
17903
|
+
const cloudAsked = cloudSummary ? new Set(cloudSummary.asked) : null;
|
|
17588
17904
|
const unvouched = outcomes.some((o) => isCloudOutcome(o) && !(cloudAsked?.has(o.policy) ?? false));
|
|
17589
17905
|
if (unvouched)
|
|
17590
17906
|
return { kind: "fallback", reason: "malformed", latencyMs, model: null };
|
|
17591
17907
|
const injection = sent ? outcome.verdict.injectionSuspected : null;
|
|
17592
17908
|
const warned = (o) => o.verdict === "instruct" && o.intent !== "downgraded-task-step";
|
|
17909
|
+
const cloudAnswers = cloudSummary?.answers ?? {};
|
|
17910
|
+
const watched = cloudSummary?.observedOutcomes ?? [];
|
|
17593
17911
|
return {
|
|
17594
17912
|
kind: "answered",
|
|
17595
17913
|
decision: outcome.verdict.decision,
|
|
17914
|
+
checks: sent ? checkRecords(outcomes, { ...outcome.answers, ...cloudAnswers }, watched) : [],
|
|
17596
17915
|
reason: outcome.verdict.reason,
|
|
17597
17916
|
policyName: jevPolicyName(outcome),
|
|
17598
17917
|
...jevDecider(outcome)?.origin ? { origin: jevDecider(outcome)?.origin } : {},
|
|
@@ -17604,7 +17923,16 @@ function toReview(outcome, cached = false) {
|
|
|
17604
17923
|
truncated: outcome.truncated && sent,
|
|
17605
17924
|
requestCut: outcome.requestCut && sent,
|
|
17606
17925
|
latencyMs,
|
|
17607
|
-
model
|
|
17926
|
+
model,
|
|
17927
|
+
...sent && cloudSummary?.observedAsked?.length ? { observedAsked: cloudSummary.observedAsked } : {},
|
|
17928
|
+
...cloudSummary?.observed?.length ? {
|
|
17929
|
+
observedCloud: cloudSummary.observed.map((o) => ({
|
|
17930
|
+
cloudPolicyId: o.cloudPolicyId,
|
|
17931
|
+
cloudVersion: o.cloudVersion,
|
|
17932
|
+
decision: o.decision,
|
|
17933
|
+
reason: o.reason
|
|
17934
|
+
}))
|
|
17935
|
+
} : {}
|
|
17608
17936
|
};
|
|
17609
17937
|
}
|
|
17610
17938
|
function toolInputRecord(raw) {
|
|
@@ -17623,7 +17951,8 @@ function startJevReview(cfg, call) {
|
|
|
17623
17951
|
if (!settled)
|
|
17624
17952
|
controller.abort();
|
|
17625
17953
|
},
|
|
17626
|
-
authorityOf
|
|
17954
|
+
authorityOf,
|
|
17955
|
+
...call.cloud ? { cloud: true } : {}
|
|
17627
17956
|
});
|
|
17628
17957
|
let route;
|
|
17629
17958
|
let throttled;
|
|
@@ -17647,7 +17976,10 @@ function startJevReview(cfg, call) {
|
|
|
17647
17976
|
}
|
|
17648
17977
|
let intent;
|
|
17649
17978
|
try {
|
|
17650
|
-
intent = intentReader.readIntent(call.sessionId
|
|
17979
|
+
intent = intentReader.readIntent(call.sessionId, undefined, {
|
|
17980
|
+
cli: call.cli,
|
|
17981
|
+
agent: call.agent !== undefined ? call.agent : call.cloud?.agent ?? null
|
|
17982
|
+
});
|
|
17651
17983
|
} catch {
|
|
17652
17984
|
intent = { userSaid: [], agentLastMessage: null };
|
|
17653
17985
|
}
|
|
@@ -17685,6 +18017,7 @@ function startJevReview(cfg, call) {
|
|
|
17685
18017
|
...options,
|
|
17686
18018
|
machineId: cloud.machineId,
|
|
17687
18019
|
agent: cloud.agent,
|
|
18020
|
+
observedPolicies: cloud.observedPolicies ?? [],
|
|
17688
18021
|
...call.localPaused ? { policies: [] } : {}
|
|
17689
18022
|
}) : evaluateSemantic(input, options);
|
|
17690
18023
|
const answered = evaluated.then((outcome) => {
|
|
@@ -17746,6 +18079,7 @@ var init_jev_review = __esm(() => {
|
|
|
17746
18079
|
init_jev_config();
|
|
17747
18080
|
init_jev_throttle();
|
|
17748
18081
|
init_session_root();
|
|
18082
|
+
init_jev_activity();
|
|
17749
18083
|
throttle = exports_jev_throttle;
|
|
17750
18084
|
intentReader = exports_intent;
|
|
17751
18085
|
ALWAYS_ON = new Set(BUILTIN_POLICIES.filter((p) => p.alwaysOn).map((p) => normalizePolicyName(p.name)));
|
|
@@ -17959,7 +18293,13 @@ async function readJevConfig(agent) {
|
|
|
17959
18293
|
return {
|
|
17960
18294
|
config: resolved.config,
|
|
17961
18295
|
defaultMode: DEFAULT_JEV_MODE,
|
|
17962
|
-
cloud: {
|
|
18296
|
+
cloud: {
|
|
18297
|
+
machineId: resolved.machineId,
|
|
18298
|
+
deployment: cloud.deployment,
|
|
18299
|
+
mode: cloud.jevMode,
|
|
18300
|
+
agent: agent ?? null,
|
|
18301
|
+
observedPolicies: (cloudJevAssignmentsFor(agent ?? null) ?? []).filter((a) => a.effect === "observe").map((a) => a.id)
|
|
18302
|
+
}
|
|
17963
18303
|
};
|
|
17964
18304
|
}
|
|
17965
18305
|
if (!existsSync22(jevConfigFile()))
|
|
@@ -18033,6 +18373,8 @@ async function startTwoTier(canonicalEventType, parsed, session, cli, opts, acti
|
|
|
18033
18373
|
return null;
|
|
18034
18374
|
if (!cloudAsks && !jevChecksInstalled())
|
|
18035
18375
|
return null;
|
|
18376
|
+
if (cloudAsks && cloudJevAssignmentsFor(agent)?.length === 0 && (activePause || !packJevChecksInstalled()))
|
|
18377
|
+
return null;
|
|
18036
18378
|
const loaded = await readJevConfig(agent);
|
|
18037
18379
|
if (!loaded)
|
|
18038
18380
|
return null;
|
|
@@ -18049,6 +18391,7 @@ async function startTwoTier(canonicalEventType, parsed, session, cli, opts, acti
|
|
|
18049
18391
|
permissionMode: session.permissionMode,
|
|
18050
18392
|
sessionId: session.sessionId,
|
|
18051
18393
|
cli,
|
|
18394
|
+
agent,
|
|
18052
18395
|
...loaded.cloud ? { cloud: loaded.cloud } : {},
|
|
18053
18396
|
...activePause ? { localPaused: true } : {}
|
|
18054
18397
|
});
|
|
@@ -18075,13 +18418,16 @@ function jevTelemetry(activity) {
|
|
|
18075
18418
|
return {};
|
|
18076
18419
|
}
|
|
18077
18420
|
}
|
|
18078
|
-
async function captureJevIntent(canonicalEventType, decision, parsed, session, cli, opts) {
|
|
18421
|
+
async function captureJevIntent(canonicalEventType, decision, parsed, session, cli, opts, agent) {
|
|
18079
18422
|
if (canonicalEventType !== "UserPromptSubmit" || jevForcedOff(opts))
|
|
18080
18423
|
return;
|
|
18081
18424
|
try {
|
|
18082
|
-
|
|
18425
|
+
const cloudAsks = cloudJevAsks(readCloudJevMode());
|
|
18426
|
+
if (!cloudAsks && !jevChecksInstalled())
|
|
18427
|
+
return;
|
|
18428
|
+
if (cloudAsks && cloudJevAssignmentsFor(agent)?.length === 0 && !packJevChecksInstalled())
|
|
18083
18429
|
return;
|
|
18084
|
-
if (!await readJevConfig())
|
|
18430
|
+
if (!await readJevConfig(agent))
|
|
18085
18431
|
return;
|
|
18086
18432
|
if (decision === "deny") {
|
|
18087
18433
|
await Promise.resolve().then(() => init_enforcement_capability());
|
|
@@ -18095,7 +18441,8 @@ async function captureJevIntent(canonicalEventType, decision, parsed, session, c
|
|
|
18095
18441
|
transcriptPath: session.transcriptPath,
|
|
18096
18442
|
cli,
|
|
18097
18443
|
payload: parsed,
|
|
18098
|
-
prompt: parsed.prompt
|
|
18444
|
+
prompt: parsed.prompt,
|
|
18445
|
+
profile: { cli, agent }
|
|
18099
18446
|
};
|
|
18100
18447
|
captureIntent(event);
|
|
18101
18448
|
} catch (err) {
|
|
@@ -18356,9 +18703,12 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
|
|
|
18356
18703
|
reason: observeVerdict.reason
|
|
18357
18704
|
});
|
|
18358
18705
|
}
|
|
18706
|
+
for (const o of result.twoTier?.observedCloud ?? []) {
|
|
18707
|
+
observedResults.push({ policyId: o.cloudPolicyId, version: o.cloudVersion, decision: o.decision, reason: o.reason });
|
|
18708
|
+
}
|
|
18359
18709
|
const durationMs = Math.round(performance.now() - startTime);
|
|
18360
18710
|
hookLogInfo(`result=${result.decision} policy=${result.policyName ?? "none"} duration=${durationMs}ms`);
|
|
18361
|
-
await captureJevIntent(canonicalEventType, result.decision, parsed, session, cli, opts);
|
|
18711
|
+
await captureJevIntent(canonicalEventType, result.decision, parsed, session, cli, opts, runtimeAgent);
|
|
18362
18712
|
const matchedPolicies = matchedBeforeRelease ?? getPoliciesForEvent(canonicalEventType, parsed.tool_name).map((p) => p.name);
|
|
18363
18713
|
const jevOrigin = result.policyName && result.twoTier?.decidedByJev ? result.twoTier.jevOrigin : undefined;
|
|
18364
18714
|
const activityEntry = {
|