failproofai 1.0.2-beta.7 → 1.0.2-beta.9
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 +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- 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 +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/build-manifest.json +2 -2
- 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 +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 +3 -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 +4 -3
- 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 +2 -2
- 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 +4 -3
- 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 +4 -4
- 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 +4 -4
- 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/build-manifest.json +2 -2
- 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 +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/build-manifest.json +2 -2
- 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/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +6 -5
- 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/build-manifest.json +2 -2
- 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/build-manifest.json +2 -2
- 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/build-manifest.json +2 -2
- 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/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
- 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]__0-9ti7z._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0sg9-3p._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__0u3wrvq._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zlqo2t._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1anxb5k._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1le9jqc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1p-qi2t._.js +5 -0
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +27 -0
- package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
- package/.next/standalone/.next/server/chunks/{_19uwam-._.js → _1-akg6w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -7
- package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.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 +10 -0
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n_lxhg._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1jjjg6g._.js → [root-of-the-server]__1_7n3xe._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1uvml5y._.js → _0b6xubz._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07gm3zl._.js → _1es2j7i._.js} +7 -21
- package/.next/standalone/.next/server/chunks/ssr/{_0_nsohj._.js → _1pj-r7q._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
- 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 +17 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- 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_pack-cli_ts_0t7me65._.js +3 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/middleware.js +1 -1
- 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 +19 -19
- package/.next/standalone/.next/static/chunks/{3swqstog1cd9u.js → 06zoac_7ffkus.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0icodhlwr9x_e.js → 0bshgqm5waivd.js} +2 -2
- package/.next/standalone/.next/static/chunks/{2-9lvhuto1iwo.js → 13grq7pifzvu5.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3i8rg2fv9nd6e.js → 16pmxmg9x48ob.js} +1 -1
- package/.next/standalone/.next/static/chunks/{44oamw33aso19.js → 1da7-a7ek66uy.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1d6c85605lsgp.js → 1fg7drro5kle-.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0tvmd0p_1i_g6.js → 1opyu56l4cdfk.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1d7o3wnt3h6se.js → 1p-o1i0lyt9un.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3vqddiy9tvlwf.js → 2mfojtsy214sf.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3jt6n16p2qpex.js → 32jj4qy40hln_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1vzyn9h2kvj-i.js → 3ww5ik9eo_1b_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1mfzsja6ftim5.css → 40nr6ehj4p3cw.css} +1 -1
- package/.next/standalone/.next/static/chunks/{turbopack-2x-o099q64i8h.js → turbopack-1gehh2qpjyj5_.js} +1 -1
- package/.next/standalone/app/actions/get-hooks-config.ts +8 -1
- package/.next/standalone/app/actions/pack-actions.ts +12 -1
- package/.next/standalone/app/policies/hooks-client.tsx +41 -4
- package/.next/standalone/fp-cloud-cli/tests/test_pagination.py +204 -0
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +57 -13
- package/dist/cli.mjs +23076 -20000
- package/dist/worker.mjs +1252 -542
- package/package.json +9 -9
- package/scripts/build-policy-pack.mjs +28 -4
- package/src/audit/index.ts +24 -4
- package/src/hooks/builtin-policies.ts +933 -8
- package/src/hooks/custom-hooks-loader.ts +98 -8
- package/src/hooks/handler.ts +26 -14
- package/src/hooks/manager.ts +36 -2
- package/src/hooks/pack-cli.ts +1224 -121
- package/src/hooks/pack-failclosed.ts +100 -4
- package/src/hooks/pack-manifest.ts +63 -1
- package/src/hooks/pack-param-key.ts +36 -0
- package/src/hooks/pack-store.ts +309 -25
- package/src/hooks/policy-catalog.ts +9 -1
- package/src/hooks/policy-evaluator.ts +77 -1
- package/src/hooks/tui.ts +21 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tg4pu6._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mgrjnx._.js +0 -10
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1opxw-7._.js +0 -5
- /package/.next/standalone/.next/static/{PKwyBPAHjy3DB8qqapaH4 → BFSuuqOY0YU7NpThROqre}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{PKwyBPAHjy3DB8qqapaH4 → BFSuuqOY0YU7NpThROqre}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{PKwyBPAHjy3DB8qqapaH4 → BFSuuqOY0YU7NpThROqre}/_ssgManifest.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.2-beta.
|
|
3
|
+
"version": "1.0.2-beta.9",
|
|
4
4
|
"description": "Observability and enforcement for AI agent harnesses. 39 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
@@ -120,15 +120,15 @@
|
|
|
120
120
|
"sharp": "0.35.0"
|
|
121
121
|
},
|
|
122
122
|
"optionalDependencies": {
|
|
123
|
-
"@failproofai/failproofaid-linux-x64": "1.0.2-beta.
|
|
124
|
-
"@failproofai/failproofaid-linux-arm64": "1.0.2-beta.
|
|
125
|
-
"@failproofai/failproofaid-darwin-x64": "1.0.2-beta.
|
|
126
|
-
"@failproofai/failproofaid-darwin-arm64": "1.0.2-beta.
|
|
123
|
+
"@failproofai/failproofaid-linux-x64": "1.0.2-beta.9",
|
|
124
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.2-beta.9",
|
|
125
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.2-beta.9",
|
|
126
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.2-beta.9"
|
|
127
127
|
},
|
|
128
128
|
"failproofaidBinaries": {
|
|
129
|
-
"linux-x64": "
|
|
130
|
-
"linux-arm64": "
|
|
131
|
-
"darwin-x64": "
|
|
132
|
-
"darwin-arm64": "
|
|
129
|
+
"linux-x64": "906b0c8a7502ad6a0494231a2220fff65db7ff8335ad7bdf15b58079a001562f",
|
|
130
|
+
"linux-arm64": "8b40f161cedf07ec3504dd736c906666d18bf042613af0a6a38f4daae8d7c7d4",
|
|
131
|
+
"darwin-x64": "7407d02234c24932ac9ece07bca348bd40c7a4edff72e0a8db9ac230a1e28a8c",
|
|
132
|
+
"darwin-arm64": "77131a4f0c1b9d3e5611ad3f4834542e26e32a404f1311903a1cf7783fe99fee"
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -37,6 +37,9 @@ import { createHash } from "node:crypto";
|
|
|
37
37
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
38
38
|
import { dirname, join, resolve } from "node:path";
|
|
39
39
|
import { fileURLToPath } from "node:url";
|
|
40
|
+
// The one place the pack's id is decided. Imported rather than restated — see
|
|
41
|
+
// PACK_ID below for what restating it cost.
|
|
42
|
+
import { CORE_SOURCE } from "../src/hooks/pack-store.ts";
|
|
40
43
|
|
|
41
44
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
42
45
|
// `--out <dir>` lets the conformance test generate into a temp directory rather
|
|
@@ -47,10 +50,17 @@ const outArg = process.argv.indexOf("--out");
|
|
|
47
50
|
const OUT_DIR = outArg !== -1 && process.argv[outArg + 1]
|
|
48
51
|
? resolve(process.argv[outArg + 1])
|
|
49
52
|
: join(ROOT, "policy-pack");
|
|
50
|
-
// Not
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
53
|
+
// Not restated. The id is the most durable place a retired word can hide — it
|
|
54
|
+
// ends up in every machine's installed.json and in the listing every user reads
|
|
55
|
+
// — and restating it here is how it hid twice: `failproofai/builtins` shipped
|
|
56
|
+
// first, was corrected to `failproofai/core` HERE and nowhere else, and then
|
|
57
|
+
// `core` was retired in pack-store while this line went on saying it. The one
|
|
58
|
+
// published release still declares `failproofai/builtins`, so a machine that
|
|
59
|
+
// installed it cannot be addressed by either name anybody would type.
|
|
60
|
+
//
|
|
61
|
+
// Read from the layer that owns the set, so the next rename reaches this file
|
|
62
|
+
// whether or not somebody remembers it exists.
|
|
63
|
+
const PACK_ID = CORE_SOURCE;
|
|
54
64
|
const ENTRY_ASSET = "failproofai-pack.mjs";
|
|
55
65
|
const MANIFEST_ASSET = "failproofai-pack.json";
|
|
56
66
|
const CHECKSUMS_ASSET = "SHA256SUMS";
|
|
@@ -60,6 +70,17 @@ const version = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8")).ver
|
|
|
60
70
|
// A generated entry that registers every non-alwaysOn builtin through the public
|
|
61
71
|
// policy API — the same API a third-party pack uses. `failproofai` stays external
|
|
62
72
|
// so the loader's shim resolves it, exactly as it does for any other pack.
|
|
73
|
+
//
|
|
74
|
+
// It registers `category` and `defaultEnabled` as well as name/description/
|
|
75
|
+
// match/fn, and that is not decoration. This script builds ITS manifest straight
|
|
76
|
+
// from POLICY_CATALOG, so omitting them from the ENTRY looked harmless — and was
|
|
77
|
+
// not: the entry IS the artifact, and anything that rebuilds a manifest from it
|
|
78
|
+
// saw 38 policies filed under "General" with none on by default. `failproofai
|
|
79
|
+
// publish` does exactly that, which is how a release that would have enforced
|
|
80
|
+
// nothing on a default install got as far as a dry run.
|
|
81
|
+
//
|
|
82
|
+
// Note for whoever edits the template below: it is a template literal, so a
|
|
83
|
+
// backtick inside it ends the string. Comments in there stay backtick-free.
|
|
63
84
|
const entrySource = `
|
|
64
85
|
import { customPolicies } from "failproofai";
|
|
65
86
|
import { BUILTIN_POLICIES } from ${JSON.stringify(join(ROOT, "src/hooks/builtin-policies.ts"))};
|
|
@@ -69,6 +90,9 @@ for (const policy of BUILTIN_POLICIES) {
|
|
|
69
90
|
customPolicies.add({
|
|
70
91
|
name: policy.name,
|
|
71
92
|
description: policy.description,
|
|
93
|
+
// Both fields matter here; see the note above entrySource.
|
|
94
|
+
category: policy.category,
|
|
95
|
+
defaultEnabled: policy.defaultEnabled === true,
|
|
72
96
|
match: policy.match,
|
|
73
97
|
fn: policy.fn,
|
|
74
98
|
});
|
package/src/audit/index.ts
CHANGED
|
@@ -100,6 +100,17 @@ interface ScanOutcome {
|
|
|
100
100
|
result: TranscriptAuditResult;
|
|
101
101
|
bytesScanned: number;
|
|
102
102
|
detectorState: DetectorSessionState;
|
|
103
|
+
/**
|
|
104
|
+
* Whether this result covers the TAIL only, or the whole transcript.
|
|
105
|
+
*
|
|
106
|
+
* The caller merges a cached prefix onto the result, which is right for a
|
|
107
|
+
* resumed scan and wrong for a full one — and a resume that could not be
|
|
108
|
+
* honoured falls back to a full read RIGHT HERE, several returns away from
|
|
109
|
+
* the merge. Without this the fallback merged a whole-file result onto a
|
|
110
|
+
* prefix that already contained it, and every finding before the resume point
|
|
111
|
+
* was counted twice.
|
|
112
|
+
*/
|
|
113
|
+
resumed: boolean;
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
async function scanOneTranscript(
|
|
@@ -125,6 +136,7 @@ async function scanOneTranscript(
|
|
|
125
136
|
// `errors` rather than silently returning an empty hits map.
|
|
126
137
|
let events: NormalizedToolEvent[];
|
|
127
138
|
let bytesScanned = 0;
|
|
139
|
+
let resumed = false;
|
|
128
140
|
// A resumed scan carries the stateful detectors' state forward across the
|
|
129
141
|
// boundary. Starting them empty would silently change what they find — the
|
|
130
142
|
// re-read detector's countdown spans tool calls, so an edit before the offset
|
|
@@ -151,6 +163,7 @@ async function scanOneTranscript(
|
|
|
151
163
|
events = scan.events;
|
|
152
164
|
bytesScanned = scan.bytesConsumed;
|
|
153
165
|
empty.cwd = scan.cwd ?? "";
|
|
166
|
+
resumed = true;
|
|
154
167
|
}
|
|
155
168
|
} else {
|
|
156
169
|
// A source with no byte offsets to speak of — a database. Scanned whole,
|
|
@@ -160,7 +173,7 @@ async function scanOneTranscript(
|
|
|
160
173
|
}
|
|
161
174
|
|
|
162
175
|
if (events.length === 0) {
|
|
163
|
-
return { result: empty, bytesScanned, detectorState: sessionState };
|
|
176
|
+
return { result: empty, bytesScanned, detectorState: sessionState, resumed };
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
const result = empty;
|
|
@@ -201,7 +214,7 @@ async function scanOneTranscript(
|
|
|
201
214
|
}
|
|
202
215
|
}
|
|
203
216
|
|
|
204
|
-
return { result, bytesScanned, detectorState: sessionState };
|
|
217
|
+
return { result, bytesScanned, detectorState: sessionState, resumed };
|
|
205
218
|
}
|
|
206
219
|
|
|
207
220
|
function formatPolicyExample(_policyName: string, event: NormalizedToolEvent): string {
|
|
@@ -447,8 +460,15 @@ async function runAuditInner(opts: RunAuditOptions, startedAt: number): Promise<
|
|
|
447
460
|
try {
|
|
448
461
|
const scan = await scanOneTranscript(meta, resume);
|
|
449
462
|
// A resumed scan produced hits for the TAIL only; the cached result holds
|
|
450
|
-
// everything before it. Merging is what makes the two halves one answer
|
|
451
|
-
|
|
463
|
+
// everything before it. Merging is what makes the two halves one answer —
|
|
464
|
+
// and `scan.resumed`, not `cachedPrefix`, is what says there are two
|
|
465
|
+
// halves. A resume the reader could not honour (truncated, unparseable
|
|
466
|
+
// from that offset, rewritten under us) falls back to reading the WHOLE
|
|
467
|
+
// file, and merging the prefix onto that counted everything before the
|
|
468
|
+
// resume point twice.
|
|
469
|
+
const fresh = cachedPrefix && scan.resumed
|
|
470
|
+
? mergeIncremental(cachedPrefix, scan.result)
|
|
471
|
+
: scan.result;
|
|
452
472
|
if (!opts.noCache) {
|
|
453
473
|
writeCachedTranscriptResult(
|
|
454
474
|
meta.transcriptPath,
|