failproofai 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +8 -7
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +9 -7
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +6 -6
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +11 -10
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +8 -7
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -6
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +7 -6
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +52 -8
- package/.next/standalone/.next/server/app/settings/page.js +12 -7
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1msfs-h._.js → [externals]__19_pzeq._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1_bftcl._.js → [externals]__20kzpkf._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ttrwnd._.js +22 -0
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
- package/.next/standalone/.next/server/chunks/{_1c3k-8x._.js → _1q5i8mb._.js} +2 -2
- package/.next/standalone/.next/server/chunks/lib_16xa545._.js +3 -0
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +5 -0
- package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +4 -2
- package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzs._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02npjtd._.js → [root-of-the-server]__056wjo4._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06pflha._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +22 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0p-5p8u._.js → [root-of-the-server]__0n0xg95._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__013jr2b._.js → [root-of-the-server]__0rwtwpm._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0da85px._.js → [root-of-the-server]__11mayhe._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12e7nhs._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19evfi8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0cxe_2_._.js → [root-of-the-server]__1mf3zp6._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ftmoxc._.js → [root-of-the-server]__1pprgri._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1p2otjt._.js → [root-of-the-server]__1q4p5b8._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_166t73i._.js → _0-vcssj._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +23 -0
- package/.next/standalone/.next/server/chunks/ssr/{_1es2j7i._.js → _1gb0ifp._.js} +5 -5
- package/.next/standalone/.next/server/chunks/ssr/{_1_qswah._.js → _1q46vxx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +13 -13
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0drixxt._.js → node_modules_next_dist_0w6mzq5._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_18_d8l1._.js +151 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0-q0umm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_06kzv9d._.js +12 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0g194sy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +4 -2
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1kx9e0d._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +3 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +67 -23
- package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +6 -0
- package/.next/standalone/.next/static/chunks/0bhidk90e-07f.css +2 -0
- package/.next/standalone/.next/static/chunks/{2mdh397ghgnvv.js → 0m-9d6yn9hx4j.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0__8a7m868fvf.js → 0wbjy0zo-m7is.js} +1 -1
- package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +1 -0
- package/.next/standalone/.next/static/chunks/{0o6qlkgubtoex.js → 21uv-uusw329x.js} +1 -1
- package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +1 -0
- package/.next/standalone/.next/static/chunks/2qdpj67x6ifk_.js +69 -0
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +1 -0
- package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +1 -0
- package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +1 -0
- package/.next/standalone/.next/static/chunks/{13i7-9is-vhys.js → 3c3qbmosdjl6w.js} +1 -1
- package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
- package/.next/standalone/app/actions/get-jev-config.ts +604 -0
- package/.next/standalone/app/actions/pack-actions.ts +12 -0
- package/.next/standalone/app/actions/update-jev-config.ts +569 -0
- package/.next/standalone/app/components/jev-notices.tsx +96 -0
- package/.next/standalone/app/policies/hooks-client.tsx +14 -3
- package/.next/standalone/app/settings/jev-panel.tsx +630 -0
- package/.next/standalone/app/settings/page.tsx +20 -1
- package/.next/standalone/app/settings/settings-client.tsx +27 -1
- package/.next/standalone/app/settings/settings.css +79 -0
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +22 -4
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +14 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +17 -3
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +3 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +22 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +169 -0
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +65 -0
- package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +61 -0
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
- package/.next/standalone/sdk/typescript/CHANGELOG.md +18 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +0 -274
- package/.next/standalone/sdk/typescript/scripts/release.mjs +30 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +3 -2
- package/bin/failproofai.mjs +148 -4
- package/dist/cli.mjs +18599 -9478
- package/dist/index.js +19 -1
- package/dist/worker.mjs +10500 -3773
- package/package.json +10 -10
- package/pi-extension/index.ts +11 -0
- package/scripts/build-policy-pack.mjs +53 -2
- package/src/audit/features.ts +3 -2
- package/src/hooks/builtin-policies.ts +195 -8
- package/src/hooks/cloud-connection.ts +190 -1
- package/src/hooks/cloud-enrollment-cli.ts +57 -8
- package/src/hooks/cloud-introspect.ts +6 -0
- package/src/hooks/cloud-managed-policies.ts +22 -0
- package/src/hooks/configure-wizard.ts +26 -6
- package/src/hooks/custom-hooks-loader.ts +98 -10
- package/src/hooks/custom-hooks-registry.ts +45 -1
- package/src/hooks/effective-reviewers.ts +243 -0
- package/src/hooks/first-run-gate.ts +5 -0
- package/src/hooks/flush-cli.ts +35 -8
- package/src/hooks/fp-config.ts +266 -1
- package/src/hooks/fp-home.ts +23 -0
- package/src/hooks/fp-reset.ts +22 -4
- package/src/hooks/handler.ts +303 -7
- package/src/hooks/hook-activity-store.ts +118 -6
- package/src/hooks/hook-telemetry.ts +41 -0
- package/src/hooks/jev-activity.ts +385 -0
- package/src/hooks/jev-cli.ts +2172 -0
- package/src/hooks/jev-cloud-connection.ts +392 -0
- package/src/hooks/loader-utils.ts +6 -0
- package/src/hooks/manager.ts +45 -7
- package/src/hooks/pack-cli.ts +568 -37
- package/src/hooks/pack-failclosed.ts +3 -0
- package/src/hooks/pack-manifest.ts +489 -7
- package/src/hooks/pack-store.ts +194 -11
- package/src/hooks/policy-authority.ts +386 -0
- package/src/hooks/policy-catalog.ts +206 -0
- package/src/hooks/policy-evaluator.ts +963 -796
- package/src/hooks/policy-registry.ts +27 -1
- package/src/hooks/policy-reviewability.ts +258 -0
- package/src/hooks/policy-types.ts +128 -0
- package/src/hooks/semantic/combine.ts +581 -0
- package/src/hooks/semantic/compile.ts +176 -0
- package/src/hooks/semantic/decide.ts +513 -0
- package/src/hooks/semantic/envelope.ts +1255 -0
- package/src/hooks/semantic/evaluator.ts +556 -0
- package/src/hooks/semantic/facts.ts +387 -0
- package/src/hooks/semantic/intent.ts +1190 -0
- package/src/hooks/semantic/jev-client.ts +1155 -0
- package/src/hooks/semantic/jev-config.ts +1142 -0
- package/src/hooks/semantic/jev-review.ts +389 -0
- package/src/hooks/semantic/jev-stats.ts +289 -0
- package/src/hooks/semantic/jev-throttle.ts +427 -0
- package/src/hooks/semantic/pack-policies.ts +294 -0
- package/src/hooks/semantic/policies.ts +597 -0
- package/src/hooks/semantic/precondition-names.ts +60 -0
- package/src/hooks/semantic/preconditions.ts +58 -0
- package/src/hooks/semantic/redact.ts +2937 -0
- package/src/hooks/semantic/session-root.ts +116 -0
- package/src/hooks/semantic/types.ts +162 -0
- package/src/hooks/semver-precedence.ts +128 -0
- package/src/hooks/tui.ts +4 -0
- package/src/hooks/types.ts +1 -1
- package/src/hooks/worker-server.ts +121 -27
- package/src/index.ts +6 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cuho4x._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_r2rbg._.js +0 -24
- package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bd3mje._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/_0h_douw._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1-i_gzc._.js +0 -23
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +0 -3
- package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +0 -1
- package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +0 -6
- package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +0 -1
- package/.next/standalone/.next/static/chunks/2klitrtzpaoe0.js +0 -1
- package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +0 -2
- package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +0 -1
- package/.next/standalone/.next/static/chunks/3rh5o7e16irrm.js +0 -69
- package/.next/standalone/.next/static/chunks/43ufqrz8qo3h-.js +0 -1
- /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_ssgManifest.js +0 -0
package/src/hooks/pack-store.ts
CHANGED
|
@@ -35,8 +35,18 @@
|
|
|
35
35
|
import { createHash } from "node:crypto";
|
|
36
36
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
37
37
|
import { dirname, resolve } from "node:path";
|
|
38
|
-
import {
|
|
39
|
-
|
|
38
|
+
import {
|
|
39
|
+
MAX_SEMANTIC_POLICIES_PER_PACK,
|
|
40
|
+
PACK_COMMIT_RE,
|
|
41
|
+
checkPackMinCliVersion,
|
|
42
|
+
packsRoot,
|
|
43
|
+
parsePackIdentity,
|
|
44
|
+
parsePackPolicy,
|
|
45
|
+
parsePackSemanticPolicy,
|
|
46
|
+
readInstalledPacks,
|
|
47
|
+
} from "./pack-manifest";
|
|
48
|
+
import { isFirstPartyPack } from "./effective-reviewers";
|
|
49
|
+
import type { ResolvedPack, SemanticManifestEntry } from "./pack-manifest";
|
|
40
50
|
import type { InstalledPackRecord } from "./pack-manifest";
|
|
41
51
|
import type { PolicyCatalogEntry } from "./policy-types";
|
|
42
52
|
import type { PolicyEffect } from "./cloud-managed-policies";
|
|
@@ -86,6 +96,18 @@ export interface AddPackResult {
|
|
|
86
96
|
selection: SelectionReason;
|
|
87
97
|
/** Category slugs the pack offers, for `--category`. */
|
|
88
98
|
categories: string[];
|
|
99
|
+
/**
|
|
100
|
+
* How many Jev question sets came with it, and not a list of names: they are
|
|
101
|
+
* not selectable and not switchable, so a name here would invite a `--policy`
|
|
102
|
+
* that cannot work. A non-zero count is what stops a semantic-only install
|
|
103
|
+
* reporting "the pack is installed and enforcing nothing".
|
|
104
|
+
*/
|
|
105
|
+
semantic: number;
|
|
106
|
+
/** Why the pack's minCliVersion was ignored, when this build could not compare it. */
|
|
107
|
+
minCliVersionNote?: string;
|
|
108
|
+
/** As recorded, so the CLI can say where its Jev checks are asked (`jevPacks`). */
|
|
109
|
+
effect?: PolicyEffect;
|
|
110
|
+
clis?: string[];
|
|
89
111
|
artifact: string;
|
|
90
112
|
}
|
|
91
113
|
|
|
@@ -454,6 +476,12 @@ interface FetchedPack {
|
|
|
454
476
|
id: string;
|
|
455
477
|
version: string;
|
|
456
478
|
policies: PolicyCatalogEntry[];
|
|
479
|
+
/** The pack's Jev question sets, validated. Empty when it declares none. */
|
|
480
|
+
semantic: SemanticManifestEntry[];
|
|
481
|
+
/** The minimum CLI it claims, once this one has been checked against it. */
|
|
482
|
+
minCliVersion?: string;
|
|
483
|
+
/** Why a minimum this build cannot compare was ignored, to be said out loud. */
|
|
484
|
+
minCliVersionNote?: string;
|
|
457
485
|
effect?: PolicyEffect;
|
|
458
486
|
/** The git commit the publisher built this from, when they had one. */
|
|
459
487
|
commit?: string;
|
|
@@ -461,6 +489,73 @@ interface FetchedPack {
|
|
|
461
489
|
artifactDigest: string;
|
|
462
490
|
}
|
|
463
491
|
|
|
492
|
+
/**
|
|
493
|
+
* The shape both fetch paths read a manifest's `semantic` array through.
|
|
494
|
+
*
|
|
495
|
+
* REFUSES what the loader would only drop, and the asymmetry is the same one
|
|
496
|
+
* `parsePackPolicy` already has on this path: nothing has been written yet, so
|
|
497
|
+
* refusing costs the user a clear error message and the publisher a fix —
|
|
498
|
+
* whereas dropping an entry here would install a pack that enforces less than
|
|
499
|
+
* the preview just showed, with the difference recorded only in a hook log. The
|
|
500
|
+
* loader drops instead because by then the pack IS installed and refusing it
|
|
501
|
+
* denies every tool call its regex policies cover.
|
|
502
|
+
*
|
|
503
|
+
* The per-pack cap is checked for the same reason. Over it, the loader keeps the
|
|
504
|
+
* first 24 in declared order and records the rest as dropped; letting that
|
|
505
|
+
* happen silently at install time means a machine quietly running a subset of
|
|
506
|
+
* what the user agreed to.
|
|
507
|
+
*
|
|
508
|
+
* The CHARACTER budget is deliberately not checked here. It lives in
|
|
509
|
+
* `semantic/pack-policies.ts`, and importing that module would pull Jev's
|
|
510
|
+
* sixteen prompts into this one — which is reachable from a Next.js server
|
|
511
|
+
* action (`app/actions/pack-actions.ts`), not just from the CLI. `failproofai
|
|
512
|
+
* publish` refuses an over-budget pack at build time, and a pack built by some
|
|
513
|
+
* other tool has its overflow dropped at resolve time with a recorded reason.
|
|
514
|
+
*/
|
|
515
|
+
function parseManifestSemantic(packId: string, value: unknown): SemanticManifestEntry[] {
|
|
516
|
+
if (value === undefined) return [];
|
|
517
|
+
if (!Array.isArray(value)) throw new Error(`pack ${packId} semantic is not an array`);
|
|
518
|
+
if (value.length > MAX_SEMANTIC_POLICIES_PER_PACK) {
|
|
519
|
+
throw new Error(
|
|
520
|
+
`pack ${packId} declares ${value.length} semantic policies, over the cap of ${MAX_SEMANTIC_POLICIES_PER_PACK}`,
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
const entries = value.map((entry, i) => parsePackSemanticPolicy(packId, entry, i));
|
|
524
|
+
const names = new Set<string>();
|
|
525
|
+
for (const entry of entries) {
|
|
526
|
+
if (names.has(entry.name)) throw new Error(`pack ${packId} declares semantic policy ${entry.name} twice`);
|
|
527
|
+
names.add(entry.name);
|
|
528
|
+
}
|
|
529
|
+
return entries;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Refuse a pack this CLI is too old to run — HERE, where the message is
|
|
534
|
+
* something the person who typed the command can act on.
|
|
535
|
+
*
|
|
536
|
+
* The loader refuses it too, and that refusal is the fail-closed one: on a
|
|
537
|
+
* machine where it lands, every tool call the pack's policies cover is denied
|
|
538
|
+
* until somebody works out why. Catching it at install turns the same fact into
|
|
539
|
+
* one line at the moment of choosing.
|
|
540
|
+
*
|
|
541
|
+
* A minimum this build cannot compare is ignored, exactly as the loader ignores
|
|
542
|
+
* it: a publisher's typo in a version string must not be able to stop anyone
|
|
543
|
+
* installing a pack. But the reason comes back as a note for the preview and
|
|
544
|
+
* the install to print, since the record keeps no unreadable value and the
|
|
545
|
+
* loader's own warning never reaches a CLI screen. `failproofai publish`
|
|
546
|
+
* refuses to write one, so this is only reachable from a pack built by some
|
|
547
|
+
* other tool.
|
|
548
|
+
*/
|
|
549
|
+
function assertMinCliVersion(
|
|
550
|
+
packId: string,
|
|
551
|
+
declared: unknown,
|
|
552
|
+
): { minCliVersion?: string; minCliVersionNote?: string } {
|
|
553
|
+
const verdict = checkPackMinCliVersion(packId, declared);
|
|
554
|
+
if (verdict.kind === "too-old") throw new Error(verdict.reason);
|
|
555
|
+
if (verdict.kind === "unreadable") return { minCliVersionNote: verdict.reason };
|
|
556
|
+
return verdict.declared ? { minCliVersion: verdict.declared } : {};
|
|
557
|
+
}
|
|
558
|
+
|
|
464
559
|
/** Fetch and fully validate a pack, without writing anything. */
|
|
465
560
|
/**
|
|
466
561
|
* The short names for the pack Failproof AI publishes.
|
|
@@ -543,6 +638,21 @@ export interface PackPreview {
|
|
|
543
638
|
/** The git commit the publisher built this from, when they had one. */
|
|
544
639
|
commit?: string;
|
|
545
640
|
policies: PolicyCatalogEntry[];
|
|
641
|
+
/**
|
|
642
|
+
* The pack's Jev question sets. Shown, not selectable: a pack's `enabled`
|
|
643
|
+
* narrowing picks which of its REGEX policies register, and its semantic set
|
|
644
|
+
* replaces this build's wholesale or not at all.
|
|
645
|
+
*
|
|
646
|
+
* Carried on the preview because the preview is what somebody consents to. A
|
|
647
|
+
* pack that quietly brings sixteen new questions to the classifier — and
|
|
648
|
+
* replaces the sixteen this build shipped — is not something to discover after
|
|
649
|
+
* installing it.
|
|
650
|
+
*/
|
|
651
|
+
semantic: SemanticManifestEntry[];
|
|
652
|
+
/** The minimum CLI this pack declares, when it declares one this build can read. */
|
|
653
|
+
minCliVersion?: string;
|
|
654
|
+
/** Why a declared minimum this build cannot read was ignored. */
|
|
655
|
+
minCliVersionNote?: string;
|
|
546
656
|
/** The exact source the preview was read from, tag resolved and pinned. */
|
|
547
657
|
source: string;
|
|
548
658
|
/** True when the tag was resolved rather than typed. */
|
|
@@ -589,22 +699,59 @@ export async function fetchPackPreview(source: string): Promise<PackPreview> {
|
|
|
589
699
|
if (!raw || typeof raw !== "object") throw new Error(`${PACK_MANIFEST_ASSET} is not an object`);
|
|
590
700
|
const value = raw as {
|
|
591
701
|
id?: unknown; version?: unknown; policies?: unknown; effect?: unknown; commit?: unknown;
|
|
702
|
+
semantic?: unknown; minCliVersion?: unknown;
|
|
592
703
|
};
|
|
593
704
|
const identity = parsePackIdentity(value);
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
705
|
+
const minCli = assertMinCliVersion(identity.id, value.minCliVersion);
|
|
706
|
+
const semantic = parseManifestSemantic(identity.id, value.semantic);
|
|
707
|
+
const policies = parseManifestPolicies(identity.id, value.policies);
|
|
708
|
+
assertDeclaresSomething(policies, semantic);
|
|
597
709
|
return {
|
|
598
710
|
id: identity.id,
|
|
599
711
|
version: identity.version,
|
|
600
712
|
effect: identity.effect,
|
|
601
713
|
...(identity.commit ? { commit: identity.commit } : {}),
|
|
602
|
-
policies
|
|
714
|
+
policies,
|
|
715
|
+
semantic,
|
|
716
|
+
...minCli,
|
|
603
717
|
source: formatPackSpec(spec),
|
|
604
718
|
resolvedFromLatest,
|
|
605
719
|
};
|
|
606
720
|
}
|
|
607
721
|
|
|
722
|
+
/**
|
|
723
|
+
* The regex half of a manifest. ABSENT is an empty list, not an error: a pack of
|
|
724
|
+
* Jev questions alone is a legitimate thing to publish now, and ours writes
|
|
725
|
+
* `policies: []` for one. Present and not an array is still malformed.
|
|
726
|
+
*/
|
|
727
|
+
function parseManifestPolicies(packId: string, value: unknown): PolicyCatalogEntry[] {
|
|
728
|
+
if (value === undefined) return [];
|
|
729
|
+
if (!Array.isArray(value)) throw new Error(`pack ${packId} policies is not an array`);
|
|
730
|
+
const policies = value.map((policy, i) => parsePackPolicy(packId, policy, i));
|
|
731
|
+
// The loader's rule: it refuses the whole record over a repeated name.
|
|
732
|
+
const names = new Set<string>();
|
|
733
|
+
for (const p of policies) {
|
|
734
|
+
if (names.has(p.name)) throw new Error(`pack ${packId} declares ${p.name} twice`);
|
|
735
|
+
names.add(p.name);
|
|
736
|
+
}
|
|
737
|
+
return policies;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* A pack has to bring SOMETHING, and either half counts.
|
|
742
|
+
*
|
|
743
|
+
* It used to be "at least one regex policy", which made a pack of Jev questions
|
|
744
|
+
* alone impossible to install — and that is a legitimate pack: the regex floor
|
|
745
|
+
* may already be somebody else's, and the two halves version independently. This
|
|
746
|
+
* is the same widening `build()` makes to its "registered no policies" refusal,
|
|
747
|
+
* so the two ends of the lane agree on what an empty pack is.
|
|
748
|
+
*/
|
|
749
|
+
function assertDeclaresSomething(policies: PolicyCatalogEntry[], semantic: SemanticManifestEntry[]): void {
|
|
750
|
+
if (policies.length === 0 && semantic.length === 0) {
|
|
751
|
+
throw new Error("pack manifest declares no policies");
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
608
755
|
/**
|
|
609
756
|
* The record this install is really an update OF — matched by id, or failing
|
|
610
757
|
* that by artifact digest.
|
|
@@ -647,20 +794,26 @@ async function fetchPack(spec: PinnedPackSpec): Promise<FetchedPack> {
|
|
|
647
794
|
if (!parsed || typeof parsed !== "object") throw new Error(`${PACK_MANIFEST_ASSET} is not an object`);
|
|
648
795
|
const raw = parsed as {
|
|
649
796
|
id?: unknown; version?: unknown; policies?: unknown; effect?: unknown; commit?: unknown;
|
|
797
|
+
semantic?: unknown; minCliVersion?: unknown;
|
|
650
798
|
};
|
|
651
799
|
const identity = parsePackIdentity(raw);
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
800
|
+
// Before the shape checks below, because being too old for the pack is not a
|
|
801
|
+
// complaint about the pack: the message to give is "update the CLI", and a
|
|
802
|
+
// manifest field this build cannot read yet must not be reported as malformed.
|
|
803
|
+
const minCli = assertMinCliVersion(identity.id, raw.minCliVersion);
|
|
655
804
|
// Validated with the SAME rules the loader applies, so a pack that could never
|
|
656
805
|
// load is refused here — while nothing has been written — rather than
|
|
657
806
|
// installing cleanly and failing silently on the next tool call.
|
|
658
|
-
const policies =
|
|
807
|
+
const policies = parseManifestPolicies(identity.id, raw.policies);
|
|
808
|
+
const semantic = parseManifestSemantic(identity.id, raw.semantic);
|
|
809
|
+
assertDeclaresSomething(policies, semantic);
|
|
659
810
|
|
|
660
811
|
return {
|
|
661
812
|
id: identity.id,
|
|
662
813
|
version: identity.version,
|
|
663
814
|
policies,
|
|
815
|
+
semantic,
|
|
816
|
+
...minCli,
|
|
664
817
|
...(raw.effect !== undefined ? { effect: identity.effect } : {}),
|
|
665
818
|
...(identity.commit ? { commit: identity.commit } : {}),
|
|
666
819
|
artifact,
|
|
@@ -685,7 +838,7 @@ export function slugifyCategory(category: string): string {
|
|
|
685
838
|
*
|
|
686
839
|
* The default is the pack's OWN `defaultEnabled` set, not everything. A pack
|
|
687
840
|
* carries an opinion about which of its policies are safe to switch on
|
|
688
|
-
* unattended — for the builtins that is 10 of
|
|
841
|
+
* unattended — for the builtins that is 10 of 39 — and installing the whole
|
|
689
842
|
* thing overrode that opinion with one nobody held. `block-kubectl`,
|
|
690
843
|
* `block-terraform` and `require-ci-green-before-stop` are off by default in the
|
|
691
844
|
* npm package precisely because they interrupt legitimate work.
|
|
@@ -866,6 +1019,16 @@ export async function addPack(
|
|
|
866
1019
|
: `Name the tag whose manifest says ${fetched.version}, or fix the pack: ${fix}.`),
|
|
867
1020
|
);
|
|
868
1021
|
}
|
|
1022
|
+
// The id is self-declared, so without this any release could install as a
|
|
1023
|
+
// FailproofAI pack: labelled FailproofAI's own wherever verdicts are shown,
|
|
1024
|
+
// and squatting the id the real pack then cannot take. Owner only — an id may
|
|
1025
|
+
// otherwise differ from its repository (`publish --id`).
|
|
1026
|
+
if (/^failproofai\//i.test(fetched.id) && !isFirstPartyPack({ source: formatPackSpec(spec) })) {
|
|
1027
|
+
throw new Error(
|
|
1028
|
+
`${fetched.id} was not installed: the FailproofAI/ namespace is reserved for releases from ` +
|
|
1029
|
+
`github.com/FailproofAI, and this one came from ${spec.owner}/${spec.repo}.`,
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
869
1032
|
const available = fetched.policies.map((p) => p.name);
|
|
870
1033
|
|
|
871
1034
|
const prior = priorRecordFor(fetched.id, fetched.artifactDigest);
|
|
@@ -931,6 +1094,22 @@ export async function addPack(
|
|
|
931
1094
|
entry: artifactRel,
|
|
932
1095
|
sha256: fetched.artifactDigest,
|
|
933
1096
|
policies: fetched.policies,
|
|
1097
|
+
// Both halves of the manifest reach the record, because `installed.json` is
|
|
1098
|
+
// the only thing enforcement reads. Left off, a pack's Jev questions were
|
|
1099
|
+
// fetched, verified, shown in the preview and then dropped on the floor: the
|
|
1100
|
+
// resolver found no `semantic` on any installed pack, kept this build's
|
|
1101
|
+
// compiled set, and every pack policy naming one of the pack's own checks in
|
|
1102
|
+
// `reviewedBy` registered as hard. Nothing failed, and the half the user
|
|
1103
|
+
// installed did nothing.
|
|
1104
|
+
//
|
|
1105
|
+
// Omitted when empty for the same reason the manifest omits it: an empty
|
|
1106
|
+
// array reads as "this pack declares semantic entries", and the replacement
|
|
1107
|
+
// rule would then have it replace the compiled-in set with nothing.
|
|
1108
|
+
...(fetched.semantic.length > 0 ? { semantic: fetched.semantic } : {}),
|
|
1109
|
+
// Recorded so the READER re-checks it. This CLI has already satisfied it or
|
|
1110
|
+
// refused the install, but the record outlives this CLI: a downgrade, or a
|
|
1111
|
+
// machine restored from another's home directory, has to meet it again.
|
|
1112
|
+
...(fetched.minCliVersion ? { minCliVersion: fetched.minCliVersion } : {}),
|
|
934
1113
|
// Provenance, carried through from the manifest so `policies` and the
|
|
935
1114
|
// dashboard can say which source produced what is installed. NOT part of
|
|
936
1115
|
// verification — `sha256` above is the pin, and this is a label beside it.
|
|
@@ -978,6 +1157,10 @@ export async function addPack(
|
|
|
978
1157
|
available,
|
|
979
1158
|
selection: reason,
|
|
980
1159
|
categories: [...new Set(fetched.policies.map((p) => slugifyCategory(p.category)))],
|
|
1160
|
+
semantic: fetched.semantic.length,
|
|
1161
|
+
...(fetched.minCliVersionNote ? { minCliVersionNote: fetched.minCliVersionNote } : {}),
|
|
1162
|
+
...(fetched.effect ? { effect: fetched.effect } : {}),
|
|
1163
|
+
...(record.clis ? { clis: record.clis } : {}),
|
|
981
1164
|
artifact: artifactAbs,
|
|
982
1165
|
};
|
|
983
1166
|
}
|