failproofai 1.0.11 → 1.0.12-beta.1
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 +23 -23
- 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/build-manifest.json +3 -3
- 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 +2 -2
- 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/build-manifest.json +3 -3
- 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 +3 -3
- 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 +5 -6
- 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 +24 -24
- 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 +2 -2
- 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 +4 -5
- 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 +6 -7
- 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 +6 -7
- 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 +5 -6
- 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 +2 -2
- 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 +3 -3
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +4 -4
- 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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- 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 +3 -3
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +7 -7
- 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 +3 -3
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +7 -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/build-manifest.json +3 -3
- 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 +8 -8
- 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 +3 -3
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +3 -3
- 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 +3 -3
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/settings/page.js +10 -10
- 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]__0qkp92tjfvw8r._.js → [externals]__0vt9i6fqinjne._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__1x24dzcbbq6-g._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02vous7mpi2xm._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03i5o4a840guz._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__a_je8fsn65._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_hsnj_a2mvl_._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1izwqj_ij_9x_._.js → [root-of-the-server]__0f_4g-vazrvxv._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-oi4gdtmlo5._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0swiyzbmvja2d._.js → [root-of-the-server]__0t9ufnv5hi2hq._.js} +5 -5
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wg9dk8x8bnau._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12kq3x-h7t7i1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a5zkndjwlc13._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1r7kbfkiw2xmu._.js → [root-of-the-server]__1aaw59g-5uty7._.js} +12 -12
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hqpg6vgmfexv._.js +3 -0
- package/.next/standalone/.next/server/chunks/_09dz7xva4ce_2._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0hf5q4xzyg40j._.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/_19011-u44143j._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68lnh2daur._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1vslkoe35wok6._.js +1 -1
- package/.next/standalone/.next/server/chunks/{_1ixl-kxq_ctsa._.js → _1y590mjzpkbos._.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 +5 -0
- package/.next/standalone/.next/server/chunks/src_hooks_builtin-policies_ts_1yq5ybgx1v98e._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3h94wnn._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_daemon-client_ts_0il_yu1zc0291._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn_4twyh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01j58mdcdw0vn._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0588st-tpiuia._.js +3 -0
- 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]__0_a8z2ldp2v3n._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0vcyntk4snf0f._.js → [root-of-the-server]__0b78b0j8iyv6l._.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]__0ffu2-38y03ic._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g8b0kyorya-t._.js +3 -0
- 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]__1_xbg2kx30wp-._.js → [root-of-the-server]__0naevg4bcoh54._.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]__075uro8t92s0_._.js → [root-of-the-server]__0pwj2h2efe5f-._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zn1d4blhd3bu._.js +3 -0
- 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]__16gb3_92zvk5x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17r4zrwanhp6r._.js +3 -0
- 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]__1lnfv02ucky7m._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mc9-zlnh656_._.js +3 -0
- 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]__1s2-ck3k3rsoo._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1l1qgu5mfapkh._.js → [root-of-the-server]__1vx7o8ukefudh._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_128ebxr83nk6g._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgifqv1ssi._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifpkowwub._.js → _1a3tubds7s7ow._.js} +10 -9
- 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 +1 -1
- 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_1f_ymmaonkksc.js → node_modules_html-to-image_es_index_1i8oid1gc7s1f.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_06kzv9ddabn3_._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0agdmptetetdt._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_0mdwgjisv4fub._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4l1tzrm._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_daemon-client_ts_0k41_i7jg6ndv._.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 +23 -23
- package/.next/standalone/.next/server/middleware.js +2 -2
- 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/{0frxv4_m-m2u5.js → 063al_q720fkj.js} +1 -1
- package/.next/standalone/.next/static/chunks/0_zfad4co-t2z.js +1 -0
- package/.next/standalone/.next/static/chunks/0jutamwqz8pg5.js +1 -0
- package/.next/standalone/.next/static/chunks/114hbolvrv94e.js +1 -0
- package/.next/standalone/.next/static/chunks/{37stoe-_yd852.js → 18433qz-8njv3.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1kwj8uqxuv85t.js → 1b32-afqacaen.js} +1 -1
- package/.next/standalone/.next/static/chunks/{44a7k2_62qc-9.js → 1p-hsi58i-6h0.js} +2 -2
- package/.next/standalone/.next/static/chunks/{302llgh97ce6w.js → 2-tf6_7u623kd.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1_c0dc7zqj1n7.js → 24w3x2da9sk49.js} +1 -1
- package/.next/standalone/.next/static/chunks/2tjfp9dirxnku.js +1 -0
- package/.next/standalone/.next/static/chunks/{16z6_d7sp61jm.js → 3-pku9qwv1yfu.js} +1 -1
- package/.next/standalone/.next/static/chunks/{15rm15u5a6dua.js → 42e8zab314654.js} +1 -1
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +41 -0
- package/.next/standalone/fp-cloud-cli/README.md +42 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +117 -12
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +285 -19
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +84 -18
- package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +170 -6
- package/.next/standalone/fp-cloud-cli/fp_cli/models.py +89 -6
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +259 -21
- package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +8 -5
- package/.next/standalone/fp-cloud-cli/skill/SKILL.md +2 -2
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +17 -9
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_jev.py +692 -0
- package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +46 -0
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +23 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +6 -6
- package/.next/standalone/hermes-plugin/README.md +6 -4
- package/.next/standalone/hermes-plugin/__init__.py +16 -0
- package/.next/standalone/hermes-plugin/client.py +5 -1
- package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/context.js +72 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/diag.js +84 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/metrics.js +50 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/propagation.js +80 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/trace.js +70 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js +52 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js +44 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js +12 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/utils.js +41 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js +27 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/context.js +52 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context-api.js +16 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js +47 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js +73 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js +34 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/types.js +33 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag-api.js +20 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/index.js +71 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/global-utils.js +60 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/semver.js +111 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/Metric.js +18 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js +118 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js +20 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js +23 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js +36 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js +58 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js +68 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js +21 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js +46 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js +46 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js +33 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/context-utils.js +71 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js +94 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js +35 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js +16 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js +25 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/span_kind.js +38 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js +66 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/status.js +29 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js +18 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/version.js +10 -0
- package/.next/standalone/node_modules/@opentelemetry/api/package.json +96 -0
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/app-render/async-local-storage.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/generate-agent-files.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/trace/tracer.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/typescript/rules/config.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +11 -11
- package/.next/standalone/package.json +11 -11
- package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
- package/.next/standalone/sdk/python/pyproject.toml +19 -0
- package/.next/standalone/sdk/python/uv.lock +520 -301
- package/.next/standalone/sdk/typescript/CHANGELOG.md +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +4 -13
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +2 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4 -13
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +3 -0
- package/.next/standalone/sdk/typescript/package-lock.json +178 -162
- package/.next/standalone/sdk/typescript/package.json +1 -1
- package/.next/standalone/sdk/typescript/src/version.ts +1 -1
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +17 -1
- package/dist/cli.mjs +2866 -1124
- package/dist/worker.mjs +1450 -145
- package/hermes-plugin/README.md +6 -4
- package/hermes-plugin/__init__.py +16 -0
- package/hermes-plugin/client.py +5 -1
- package/hermes-plugin/plugin.yaml +1 -1
- package/package.json +11 -11
- package/src/hooks/agent-roster.ts +172 -0
- package/src/hooks/agent-targets.ts +60 -0
- package/src/hooks/cloud-connection.ts +97 -27
- package/src/hooks/cloud-enrollment-cli.ts +7 -4
- package/src/hooks/cloud-managed-policies.ts +380 -20
- package/src/hooks/cloud-policy-errors.ts +481 -0
- package/src/hooks/config-status.ts +1 -1
- package/src/hooks/custom-hooks-loader.ts +26 -3
- package/src/hooks/daemon-client.ts +9 -4
- package/src/hooks/daemon-service.ts +2 -1
- package/src/hooks/effective-reviewers.ts +22 -1
- package/src/hooks/fp-home.ts +6 -0
- package/src/hooks/handler.ts +235 -18
- package/src/hooks/health-probe.ts +15 -0
- package/src/hooks/integrations.ts +18 -11
- package/src/hooks/jev-cli.ts +197 -0
- package/src/hooks/jev-cloud-connection.ts +92 -0
- package/src/hooks/manager.ts +122 -16
- package/src/hooks/pack-failclosed.ts +2 -0
- package/src/hooks/pack-manifest.ts +8 -1
- package/src/hooks/policy-evaluator.ts +5 -1
- package/src/hooks/policy-registry.ts +3 -2
- package/src/hooks/policy-reviewability.ts +21 -5
- package/src/hooks/semantic/cloud-jev-health.ts +227 -0
- package/src/hooks/semantic/cloud-jev.ts +677 -0
- package/src/hooks/semantic/jev-client.ts +18 -1
- package/src/hooks/semantic/jev-config.ts +173 -3
- package/src/hooks/semantic/jev-review.ts +129 -10
- package/src/hooks/semantic/pack-policies.ts +2 -1
- package/src/hooks/semantic/types.ts +8 -0
- package/src/hooks/session-pause-cli.ts +1 -1
- package/src/hooks/worker-server.ts +5 -1
- package/.next/standalone/.next/server/chunks/[externals]__0hjaw70fchx66._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07l68zv0hqdiu._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0car70pylmvor._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u3i025_setk_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10a2f6s636yc7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qt5u58xrcuk6._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_077n_4ip5__fu._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mqvvxcn6v0op._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0pb7ds5g0vzgn._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1gasm5xkeqmm3._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1q1heqmkhh8l4._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_hooks_1aveq0uhs2t1b._.js +0 -5
- package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7cyqlb2._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0888k4s6spfmh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_bflu046ep5j._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_lbstb5x2t15._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0fdwgktjfhedo._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s4deza787asx._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__18qe-hu0gwqm4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_p_9xe520fex._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fmhm8_s9i4re._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1g76awtnmimd1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pczevlpk5lxh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0dc-of_bn0cim._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo55j16x._.js +0 -5
- package/.next/standalone/.next/static/chunks/0m-tv1y6ghhtk.js +0 -1
- package/.next/standalone/.next/static/chunks/0ol2gj4ntfn56.js +0 -1
- package/.next/standalone/.next/static/chunks/3hj5_7i3nw4zj.js +0 -1
- package/.next/standalone/.next/static/chunks/3iyoapeoq_hup.js +0 -1
- /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{kEFP3ybXwZdriNEQmWwlH → xq8UgF5yFxty1VWxY2hyn}/_ssgManifest.js +0 -0
|
@@ -4,6 +4,36 @@
|
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
6
|
|
|
7
|
+
- `fp fleet deploy --target POLICY=INTEGRATION[/agt_ID]` scopes a machine's assignment; repeat the flag to include multiple alternatives. `--all-agents POLICY` explicitly clears its scope. Deploy plans, show, history, rollback and JSON readback retain assignment targets.
|
|
8
|
+
- `fp policies publish <id> --kind regex|jev|both [--source f.mjs] [--semantic f.json]`: a
|
|
9
|
+
FailproofAI Cloud policy can carry Jev checks — `jev` (declarations only, no JavaScript) or
|
|
10
|
+
`both` (JavaScript reviewable by exactly its own checks; the server derives the authority).
|
|
11
|
+
The kind follows from what is given when `--kind` is omitted, and a kind that contradicts its
|
|
12
|
+
inputs is exit 2 before anything is sent. The positional source still works.
|
|
13
|
+
- `fp fleet deploy … --jev-mode off|observe|enforce|local` sets the machine's Jev mode from
|
|
14
|
+
FailproofAI Cloud (overriding the machine's own; `local` hands it back). Omitted, the request
|
|
15
|
+
carries no `jevMode` and the mode is unchanged; `--jev-mode` alone is a valid deploy. An
|
|
16
|
+
`observe` effect on a `jev` policy is refused (exit 2) — Jev is observed through the mode.
|
|
17
|
+
- `fp fleet jev-mode <machine…|--all> <mode>` changes only the Jev mode, through its own
|
|
18
|
+
route (`PUT /api/enforcement/deployments/{id}/jev-mode`), never the policy set — and
|
|
19
|
+
`fp fleet deploy --jev-mode` with no change to the set now uses it too. A deploy is a full
|
|
20
|
+
replace of the set the CLI read, which leaves out disabled policies' assignments, so a
|
|
21
|
+
mode change sent as a deploy deleted them and reverted concurrent edits.
|
|
22
|
+
- `fp fleet rollback` says which Jev mode it restores (`jev mode <now> → <then>`, and
|
|
23
|
+
`jevModeBefore` in `--json`); `fp fleet history` shows each generation's Jev mode and marks a
|
|
24
|
+
mode-only generation as a change.
|
|
25
|
+
- The `--jev-mode` and `fleet jev-mode` help says what `enforce` does: Jev's checks block calls
|
|
26
|
+
as well as clearing what they review, machine-wide (installed packs' checks included); an
|
|
27
|
+
`observe` effect on a `both` policy withholds its Jev checks.
|
|
28
|
+
- The `fleet deploy`, `fleet jev-mode` and `policies publish` help says Jev checks run on
|
|
29
|
+
FailproofAI Cloud and nothing is installed on the machine, and `fleet show`/`fleet jev-mode`
|
|
30
|
+
name the reasons a machine with a mode cannot ask (`jev_unconfigured`, `transcripts_disabled`)
|
|
31
|
+
and the `jev_budget` report.
|
|
32
|
+
- `fp policies list/show` print each version's kind and Jev check names (`show` also the
|
|
33
|
+
declarations); `fp fleet list/show` print the machine's Jev mode and the policy errors it
|
|
34
|
+
reported, and `--json` carries `kind`/`semantic`/`semanticSha256`/`authority`/`reviewedBy`,
|
|
35
|
+
`jevMode` and `policyErrors`/`policyErrorsAt` when the server sends them.
|
|
36
|
+
|
|
7
37
|
- `jev:evaluate` is a known permission — Jev through FailproofAI Cloud, charged to the
|
|
8
38
|
org's plan — so `fp keys` and `fp users` accept it instead of refusing it as unknown,
|
|
9
39
|
and the `admin` preset carries it, as the server's built-in admin set now does. The
|
|
@@ -13,9 +43,15 @@
|
|
|
13
43
|
(`events:add` + `policies:pull` + `jev:evaluate`), for an enrolled machine using Jev through
|
|
14
44
|
FailproofAI Cloud. `fp keys` also refuses `jev:evaluate` without both prerequisites itself
|
|
15
45
|
(exit 2, naming what is missing) instead of sending the key for the server's 422. (#833)
|
|
46
|
+
- `fp policies list` and `fp policies show` print what a `jev`/`both` version's checks take of a
|
|
47
|
+
machine's Jev question budget (`jevChars`), and a deploy refused with `jev_budget_exceeded`
|
|
48
|
+
lists each Jev policy's share, largest first (the `hint` under `--json`), so the refusal says
|
|
49
|
+
which policy to leave off.
|
|
16
50
|
|
|
17
51
|
### Changed
|
|
18
52
|
|
|
53
|
+
- `fp policies publish`'s refusal of Jev fields in the JavaScript now says where Jev checks go:
|
|
54
|
+
the policy's own declarations, `--kind both --semantic checks.json`.
|
|
19
55
|
- `fp guardrails summary` shows how many machines run Jev in each mode, reading the summary's
|
|
20
56
|
`jev.machines.observe` and `jev.machines.enforce`.
|
|
21
57
|
- `fp policies publish` (and `policies compose --publish`) refuses a source carrying Jev
|
|
@@ -27,6 +63,11 @@
|
|
|
27
63
|
same comment-aware detection, as the dashboard's publish form; the server does not read
|
|
28
64
|
the source, so nothing else refuses it for `fp`. (#833)
|
|
29
65
|
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- `fp fleet history` keeps `gen`, `when` and `jev` visible at 80 columns (rollback needs `gen`): the policy list is shortened, then dropped, and `change` wraps first.
|
|
69
|
+
- `fp fleet show` and `fp fleet history` name an exact-profile target by the profile label the machine reports (`claude/.claude-work`, with the `agt_…` id kept in `show`), falling back to the bare id.
|
|
70
|
+
|
|
30
71
|
## 0.0.1 — 2026-09-22
|
|
31
72
|
|
|
32
73
|
**First stable release.** `0.0.1b1` and `0.0.1b2` are the two betas behind it; the
|
|
@@ -139,6 +139,48 @@ fp fleet deploy ci-runner-01 --add no-force-push
|
|
|
139
139
|
fp guardrails summary --since 24h
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
A policy has a **kind**: `regex` (JavaScript — the default, and what every
|
|
143
|
+
earlier version is), `jev` (Jev checks only, from a JSON file of declarations —
|
|
144
|
+
each exactly a failproofai pack manifest's semantic entry), or `both`
|
|
145
|
+
(JavaScript whose verdict its own Jev checks may clear, deployed as one).
|
|
146
|
+
Jev checks run on FailproofAI Cloud; nothing is installed on the machine.
|
|
147
|
+
`--jev-mode` sets a machine's Jev mode from FailproofAI Cloud, overriding the
|
|
148
|
+
machine's own; omit it and the mode is left alone. Under `observe` or `enforce`
|
|
149
|
+
the machine sends each checked tool call to FailproofAI Cloud, which asks the
|
|
150
|
+
checks deployed to it. The mode is the machine's, so it covers installed packs'
|
|
151
|
+
checks too, and in `enforce` Jev's checks **block** calls as well as clearing
|
|
152
|
+
the regex verdicts they review. `fp fleet jev-mode` changes only the mode, and
|
|
153
|
+
never rewrites a machine's policy set.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
fp policies publish prod-db-intent --kind jev --semantic ./checks.json
|
|
157
|
+
fp policies publish no-prod-db --kind both --source ./rule.mjs --semantic ./checks.json
|
|
158
|
+
fp fleet deploy ci-runner-01 --add prod-db-intent --jev-mode observe
|
|
159
|
+
fp fleet jev-mode --all enforce # the mode alone, every machine with a deployment
|
|
160
|
+
fp fleet show ci-runner-01 # its Jev mode, and any policy errors it reported
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Published policy versions do not contain agent-routing code. Each assignment
|
|
164
|
+
can instead target every agent (the default), an integration including future
|
|
165
|
+
profiles, or a particular profile reported by that machine. The same target
|
|
166
|
+
applies to the regex and Jev parts of a `both` policy:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
fp fleet deploy ci-runner-01 --add no-prod-db --target no-prod-db=hermes
|
|
170
|
+
fp fleet deploy ci-runner-01 --target no-prod-db=hermes/agt_1234567890abcdef
|
|
171
|
+
fp fleet deploy ci-runner-01 --all-agents no-prod-db # explicitly remove targeting
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Repeat `--target` for multiple alternatives on one assignment. `fp fleet
|
|
175
|
+
show` and `fp fleet history` display the assigned scope; `--json` includes
|
|
176
|
+
`agentTargets` on each targeted policy. A machine must report agent-scoping
|
|
177
|
+
support before accepting a new target. When its identity cannot be resolved,
|
|
178
|
+
a targeted policy does not match; unscoped policy remains in force.
|
|
179
|
+
Newly installed shell hooks carry their settings scope. Reinstall older hooks
|
|
180
|
+
to add the hint; without it, or for an integration that cannot report the
|
|
181
|
+
source of multiple installed scopes, the machine reports
|
|
182
|
+
`agent_scope_unresolved` rather than guessing which profile ran the call.
|
|
183
|
+
|
|
142
184
|
**A deploy REPLACES a machine's whole policy set.** The server takes the full
|
|
143
185
|
list and does not merge, so `fleet deploy` reads what the machine currently runs,
|
|
144
186
|
applies your `--add`/`--remove`, prints the complete resulting set, and writes
|
|
@@ -256,4 +298,3 @@ working as an opt-out if it is ever switched back on. See
|
|
|
256
298
|
cd fp-cloud-cli
|
|
257
299
|
uv run --extra dev pytest
|
|
258
300
|
```
|
|
259
|
-
|
|
@@ -23,7 +23,7 @@ import re
|
|
|
23
23
|
import uuid
|
|
24
24
|
from dataclasses import dataclass
|
|
25
25
|
from enum import Enum
|
|
26
|
-
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Union
|
|
26
|
+
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Tuple, Union
|
|
27
27
|
|
|
28
28
|
import httpx
|
|
29
29
|
|
|
@@ -487,9 +487,39 @@ def _raise_for_status(response: httpx.Response, ctx: ClientContext) -> None:
|
|
|
487
487
|
message or f"Request failed with status {response.status_code}.",
|
|
488
488
|
status=response.status_code,
|
|
489
489
|
request_id=request_id,
|
|
490
|
+
hint=_jev_budget_breakdown(response),
|
|
490
491
|
)
|
|
491
492
|
|
|
492
493
|
|
|
494
|
+
def _jev_budget_breakdown(response: httpx.Response) -> Optional[str]:
|
|
495
|
+
"""The per-policy breakdown of a deploy's ``jev_budget_exceeded`` refusal.
|
|
496
|
+
|
|
497
|
+
The message carries only the total (``used``/``budget``); the body also lists
|
|
498
|
+
every Jev policy version the machine would carry with its question
|
|
499
|
+
characters (``policies: [{id, version, chars}]``), which is what tells an
|
|
500
|
+
operator WHICH policy to leave off. Largest first. ``None`` for any other
|
|
501
|
+
error, and for a publish refusal, which names no other policies.
|
|
502
|
+
"""
|
|
503
|
+
try:
|
|
504
|
+
data = response.json()
|
|
505
|
+
except Exception:
|
|
506
|
+
return None
|
|
507
|
+
if not isinstance(data, dict) or data.get("code") != "jev_budget_exceeded":
|
|
508
|
+
return None
|
|
509
|
+
rows = [
|
|
510
|
+
(str(p.get("id", "")), p.get("version"), p["chars"])
|
|
511
|
+
for p in data.get("policies") or []
|
|
512
|
+
if isinstance(p, dict) and isinstance(p.get("chars"), int)
|
|
513
|
+
]
|
|
514
|
+
if not rows:
|
|
515
|
+
return None
|
|
516
|
+
rows.sort(key=lambda row: -row[2])
|
|
517
|
+
parts = [f"{pid}@{version} {chars:,}" if version is not None else f"{pid} {chars:,}"
|
|
518
|
+
for pid, version, chars in rows]
|
|
519
|
+
return ("Jev question characters per policy: " + " · ".join(parts)
|
|
520
|
+
+ " — deploy fewer of these Jev policies to this machine")
|
|
521
|
+
|
|
522
|
+
|
|
493
523
|
def _get_json(ctx: ClientContext, path: str, params: Optional[Dict[str, Any]] = None) -> Any:
|
|
494
524
|
clean = {k: v for k, v in (params or {}).items() if v is not None}
|
|
495
525
|
url = _path(ctx, path) # chokepoint 1 of 4 for the /api -> /v1 rewrite
|
|
@@ -1643,22 +1673,43 @@ def list_policies(ctx: ClientContext) -> List[PolicyVersion]:
|
|
|
1643
1673
|
|
|
1644
1674
|
|
|
1645
1675
|
def publish_policy(
|
|
1646
|
-
ctx: ClientContext,
|
|
1676
|
+
ctx: ClientContext,
|
|
1677
|
+
policy_id: str,
|
|
1678
|
+
source: Optional[str],
|
|
1679
|
+
description: str = "",
|
|
1680
|
+
*,
|
|
1681
|
+
kind: Optional[str] = None,
|
|
1682
|
+
semantic: Optional[List[Any]] = None,
|
|
1647
1683
|
) -> PolicyVersion:
|
|
1648
1684
|
"""POST /api/enforcement/policies — mints a NEW VERSION; never edits in place.
|
|
1649
1685
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1686
|
+
``kind`` is ``regex`` (JavaScript ``source`` only — what an omitted kind
|
|
1687
|
+
means to the server), ``jev`` (Jev declarations in ``semantic``, no
|
|
1688
|
+
``source``) or ``both`` (the two together: the JavaScript is reviewable by
|
|
1689
|
+
exactly its own checks). ``authority``/``reviewedBy`` are derived by the
|
|
1690
|
+
server from the kind and are never sent.
|
|
1691
|
+
|
|
1692
|
+
Refuses Jev fields in the JAVASCRIPT before anything is sent, here because
|
|
1693
|
+
`policies publish` and `policies compose --publish` both route through it —
|
|
1694
|
+
and regardless of `--no-verify`, which only skips the syntax check. Jev
|
|
1695
|
+
checks belong in ``semantic``, where they take effect.
|
|
1653
1696
|
"""
|
|
1654
|
-
problem = cloud_publish_problem(source)
|
|
1697
|
+
problem = cloud_publish_problem(source or "")
|
|
1655
1698
|
if problem:
|
|
1656
1699
|
raise ApiError(
|
|
1657
1700
|
f"{policy_id} cannot be published as a cloud policy: {problem}",
|
|
1658
|
-
hint=("Jev checks
|
|
1659
|
-
"
|
|
1701
|
+
hint=("put Jev checks in the policy's Jev declarations — `--kind both --semantic "
|
|
1702
|
+
"checks.json` — or ship them in a failproofai pack with `failproofai publish`"),
|
|
1660
1703
|
)
|
|
1661
|
-
body = {"id": policy_id, "
|
|
1704
|
+
body: Dict[str, Any] = {"id": policy_id, "description": description}
|
|
1705
|
+
# `source` is omitted for a Jev-only policy: the server takes absent (or
|
|
1706
|
+
# empty) as "no JavaScript", which is what a `jev` version is.
|
|
1707
|
+
if source:
|
|
1708
|
+
body["source"] = source
|
|
1709
|
+
if kind is not None:
|
|
1710
|
+
body["kind"] = kind
|
|
1711
|
+
if semantic is not None:
|
|
1712
|
+
body["semantic"] = semantic
|
|
1662
1713
|
return PolicyVersion.from_dict(_post_json(ctx, "/api/enforcement/policies", body) or {})
|
|
1663
1714
|
|
|
1664
1715
|
|
|
@@ -1681,6 +1732,29 @@ def list_machines(ctx: ClientContext) -> List[Machine]:
|
|
|
1681
1732
|
return [Machine.from_dict(m) for m in items]
|
|
1682
1733
|
|
|
1683
1734
|
|
|
1735
|
+
def machine_agents(ctx: ClientContext, machine_id: str) -> List[Dict[str, Any]]:
|
|
1736
|
+
"""GET /api/enforcement/machines/{id}/agents — the agent profiles the daemon
|
|
1737
|
+
last reported: `[{instanceId, integration, profileLabel, scope, ...}]`."""
|
|
1738
|
+
data = _get_json(ctx, f"/api/enforcement/machines/{machine_id}/agents")
|
|
1739
|
+
items = data if isinstance(data, list) else (data or {}).get("agents", [])
|
|
1740
|
+
return [a for a in items if isinstance(a, dict)]
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
def agent_labels(ctx: ClientContext, machine_id: str) -> Dict[str, str]:
|
|
1744
|
+
"""`{instanceId: profileLabel}` for one machine, or `{}` when unavailable.
|
|
1745
|
+
|
|
1746
|
+
Best effort on purpose: it only names the `agt_…` ids an exact-profile
|
|
1747
|
+
assignment carries. A server without the roster route, or a machine that
|
|
1748
|
+
never reported one, falls back to the bare id rather than failing the view.
|
|
1749
|
+
"""
|
|
1750
|
+
try:
|
|
1751
|
+
agents = machine_agents(ctx, machine_id)
|
|
1752
|
+
except Exception: # noqa: BLE001 — a missing label must never fail the read
|
|
1753
|
+
return {}
|
|
1754
|
+
return {str(a["instanceId"]): str(a["profileLabel"])
|
|
1755
|
+
for a in agents if a.get("instanceId") and a.get("profileLabel")}
|
|
1756
|
+
|
|
1757
|
+
|
|
1684
1758
|
def rename_machine(ctx: ClientContext, machine_id: str, label: str) -> Dict[str, Any]:
|
|
1685
1759
|
"""PATCH /api/enforcement/machines/{id} — a human label, not the id."""
|
|
1686
1760
|
path = f"/api/enforcement/machines/{machine_id}"
|
|
@@ -1708,14 +1782,45 @@ def get_deployment(ctx: ClientContext, machine_id: str) -> Optional[Deployment]:
|
|
|
1708
1782
|
|
|
1709
1783
|
|
|
1710
1784
|
def deploy_policies(
|
|
1711
|
-
ctx: ClientContext,
|
|
1785
|
+
ctx: ClientContext,
|
|
1786
|
+
machine_id: str,
|
|
1787
|
+
policies: Sequence[PolicyRef],
|
|
1788
|
+
jev_mode: Optional[str] = None,
|
|
1712
1789
|
) -> Deployment:
|
|
1713
|
-
"""PUT /api/enforcement/deployments/{id} — REPLACES the machine's whole set.
|
|
1790
|
+
"""PUT /api/enforcement/deployments/{id} — REPLACES the machine's whole set.
|
|
1791
|
+
|
|
1792
|
+
``jev_mode`` (``off|observe|enforce|local``) is sent only when given: the
|
|
1793
|
+
server reads an ABSENT ``jevMode`` as "keep the machine's current one", so a
|
|
1794
|
+
deploy that says nothing about Jev never changes it. ``local`` stops
|
|
1795
|
+
FailproofAI Cloud overriding the machine's own mode.
|
|
1796
|
+
"""
|
|
1714
1797
|
path = f"/api/enforcement/deployments/{machine_id}"
|
|
1715
|
-
body = {"policies": [p.to_dict() for p in policies]}
|
|
1798
|
+
body: Dict[str, Any] = {"policies": [p.to_dict() for p in policies]}
|
|
1799
|
+
if jev_mode is not None:
|
|
1800
|
+
body["jevMode"] = jev_mode
|
|
1716
1801
|
return Deployment.from_dict(_request_json(ctx, "PUT", path, json_body=body) or {})
|
|
1717
1802
|
|
|
1718
1803
|
|
|
1804
|
+
def set_jev_mode(ctx: ClientContext, machine_id: str, jev_mode: str) -> Tuple[Deployment, bool]:
|
|
1805
|
+
"""PUT /api/enforcement/deployments/{id}/jev-mode — change ONLY the Jev mode.
|
|
1806
|
+
|
|
1807
|
+
``jev_mode`` is ``off|observe|enforce|local`` (``local`` stops FailproofAI
|
|
1808
|
+
Cloud overriding the machine's own mode). Unlike a deploy, this never
|
|
1809
|
+
touches the machine's policy set: a deploy is a full replace of the set, and
|
|
1810
|
+
the set a client can read leaves out disabled policies' assignments, so a
|
|
1811
|
+
mode change sent as a deploy deleted them — and reverted any edit made since
|
|
1812
|
+
the set was read. It still mints a new generation, which is how the machine
|
|
1813
|
+
picks the mode up.
|
|
1814
|
+
|
|
1815
|
+
Returns the deployment and whether anything changed: setting the mode the
|
|
1816
|
+
machine already has changes nothing and mints nothing (``changed: false``).
|
|
1817
|
+
A machine with no deployment is a 404 — a deploy is how it gets its first.
|
|
1818
|
+
"""
|
|
1819
|
+
path = f"/api/enforcement/deployments/{machine_id}/jev-mode"
|
|
1820
|
+
data = _request_json(ctx, "PUT", path, json_body={"jevMode": jev_mode}) or {}
|
|
1821
|
+
return Deployment.from_dict(data), bool(data.get("changed", True))
|
|
1822
|
+
|
|
1823
|
+
|
|
1719
1824
|
def deployment_history(ctx: ClientContext, machine_id: str) -> List[Dict[str, Any]]:
|
|
1720
1825
|
"""GET /api/enforcement/deployments/{id}/history — every generation, newest first."""
|
|
1721
1826
|
path = f"/api/enforcement/deployments/{machine_id}/history"
|