failproofai 1.0.8 → 1.0.9-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.
Files changed (191) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/index.html +1 -1
  36. package/.next/standalone/.next/server/app/index.rsc +15 -15
  37. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  38. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  39. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  40. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +4 -4
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  63. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +20 -20
  68. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  70. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
  73. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03m2iw6._.js +3 -0
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
  80. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12e7nhs._.js → [root-of-the-server]__1-bm5zf._.js} +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
  86. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
  89. package/.next/standalone/.next/server/chunks/ssr/_11ilmst._.js +23 -0
  90. package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +3 -3
  91. package/.next/standalone/.next/server/chunks/ssr/{_0-vcssj._.js → _1jatlmf._.js} +1 -1
  92. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  93. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +3 -3
  94. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +1 -1
  102. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  103. package/.next/standalone/.next/server/pages/404.html +1 -1
  104. package/.next/standalone/.next/server/pages/500.html +1 -1
  105. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
  107. package/.next/standalone/.next/static/chunks/{06jxjnw8bfczc.js → 0542cuk_va8g1.js} +1 -1
  108. package/.next/standalone/.next/static/chunks/{0wbjy0zo-m7is.js → 08ckontevw-0w.js} +1 -1
  109. package/.next/standalone/.next/static/chunks/0pefjgvu4x-sx.js +1 -0
  110. package/.next/standalone/.next/static/chunks/{21uv-uusw329x.js → 1-d48e9k-7e1a.js} +1 -1
  111. package/.next/standalone/.next/static/chunks/{0m-9d6yn9hx4j.js → 1r74hmr1wm_sd.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/1uec0n0lcx5h1.js +1 -0
  113. package/.next/standalone/.next/static/chunks/21-pqc3-l9ak2.js +6 -0
  114. package/.next/standalone/.next/static/chunks/21qlo00jis4w-.js +1 -0
  115. package/.next/standalone/.next/static/chunks/2n00c3zqyloy9.js +1 -0
  116. package/.next/standalone/.next/static/chunks/{0bhidk90e-07f.css → 3_e_wg5_oay87.css} +1 -1
  117. package/.next/standalone/.next/static/chunks/{3c3qbmosdjl6w.js → 3tv107_for_n7.js} +1 -1
  118. package/.next/standalone/.next/static/chunks/{2qdpj67x6ifk_.js → 3vp54x0dyrrm6.js} +1 -1
  119. package/.next/standalone/.next/static/chunks/{turbopack-38nzuvp95_2rv.js → turbopack-11dn2pegmg9_9.js} +1 -1
  120. package/.next/standalone/app/actions/get-jev-config.ts +2 -2
  121. package/.next/standalone/app/actions/update-jev-config.ts +12 -9
  122. package/.next/standalone/app/components/jev-notices.tsx +10 -10
  123. package/.next/standalone/app/settings/jev-panel.tsx +11 -11
  124. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +2 -0
  125. package/.next/standalone/fp-cloud-cli/fp_cli/output.py +26 -0
  126. package/.next/standalone/fp-cloud-cli/tests/test_output.py +27 -0
  127. package/.next/standalone/fp-cloud-cli/uv.lock +3 -3
  128. package/.next/standalone/hermes-plugin/README.md +18 -8
  129. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  130. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  131. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
  132. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  133. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  134. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  135. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  136. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  137. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  138. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  139. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  140. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  141. package/.next/standalone/node_modules/next/package.json +10 -10
  142. package/.next/standalone/package.json +12 -12
  143. package/.next/standalone/sdk/python/uv.lock +18 -18
  144. package/.next/standalone/server.js +1 -1
  145. package/bin/failproofai.mjs +33 -7
  146. package/dist/cli.mjs +1385 -1158
  147. package/dist/worker.mjs +59 -375
  148. package/hermes-plugin/README.md +18 -8
  149. package/package.json +12 -12
  150. package/scripts/build-policy-pack.mjs +6 -9
  151. package/src/hooks/cloud-connection.ts +12 -6
  152. package/src/hooks/custom-hooks-loader.ts +1 -1
  153. package/src/hooks/effective-reviewers.ts +50 -43
  154. package/src/hooks/handler.ts +25 -16
  155. package/src/hooks/hermes-update.ts +74 -0
  156. package/src/hooks/hook-activity-store.ts +3 -3
  157. package/src/hooks/integrations.ts +472 -68
  158. package/src/hooks/jev-activity.ts +8 -3
  159. package/src/hooks/jev-cli.ts +17 -17
  160. package/src/hooks/jev-cloud-connection.ts +4 -4
  161. package/src/hooks/manager.ts +3 -2
  162. package/src/hooks/pack-cli.ts +24 -23
  163. package/src/hooks/pack-manifest.ts +25 -2
  164. package/src/hooks/pack-store.ts +2 -2
  165. package/src/hooks/policy-authority.ts +51 -32
  166. package/src/hooks/policy-evaluator.ts +5 -5
  167. package/src/hooks/policy-registry.ts +5 -7
  168. package/src/hooks/policy-reviewability.ts +30 -12
  169. package/src/hooks/policy-types.ts +4 -4
  170. package/src/hooks/safe-config-write.ts +119 -0
  171. package/src/hooks/semantic/combine.ts +13 -13
  172. package/src/hooks/semantic/evaluator.ts +5 -5
  173. package/src/hooks/semantic/jev-client.ts +1 -1
  174. package/src/hooks/semantic/jev-config.ts +21 -12
  175. package/src/hooks/semantic/jev-review.ts +3 -3
  176. package/src/hooks/semantic/jev-stats.ts +17 -17
  177. package/src/hooks/semantic/pack-policies.ts +48 -48
  178. package/src/hooks/semantic/policies.ts +13 -425
  179. package/src/hooks/semantic/precondition-names.ts +1 -1
  180. package/src/hooks/semantic/preconditions.ts +1 -1
  181. package/src/hooks/semantic/types.ts +1 -1
  182. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +0 -3
  183. package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +0 -23
  184. package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +0 -6
  185. package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +0 -1
  186. package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +0 -1
  187. package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +0 -1
  188. package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +0 -1
  189. /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → ozuWoyIwOTqeUUjKqOKiH}/_buildManifest.js +0 -0
  190. /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → ozuWoyIwOTqeUUjKqOKiH}/_clientMiddlewareManifest.js +0 -0
  191. /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → ozuWoyIwOTqeUUjKqOKiH}/_ssgManifest.js +0 -0
package/dist/worker.mjs CHANGED
@@ -1162,7 +1162,7 @@ function instruct(reason) {
1162
1162
  }
1163
1163
 
1164
1164
  // package.json
1165
- var version = "1.0.8";
1165
+ var version = "1.0.9-beta.1";
1166
1166
  var init_package = () => {};
1167
1167
 
1168
1168
  // src/hooks/policy-types.ts
@@ -1179,7 +1179,7 @@ function effectiveAuthority(p) {
1179
1179
 
1180
1180
  // src/hooks/policy-authority.ts
1181
1181
  import { existsSync as existsSync3 } from "node:fs";
1182
- function resolvePolicyAuthority(decl, knownReviewers = SEMANTIC_REVIEWER_NAMES, contested) {
1182
+ function resolvePolicyAuthority(decl, knownReviewers = NO_REVIEWERS, contested) {
1183
1183
  const declaredReviewable = decl?.authority === "reviewable";
1184
1184
  if (!decl || effectiveAuthority(decl) === "hard") {
1185
1185
  if (!declaredReviewable)
@@ -1191,6 +1191,8 @@ function resolvePolicyAuthority(decl, knownReviewers = SEMANTIC_REVIEWER_NAMES,
1191
1191
  return { authority: "hard", downgraded: "reviewedBy is not a list of semantic policy names" };
1192
1192
  }
1193
1193
  const unknown = names.filter((n) => !knownReviewers.has(n));
1194
+ if (knownReviewers.size === 0 && !unknown.some((n) => contested?.has(n)))
1195
+ return { authority: "hard" };
1194
1196
  if (unknown.length > 0) {
1195
1197
  return { authority: "hard", downgraded: `reviewedBy names ${unknown.map((n) => whyUnknown(n, knownReviewers, contested)).join("; ")}` };
1196
1198
  }
@@ -1225,7 +1227,7 @@ function authorityFieldsOf(raw) {
1225
1227
  }
1226
1228
  return out;
1227
1229
  }
1228
- function withMergedAuthority(record, declarations, knownReviewers = SEMANTIC_REVIEWER_NAMES) {
1230
+ function withMergedAuthority(record, declarations, knownReviewers = NO_REVIEWERS) {
1229
1231
  const resolved = declarations.map((d) => resolvePolicyAuthority(d, knownReviewers));
1230
1232
  const allReviewable = resolved.length > 0 && resolved.every((r) => r.authority === "reviewable");
1231
1233
  const decided = declarations[resolved.findIndex((r) => r.authority !== "reviewable")] ?? {};
@@ -1264,7 +1266,7 @@ function authorityDeclarationFor(hook, source) {
1264
1266
  }
1265
1267
  return { authority: hook.authority, reviewedBy: hook.reviewedBy };
1266
1268
  }
1267
- var SEMANTIC_POLICY_NAMES, SEMANTIC_REVIEWER_NAMES, isName = (n) => typeof n === "string" && n.length > 0, warnedAuthority;
1269
+ var SEMANTIC_POLICY_NAMES, SEMANTIC_REVIEWER_NAMES, NO_REVIEWERS, isName = (n) => typeof n === "string" && n.length > 0, warnedAuthority;
1268
1270
  var init_policy_authority = __esm(() => {
1269
1271
  init_fp_home();
1270
1272
  init_hook_logger();
@@ -1287,6 +1289,7 @@ var init_policy_authority = __esm(() => {
1287
1289
  "external-data-egress"
1288
1290
  ];
1289
1291
  SEMANTIC_REVIEWER_NAMES = new Set(SEMANTIC_POLICY_NAMES);
1292
+ NO_REVIEWERS = new Set;
1290
1293
  warnedAuthority = new Set;
1291
1294
  });
1292
1295
 
@@ -1480,10 +1483,12 @@ function parsePackIdentity(value) {
1480
1483
  ...commit ? { commit } : {}
1481
1484
  };
1482
1485
  }
1483
- function hasInstalledPacks() {
1486
+ function hasInstalledRegexPacks() {
1484
1487
  try {
1485
1488
  const raw = JSON.parse(readFileSync3(installedFilePath(), "utf8"));
1486
- return Array.isArray(raw.packs) && raw.packs.length > 0;
1489
+ if (!Array.isArray(raw.packs))
1490
+ return false;
1491
+ return raw.packs.some((p) => !!p && typeof p === "object" && Array.isArray(p.policies) && p.policies.length > 0);
1487
1492
  } catch {
1488
1493
  return false;
1489
1494
  }
@@ -1903,7 +1908,7 @@ function isReservedClaim(pack, name) {
1903
1908
  function effectiveReviewerNames() {
1904
1909
  if (cached)
1905
1910
  return cached;
1906
- let names = SEMANTIC_REVIEWER_NAMES;
1911
+ let names = NO_REVIEWERS;
1907
1912
  cachedContested = new Map;
1908
1913
  try {
1909
1914
  const packs = jevPacks(readInstalledPacks().packs, reviewerCli);
@@ -1917,15 +1922,15 @@ function contestedReviewerNames() {
1917
1922
  effectiveReviewerNames();
1918
1923
  return cachedContested;
1919
1924
  }
1920
- function replacesBuiltinChecks(packs) {
1921
- return packs.some((p) => isFirstPartyPack(p) && (p.semantic ?? []).length > 0);
1925
+ function jevChecksInstalled() {
1926
+ return effectiveReviewerNames().size > 0;
1922
1927
  }
1923
1928
  function reviewerNamesFor(packs) {
1924
1929
  const contested = contestedSemanticNames(packs);
1925
1930
  const declared = packs.flatMap((p) => (p.semantic ?? []).filter((s) => !isReservedClaim(p, s.name)).map((s) => s.name)).filter((name) => !contested.has(name));
1926
1931
  if (declared.length === 0)
1927
- return SEMANTIC_REVIEWER_NAMES;
1928
- return new Set(replacesBuiltinChecks(packs) ? declared : [...SEMANTIC_REVIEWER_NAMES, ...declared]);
1932
+ return NO_REVIEWERS;
1933
+ return new Set(declared);
1929
1934
  }
1930
1935
  function forgetEffectiveReviewerNames(cli) {
1931
1936
  cached = null;
@@ -4167,8 +4172,11 @@ function sanitizeJevActivity(entry) {
4167
4172
  drop("evaluator");
4168
4173
  if (!(typeof out.jevDecision === "string" && DECISIONS.has(out.jevDecision)))
4169
4174
  drop("jevDecision");
4175
+ const unknownMode = out.jevMode !== undefined && !(typeof out.jevMode === "string" && MODES.has(out.jevMode));
4170
4176
  if (!(typeof out.jevMode === "string" && MODES.has(out.jevMode)))
4171
4177
  drop("jevMode");
4178
+ if (unknownMode)
4179
+ drop("jevCleared");
4172
4180
  if (Array.isArray(out.jevCleared)) {
4173
4181
  const names = [
4174
4182
  ...new Set(out.jevCleared.filter(isJevPolicyName))
@@ -4222,7 +4230,7 @@ var init_jev_activity = __esm(() => {
4222
4230
  ];
4223
4231
  EVALUATORS = new Set(["jev", "jev-fallback"]);
4224
4232
  DECISIONS = new Set(["allow", "instruct", "deny"]);
4225
- MODES = new Set(["shadow", "enforce"]);
4233
+ MODES = new Set(["observe", "enforce"]);
4226
4234
  REASON_HEAD_RE = /^([a-z0-9]+(?:-[a-z0-9]+)*)\s*(?:$|[:(])/;
4227
4235
  HTTP_CODE_RE = /^http-\d{3}$/;
4228
4236
  JEV_REASON_CODE_LIST = [
@@ -4327,14 +4335,14 @@ function combineTwoTier(verdicts, review, mode) {
4327
4335
  ...review.model ? { jevModel: review.model } : {},
4328
4336
  jevMode: mode
4329
4337
  };
4330
- if (mode === "shadow") {
4331
- const shadowVerdict = review.decision === "deny" || review.decision === "instruct" ? {
4338
+ if (mode === "observe") {
4339
+ const observeVerdict = review.decision === "deny" || review.decision === "instruct" ? {
4332
4340
  policyName: jevEntry.policyName,
4333
4341
  decision: review.decision,
4334
4342
  reason: jevEntry.reason,
4335
4343
  version: review.model && JEV_MODEL_RE.test(review.model) ? review.model : "jev"
4336
4344
  } : undefined;
4337
- return { final: legacy, cleared, decidedByJev: false, activity, ...shadowVerdict ? { shadowVerdict } : {} };
4345
+ return { final: legacy, cleared, decidedByJev: false, activity, ...observeVerdict ? { observeVerdict } : {} };
4338
4346
  }
4339
4347
  return { ...enforced, cleared, activity };
4340
4348
  }
@@ -4908,7 +4916,7 @@ async function evaluatePolicies(eventType, payload, session, config, twoTier) {
4908
4916
  }
4909
4917
  const combined = combineTwoTier(collected.verdicts, review, twoTier.mode);
4910
4918
  if (combined.cleared.length > 0) {
4911
- hookLogInfo(`jev ${twoTier.mode === "shadow" ? "would clear" : "cleared"}: ${combined.cleared.join(", ")}`);
4919
+ hookLogInfo(`jev ${twoTier.mode === "observe" ? "would clear" : "cleared"}: ${combined.cleared.join(", ")}`);
4912
4920
  }
4913
4921
  if (combined.activity.evaluator === "jev-fallback") {
4914
4922
  hookLogInfo(combined.activity.jevFallbackReason === JEV_REASON_REQUEST_CUT ? "jev could not be shown the whole call; it cleared nothing, and the call was not allowed on a partial read" : `jev unavailable (${combined.activity.jevFallbackReason}); the regex result decided this call`);
@@ -4919,7 +4927,7 @@ async function evaluatePolicies(eventType, payload, session, config, twoTier) {
4919
4927
  activity: combined.activity,
4920
4928
  decidedByJev: combined.decidedByJev,
4921
4929
  ...combined.decidedByJev && review.kind === "answered" && review.origin ? { jevOrigin: review.origin } : {},
4922
- ...combined.shadowVerdict ? { shadowVerdict: combined.shadowVerdict } : {}
4930
+ ...combined.observeVerdict ? { observeVerdict: combined.observeVerdict } : {}
4923
4931
  }
4924
4932
  };
4925
4933
  }
@@ -11479,6 +11487,9 @@ var init_fp_reset = __esm(() => {
11479
11487
  // src/hooks/semantic/jev-config.ts
11480
11488
  import { closeSync as closeSync2, constants as fsConstants2, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2, statSync as statSync15 } from "node:fs";
11481
11489
  import { dirname as dirname6 } from "node:path";
11490
+ function parseJevMode(raw) {
11491
+ return raw === "off" || raw === "observe" || raw === "enforce" ? raw : null;
11492
+ }
11482
11493
  function jevConfigPath() {
11483
11494
  return jevConfigFile();
11484
11495
  }
@@ -11665,14 +11676,15 @@ function validateJevConfig(raw, envKey, cloud) {
11665
11676
  cfg.timeoutMs = t;
11666
11677
  }
11667
11678
  if (o.mode !== undefined) {
11668
- if (o.mode !== "off" && o.mode !== "shadow" && o.mode !== "enforce")
11669
- return { ok: false, problem: 'mode must be "off", "shadow" or "enforce"' };
11670
- cfg.mode = o.mode;
11679
+ const mode = parseJevMode(o.mode);
11680
+ if (mode === null)
11681
+ return { ok: false, problem: 'mode must be "off", "observe" or "enforce"' };
11682
+ cfg.mode = mode;
11671
11683
  }
11672
11684
  if (cfg.baseUrl !== undefined && isPlainHttp(cfg.baseUrl) && cfg.mode === "enforce") {
11673
11685
  return {
11674
11686
  ok: false,
11675
- problem: "plain http (to localhost) is accepted only with mode shadow: in enforce mode Jev's answers can clear a deny, " + "and while the local proxy is down any process on this machine could take its port and answer. " + (cfg.provider === JEV_CLOUD_PROVIDER ? "Reconnect to an https FailproofAI Cloud URL (failproofai config --token <key> --url https://…), or keep mode shadow" : "Use https, or mode shadow")
11687
+ problem: "plain http (to localhost) is accepted only with mode observe: in enforce mode Jev's answers can clear a deny, " + "and while the local proxy is down any process on this machine could take its port and answer. " + (cfg.provider === JEV_CLOUD_PROVIDER ? "Reconnect to an https FailproofAI Cloud URL (failproofai config --token <key> --url https://…), or keep mode observe" : "Use https, or mode observe")
11676
11688
  };
11677
11689
  }
11678
11690
  return { ok: true, value: cfg };
@@ -12525,7 +12537,7 @@ function outsideProject(facts, p) {
12525
12537
  return false;
12526
12538
  return p.resolved !== cwd && !p.resolved.startsWith(cwd.endsWith("/") ? cwd : cwd + "/");
12527
12539
  }
12528
- var PROTECTED_BRANCHES, OUTSIDE_PROJECT, SEMANTIC_POLICIES, SCOPE_PROBE, INJECTION_PROBE, HUMAN_ONLY, TASK_STEP_PROBE, OP_REQUESTED_PROBE, BEYOND_TASK_PROBE, TASK_PROBES;
12540
+ var PROTECTED_BRANCHES, OUTSIDE_PROJECT, SCOPE_PROBE, INJECTION_PROBE, HUMAN_ONLY, TASK_STEP_PROBE, OP_REQUESTED_PROBE, BEYOND_TASK_PROBE, TASK_PROBES;
12529
12541
  var init_policies = __esm(() => {
12530
12542
  PROTECTED_BRANCHES = new Set(["main", "master", "production", "prod", "release", "trunk"]);
12531
12543
  OUTSIDE_PROJECT = new Set([
@@ -12534,334 +12546,6 @@ var init_policies = __esm(() => {
12534
12546
  "system",
12535
12547
  "root"
12536
12548
  ]);
12537
- SEMANTIC_POLICIES = [
12538
- {
12539
- name: "destructive-deletion",
12540
- title: "Tried to permanently delete data that cannot be regenerated",
12541
- appliesTo: ["shell", "write"],
12542
- mode: "deny",
12543
- userCanOverride: true,
12544
- probes: [
12545
- {
12546
- id: "destroys",
12547
- instructions: "The tool call in `agent_request` permanently deletes, wipes, truncates or overwrites existing files, " + "directories or disks — for example `rm -r`, `find -delete`, `shred`, `dd of=`, `mkfs`, `truncate`, " + "`rsync --delete`, `git clean -fdx`, or redirecting output over an existing file.",
12548
- criteria: {
12549
- true: "Existing data would be destroyed or irreversibly overwritten.",
12550
- false: "Nothing existing is destroyed: it reads, lists, creates new files, or moves data somewhere recoverable."
12551
- }
12552
- },
12553
- {
12554
- id: "irreplaceable",
12555
- instructions: "What would be destroyed is outside the project, is the whole project, is the user's home directory, " + "is the filesystem root, or is data that cannot simply be regenerated (source code, documents, databases, " + "keys). Use `facts.paths[].relation` to see where each target sits relative to the project.",
12556
- criteria: {
12557
- true: "The destroyed data matters and could not be rebuilt by running a command.",
12558
- false: "Only regenerable data inside the project is affected: build output, dist/, caches, node_modules, " + "virtualenvs, coverage reports, temp files, or files the agent itself just created."
12559
- }
12560
- }
12561
- ],
12562
- guidance: "This permanently deletes data that cannot be rebuilt. Confirm the exact paths with the user first."
12563
- },
12564
- {
12565
- name: "production-infra-change",
12566
- title: "Tried to change live infrastructure",
12567
- appliesTo: ["shell"],
12568
- mode: "deny",
12569
- userCanOverride: true,
12570
- probes: [
12571
- {
12572
- id: "mutates",
12573
- instructions: "The command in `agent_request` changes the state of cloud or cluster infrastructure: it creates, " + "updates, deletes, applies, scales, restarts, rolls out, deploys or destroys resources in a cloud " + "account, Kubernetes cluster, managed database, DNS, CDN or hosting platform (any CLI: kubectl, helm, " + "terraform, tofu, pulumi, aws, gcloud, az, doctl, flyctl, vercel, wrangler, railway, and so on — " + "however the binary is spelled or pathed).",
12574
- criteria: {
12575
- true: "It mutates infrastructure.",
12576
- false: "It only reads or plans: get, list, describe, logs, status, plan, diff, validate, whoami, or --dry-run."
12577
- }
12578
- },
12579
- {
12580
- id: "not_local",
12581
- instructions: "The target of that change is a shared or production environment, or its environment cannot be told " + "from the command.",
12582
- criteria: {
12583
- true: "Production, shared, or unknown environment.",
12584
- false: "Clearly a local or throwaway environment: localhost, kind, minikube, docker-desktop, k3d, or a " + "context, workspace or profile whose name says dev, test, staging, sandbox or local."
12585
- }
12586
- }
12587
- ],
12588
- guidance: "This changes live infrastructure. Run it against a non-production target, or hand the command to a human."
12589
- },
12590
- {
12591
- name: "git-history-rewrite",
12592
- title: "Tried to rewrite or discard shared git history",
12593
- appliesTo: ["shell"],
12594
- mode: "deny",
12595
- userCanOverride: true,
12596
- probes: [
12597
- {
12598
- id: "rewrites_remote",
12599
- instructions: "The command in `agent_request` force-pushes or otherwise overwrites history on a git remote: " + "`git push --force`, `--force-with-lease`, `-f`, a `+refspec` such as `+HEAD:main`, or deleting a " + "remote branch. Git's global options before the subcommand (`git -C dir`, `git -c key=val`) and an " + "absolute path to the git binary do not change what the command does.",
12600
- criteria: {
12601
- true: "Remote history would be overwritten or a remote branch deleted.",
12602
- false: "A normal push that only adds commits, or no push at all."
12603
- }
12604
- }
12605
- ],
12606
- guidance: "Force-pushing rewrites history other people may have pulled. Confirm with the user first."
12607
- },
12608
- {
12609
- name: "push-to-protected-branch",
12610
- title: "Tried to push directly to a protected branch",
12611
- appliesTo: ["shell"],
12612
- mode: "instruct",
12613
- userCanOverride: true,
12614
- probes: [
12615
- {
12616
- id: "pushes_protected",
12617
- instructions: "The command in `agent_request` pushes commits to a remote branch named main, master, production, " + "release or trunk — either named explicitly or implied because `facts.current_git_branch` is one of " + "those and the push names no other branch.",
12618
- criteria: {
12619
- true: "Commits land directly on a protected remote branch.",
12620
- false: "It pushes a feature branch whose name merely contains a word like main (e.g. feature/main-menu), " + "or it does not push."
12621
- }
12622
- }
12623
- ],
12624
- guidance: "Pushing straight to a protected branch skips review. Push a branch and open a PR unless the user asked for this."
12625
- },
12626
- {
12627
- name: "commit-on-protected-branch",
12628
- title: "Tried to commit directly on a protected branch",
12629
- appliesTo: ["shell"],
12630
- mode: "instruct",
12631
- userCanOverride: true,
12632
- precondition: (facts) => facts.currentGitBranch !== null && PROTECTED_BRANCHES.has(facts.currentGitBranch),
12633
- probes: [
12634
- {
12635
- id: "creates_commit",
12636
- instructions: "The command in `agent_request` creates or amends a git commit, merge, rebase or cherry-pick in the " + "repository (including `git -C dir commit` and `git commit -a`).",
12637
- criteria: {
12638
- true: "A new commit is written to the current branch.",
12639
- false: "It only inspects history (log, show, diff, status) or mentions `commit` in a message or search."
12640
- }
12641
- }
12642
- ],
12643
- guidance: "You are on a protected branch. Create a feature branch before committing unless the user asked otherwise."
12644
- },
12645
- {
12646
- name: "secret-exposure",
12647
- title: "Tried to read or copy credentials",
12648
- appliesTo: ["shell", "read", "write"],
12649
- mode: "deny",
12650
- userCanOverride: true,
12651
- probes: [
12652
- {
12653
- id: "touches_secrets",
12654
- instructions: "The tool call in `agent_request` reads, prints, copies, or writes credential material: SSH private " + "keys (~/.ssh/id_*), authorized_keys, cloud credentials (~/.aws, ~/.config/gcloud, ~/.azure, " + "~/.kube/config), .env files containing real secret values, API tokens, password stores, keychains, " + "or browser cookie databases.",
12655
- criteria: {
12656
- true: "Actual secret values would be read, displayed, copied or written.",
12657
- false: "It only references the concept: source code that reads process.env, a variable name, an .env.example " + "template, a test fixture, documentation about credentials, or a grep for the word."
12658
- }
12659
- }
12660
- ],
12661
- guidance: "This exposes real credentials. Ask the user before reading or copying secret material."
12662
- },
12663
- {
12664
- name: "credential-exfiltration",
12665
- title: "Tried to send secrets or private files off the machine",
12666
- appliesTo: ["shell", "network"],
12667
- mode: "deny",
12668
- userCanOverride: false,
12669
- probes: [
12670
- {
12671
- id: "sends_out",
12672
- instructions: "The tool call in `agent_request` sends data to a network destination: an HTTP POST or PUT (curl -d, " + "curl -F, curl -T, wget --post-data), scp, sftp, rsync or rclone to a remote, nc or socat, an upload to " + "a paste site, bucket or webhook, or a DNS lookup carrying encoded data.",
12673
- criteria: {
12674
- true: "Data leaves this machine.",
12675
- false: "It only downloads, or only talks to localhost."
12676
- }
12677
- },
12678
- {
12679
- id: "sensitive_payload",
12680
- instructions: "The data being sent includes credentials, keys, tokens, environment variables, or the contents of files " + "from outside the project (see `facts.paths`).",
12681
- criteria: {
12682
- true: "Secrets or private files are in what is sent.",
12683
- false: "What is sent is ordinary project data the user would expect to share, like a test request body."
12684
- }
12685
- }
12686
- ],
12687
- guidance: "This sends secrets or private files to a remote destination, which the user cannot approve. Do not send them."
12688
- },
12689
- {
12690
- name: "remote-code-execution",
12691
- title: "Tried to run code downloaded from the internet",
12692
- appliesTo: ["shell"],
12693
- mode: "deny",
12694
- userCanOverride: true,
12695
- probes: [
12696
- {
12697
- id: "download_and_run",
12698
- instructions: "The command in `agent_request` downloads code or a script from the internet and executes it: " + '`curl … | sh`, `bash <(curl …)`, `wget … -O x.sh && bash x.sh`, `python3 -c "$(curl …)"`, piping into ' + "any interpreter (sh, bash, zsh, python, node, perl, ruby), or eval of a fetched string.",
12699
- criteria: {
12700
- true: "Fetched code is executed.",
12701
- false: "It only downloads without running, runs a local file, or merely searches for or quotes such a command " + "(for example grep over a README)."
12702
- }
12703
- }
12704
- ],
12705
- exempt: {
12706
- id: "official_installer",
12707
- instructions: "The URL being executed is the documented official installer of a widely used developer tool, served from " + "that tool's own domain (for example bun.sh, sh.rustup.rs, get.docker.com, deb.nodesource.com, " + "raw.githubusercontent.com/nvm-sh/nvm, astral.sh/uv)."
12708
- },
12709
- guidance: "This executes code fetched from the internet. Download it, show it to the user, then run it."
12710
- },
12711
- {
12712
- name: "privilege-escalation",
12713
- title: "Tried to run with elevated privileges",
12714
- appliesTo: ["shell"],
12715
- mode: "deny",
12716
- userCanOverride: true,
12717
- probes: [
12718
- {
12719
- id: "elevates",
12720
- instructions: "The command in `agent_request` runs something as root or another user: sudo, doas, su, pkexec, run0, " + "`sudo -i`, `sudo -s`, including when the binary is written as an absolute path or reached through a " + "variable or wrapper.",
12721
- criteria: {
12722
- true: "Privileges are elevated.",
12723
- false: "It runs as the current user, or only mentions sudo in text, a comment, or a search pattern."
12724
- }
12725
- }
12726
- ],
12727
- guidance: "This runs with elevated privileges. Ask the user to run it themselves."
12728
- },
12729
- {
12730
- name: "database-destruction",
12731
- title: "Tried to destroy or mass-modify database data",
12732
- appliesTo: ["shell"],
12733
- mode: "deny",
12734
- userCanOverride: true,
12735
- probes: [
12736
- {
12737
- id: "destructive_sql",
12738
- instructions: "The command in `agent_request` executes SQL or a database command that drops or truncates a table, " + "schema or database, or deletes or updates rows without a condition that narrows them to specific " + "records. A condition that is always true (`WHERE 1=1`, `WHERE true`, `WHERE id > 0`) does not narrow " + "anything. Also counts: `redis-cli FLUSHALL`, `dropdb`, `mongo … dropDatabase()`.",
12739
- criteria: {
12740
- true: "Many rows, a table, or a whole database would be removed or overwritten.",
12741
- false: "It reads, inserts, or changes a specific identified record, or runs a migration file by name."
12742
- }
12743
- },
12744
- {
12745
- id: "real_database",
12746
- instructions: "The database it targets holds real data rather than being a disposable test database.",
12747
- criteria: {
12748
- true: "A real or shared database, or one whose purpose cannot be told.",
12749
- false: "Clearly an in-memory, test, fixture or throwaway local database (sqlite :memory:, a test_ database)."
12750
- }
12751
- }
12752
- ],
12753
- guidance: "This destroys database data. Confirm the target and scope with the user first."
12754
- },
12755
- {
12756
- name: "read-outside-workspace",
12757
- title: "Read files outside the project",
12758
- appliesTo: ["shell", "read"],
12759
- mode: "instruct",
12760
- userCanOverride: true,
12761
- precondition: (facts) => facts.paths.some((p) => outsideProject(facts, p)),
12762
- probes: [
12763
- {
12764
- id: "reads_outside",
12765
- instructions: "The tool call in `agent_request` reads the contents of files that `facts.paths` marks as outside the " + "project, in the user's home directory (for example another repository, Documents, or dotfiles).",
12766
- criteria: {
12767
- true: "It reads file contents from outside the project.",
12768
- false: "It only changes directory, lists names, checks existence, or touches the agent's own tool caches."
12769
- }
12770
- }
12771
- ],
12772
- guidance: "This reads files outside the current project. Mention why before continuing."
12773
- },
12774
- {
12775
- name: "agent-config-tampering",
12776
- title: "Tried to change the agent's own safety configuration",
12777
- appliesTo: ["shell", "write"],
12778
- mode: "deny",
12779
- userCanOverride: false,
12780
- probes: [
12781
- {
12782
- id: "edits_agent_config",
12783
- instructions: "The tool call in `agent_request` modifies or deletes an AI agent's own configuration, hooks, " + "permissions or guardrails: .claude/settings.json, .claude/settings.local.json, ~/.claude/, .codex/, " + ".cursor/hooks.json, .gemini/, .factory/, failproofai configuration or policies, or permission and " + "safety sections of AGENTS.md or CLAUDE.md.",
12784
- criteria: {
12785
- true: "The agent's hooks, permissions or safety settings would change.",
12786
- false: "It only reads those files, or edits ordinary project documentation."
12787
- }
12788
- }
12789
- ],
12790
- guidance: "An agent must not change its own guardrails. Ask the user to make this change."
12791
- },
12792
- {
12793
- name: "system-modification",
12794
- title: "Tried to change the system outside the project",
12795
- appliesTo: ["shell"],
12796
- mode: "instruct",
12797
- userCanOverride: true,
12798
- probes: [
12799
- {
12800
- id: "modifies_system",
12801
- instructions: "The command in `agent_request` installs or removes software system-wide or changes machine " + "configuration: apt, dnf, pacman, brew install, `npm install -g`, `pip install` outside a virtualenv, " + "editing files under /etc, systemctl enable or disable, crontab, or changing shell startup files.",
12802
- criteria: {
12803
- true: "The machine changes outside the project directory.",
12804
- false: "It installs project dependencies locally (npm install, bun install, pip install in a venv)."
12805
- }
12806
- }
12807
- ],
12808
- guidance: "This changes the machine outside the project. Mention it to the user."
12809
- },
12810
- {
12811
- name: "env-secrets-dump",
12812
- title: "Tried to print environment secrets",
12813
- appliesTo: ["shell"],
12814
- mode: "instruct",
12815
- userCanOverride: true,
12816
- probes: [
12817
- {
12818
- id: "dumps_env",
12819
- instructions: "The command in `agent_request` prints environment variable VALUES that may be secret: `env`, " + "`printenv`, `set`, `export -p`, or `echo` of a variable whose name suggests a key, token, password " + "or secret.",
12820
- criteria: {
12821
- true: "Secret-looking environment values would be printed.",
12822
- false: "It echoes a literal string, prints a non-secret variable like PATH or HOME, creates a virtualenv " + "named env, or searches code for the word export."
12823
- }
12824
- }
12825
- ],
12826
- guidance: "This prints environment values that may be secrets into the transcript."
12827
- },
12828
- {
12829
- name: "external-destructive-action",
12830
- title: "Tried an irreversible action through an external tool",
12831
- appliesTo: ["other"],
12832
- mode: "deny",
12833
- userCanOverride: true,
12834
- probes: [
12835
- {
12836
- id: "irreversible_external",
12837
- instructions: "The tool call in `agent_request` (an MCP or integration tool, see `facts.tool_name`) performs an " + "irreversible or externally visible action: deleting records, repositories, files or accounts; " + "sending email, chat or social messages on the user's behalf; making payments or purchases; merging or " + "closing pull requests; changing permissions, access or billing; or writing to a production system.",
12838
- criteria: {
12839
- true: "Something outside this machine changes in a way that cannot be quietly undone.",
12840
- false: "It reads, searches, lists, fetches, or creates a draft that nobody else sees yet."
12841
- }
12842
- }
12843
- ],
12844
- guidance: "This takes an irreversible action in an external system. Confirm with the user first."
12845
- },
12846
- {
12847
- name: "external-data-egress",
12848
- title: "Sent private data to an external tool",
12849
- appliesTo: ["other"],
12850
- mode: "instruct",
12851
- userCanOverride: true,
12852
- probes: [
12853
- {
12854
- id: "egresses_private",
12855
- instructions: "The arguments in `agent_request` send private data to an external service: source code, file " + "contents, credentials, customer data, or personal information.",
12856
- criteria: {
12857
- true: "Private data is being shared with a third party.",
12858
- false: "Only a query, identifier or public information is sent."
12859
- }
12860
- }
12861
- ],
12862
- guidance: "This shares private data with an external service. Mention what is being sent."
12863
- }
12864
- ];
12865
12549
  SCOPE_PROBE = {
12866
12550
  id: "scope",
12867
12551
  instructions: "Everything `agent_request` would affect — every branch, file, directory, table, record, environment, " + "account or recipient — is covered by what the human asked for in `user_said`. It reaches no further: not " + "all branches when they named one, not production when they said local or staging, not a parent directory " + 'when they named one folder, not every record when they named some. References such as "it", "this PR" ' + 'or "that volume" mean whatever the conversation is about. Details the agent filled in to carry the ' + "request out (a commit title, a flag the operation needs) do not make it broader.",
@@ -16004,14 +15688,13 @@ function toSemanticPolicy(entry, pack) {
16004
15688
  function semanticPoliciesFromPacks(packs) {
16005
15689
  const declared = packs.filter((p) => packSemantic(p).length > 0);
16006
15690
  if (declared.length === 0)
16007
- return { policies: SEMANTIC_POLICIES, fromPack: false, errors: [] };
16008
- const replace = replacesBuiltinChecks(declared);
15691
+ return { policies: [], fromPack: false, errors: [] };
16009
15692
  const ordered = [...declared.filter((p) => isFirstPartyPack(p)), ...declared.filter((p) => !isFirstPartyPack(p))];
16010
- const policies = replace ? [] : [...SEMANTIC_POLICIES];
15693
+ const policies = [];
16011
15694
  const errors = [];
16012
- const seen = new Set(policies.map((p) => p.name));
15695
+ const seen = new Set;
16013
15696
  const contested = contestedSemanticNames(declared);
16014
- let spent = replace ? 0 : BUILTIN_QUESTION_CHARS;
15697
+ let spent = 0;
16015
15698
  for (const pack of ordered) {
16016
15699
  for (const entry of packSemantic(pack)) {
16017
15700
  if (isReservedClaim(pack, entry.name)) {
@@ -16044,9 +15727,7 @@ function semanticPoliciesFromPacks(packs) {
16044
15727
  spent += cost;
16045
15728
  }
16046
15729
  }
16047
- if (policies.length === (replace ? 0 : SEMANTIC_POLICIES.length))
16048
- return { policies: SEMANTIC_POLICIES, fromPack: false, errors };
16049
- return { policies, fromPack: true, errors };
15730
+ return { policies, fromPack: policies.length > 0, errors };
16050
15731
  }
16051
15732
  function resolveSemanticPolicies(cli) {
16052
15733
  let packs = [];
@@ -16056,7 +15737,7 @@ function resolveSemanticPolicies(cli) {
16056
15737
  packs = read.packs;
16057
15738
  manifestErrors = read.warnings ?? [];
16058
15739
  } catch {
16059
- return SEMANTIC_POLICIES;
15740
+ return [];
16060
15741
  }
16061
15742
  const resolved = semanticPoliciesFromPacks(jevPacks(packs, cli));
16062
15743
  for (const message of [...manifestErrors, ...resolved.errors]) {
@@ -16067,7 +15748,7 @@ function resolveSemanticPolicies(cli) {
16067
15748
  }
16068
15749
  return resolved.policies;
16069
15750
  }
16070
- var GLOBAL_QUESTION_CHARS, MAX_PACK_QUESTION_CHARS, BUILTIN_QUESTION_CHARS, warned;
15751
+ var GLOBAL_QUESTION_CHARS, MAX_PACK_QUESTION_CHARS, warned;
16071
15752
  var init_pack_policies = __esm(() => {
16072
15753
  init_effective_reviewers();
16073
15754
  init_hook_logger();
@@ -16079,7 +15760,6 @@ var init_pack_policies = __esm(() => {
16079
15760
  init_precondition_names();
16080
15761
  GLOBAL_QUESTION_CHARS = Math.max(JSON.stringify({ [INJECTION_PROBE.id]: noulOf(INJECTION_PROBE), [SCOPE_PROBE.id]: noulOf(SCOPE_PROBE) }).length, JSON.stringify(Object.fromEntries([INJECTION_PROBE, ...TASK_PROBES].map((p) => [p.id, noulOf(p)]))).length);
16081
15762
  MAX_PACK_QUESTION_CHARS = MAX_REQUEST_CHARS - MAX_STATE_CHARS - GLOBAL_QUESTION_CHARS;
16082
- BUILTIN_QUESTION_CHARS = SEMANTIC_POLICIES.reduce((n, p) => n + questionChars(p), 0);
16083
15763
  warned = new Set;
16084
15764
  });
16085
15765
 
@@ -16584,7 +16264,7 @@ function authorityOf(p) {
16584
16264
  return { authority, reviewedBy };
16585
16265
  }
16586
16266
  function resolveMode(cfg) {
16587
- return cfg.mode === "shadow" || cfg.mode === "enforce" ? cfg.mode : DEFAULT_JEV_MODE;
16267
+ return cfg.mode === "observe" || cfg.mode === "enforce" ? cfg.mode : DEFAULT_JEV_MODE;
16588
16268
  }
16589
16269
  function resolveTimeout(cfg) {
16590
16270
  const t = cfg.timeoutMs;
@@ -16702,7 +16382,7 @@ function startJevReview(cfg, call) {
16702
16382
  sessionId: call.sessionId,
16703
16383
  cli: call.cli,
16704
16384
  eventType: call.eventType,
16705
- applied: abandoned || review.kind !== "answered" ? "legacy-fallback" : mode === "shadow" ? "shadow" : "two-tier"
16385
+ applied: abandoned || review.kind !== "answered" ? "legacy-fallback" : mode === "observe" ? "observe" : "two-tier"
16706
16386
  });
16707
16387
  appendVerdictLog(hit ? { ...row, cached: true } : row);
16708
16388
  }
@@ -16953,6 +16633,8 @@ async function startTwoTier(canonicalEventType, parsed, session, cli, opts, acti
16953
16633
  return null;
16954
16634
  if (jevForcedOff(opts) || activePause)
16955
16635
  return null;
16636
+ if (!jevChecksInstalled())
16637
+ return null;
16956
16638
  const loaded = await readJevConfig();
16957
16639
  if (!loaded)
16958
16640
  return null;
@@ -16971,7 +16653,7 @@ async function startTwoTier(canonicalEventType, parsed, session, cli, opts, acti
16971
16653
  } catch (err) {
16972
16654
  hookLogInfo(`Jev review could not start (${err instanceof Error ? err.message : String(err)})`);
16973
16655
  return {
16974
- mode: cfg.mode === "shadow" || cfg.mode === "enforce" ? cfg.mode : loaded.defaultMode,
16656
+ mode: cfg.mode === "observe" || cfg.mode === "enforce" ? cfg.mode : loaded.defaultMode,
16975
16657
  review: Promise.resolve({ kind: "fallback", reason: "error", latencyMs: null, model: null }),
16976
16658
  abort: () => {},
16977
16659
  authorityOf: () => ({ authority: "hard", reviewedBy: [] })
@@ -16995,6 +16677,8 @@ async function captureJevIntent(canonicalEventType, decision, parsed, session, c
16995
16677
  if (canonicalEventType !== "UserPromptSubmit" || jevForcedOff(opts))
16996
16678
  return;
16997
16679
  try {
16680
+ if (!jevChecksInstalled())
16681
+ return;
16998
16682
  if (!await readJevConfig())
16999
16683
  return;
17000
16684
  if (decision === "deny") {
@@ -17075,7 +16759,7 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
17075
16759
  config = readMergedHooksConfig(session.cwd);
17076
16760
  clearPolicies(cli);
17077
16761
  activePause = readActivePause(session.sessionId);
17078
- const packsInstalledHere = hasInstalledPacks();
16762
+ const packsInstalledHere = hasInstalledRegexPacks();
17079
16763
  const legacyNames = activePause || packsInstalledHere ? [] : config.enabledPolicies;
17080
16764
  registerBuiltinPolicies(activePause ? [] : legacyNames);
17081
16765
  if (legacyNames.length > 0) {
@@ -17149,14 +16833,14 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
17149
16833
  const observeOnly = cloudManaged?.effect === "observe" || pack?.effect === "observe";
17150
16834
  const fn = async (ctx) => {
17151
16835
  if (observeOnly) {
17152
- const shadow = await runObserved(hook, ctx, hookName, eventType, cli);
17153
- if (shadow.decision !== "allow") {
16836
+ const observed = await runObserved(hook, ctx, hookName, eventType, cli);
16837
+ if (observed.decision !== "allow") {
17154
16838
  const observer = cloudManaged ?? pack;
17155
16839
  observedResults.push({
17156
16840
  policyId: observer.id,
17157
16841
  version: observer.version,
17158
- decision: shadow.decision,
17159
- reason: shadow.reason ?? null
16842
+ decision: observed.decision,
16843
+ reason: observed.reason ?? null
17160
16844
  });
17161
16845
  }
17162
16846
  return { decision: "allow" };
@@ -17246,13 +16930,13 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
17246
16930
  ...twoTier,
17247
16931
  releaseRegistry: opts?.releaseRegistry
17248
16932
  }) : await evaluatePolicies(canonicalEventType, parsed, session, config);
17249
- const shadowVerdict = result.twoTier?.shadowVerdict;
17250
- if (shadowVerdict) {
16933
+ const observeVerdict = result.twoTier?.observeVerdict;
16934
+ if (observeVerdict) {
17251
16935
  observedResults.push({
17252
- policyId: shadowVerdict.policyName,
17253
- version: shadowVerdict.version,
17254
- decision: shadowVerdict.decision,
17255
- reason: shadowVerdict.reason
16936
+ policyId: observeVerdict.policyName,
16937
+ version: observeVerdict.version,
16938
+ decision: observeVerdict.decision,
16939
+ reason: observeVerdict.reason
17256
16940
  });
17257
16941
  }
17258
16942
  const durationMs = Math.round(performance.now() - startTime);