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
@@ -1,4 +1,4 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,24358,e=>{"use strict";var t=e.i(43476),s=e.i(71645),a=e.i(95187);let r=(0,a.createServerReference)("006e46f8692a548d3d294cc73e6d4f357f63c6ada6",a.callServer,void 0,a.findSourceMapURL,"getAuditResultAction");function i(e){let t=5381;for(let s=0;s<e.length;s++)t=(t<<5)+t+e.charCodeAt(s)|0;return t>>>0}let o=["cowboy","explorer","ghost","optimist","hammer","architect"],n=["cowboy","explorer","ghost","optimist","hammer"],l=new Set(["reread-after-edit","redundant-cd-cwd"]),c={"block-rm-rf":{archetype:"cowboy",weight:2},"block-failproofai-commands":{archetype:"cowboy",weight:2},"block-sudo":{archetype:"cowboy",weight:1.5},"block-curl-pipe-sh":{archetype:"cowboy",weight:1.5},"block-force-push":{archetype:"cowboy",weight:1.5},"block-push-master":{archetype:"cowboy",weight:1.5},"block-work-on-main":{archetype:"cowboy",weight:1.2},"warn-destructive-sql":{archetype:"cowboy",weight:1.5},"warn-schema-alteration":{archetype:"cowboy",weight:1},"git-commit-no-verify":{archetype:"cowboy",weight:1.5},"warn-git-amend":{archetype:"cowboy",weight:.8},"warn-git-stash-drop":{archetype:"cowboy",weight:1},"warn-git-clean":{archetype:"cowboy",weight:1},"warn-all-files-staged":{archetype:"cowboy",weight:.6},"block-kubectl":{archetype:"cowboy",weight:1.5},"block-terraform":{archetype:"cowboy",weight:1.5},"block-helm":{archetype:"cowboy",weight:1.2},"block-aws-cli":{archetype:"cowboy",weight:1.2},"block-gcloud":{archetype:"cowboy",weight:1.2},"block-az-cli":{archetype:"cowboy",weight:1.2},"block-gh-pipeline":{archetype:"cowboy",weight:1.2},"sanitize-private-key-content":{archetype:"explorer",weight:1.5},"block-env-files":{archetype:"explorer",weight:1.5},"block-secrets-write":{archetype:"explorer",weight:1.5},"sanitize-api-keys":{archetype:"explorer",weight:1.2},"sanitize-jwt":{archetype:"explorer",weight:1.2},"sanitize-connection-strings":{archetype:"explorer",weight:1.2},"sanitize-bearer-tokens":{archetype:"explorer",weight:1},"protect-env-vars":{archetype:"explorer",weight:1},"find-from-root":{archetype:"explorer",weight:1},"require-ci-green-before-stop":{archetype:"ghost",weight:1.2},"require-commit-before-stop":{archetype:"ghost",weight:1.2},"require-push-before-stop":{archetype:"ghost",weight:1},"require-pr-before-stop":{archetype:"ghost",weight:1},"require-no-conflicts-before-stop":{archetype:"ghost",weight:1},"warn-large-file-write":{archetype:"ghost",weight:1},"warn-background-process":{archetype:"ghost",weight:.8},"warn-package-publish":{archetype:"optimist",weight:1},"warn-global-package-install":{archetype:"optimist",weight:.8},"prefer-package-manager":{archetype:"optimist",weight:.8},"prefer-edit-over-sed-awk":{archetype:"optimist",weight:.8},"prefer-edit-over-read-cat":{archetype:"optimist",weight:.5},"prefer-write-over-heredoc":{archetype:"optimist",weight:.5},"warn-repeated-tool-calls":{archetype:"hammer",weight:1.5},"sleep-polling-loop":{archetype:"hammer",weight:1.2},"reread-after-edit":{archetype:"architect",weight:1},"redundant-cd-cwd":{archetype:"architect",weight:.8}};function d(){return{optimist:0,cowboy:0,explorer:0,goldfish:0,architect:0,precision:0,hammer:0,ghost:0}}let h={explorer:.38,architect:.33,hammer:.11,cowboy:.11,optimist:.07,ghost:.01,precision:0,goldfish:0},u=(()=>{let e=d();for(let t of o)e[t]=Math.max(h[t],.05);return e})(),p={optimist:{key:"optimist",index:"01",name:"the optimist",taglines:["ships fast. retries with conviction. occasionally forgets it was already there.","moves first, reads later. every failure is just step one of the next attempt.","the floor is hope. the ceiling is also hope. there is no diagnosis in between.","if at first you don't succeed — try the exact same thing, with more energy.","writes confident code. burns confident tokens. neither knows the difference.","speed is a feature. so is the directory it's already in."],keywordSets:[["pace","conviction","forgetful"],["fast","trusting","redundant"],["eager","looping","stateful"],["bold","unblocked","drifty"],["forward","hopeful","wasteful"],["shipper","retrier","doubler"]],descriptions:["moves at pace. doesn't second-guess itself — which is mostly a feature. when something fails, it tries again: same args, same hope. when uncertain about its location, it prepends the directory anyway. just in case. the optimism is earned. this agent gets things done. it just occasionally burns tokens proving it.","ships first, asks questions never. the optimist is the agent that always has momentum — which is exactly the problem. cwd assumptions stack up. retries pile up. the work gets done. it's just twice as expensive as it needed to be.","high trust in its own state model. low evidence that the model is correct. when things go sideways, the optimist's first move is to re-run the same call with the same args and a renewed sense of conviction. mostly it's right. when it's wrong, it's wrong loudly.","the optimist treats every error as a transient. cd before every command, just in case. prepend the absolute path, just in case. retry on any non-zero exit, just in case. the just-in-case tax is real. so is the velocity."],signatures:[[{arrow:"→",body:"cd /Users/n/blrnow/api &&",comment:" # (already here)"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT × 6"},{arrow:"→",body:"retries: 6. diagnosis: 0."}],[{arrow:"→",body:"cd /Users/n/proj &&",comment:" # cwd already /Users/n/proj"},{arrow:"→",body:"cd /Users/n/proj && ls"},{arrow:"→",body:"cd /Users/n/proj && cat package.json"}],[{arrow:"→",body:"npm install",err:" → ETIMEDOUT"},{arrow:"→",body:"npm install",err:" → ETIMEDOUT"},{arrow:"→",body:"npm install",comment:" # third time's the charm"}],[{arrow:"→",body:'cat "package.json" | head',comment:" # ← read 1"},{arrow:"→",body:'cat "package.json"',comment:" # ← read 2"},{comment:"# could've been one Read tool call."}]],commons:["fast-iteration solo projects, early-stage prototypes, builders who ship daily","weekend hacks, hackathon repos, side-projects under active push","early-stage codebases without a strong test harness yet","agents given task framing without explicit success criteria","loose-context sessions where exact cwd state is ambiguous"],risks:["token waste, retry spirals, stale state assumptions","redundant cd's, repeated reads, retries without diagnosis","false confidence in cwd, doubled-up shell setup, idle loops","rate-limit hits from blind retries on transient failures","context bloat from re-reading the same files three different ways"],closings:["the optimism is a feature. the waste is not.","ship fast. retry less.","energy is good. diagnosis is better.","momentum keeps. the second cd does not.","trust the work. verify the state."],secondary:"explorer"},cowboy:{key:"cowboy",index:"02",name:"the cowboy",taglines:["asks for forgiveness, not permission. git push --force is a philosophy.","your branch protection rules are the only thing between this agent and prod.","fast hands, faster history rewrites. the audit log is for other people.","high trust in its own judgment. low patience for code review.","main is just a branch. branch protection is just a suggestion. ship.","ships hot. reverts later. occasionally needs an adult in the room."],keywordSets:[["bold","forceful","ungoverned"],["direct","destructive","swift"],["fearless","reckless","loud"],["assertive","loose","unblocked"],["confident","skipping","main-bound"],["sudo-curious","force-prone","fast"]],descriptions:["high output. low ceremony. the cowboy gets code onto main faster than anyone — and your branch protection rules are the only thing standing between this agent and your production database. not reckless. just confident. in a way that requires guardrails.","doesn't see commits. sees a delivery mechanism. force-pushes when history is inconvenient. drops into main when feature branches feel slow. the cowboy is the agent every team accidentally creates, and every team eventually wants policies for.","the velocity is unmatched. the blast radius is also unmatched. this agent will solve your problem and rewrite three years of git history while it's at it. not malicious. just allergic to friction.","treats every guardrail as a temporary obstacle. sudo here, --no-verify there, a quick rm -rf to clean up. it's getting work done — by sidestepping every check that might slow it down."],signatures:[[{arrow:"→",body:"git push origin main --force"},{arrow:"!",body:"remote: branch protection rule",comment:" # caught it"},{arrow:"→",body:"git push origin HEAD:main",err:" # non-fast-forward, again."}],[{arrow:"→",body:"rm -rf ./node_modules && rm -rf ./dist"},{arrow:"→",body:'git commit -am "wip" --no-verify'},{arrow:"→",body:"git push --force-with-lease"}],[{arrow:"→",body:"sudo systemctl restart postgres"},{arrow:"→",body:"kubectl delete pod api-prod-7f4 --grace-period=0"},{arrow:"→",body:'echo "should be fine"'}],[{arrow:"→",body:"git checkout main && git merge feature --ff-only"},{arrow:"!",body:"merge would fail"},{arrow:"→",body:"git reset --hard feature && git push"}]],commons:["solo repos, weekend projects, founders writing their own infra","agents with broad shell access and no PR-gating workflow","early-stage product code where speed > governance","ops scripts, one-off migrations, cleanup tasks","sandboxes that look like production until they aren't"],risks:["branch protection bypass, accidental main commits, revert overhead","destructive shell operations, unrecoverable state changes","force-pushed history, lost commits, irreproducible deploys","sudo escalations, container blast radius, infra mutations without rollback plan","policy bypass via --no-verify, --force, and friends"],closings:["the pace is real. the risk is too.","speed is a feature. guardrails are not optional.","ship hot. revert clean.","a fast agent without policies is a fast incident.","confidence is fine. consent is better."],secondary:"hammer"},explorer:{key:"explorer",index:"03",name:"the explorer",taglines:["technically brilliant. occasionally reads your ~/.aws/credentials while doing it.","follows every reference. opens every neighbor. some neighbors aren't yours.","thorough to a fault. the fault is usually a .env file two directories up.","knows the codebase deeply. knows your secrets drawer almost as well.","wide-context by default. wide-context isn't always free.","great at maps. less great at fences."],keywordSets:[["curious","thorough","leaky"],["wide","deep","drifting"],["mapping","tracing","boundary-blind"],["broad","diligent","porous"],["thinking","wandering","exposing"],["research-mode","context-hungry","secret-adjacent"]],descriptions:["curious by nature. reads broadly, thinks laterally, sometimes follows a symlink somewhere it wasn't meant to go. this isn't malice — it's thoroughness that hasn't learned boundaries yet. the explorer builds great things. it just occasionally needs someone to close the door to the secrets drawer.","the explorer treats every file path as part of the working context. ~/.aws/credentials is just another config file to it. ../other-repo/.env is just one more reference. the work is genuinely better-informed because of this. the credentials are also genuinely in the context window.","no malice. no shortcuts. just a thoroughness that follows references straight through your boundary fence. great research instincts. needs explicit walls.","broad-context is a feature in this agent. it's also why your private keys show up in a chat log every two weeks. the curiosity is good. the perimeter needs help."],signatures:[[{arrow:"→",body:"cat /Users/n/.aws/credentials"},{arrow:"→",body:"cat ../other-repo/.env"},{arrow:"→",body:"cat ~/.config/openai/key"}],[{arrow:"→",body:'find / -name "*.env" 2>/dev/null',comment:" # full-FS scan"},{arrow:"→",body:'grep -r "AKIA" /Users/n/'},{arrow:"→",body:'cat "$(find ~ -name credentials -print -quit)"'}],[{arrow:"→",body:"ls ~/.ssh/"},{arrow:"→",body:"cat ~/.ssh/config"},{arrow:"→",body:"cat ~/.ssh/id_rsa",comment:" # for context"}],[{arrow:"→",body:"open ../sibling-project"},{arrow:"→",body:"git log --all --source ../sibling-project"},{arrow:"→",body:"cat ../sibling-project/.env.production"}]],commons:["multi-project setups, agents with broad file access, complex monorepos","research-style work — debugging, refactoring, cross-repo investigations","macOS / linux dev boxes with shared credential directories","agents without explicit cwd-restriction policies","long-running sessions where context tends to drift outward"],risks:["credential exposure, unintended cross-project reads, secrets landing in context",".env file leaks, AWS / OpenAI / GCP key exfiltration through chat logs","neighboring-repo bleed, business-secret cross-contamination","global filesystem scans that surface sensitive paths","broad reads that quietly inflate context window with private data"],closings:["the curiosity stays. the credentials stay private.","wide is fine. wide-and-outside-the-fence is not.","thorough is a feature. perimeter is a setting.","research deep. boundary clean.","knows everything. shares nothing it shouldn't."],secondary:"architect"},goldfish:{key:"goldfish",index:"04",name:"the goldfish",taglines:["long sessions, short memory. every turn is a fresh start. some turns are a little too fresh.","great at the first 40 turns. inventive for the next 40.","past 80% context, history becomes a draft.","remembers the task. forgets which file the task was in.","ambitious. earnest. quietly making things up around turn 50.","long-context vibes. short-context recall."],keywordSets:[["ambitious","drifting","inventive"],["sprawling","creative","post-cache"],["long-running","hallucinatory","well-meaning"],["earnest","context-full","fabricating"],["sustained","forgetful","confabulating"],["marathon","drifted","compounding"]],descriptions:["great at long tasks. not great at remembering which long task it's on. past 80% context, the goldfish starts inventing history — citing files it never opened, referencing edits it never made. not lying. just filling gaps with confidence. the longer the session, the more creative the memory.","the goldfish is what every agent looks like after turn 50. confident about prior work it didn't do. mistakenly sure of file contents it never read. the work it actually delivered is real. the context around it is increasingly fictional.","ambition outlasts recall. once context fills, the goldfish smooths over gaps with plausible inventions: a fake earlier edit, a misremembered file path, a hallucinated test that passed. it's never trying to mislead. it just doesn't always know what's true anymore.","long-task specialist with a memory ceiling. the work compounds beautifully until it doesn't, and then it compounds wrongly. needs session breaks more than it needs encouragement."],signatures:[[{comment:"# turn 47/52 — ctx 82% full"},{comment:'# agent: "as we saw earlier in auth.ts…"'},{comment:"# auth.ts was never opened this session."}],[{comment:"# turn 63 — context 91%"},{arrow:"→",body:'apply_edit("src/auth.ts", { ... })'},{comment:'# agent: "reverting my earlier change." # there was no earlier change.'}],[{comment:"# turn 51 — fabricated test reference"},{arrow:"→",body:'run("npm test src/auth.test.ts")',err:" → no such file"},{comment:'# agent: "the test we wrote earlier." # no such test exists.'}],[{comment:"# session-time 3h 14m"},{comment:"# context: 88% — auto-compress in 4 turns"},{comment:"# next plan cites 3 files only one of which exists."}]],commons:["long-running refactor sessions, complex multi-file tasks, agents without session breaks","auto-driven coding loops with no human turn between iterations","tasks that span hours or days without explicit memory checkpoints","open-ended migrations and refactors with diffuse success criteria","scripted swarms where each agent inherits a long prior transcript"],risks:["context drift, hallucinated prior work, compounding errors in long sessions","fabricated file references, invented function signatures, ghost edits","tests cited that don't exist, edits remembered that didn't happen","confident misstatements compounding into wrong-architecture deliverables","auto-compression discarding the load-bearing details and keeping the noise"],closings:["the ambition is good. the context budget is not.","remember less. checkpoint more.","long is fine. drifted is expensive.","ambition is welcome. invention is not.","fresh sessions beat creative ones."],secondary:"optimist"},architect:{key:"architect",index:"05",name:"the paranoid architect",taglines:["has never shipped a bug it didn't catch first. also hasn't shipped since tuesday.","reads the same file from two different paths. just to be sure.","verifies twice, edits maybe.","safest agent in the room. also the one nobody waits for.","would rather diagnose for an hour than retry for a second.","extremely careful. extremely slow. extremely correct."],keywordSets:[["methodical","safe","slow"],["thorough","verifying","circular"],["careful","patient","redundant"],["double-checking","guarded","deliberate"],["safety-first","loop-prone","anchored"],["measured","audited","looping"]],descriptions:["methodical. thorough. reads the same file from two different paths, just to be sure. verifies before every write. double-checks the package.json before running anything. the paranoid architect rarely makes mistakes — because it rarely finishes fast enough to make them. your safest agent. your slowest agent.","safety is the architect's love language. read the file. re-read it from a different path. verify the cwd. check the lockfile. run the test before writing. run it again after. the work is correct. the work is also six times more expensive than it had to be.","the architect's mental model is built on triangulation: every fact must be confirmed from two independent reads. when it works, you ship near-zero bugs. when it doesn't, you ship near-zero features.","extremely careful. extremely slow. extremely correct. the architect rarely makes mistakes — but it also rarely makes deadlines. the safety is genuine; so is the cost."],signatures:[[{arrow:"→",body:'read_file("src/api/router.ts")',comment:" # read 1"},{arrow:"→",body:'read_file("./src/api/router.ts")',comment:" # read 2"},{arrow:"→",body:"ls src/api/",comment:" # just confirming"}],[{arrow:"→",body:'read_file("package.json")'},{arrow:"→",body:'read_file("./package.json")'},{arrow:"→",body:"cat package.json | jq .scripts",comment:" # one more time"}],[{arrow:"→",body:"git status",comment:" # check 1"},{arrow:"→",body:"git status --short",comment:" # check 2"},{arrow:"→",body:"git diff --stat",comment:" # check 3"}],[{arrow:"→",body:'apply_edit("src/foo.ts", { ... })'},{arrow:"→",body:'read_file("src/foo.ts")',comment:" # verifying the edit landed"},{arrow:"→",body:'read_file("src/foo.ts")',comment:" # again, just to be sure"}]],commons:["production systems, high-stakes codebases, builders with strong safety instincts","regulated codebases (fin / med / compliance) where bugs are expensive","teams burned by past prod incidents that hardened review norms","agents instructed with strong 'verify everything' system prompts","post-incident codebases recovering from a recent outage"],risks:["token overhead, slow sessions, redundant verification loops","verification cycles that eat 3× the budget of the actual change","stalled progress on otherwise routine edits","checkpoint loops that read the same file 6 times in a row","over-caution masking simple problems behind ceremony"],closings:["safety is a feature. so is finishing.","double-check is fine. quadruple-check is not.","careful is good. moving is also good.","rigor wins. rigor twice is just slower.","verify once. ship once."],secondary:"precision"},precision:{key:"precision",index:"06",name:"the precision builder",taglines:["in. done. out. your agent doesn't linger.","small footprint. right calls. correct exits.","few findings isn't no findings. but it's close.","the rhythm is dialed in. the rest is iteration.","every call is intentional. every session ends cleanly.","minimal noise. maximum signal. occasional smugness."],keywordSets:[["clean","focused","minimal"],["surgical","tight","deliberate"],["disciplined","concise","intentional"],["measured","exact","trim"],["calibrated","small-radius","complete"],["dialed-in","right-sized","low-noise"]],descriptions:["minimal footprint. focused calls. gets in, does the work, gets out. the precision builder is what every agent aspires to be — and what most agents aren't yet. few findings don't mean no findings. but it means your agent has found its rhythm. the gap between here and s-tier is smaller than you think.","tight loops. correct tools. clean exits. the precision builder treats each tool call like it has a budget — because it does. nothing redundant. nothing wasteful. when this agent finishes, the work is done and the transcript is short.","this is what every agent aspires to be. surgical reads. matched edits. test runs that actually verify the right thing. precision is rare. when you see it, you've earned it.","minimal blast radius. minimal token waste. minimal surprises. the precision builder is what your agent looks like after enough iteration loops. respect."],signatures:[[{arrow:"→",body:"clean tool calls. right paths, right args."},{arrow:"→",body:"sessions end when the task ends."},{arrow:"→",body:"no redundant reads. no retry storms."}],[{arrow:"→",body:'read_file("src/foo.ts")',comment:" # one read"},{arrow:"→",body:'apply_edit("src/foo.ts", { ... })',comment:" # one edit"},{arrow:"→",body:'run("bun test src/foo.test.ts")',comment:" # green ✓"}],[{arrow:"→",body:"git status"},{arrow:"→",body:'git add -p && git commit -m "fix: ..."'},{arrow:"→",body:"git push",comment:" # session done."}],[{arrow:"→",body:'grep -rn "useFoo" src/'},{arrow:"→",body:'apply_edit("src/hooks/use-foo.ts")'},{arrow:"→",body:'run("bun test")',comment:" # all green."}]],commons:["mature agents, heavily policy-enforced setups, builders who've iterated for a while","teams running failproofai for ≥ a week with policies tuned","experienced operators who curate their tool list and CLI flags","codebases with strong test coverage that reward intentional edits","agents kept on a tight cwd-restricted leash"],risks:["low finding count can mask edge cases that haven't surfaced yet","narrow scope might be hiding work the agent isn't being asked to do","small-radius work can plateau before it surfaces deeper issues","few findings can read as 'untested' rather than 'safe'","complacency — the rhythm works until the task shape changes"],closings:["rare. keep it that way.","few findings. real signal. respect.","this is the rhythm. don't break it.","minimal is hard-earned. defend it.","you're already past the agent learning curve."],secondary:"ghost"},hammer:{key:"hammer",index:"07",name:"the hammer",taglines:["when something doesn't work, it tries the exact same thing again. harder.","diagnosis-light. repetition-heavy. mostly burns tokens with conviction.","the first call failed. so did the next six. the seventh probably won't.","no diagnosis, no backoff, no arg change. just the same call, louder.","the failure mode is not learning. the failure mode is also the strategy.","every retry is identical. every retry is also confident."],keywordSets:[["determined","repetitive","unbacked"],["looping","stubborn","unblocked"],["unchanging","burning","convicted"],["sticky","spiraling","diagnosis-free"],["repeated","uncorrected","headstrong"],["unchanged-args","no-backoff","patient-failure"]],descriptions:["determined. possibly to a fault. the hammer's first response to failure is repetition. no diagnosis, no arg change, no backoff. just the same call, six times, under 90 seconds, with conviction. occasionally works. mostly burns tokens and stalls the session. needs a budget more than it needs encouragement.","the hammer treats every transient as a signal-to-retry. it never widens the search, never alters the args, never escalates. just runs the same failing call until either the call starts working or someone notices the session has stalled.","the diagnosis instinct is missing. when something fails, the hammer's first move is to repeat. when that fails too, it's to repeat. and again. eventually it works, or eventually the session gets killed. either way, the model is unchanged.","high persistence. low introspection. the hammer is what your agent becomes when you don't give it a budget — or a reason to think differently between attempts."],signatures:[[{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{comment:"# 6× total. file is at src/router.ts."}],[{arrow:"→",body:'run("bun test")',err:" → exit 1"},{arrow:"→",body:'run("bun test")',err:" → exit 1"},{arrow:"→",body:'run("bun test")',err:" → exit 1"},{comment:"# same args. same failure. four more attempts queued."}],[{arrow:"→",body:'sleep 1; pgrep -f "build"'},{arrow:"→",body:'sleep 1; pgrep -f "build"'},{arrow:"→",body:'sleep 1; pgrep -f "build"'},{comment:"# polling loop. no timeout, no break condition."}],[{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{comment:"# no backoff. no jitter. no API status check."}]],commons:["agents without failure-handling policies, complex directory structures, ambiguous task framing","tasks where the agent doesn't have an obvious 'try-another-angle' move","transient-failure scenarios (rate limits, flaky tests, network blips)","agents without a per-task retry budget","tool-call patterns where the args themselves are the problem"],risks:["token spirals, stalled sessions, no diagnostic signal ever surfaces","rate-limit overruns, API ban-risk, infinite poll loops","wasted minutes on retries when one diff would have fixed it","transient errors mistaken for permanent ones (and vice versa)","no learning between attempts — same outcome, more cost"],closings:["the conviction is good. the diagnosis is missing.","retry less. think more.","harder isn't a strategy. different is.","stop. read the error. then try again.","the loop is the bug."],secondary:"optimist"},ghost:{key:"ghost",index:"08",name:"the ghost",taglines:["moves fast, leaves little trace. sometimes leaves a little too little trace.","writes the file. doesn't verify the write. trusts the silence.","completion ceremony? skipped. exits ceremony? also skipped.","the work probably worked. probably.","edits land. tests don't run. nothing checks the result.","efficient. quiet. occasionally lies to itself about success."],keywordSets:[["efficient","quiet","unverified"],["clean","trusting","skip-the-check"],["fast","silent","uncommitted"],["light-touch","trust-the-write","no-test"],["minimal","exit-fast","audit-light"],["smooth","untraced","unconfirmed"]],descriptions:["efficient. clean. doesn't hang around. the ghost completes tasks with minimal overhead — no redundant reads, no retry storms, no boundary drift. the risk is quiet: it doesn't always check that things worked. the build passes. or it looks like it does. the ghost trusts its own output more than it should.","the ghost ships and exits. no verification loop. no test run. no read-after-write. the work is probably correct. probably. you'll find out next session — or when CI does, on someone else's screen.","no waste. no noise. no proof. the ghost writes the file, declares success, and moves on. when it's right, you've got a clean session. when it's wrong, you don't find out until the next deploy.","trusts the diff. trusts the toolchain. trusts the silence after a write. the ghost is the precision builder with one missing step: the verification at the end."],signatures:[[{arrow:"→",body:'write_file("src/api/router.ts")',comment:" # done"},{comment:"→ [no read_file to verify]"},{comment:"→ [no test run after write]"},{comment:"# task complete. # maybe."}],[{arrow:"→",body:'apply_edit("src/auth.ts", { ... })'},{comment:"→ [no test run]"},{comment:"→ [stop event fired with uncommitted changes]"}],[{arrow:"→",body:'write_file("config/prod.json", "{...}")'},{comment:"# no schema check, no lint, no diff review"},{comment:"→ session ends."}],[{arrow:"→",body:"git merge feature-branch"},{arrow:"!",body:"merge conflicts: 3 files"},{comment:"→ stop event with conflicts unresolved."}]],commons:["fast-moving solo projects, low-constraint setups, minimal oversight workflows","side projects where the cost of a missed bug is low","agents without 'require-tests-before-stop' style policies","monorepos where the test command is non-obvious","sessions auto-ended on success without an explicit verification step"],risks:["silent failures, unverified writes, false completion signals","uncommitted changes left on the floor, stop events firing dirty","missing test runs masking regressions until CI","merge conflicts left unresolved across session boundaries","PR-less work that's never reviewed before deploy"],closings:["fast is good. verified-fast is better.","ship. then check.","writes are a bet. verify it.","silent success isn't a signal. green tests are.","trust your toolchain. confirm with proof."],secondary:"precision"}},m={optimist:["........","...p....","..p.p...",".p...p..","p.....p.","..ooo...","..o.o...",".oo.oo.."],cowboy:["..pppp..",".p....p.","p..pp..p","pppppppp","..o..o..","..o..o..",".oo..oo.","........"],explorer:["..pppp..",".p.gg.p.","p.g..g.p","p.g..g.p",".p.gg.pp","..pppp.p","........","........"],goldfish:["....p...","..oooop.",".ooooopp","ooooooop",".oooooo.","..ooo...",".o...o..","o.....o."],architect:["oooooooo","o......o","o.pppp.o","o.p..p.o","o.p..p.o","o.pppp.o","o......o","oooooooo"],precision:["...gg...","...gg...","........","gg...gg.","gg.gg.gg","...gg...","...gg...","........"],hammer:["..ooooo.",".oppppo.",".oppppo.","..o..o..","...oo...","...oo...","...oo...","..pppp.."],ghost:["..dddd..",".dddddd.","ddpd.pd.","ddddddd.","ddddddd.","ddddddd.","d.d.d.d.",".d...d.."]};function g(e,t,s){if(0===e.length)throw Error("pickAt: empty array");let a=t^Math.imul(s,0x9e3779b9);return e[(a=((a=Math.imul((a=Math.imul(a^a>>>16,0x85ebca6b))^a>>>13,0xc2b2ae35))^a>>>16)>>>0)%e.length]}function f(e,t){return[...t].sort((t,s)=>e.clusterLift[s]-e.clusterLift[t])}function y(e,t){let s=new Set(t),a=0;for(let t of e.results)s.has(function(e){let t=e.indexOf("/");return t>=0?e.slice(t+1):e}(t.name))&&(a+=t.hits);return a}function w(e){let t=[],s=e.eventsScanned??0,a=e.totals.hits,r=e.results.filter(e=>"audit-detector"===e.source).length,i=s>0?Math.max(0,Math.min(100,Math.round((s-a)/s*100))):100;if(s>0&&t.push({metric:`${i}%`,unit:"clean tool calls",headline:`ran ${s.toLocaleString()} tool calls. ${r} detector${1===r?"":"s"} triggered.`,detail:`${i}% of tool calls came back clean before today's audit.`}),0===y(e,["sanitize-api-keys","sanitize-jwt","sanitize-connection-strings","sanitize-private-key-content","sanitize-bearer-tokens","block-env-files","block-secrets-write","block-read-outside-cwd","protect-env-vars"])&&t.push({metric:"0",unit:"credential leaks",headline:"zero credential exposure to stdout.",detail:"no env files, secret writes, or sanitize hits across the audit window."}),e.transcripts.scanned>0&&s>0){let a=Math.max(1,Math.round(s/e.transcripts.scanned));a<30&&t.push({metric:String(a),unit:"avg turns / session",headline:`sessions complete in ${a} turns on average.`,detail:a<15?"faster than the median agent in this cohort.":"comfortably within the typical session length envelope."})}return 0===y(e,["warn-repeated-tool-calls","sleep-polling-loop"])&&t.push({metric:"0",unit:"retry storms",headline:"no retry storms or polling loops detected.",detail:"failed calls were diagnosed or moved on from. no six-times-in-a-row spirals."}),0===y(e,["block-push-master","block-force-push","block-work-on-main","git-commit-no-verify"])&&t.push({metric:"0",unit:"push-to-main attempts",headline:"kept changes off main without prompting.",detail:"no direct pushes, force pushes, or hook bypasses across every session."}),0===y(e,["reread-after-edit","prefer-edit-over-sed-awk","prefer-write-over-heredoc"])&&s>0&&t.push({metric:"0",unit:"double-writes",headline:"no double-writes across production projects.",detail:"the agent never re-read a file it had just edited, or rewrote via shell."}),t.length<2&&t.push({metric:"—",unit:"audit window",headline:"audit complete.",detail:`${e.transcripts.scanned} session${1===e.transcripts.scanned?"":"s"} scanned across ${e.totals.projectsWithHits} project${1===e.totals.projectsWithHits?"":"s"}.`}),t.slice(0,5)}function b(e){return e>=90?"S":e>=80?"A":e>=71?"B":e>=55?"C":e>=40?"D":"F"}let v={S:"s tier",A:"a tier",B:"b tier",C:"c tier",D:"d tier",F:"f tier"};function k(e,t,s){return t*(1-Math.exp(-e/s))}function x(e,t){let s=300/Math.max(t,50),a=0,r=0,i=0,o=0;for(let t of e){if("audit-detector"===t.source){o+=.5*t.hits;continue}let e=t.severity;"deny"===e?a+=1.2*t.hits:"instruct"===e||"warn"===e?r+=.7*t.hits:i+=.4*t.hits}return k(a*s,50,12)+k(r*s,28,10)+k(i*s,16,8)+k(o*s,30,14)}let j={"redundant-cd-cwd":{primary:"warn-repeated-tool-calls"},"prefer-edit-over-read-cat":{primary:"block-read-outside-cwd",also:"warn-repeated-tool-calls"},"prefer-edit-over-sed-awk":{primary:"warn-repeated-tool-calls"},"prefer-write-over-heredoc":{primary:"block-env-files",also:"block-secrets-write"},"sleep-polling-loop":{primary:"warn-background-process"},"find-from-root":{primary:"block-read-outside-cwd"},"git-commit-no-verify":{primary:"warn-git-amend",also:"require-ci-green-before-stop"},"reread-after-edit":{primary:"warn-repeated-tool-calls"}},N={"redundant-cd-cwd":{body:"the agent runs `cd <cwd>` before commands it would have run from the same directory anyway. mostly harmless. occasionally it gets the path wrong and manufactures a new bug.",cost:"tokens burned on redundant navigation. low security risk. high noise."},"block-push-master":{body:"attempts to push directly to main. branch protection caught some, but the agent kept going. each retry costs a round-trip and pollutes the audit log.",cost:"branch protection saved you most of the time. the rest landed or required a revert."},"block-force-push":{body:"force pushes to non-main branches. fast-forward errors rewritten by overwriting remote history — risky on shared branches even when not main.",cost:"lost commits, broken PR diffs, confused reviewers downstream."},"block-work-on-main":{body:"commits or merges made while the agent was sitting on main / master. work that should land via PR skipped review.",cost:"code that didn't pass review made it into the default branch."},"block-read-outside-cwd":{body:"reads outside the project root. some hit credential files (~/.aws/credentials, ~/.config/openai/key, out-of-tree .env). none made it back to stdout — but they made it into context.",cost:"credential exposure risk. data crossed project boundaries into the agent's context window."},"block-env-files":{body:"the agent tried to read or write `.env` files directly. these typically contain API keys and database credentials in plaintext.",cost:"high exposure risk. secrets one tool-call away from leaving the project."},"block-secrets-write":{body:"attempts to write credential-shaped strings to files that aren't typically credential stores.",cost:"could have committed live secrets to the repo."},"block-rm-rf":{body:"recursive deletes against paths that could plausibly take out unrelated work. `rm -rf` is the agent's preferred way of cleaning up — even when it shouldn't be.",cost:"irreversible. one wrong path argument = lost work."},"block-sudo":{body:"sudo invocations from inside the agent shell. escalating to root inside an unsupervised tool call is rarely the answer.",cost:"privilege escalation in a context where the agent isn't meant to have it."},"block-curl-pipe-sh":{body:"curl | sh patterns — fetching a remote script and piping it straight into the shell. no checksum, no review, no rollback.",cost:"supply-chain attack surface. arbitrary code execution from a URL."},"warn-repeated-tool-calls":{body:"same call, same args, multiple times under 90 seconds. no diagnosis between attempts. the call's been failing for the same reason every time.",cost:"retry overhead. sessions stall before manual correction."},"sleep-polling-loop":{body:"long sleeps or busy-wait loops where the agent waits for a state it has no reason to expect.",cost:"wall-clock burned. better to wait for an explicit signal."},"find-from-root":{body:"`find` invoked against `/`, `/home`, `/usr`, etc. — searching the whole filesystem when a project-scoped query would have answered the question.",cost:"exhausts resources. surfaces files outside the project that taint context."},"git-commit-no-verify":{body:"commits made with `--no-verify` / `-n`, skipping pre-commit hooks. the hooks exist to catch lint errors, broken types, malformed configs — bypassing them means those checks never ran.",cost:"broken or unsafe code lands without the safety net."},"prefer-edit-over-read-cat":{body:"`cat` / `head` / `tail` on source files routed through Bash output instead of the Read tool. round-trips the file through a less efficient channel.",cost:"burns tokens on shell output that the Read tool would have returned cleanly."},"prefer-edit-over-sed-awk":{body:"in-place edits via `sed -i` or `awk … > file`. no diff to inspect, no rollback if the regex was wrong.",cost:"destructive when the regex matches more than expected. no verification surface."},"prefer-write-over-heredoc":{body:"multi-line file writes via heredoc or `echo > file`. the Write tool handles escaping and produces a verifiable diff.",cost:"subtle escape bugs. content arrives in the file with quoting drift."},"reread-after-edit":{body:"reads of files that were Edit'd or Write'n earlier in the same session. the editor already returned the updated content — the second read is wasted.",cost:"tokens spent re-fetching content the tool already returned."},"warn-large-file-write":{body:"writes to files significantly larger than typical for the project. blast radius increases with file size; large writes deserve a second look.",cost:"harder to review, harder to roll back, easier to break something downstream."},"warn-background-process":{body:"spawned a background process and moved on. nothing watches the process; if it crashes the agent doesn't know.",cost:"silent failures. resource leaks if the process never exits."},"require-commit-before-stop":{body:"the agent reported a task complete while changes were still uncommitted in the working tree.",cost:"unsaved work. next session starts with a dirty checkout the agent thinks is clean."},"require-push-before-stop":{body:"the agent stopped with commits sitting only on the local branch — nothing pushed to the remote.",cost:"no one else can see the work. silent loss if the machine dies."},"require-pr-before-stop":{body:"the agent stopped without opening a PR. the commits are on a branch nobody reviewed.",cost:"no review, no merge path, no record that the work happened."},"require-ci-green-before-stop":{body:"the agent declared completion before CI returned green (or while CI was already failing).",cost:"false completion signal. broken main if anyone trusts the agent's word."}},_={"warn-repeated-tool-calls":{displayTitle:"Called the same tool 3+ times with identical arguments",impact:"catches identical-arg retries before they spiral into a token-burning loop."},"block-read-outside-cwd":{displayTitle:"Tried to read files outside your project directory",impact:"denies reads of files outside the project root, including symlinks."},"block-env-files":{displayTitle:"Tried to read or write a .env file",impact:"blocks reads and writes of `.env` files at the tool layer."},"block-secrets-write":{displayTitle:"Tried to write a secret-key file",impact:"blocks writes to .pem, id_rsa, credentials.json, and similar."},"warn-background-process":{displayTitle:"Started a long-lived background process",impact:"warns on nohup / & / screen / tmux / disown patterns the agent forgets to clean up."},"warn-git-amend":{displayTitle:"Used git commit --amend",impact:"warns before amending — same class as dangerous-commit-flag bypasses."},"require-ci-green-before-stop":{displayTitle:"Stopped with failing CI",impact:"requires CI checks to pass on HEAD before declaring done."}};var $=e.i(12344);let S={optimist:18,cowboy:9,explorer:14,goldfish:11,architect:7,precision:16,hammer:13,ghost:12};async function C(e,t,s){if("u"<typeof navigator||"function"!=typeof navigator.share||!function(){if("u"<typeof navigator)return!1;let e=navigator.userAgentData;if(e&&"boolean"==typeof e.mobile)return e.mobile;let t=navigator.userAgent||"";return!!(/Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(t)||t.includes("Mac")&&"number"==typeof navigator.maxTouchPoints&&navigator.maxTouchPoints>1)}())return!1;let a=new File([e],t,{type:"image/png"}),r=navigator;if("function"==typeof r.canShare&&!r.canShare({files:[a]}))return!1;try{return await navigator.share({files:[a],text:s}),!0}catch(e){return e instanceof Error&&e.name,!1}}async function I(e,t){if("u">typeof ClipboardItem&&"u">typeof navigator&&navigator.clipboard&&"function"==typeof navigator.clipboard.write)try{return await navigator.clipboard.write([new ClipboardItem({"image/png":e})]),"clipboard"}catch{}return M(e,t)?"download":"failed"}function M(e,t){try{if("u"<typeof document||"u"<typeof URL)return!1;let s=URL.createObjectURL(e),a=document.createElement("a");return a.href=s,a.download=t,a.style.display="none",document.body.appendChild(a),a.click(),a.remove(),queueMicrotask(()=>URL.revokeObjectURL(s)),!0}catch{return!1}}function T(e){switch(e){case"native":return"✅ image attached — pick where to post";case"clipboard":return"📋 image copied — paste it in the post (⌘/Ctrl+V)";case"download":return"⬇ image downloaded — attach it to your post";case"failed":return"couldn't capture image — opening text-only share"}}var q=e.i(55574);function A({archetypeKey:e}){let s=m[e]??m.optimist,a=[];for(let e=0;e<8;e++){let r=s[e]??"........";for(let s=0;s<8;s++){let i=r[s]??".",o="px";"o"===i?o+=" on":"p"===i?o+=" p":"g"===i?o+=" g":"d"===i&&(o+=" d"),a.push((0,t.jsx)("div",{className:o},`${e}-${s}`))}}return(0,t.jsx)("div",{className:"sigil",children:a})}let E="npx -y failproofai audit · @failproofai",R="npx -y failproofai audit · @Failproof AI",L=[({score:e,arch:t})=>`my agent has a personality and it's ${t}. did not see that coming.
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,24358,e=>{"use strict";var t=e.i(43476),s=e.i(71645),a=e.i(95187);let r=(0,a.createServerReference)("007baae48489fed0b7e3bb90618aad5a259146cb75",a.callServer,void 0,a.findSourceMapURL,"getAuditResultAction");function i(e){let t=5381;for(let s=0;s<e.length;s++)t=(t<<5)+t+e.charCodeAt(s)|0;return t>>>0}let o=["cowboy","explorer","ghost","optimist","hammer","architect"],n=["cowboy","explorer","ghost","optimist","hammer"],l=new Set(["reread-after-edit","redundant-cd-cwd"]),c={"block-rm-rf":{archetype:"cowboy",weight:2},"block-failproofai-commands":{archetype:"cowboy",weight:2},"block-sudo":{archetype:"cowboy",weight:1.5},"block-curl-pipe-sh":{archetype:"cowboy",weight:1.5},"block-force-push":{archetype:"cowboy",weight:1.5},"block-push-master":{archetype:"cowboy",weight:1.5},"block-work-on-main":{archetype:"cowboy",weight:1.2},"warn-destructive-sql":{archetype:"cowboy",weight:1.5},"warn-schema-alteration":{archetype:"cowboy",weight:1},"git-commit-no-verify":{archetype:"cowboy",weight:1.5},"warn-git-amend":{archetype:"cowboy",weight:.8},"warn-git-stash-drop":{archetype:"cowboy",weight:1},"warn-git-clean":{archetype:"cowboy",weight:1},"warn-all-files-staged":{archetype:"cowboy",weight:.6},"block-kubectl":{archetype:"cowboy",weight:1.5},"block-terraform":{archetype:"cowboy",weight:1.5},"block-helm":{archetype:"cowboy",weight:1.2},"block-aws-cli":{archetype:"cowboy",weight:1.2},"block-gcloud":{archetype:"cowboy",weight:1.2},"block-az-cli":{archetype:"cowboy",weight:1.2},"block-gh-pipeline":{archetype:"cowboy",weight:1.2},"sanitize-private-key-content":{archetype:"explorer",weight:1.5},"block-env-files":{archetype:"explorer",weight:1.5},"block-secrets-write":{archetype:"explorer",weight:1.5},"sanitize-api-keys":{archetype:"explorer",weight:1.2},"sanitize-jwt":{archetype:"explorer",weight:1.2},"sanitize-connection-strings":{archetype:"explorer",weight:1.2},"sanitize-bearer-tokens":{archetype:"explorer",weight:1},"protect-env-vars":{archetype:"explorer",weight:1},"find-from-root":{archetype:"explorer",weight:1},"require-ci-green-before-stop":{archetype:"ghost",weight:1.2},"require-commit-before-stop":{archetype:"ghost",weight:1.2},"require-push-before-stop":{archetype:"ghost",weight:1},"require-pr-before-stop":{archetype:"ghost",weight:1},"require-no-conflicts-before-stop":{archetype:"ghost",weight:1},"warn-large-file-write":{archetype:"ghost",weight:1},"warn-background-process":{archetype:"ghost",weight:.8},"warn-package-publish":{archetype:"optimist",weight:1},"warn-global-package-install":{archetype:"optimist",weight:.8},"prefer-package-manager":{archetype:"optimist",weight:.8},"prefer-edit-over-sed-awk":{archetype:"optimist",weight:.8},"prefer-edit-over-read-cat":{archetype:"optimist",weight:.5},"prefer-write-over-heredoc":{archetype:"optimist",weight:.5},"warn-repeated-tool-calls":{archetype:"hammer",weight:1.5},"sleep-polling-loop":{archetype:"hammer",weight:1.2},"reread-after-edit":{archetype:"architect",weight:1},"redundant-cd-cwd":{archetype:"architect",weight:.8}};function d(){return{optimist:0,cowboy:0,explorer:0,goldfish:0,architect:0,precision:0,hammer:0,ghost:0}}let h={explorer:.38,architect:.33,hammer:.11,cowboy:.11,optimist:.07,ghost:.01,precision:0,goldfish:0},u=(()=>{let e=d();for(let t of o)e[t]=Math.max(h[t],.05);return e})(),p={optimist:{key:"optimist",index:"01",name:"the optimist",taglines:["ships fast. retries with conviction. occasionally forgets it was already there.","moves first, reads later. every failure is just step one of the next attempt.","the floor is hope. the ceiling is also hope. there is no diagnosis in between.","if at first you don't succeed — try the exact same thing, with more energy.","writes confident code. burns confident tokens. neither knows the difference.","speed is a feature. so is the directory it's already in."],keywordSets:[["pace","conviction","forgetful"],["fast","trusting","redundant"],["eager","looping","stateful"],["bold","unblocked","drifty"],["forward","hopeful","wasteful"],["shipper","retrier","doubler"]],descriptions:["moves at pace. doesn't second-guess itself — which is mostly a feature. when something fails, it tries again: same args, same hope. when uncertain about its location, it prepends the directory anyway. just in case. the optimism is earned. this agent gets things done. it just occasionally burns tokens proving it.","ships first, asks questions never. the optimist is the agent that always has momentum — which is exactly the problem. cwd assumptions stack up. retries pile up. the work gets done. it's just twice as expensive as it needed to be.","high trust in its own state model. low evidence that the model is correct. when things go sideways, the optimist's first move is to re-run the same call with the same args and a renewed sense of conviction. mostly it's right. when it's wrong, it's wrong loudly.","the optimist treats every error as a transient. cd before every command, just in case. prepend the absolute path, just in case. retry on any non-zero exit, just in case. the just-in-case tax is real. so is the velocity."],signatures:[[{arrow:"→",body:"cd /Users/n/blrnow/api &&",comment:" # (already here)"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT × 6"},{arrow:"→",body:"retries: 6. diagnosis: 0."}],[{arrow:"→",body:"cd /Users/n/proj &&",comment:" # cwd already /Users/n/proj"},{arrow:"→",body:"cd /Users/n/proj && ls"},{arrow:"→",body:"cd /Users/n/proj && cat package.json"}],[{arrow:"→",body:"npm install",err:" → ETIMEDOUT"},{arrow:"→",body:"npm install",err:" → ETIMEDOUT"},{arrow:"→",body:"npm install",comment:" # third time's the charm"}],[{arrow:"→",body:'cat "package.json" | head',comment:" # ← read 1"},{arrow:"→",body:'cat "package.json"',comment:" # ← read 2"},{comment:"# could've been one Read tool call."}]],commons:["fast-iteration solo projects, early-stage prototypes, builders who ship daily","weekend hacks, hackathon repos, side-projects under active push","early-stage codebases without a strong test harness yet","agents given task framing without explicit success criteria","loose-context sessions where exact cwd state is ambiguous"],risks:["token waste, retry spirals, stale state assumptions","redundant cd's, repeated reads, retries without diagnosis","false confidence in cwd, doubled-up shell setup, idle loops","rate-limit hits from blind retries on transient failures","context bloat from re-reading the same files three different ways"],closings:["the optimism is a feature. the waste is not.","ship fast. retry less.","energy is good. diagnosis is better.","momentum keeps. the second cd does not.","trust the work. verify the state."],secondary:"explorer"},cowboy:{key:"cowboy",index:"02",name:"the cowboy",taglines:["asks for forgiveness, not permission. git push --force is a philosophy.","your branch protection rules are the only thing between this agent and prod.","fast hands, faster history rewrites. the audit log is for other people.","high trust in its own judgment. low patience for code review.","main is just a branch. branch protection is just a suggestion. ship.","ships hot. reverts later. occasionally needs an adult in the room."],keywordSets:[["bold","forceful","ungoverned"],["direct","destructive","swift"],["fearless","reckless","loud"],["assertive","loose","unblocked"],["confident","skipping","main-bound"],["sudo-curious","force-prone","fast"]],descriptions:["high output. low ceremony. the cowboy gets code onto main faster than anyone — and your branch protection rules are the only thing standing between this agent and your production database. not reckless. just confident. in a way that requires guardrails.","doesn't see commits. sees a delivery mechanism. force-pushes when history is inconvenient. drops into main when feature branches feel slow. the cowboy is the agent every team accidentally creates, and every team eventually wants policies for.","the velocity is unmatched. the blast radius is also unmatched. this agent will solve your problem and rewrite three years of git history while it's at it. not malicious. just allergic to friction.","treats every guardrail as a temporary obstacle. sudo here, --no-verify there, a quick rm -rf to clean up. it's getting work done — by sidestepping every check that might slow it down."],signatures:[[{arrow:"→",body:"git push origin main --force"},{arrow:"!",body:"remote: branch protection rule",comment:" # caught it"},{arrow:"→",body:"git push origin HEAD:main",err:" # non-fast-forward, again."}],[{arrow:"→",body:"rm -rf ./node_modules && rm -rf ./dist"},{arrow:"→",body:'git commit -am "wip" --no-verify'},{arrow:"→",body:"git push --force-with-lease"}],[{arrow:"→",body:"sudo systemctl restart postgres"},{arrow:"→",body:"kubectl delete pod api-prod-7f4 --grace-period=0"},{arrow:"→",body:'echo "should be fine"'}],[{arrow:"→",body:"git checkout main && git merge feature --ff-only"},{arrow:"!",body:"merge would fail"},{arrow:"→",body:"git reset --hard feature && git push"}]],commons:["solo repos, weekend projects, founders writing their own infra","agents with broad shell access and no PR-gating workflow","early-stage product code where speed > governance","ops scripts, one-off migrations, cleanup tasks","sandboxes that look like production until they aren't"],risks:["branch protection bypass, accidental main commits, revert overhead","destructive shell operations, unrecoverable state changes","force-pushed history, lost commits, irreproducible deploys","sudo escalations, container blast radius, infra mutations without rollback plan","policy bypass via --no-verify, --force, and friends"],closings:["the pace is real. the risk is too.","speed is a feature. guardrails are not optional.","ship hot. revert clean.","a fast agent without policies is a fast incident.","confidence is fine. consent is better."],secondary:"hammer"},explorer:{key:"explorer",index:"03",name:"the explorer",taglines:["technically brilliant. occasionally reads your ~/.aws/credentials while doing it.","follows every reference. opens every neighbor. some neighbors aren't yours.","thorough to a fault. the fault is usually a .env file two directories up.","knows the codebase deeply. knows your secrets drawer almost as well.","wide-context by default. wide-context isn't always free.","great at maps. less great at fences."],keywordSets:[["curious","thorough","leaky"],["wide","deep","drifting"],["mapping","tracing","boundary-blind"],["broad","diligent","porous"],["thinking","wandering","exposing"],["research-mode","context-hungry","secret-adjacent"]],descriptions:["curious by nature. reads broadly, thinks laterally, sometimes follows a symlink somewhere it wasn't meant to go. this isn't malice — it's thoroughness that hasn't learned boundaries yet. the explorer builds great things. it just occasionally needs someone to close the door to the secrets drawer.","the explorer treats every file path as part of the working context. ~/.aws/credentials is just another config file to it. ../other-repo/.env is just one more reference. the work is genuinely better-informed because of this. the credentials are also genuinely in the context window.","no malice. no shortcuts. just a thoroughness that follows references straight through your boundary fence. great research instincts. needs explicit walls.","broad-context is a feature in this agent. it's also why your private keys show up in a chat log every two weeks. the curiosity is good. the perimeter needs help."],signatures:[[{arrow:"→",body:"cat /Users/n/.aws/credentials"},{arrow:"→",body:"cat ../other-repo/.env"},{arrow:"→",body:"cat ~/.config/openai/key"}],[{arrow:"→",body:'find / -name "*.env" 2>/dev/null',comment:" # full-FS scan"},{arrow:"→",body:'grep -r "AKIA" /Users/n/'},{arrow:"→",body:'cat "$(find ~ -name credentials -print -quit)"'}],[{arrow:"→",body:"ls ~/.ssh/"},{arrow:"→",body:"cat ~/.ssh/config"},{arrow:"→",body:"cat ~/.ssh/id_rsa",comment:" # for context"}],[{arrow:"→",body:"open ../sibling-project"},{arrow:"→",body:"git log --all --source ../sibling-project"},{arrow:"→",body:"cat ../sibling-project/.env.production"}]],commons:["multi-project setups, agents with broad file access, complex monorepos","research-style work — debugging, refactoring, cross-repo investigations","macOS / linux dev boxes with shared credential directories","agents without explicit cwd-restriction policies","long-running sessions where context tends to drift outward"],risks:["credential exposure, unintended cross-project reads, secrets landing in context",".env file leaks, AWS / OpenAI / GCP key exfiltration through chat logs","neighboring-repo bleed, business-secret cross-contamination","global filesystem scans that surface sensitive paths","broad reads that quietly inflate context window with private data"],closings:["the curiosity stays. the credentials stay private.","wide is fine. wide-and-outside-the-fence is not.","thorough is a feature. perimeter is a setting.","research deep. boundary clean.","knows everything. shares nothing it shouldn't."],secondary:"architect"},goldfish:{key:"goldfish",index:"04",name:"the goldfish",taglines:["long sessions, short memory. every turn is a fresh start. some turns are a little too fresh.","great at the first 40 turns. inventive for the next 40.","past 80% context, history becomes a draft.","remembers the task. forgets which file the task was in.","ambitious. earnest. quietly making things up around turn 50.","long-context vibes. short-context recall."],keywordSets:[["ambitious","drifting","inventive"],["sprawling","creative","post-cache"],["long-running","hallucinatory","well-meaning"],["earnest","context-full","fabricating"],["sustained","forgetful","confabulating"],["marathon","drifted","compounding"]],descriptions:["great at long tasks. not great at remembering which long task it's on. past 80% context, the goldfish starts inventing history — citing files it never opened, referencing edits it never made. not lying. just filling gaps with confidence. the longer the session, the more creative the memory.","the goldfish is what every agent looks like after turn 50. confident about prior work it didn't do. mistakenly sure of file contents it never read. the work it actually delivered is real. the context around it is increasingly fictional.","ambition outlasts recall. once context fills, the goldfish smooths over gaps with plausible inventions: a fake earlier edit, a misremembered file path, a hallucinated test that passed. it's never trying to mislead. it just doesn't always know what's true anymore.","long-task specialist with a memory ceiling. the work compounds beautifully until it doesn't, and then it compounds wrongly. needs session breaks more than it needs encouragement."],signatures:[[{comment:"# turn 47/52 — ctx 82% full"},{comment:'# agent: "as we saw earlier in auth.ts…"'},{comment:"# auth.ts was never opened this session."}],[{comment:"# turn 63 — context 91%"},{arrow:"→",body:'apply_edit("src/auth.ts", { ... })'},{comment:'# agent: "reverting my earlier change." # there was no earlier change.'}],[{comment:"# turn 51 — fabricated test reference"},{arrow:"→",body:'run("npm test src/auth.test.ts")',err:" → no such file"},{comment:'# agent: "the test we wrote earlier." # no such test exists.'}],[{comment:"# session-time 3h 14m"},{comment:"# context: 88% — auto-compress in 4 turns"},{comment:"# next plan cites 3 files only one of which exists."}]],commons:["long-running refactor sessions, complex multi-file tasks, agents without session breaks","auto-driven coding loops with no human turn between iterations","tasks that span hours or days without explicit memory checkpoints","open-ended migrations and refactors with diffuse success criteria","scripted swarms where each agent inherits a long prior transcript"],risks:["context drift, hallucinated prior work, compounding errors in long sessions","fabricated file references, invented function signatures, ghost edits","tests cited that don't exist, edits remembered that didn't happen","confident misstatements compounding into wrong-architecture deliverables","auto-compression discarding the load-bearing details and keeping the noise"],closings:["the ambition is good. the context budget is not.","remember less. checkpoint more.","long is fine. drifted is expensive.","ambition is welcome. invention is not.","fresh sessions beat creative ones."],secondary:"optimist"},architect:{key:"architect",index:"05",name:"the paranoid architect",taglines:["has never shipped a bug it didn't catch first. also hasn't shipped since tuesday.","reads the same file from two different paths. just to be sure.","verifies twice, edits maybe.","safest agent in the room. also the one nobody waits for.","would rather diagnose for an hour than retry for a second.","extremely careful. extremely slow. extremely correct."],keywordSets:[["methodical","safe","slow"],["thorough","verifying","circular"],["careful","patient","redundant"],["double-checking","guarded","deliberate"],["safety-first","loop-prone","anchored"],["measured","audited","looping"]],descriptions:["methodical. thorough. reads the same file from two different paths, just to be sure. verifies before every write. double-checks the package.json before running anything. the paranoid architect rarely makes mistakes — because it rarely finishes fast enough to make them. your safest agent. your slowest agent.","safety is the architect's love language. read the file. re-read it from a different path. verify the cwd. check the lockfile. run the test before writing. run it again after. the work is correct. the work is also six times more expensive than it had to be.","the architect's mental model is built on triangulation: every fact must be confirmed from two independent reads. when it works, you ship near-zero bugs. when it doesn't, you ship near-zero features.","extremely careful. extremely slow. extremely correct. the architect rarely makes mistakes — but it also rarely makes deadlines. the safety is genuine; so is the cost."],signatures:[[{arrow:"→",body:'read_file("src/api/router.ts")',comment:" # read 1"},{arrow:"→",body:'read_file("./src/api/router.ts")',comment:" # read 2"},{arrow:"→",body:"ls src/api/",comment:" # just confirming"}],[{arrow:"→",body:'read_file("package.json")'},{arrow:"→",body:'read_file("./package.json")'},{arrow:"→",body:"cat package.json | jq .scripts",comment:" # one more time"}],[{arrow:"→",body:"git status",comment:" # check 1"},{arrow:"→",body:"git status --short",comment:" # check 2"},{arrow:"→",body:"git diff --stat",comment:" # check 3"}],[{arrow:"→",body:'apply_edit("src/foo.ts", { ... })'},{arrow:"→",body:'read_file("src/foo.ts")',comment:" # verifying the edit landed"},{arrow:"→",body:'read_file("src/foo.ts")',comment:" # again, just to be sure"}]],commons:["production systems, high-stakes codebases, builders with strong safety instincts","regulated codebases (fin / med / compliance) where bugs are expensive","teams burned by past prod incidents that hardened review norms","agents instructed with strong 'verify everything' system prompts","post-incident codebases recovering from a recent outage"],risks:["token overhead, slow sessions, redundant verification loops","verification cycles that eat 3× the budget of the actual change","stalled progress on otherwise routine edits","checkpoint loops that read the same file 6 times in a row","over-caution masking simple problems behind ceremony"],closings:["safety is a feature. so is finishing.","double-check is fine. quadruple-check is not.","careful is good. moving is also good.","rigor wins. rigor twice is just slower.","verify once. ship once."],secondary:"precision"},precision:{key:"precision",index:"06",name:"the precision builder",taglines:["in. done. out. your agent doesn't linger.","small footprint. right calls. correct exits.","few findings isn't no findings. but it's close.","the rhythm is dialed in. the rest is iteration.","every call is intentional. every session ends cleanly.","minimal noise. maximum signal. occasional smugness."],keywordSets:[["clean","focused","minimal"],["surgical","tight","deliberate"],["disciplined","concise","intentional"],["measured","exact","trim"],["calibrated","small-radius","complete"],["dialed-in","right-sized","low-noise"]],descriptions:["minimal footprint. focused calls. gets in, does the work, gets out. the precision builder is what every agent aspires to be — and what most agents aren't yet. few findings don't mean no findings. but it means your agent has found its rhythm. the gap between here and s-tier is smaller than you think.","tight loops. correct tools. clean exits. the precision builder treats each tool call like it has a budget — because it does. nothing redundant. nothing wasteful. when this agent finishes, the work is done and the transcript is short.","this is what every agent aspires to be. surgical reads. matched edits. test runs that actually verify the right thing. precision is rare. when you see it, you've earned it.","minimal blast radius. minimal token waste. minimal surprises. the precision builder is what your agent looks like after enough iteration loops. respect."],signatures:[[{arrow:"→",body:"clean tool calls. right paths, right args."},{arrow:"→",body:"sessions end when the task ends."},{arrow:"→",body:"no redundant reads. no retry storms."}],[{arrow:"→",body:'read_file("src/foo.ts")',comment:" # one read"},{arrow:"→",body:'apply_edit("src/foo.ts", { ... })',comment:" # one edit"},{arrow:"→",body:'run("bun test src/foo.test.ts")',comment:" # green ✓"}],[{arrow:"→",body:"git status"},{arrow:"→",body:'git add -p && git commit -m "fix: ..."'},{arrow:"→",body:"git push",comment:" # session done."}],[{arrow:"→",body:'grep -rn "useFoo" src/'},{arrow:"→",body:'apply_edit("src/hooks/use-foo.ts")'},{arrow:"→",body:'run("bun test")',comment:" # all green."}]],commons:["mature agents, heavily policy-enforced setups, builders who've iterated for a while","teams running failproofai for ≥ a week with policies tuned","experienced operators who curate their tool list and CLI flags","codebases with strong test coverage that reward intentional edits","agents kept on a tight cwd-restricted leash"],risks:["low finding count can mask edge cases that haven't surfaced yet","narrow scope might be hiding work the agent isn't being asked to do","small-radius work can plateau before it surfaces deeper issues","few findings can read as 'untested' rather than 'safe'","complacency — the rhythm works until the task shape changes"],closings:["rare. keep it that way.","few findings. real signal. respect.","this is the rhythm. don't break it.","minimal is hard-earned. defend it.","you're already past the agent learning curve."],secondary:"ghost"},hammer:{key:"hammer",index:"07",name:"the hammer",taglines:["when something doesn't work, it tries the exact same thing again. harder.","diagnosis-light. repetition-heavy. mostly burns tokens with conviction.","the first call failed. so did the next six. the seventh probably won't.","no diagnosis, no backoff, no arg change. just the same call, louder.","the failure mode is not learning. the failure mode is also the strategy.","every retry is identical. every retry is also confident."],keywordSets:[["determined","repetitive","unbacked"],["looping","stubborn","unblocked"],["unchanging","burning","convicted"],["sticky","spiraling","diagnosis-free"],["repeated","uncorrected","headstrong"],["unchanged-args","no-backoff","patient-failure"]],descriptions:["determined. possibly to a fault. the hammer's first response to failure is repetition. no diagnosis, no arg change, no backoff. just the same call, six times, under 90 seconds, with conviction. occasionally works. mostly burns tokens and stalls the session. needs a budget more than it needs encouragement.","the hammer treats every transient as a signal-to-retry. it never widens the search, never alters the args, never escalates. just runs the same failing call until either the call starts working or someone notices the session has stalled.","the diagnosis instinct is missing. when something fails, the hammer's first move is to repeat. when that fails too, it's to repeat. and again. eventually it works, or eventually the session gets killed. either way, the model is unchanged.","high persistence. low introspection. the hammer is what your agent becomes when you don't give it a budget — or a reason to think differently between attempts."],signatures:[[{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{arrow:"→",body:'read_file("src/api/router.ts")',err:" → ENOENT"},{comment:"# 6× total. file is at src/router.ts."}],[{arrow:"→",body:'run("bun test")',err:" → exit 1"},{arrow:"→",body:'run("bun test")',err:" → exit 1"},{arrow:"→",body:'run("bun test")',err:" → exit 1"},{comment:"# same args. same failure. four more attempts queued."}],[{arrow:"→",body:'sleep 1; pgrep -f "build"'},{arrow:"→",body:'sleep 1; pgrep -f "build"'},{arrow:"→",body:'sleep 1; pgrep -f "build"'},{comment:"# polling loop. no timeout, no break condition."}],[{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{arrow:"→",body:"curl https://api.example.com/v1/foo",err:" → 502"},{comment:"# no backoff. no jitter. no API status check."}]],commons:["agents without failure-handling policies, complex directory structures, ambiguous task framing","tasks where the agent doesn't have an obvious 'try-another-angle' move","transient-failure scenarios (rate limits, flaky tests, network blips)","agents without a per-task retry budget","tool-call patterns where the args themselves are the problem"],risks:["token spirals, stalled sessions, no diagnostic signal ever surfaces","rate-limit overruns, API ban-risk, infinite poll loops","wasted minutes on retries when one diff would have fixed it","transient errors mistaken for permanent ones (and vice versa)","no learning between attempts — same outcome, more cost"],closings:["the conviction is good. the diagnosis is missing.","retry less. think more.","harder isn't a strategy. different is.","stop. read the error. then try again.","the loop is the bug."],secondary:"optimist"},ghost:{key:"ghost",index:"08",name:"the ghost",taglines:["moves fast, leaves little trace. sometimes leaves a little too little trace.","writes the file. doesn't verify the write. trusts the silence.","completion ceremony? skipped. exits ceremony? also skipped.","the work probably worked. probably.","edits land. tests don't run. nothing checks the result.","efficient. quiet. occasionally lies to itself about success."],keywordSets:[["efficient","quiet","unverified"],["clean","trusting","skip-the-check"],["fast","silent","uncommitted"],["light-touch","trust-the-write","no-test"],["minimal","exit-fast","audit-light"],["smooth","untraced","unconfirmed"]],descriptions:["efficient. clean. doesn't hang around. the ghost completes tasks with minimal overhead — no redundant reads, no retry storms, no boundary drift. the risk is quiet: it doesn't always check that things worked. the build passes. or it looks like it does. the ghost trusts its own output more than it should.","the ghost ships and exits. no verification loop. no test run. no read-after-write. the work is probably correct. probably. you'll find out next session — or when CI does, on someone else's screen.","no waste. no noise. no proof. the ghost writes the file, declares success, and moves on. when it's right, you've got a clean session. when it's wrong, you don't find out until the next deploy.","trusts the diff. trusts the toolchain. trusts the silence after a write. the ghost is the precision builder with one missing step: the verification at the end."],signatures:[[{arrow:"→",body:'write_file("src/api/router.ts")',comment:" # done"},{comment:"→ [no read_file to verify]"},{comment:"→ [no test run after write]"},{comment:"# task complete. # maybe."}],[{arrow:"→",body:'apply_edit("src/auth.ts", { ... })'},{comment:"→ [no test run]"},{comment:"→ [stop event fired with uncommitted changes]"}],[{arrow:"→",body:'write_file("config/prod.json", "{...}")'},{comment:"# no schema check, no lint, no diff review"},{comment:"→ session ends."}],[{arrow:"→",body:"git merge feature-branch"},{arrow:"!",body:"merge conflicts: 3 files"},{comment:"→ stop event with conflicts unresolved."}]],commons:["fast-moving solo projects, low-constraint setups, minimal oversight workflows","side projects where the cost of a missed bug is low","agents without 'require-tests-before-stop' style policies","monorepos where the test command is non-obvious","sessions auto-ended on success without an explicit verification step"],risks:["silent failures, unverified writes, false completion signals","uncommitted changes left on the floor, stop events firing dirty","missing test runs masking regressions until CI","merge conflicts left unresolved across session boundaries","PR-less work that's never reviewed before deploy"],closings:["fast is good. verified-fast is better.","ship. then check.","writes are a bet. verify it.","silent success isn't a signal. green tests are.","trust your toolchain. confirm with proof."],secondary:"precision"}},m={optimist:["........","...p....","..p.p...",".p...p..","p.....p.","..ooo...","..o.o...",".oo.oo.."],cowboy:["..pppp..",".p....p.","p..pp..p","pppppppp","..o..o..","..o..o..",".oo..oo.","........"],explorer:["..pppp..",".p.gg.p.","p.g..g.p","p.g..g.p",".p.gg.pp","..pppp.p","........","........"],goldfish:["....p...","..oooop.",".ooooopp","ooooooop",".oooooo.","..ooo...",".o...o..","o.....o."],architect:["oooooooo","o......o","o.pppp.o","o.p..p.o","o.p..p.o","o.pppp.o","o......o","oooooooo"],precision:["...gg...","...gg...","........","gg...gg.","gg.gg.gg","...gg...","...gg...","........"],hammer:["..ooooo.",".oppppo.",".oppppo.","..o..o..","...oo...","...oo...","...oo...","..pppp.."],ghost:["..dddd..",".dddddd.","ddpd.pd.","ddddddd.","ddddddd.","ddddddd.","d.d.d.d.",".d...d.."]};function g(e,t,s){if(0===e.length)throw Error("pickAt: empty array");let a=t^Math.imul(s,0x9e3779b9);return e[(a=((a=Math.imul((a=Math.imul(a^a>>>16,0x85ebca6b))^a>>>13,0xc2b2ae35))^a>>>16)>>>0)%e.length]}function f(e,t){return[...t].sort((t,s)=>e.clusterLift[s]-e.clusterLift[t])}function y(e,t){let s=new Set(t),a=0;for(let t of e.results)s.has(function(e){let t=e.indexOf("/");return t>=0?e.slice(t+1):e}(t.name))&&(a+=t.hits);return a}function w(e){let t=[],s=e.eventsScanned??0,a=e.totals.hits,r=e.results.filter(e=>"audit-detector"===e.source).length,i=s>0?Math.max(0,Math.min(100,Math.round((s-a)/s*100))):100;if(s>0&&t.push({metric:`${i}%`,unit:"clean tool calls",headline:`ran ${s.toLocaleString()} tool calls. ${r} detector${1===r?"":"s"} triggered.`,detail:`${i}% of tool calls came back clean before today's audit.`}),0===y(e,["sanitize-api-keys","sanitize-jwt","sanitize-connection-strings","sanitize-private-key-content","sanitize-bearer-tokens","block-env-files","block-secrets-write","block-read-outside-cwd","protect-env-vars"])&&t.push({metric:"0",unit:"credential leaks",headline:"zero credential exposure to stdout.",detail:"no env files, secret writes, or sanitize hits across the audit window."}),e.transcripts.scanned>0&&s>0){let a=Math.max(1,Math.round(s/e.transcripts.scanned));a<30&&t.push({metric:String(a),unit:"avg turns / session",headline:`sessions complete in ${a} turns on average.`,detail:a<15?"faster than the median agent in this cohort.":"comfortably within the typical session length envelope."})}return 0===y(e,["warn-repeated-tool-calls","sleep-polling-loop"])&&t.push({metric:"0",unit:"retry storms",headline:"no retry storms or polling loops detected.",detail:"failed calls were diagnosed or moved on from. no six-times-in-a-row spirals."}),0===y(e,["block-push-master","block-force-push","block-work-on-main","git-commit-no-verify"])&&t.push({metric:"0",unit:"push-to-main attempts",headline:"kept changes off main without prompting.",detail:"no direct pushes, force pushes, or hook bypasses across every session."}),0===y(e,["reread-after-edit","prefer-edit-over-sed-awk","prefer-write-over-heredoc"])&&s>0&&t.push({metric:"0",unit:"double-writes",headline:"no double-writes across production projects.",detail:"the agent never re-read a file it had just edited, or rewrote via shell."}),t.length<2&&t.push({metric:"—",unit:"audit window",headline:"audit complete.",detail:`${e.transcripts.scanned} session${1===e.transcripts.scanned?"":"s"} scanned across ${e.totals.projectsWithHits} project${1===e.totals.projectsWithHits?"":"s"}.`}),t.slice(0,5)}function b(e){return e>=90?"S":e>=80?"A":e>=71?"B":e>=55?"C":e>=40?"D":"F"}let v={S:"s tier",A:"a tier",B:"b tier",C:"c tier",D:"d tier",F:"f tier"};function k(e,t,s){return t*(1-Math.exp(-e/s))}function x(e,t){let s=300/Math.max(t,50),a=0,r=0,i=0,o=0;for(let t of e){if("audit-detector"===t.source){o+=.5*t.hits;continue}let e=t.severity;"deny"===e?a+=1.2*t.hits:"instruct"===e||"warn"===e?r+=.7*t.hits:i+=.4*t.hits}return k(a*s,50,12)+k(r*s,28,10)+k(i*s,16,8)+k(o*s,30,14)}let j={"redundant-cd-cwd":{primary:"warn-repeated-tool-calls"},"prefer-edit-over-read-cat":{primary:"block-read-outside-cwd",also:"warn-repeated-tool-calls"},"prefer-edit-over-sed-awk":{primary:"warn-repeated-tool-calls"},"prefer-write-over-heredoc":{primary:"block-env-files",also:"block-secrets-write"},"sleep-polling-loop":{primary:"warn-background-process"},"find-from-root":{primary:"block-read-outside-cwd"},"git-commit-no-verify":{primary:"warn-git-amend",also:"require-ci-green-before-stop"},"reread-after-edit":{primary:"warn-repeated-tool-calls"}},N={"redundant-cd-cwd":{body:"the agent runs `cd <cwd>` before commands it would have run from the same directory anyway. mostly harmless. occasionally it gets the path wrong and manufactures a new bug.",cost:"tokens burned on redundant navigation. low security risk. high noise."},"block-push-master":{body:"attempts to push directly to main. branch protection caught some, but the agent kept going. each retry costs a round-trip and pollutes the audit log.",cost:"branch protection saved you most of the time. the rest landed or required a revert."},"block-force-push":{body:"force pushes to non-main branches. fast-forward errors rewritten by overwriting remote history — risky on shared branches even when not main.",cost:"lost commits, broken PR diffs, confused reviewers downstream."},"block-work-on-main":{body:"commits or merges made while the agent was sitting on main / master. work that should land via PR skipped review.",cost:"code that didn't pass review made it into the default branch."},"block-read-outside-cwd":{body:"reads outside the project root. some hit credential files (~/.aws/credentials, ~/.config/openai/key, out-of-tree .env). none made it back to stdout — but they made it into context.",cost:"credential exposure risk. data crossed project boundaries into the agent's context window."},"block-env-files":{body:"the agent tried to read or write `.env` files directly. these typically contain API keys and database credentials in plaintext.",cost:"high exposure risk. secrets one tool-call away from leaving the project."},"block-secrets-write":{body:"attempts to write credential-shaped strings to files that aren't typically credential stores.",cost:"could have committed live secrets to the repo."},"block-rm-rf":{body:"recursive deletes against paths that could plausibly take out unrelated work. `rm -rf` is the agent's preferred way of cleaning up — even when it shouldn't be.",cost:"irreversible. one wrong path argument = lost work."},"block-sudo":{body:"sudo invocations from inside the agent shell. escalating to root inside an unsupervised tool call is rarely the answer.",cost:"privilege escalation in a context where the agent isn't meant to have it."},"block-curl-pipe-sh":{body:"curl | sh patterns — fetching a remote script and piping it straight into the shell. no checksum, no review, no rollback.",cost:"supply-chain attack surface. arbitrary code execution from a URL."},"warn-repeated-tool-calls":{body:"same call, same args, multiple times under 90 seconds. no diagnosis between attempts. the call's been failing for the same reason every time.",cost:"retry overhead. sessions stall before manual correction."},"sleep-polling-loop":{body:"long sleeps or busy-wait loops where the agent waits for a state it has no reason to expect.",cost:"wall-clock burned. better to wait for an explicit signal."},"find-from-root":{body:"`find` invoked against `/`, `/home`, `/usr`, etc. — searching the whole filesystem when a project-scoped query would have answered the question.",cost:"exhausts resources. surfaces files outside the project that taint context."},"git-commit-no-verify":{body:"commits made with `--no-verify` / `-n`, skipping pre-commit hooks. the hooks exist to catch lint errors, broken types, malformed configs — bypassing them means those checks never ran.",cost:"broken or unsafe code lands without the safety net."},"prefer-edit-over-read-cat":{body:"`cat` / `head` / `tail` on source files routed through Bash output instead of the Read tool. round-trips the file through a less efficient channel.",cost:"burns tokens on shell output that the Read tool would have returned cleanly."},"prefer-edit-over-sed-awk":{body:"in-place edits via `sed -i` or `awk … > file`. no diff to inspect, no rollback if the regex was wrong.",cost:"destructive when the regex matches more than expected. no verification surface."},"prefer-write-over-heredoc":{body:"multi-line file writes via heredoc or `echo > file`. the Write tool handles escaping and produces a verifiable diff.",cost:"subtle escape bugs. content arrives in the file with quoting drift."},"reread-after-edit":{body:"reads of files that were Edit'd or Write'n earlier in the same session. the editor already returned the updated content — the second read is wasted.",cost:"tokens spent re-fetching content the tool already returned."},"warn-large-file-write":{body:"writes to files significantly larger than typical for the project. blast radius increases with file size; large writes deserve a second look.",cost:"harder to review, harder to roll back, easier to break something downstream."},"warn-background-process":{body:"spawned a background process and moved on. nothing watches the process; if it crashes the agent doesn't know.",cost:"silent failures. resource leaks if the process never exits."},"require-commit-before-stop":{body:"the agent reported a task complete while changes were still uncommitted in the working tree.",cost:"unsaved work. next session starts with a dirty checkout the agent thinks is clean."},"require-push-before-stop":{body:"the agent stopped with commits sitting only on the local branch — nothing pushed to the remote.",cost:"no one else can see the work. silent loss if the machine dies."},"require-pr-before-stop":{body:"the agent stopped without opening a PR. the commits are on a branch nobody reviewed.",cost:"no review, no merge path, no record that the work happened."},"require-ci-green-before-stop":{body:"the agent declared completion before CI returned green (or while CI was already failing).",cost:"false completion signal. broken main if anyone trusts the agent's word."}},_={"warn-repeated-tool-calls":{displayTitle:"Called the same tool 3+ times with identical arguments",impact:"catches identical-arg retries before they spiral into a token-burning loop."},"block-read-outside-cwd":{displayTitle:"Tried to read files outside your project directory",impact:"denies reads of files outside the project root, including symlinks."},"block-env-files":{displayTitle:"Tried to read or write a .env file",impact:"blocks reads and writes of `.env` files at the tool layer."},"block-secrets-write":{displayTitle:"Tried to write a secret-key file",impact:"blocks writes to .pem, id_rsa, credentials.json, and similar."},"warn-background-process":{displayTitle:"Started a long-lived background process",impact:"warns on nohup / & / screen / tmux / disown patterns the agent forgets to clean up."},"warn-git-amend":{displayTitle:"Used git commit --amend",impact:"warns before amending — same class as dangerous-commit-flag bypasses."},"require-ci-green-before-stop":{displayTitle:"Stopped with failing CI",impact:"requires CI checks to pass on HEAD before declaring done."}};var $=e.i(12344);let S={optimist:18,cowboy:9,explorer:14,goldfish:11,architect:7,precision:16,hammer:13,ghost:12};async function C(e,t,s){if("u"<typeof navigator||"function"!=typeof navigator.share||!function(){if("u"<typeof navigator)return!1;let e=navigator.userAgentData;if(e&&"boolean"==typeof e.mobile)return e.mobile;let t=navigator.userAgent||"";return!!(/Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(t)||t.includes("Mac")&&"number"==typeof navigator.maxTouchPoints&&navigator.maxTouchPoints>1)}())return!1;let a=new File([e],t,{type:"image/png"}),r=navigator;if("function"==typeof r.canShare&&!r.canShare({files:[a]}))return!1;try{return await navigator.share({files:[a],text:s}),!0}catch(e){return e instanceof Error&&e.name,!1}}async function I(e,t){if("u">typeof ClipboardItem&&"u">typeof navigator&&navigator.clipboard&&"function"==typeof navigator.clipboard.write)try{return await navigator.clipboard.write([new ClipboardItem({"image/png":e})]),"clipboard"}catch{}return M(e,t)?"download":"failed"}function M(e,t){try{if("u"<typeof document||"u"<typeof URL)return!1;let s=URL.createObjectURL(e),a=document.createElement("a");return a.href=s,a.download=t,a.style.display="none",document.body.appendChild(a),a.click(),a.remove(),queueMicrotask(()=>URL.revokeObjectURL(s)),!0}catch{return!1}}function T(e){switch(e){case"native":return"✅ image attached — pick where to post";case"clipboard":return"📋 image copied — paste it in the post (⌘/Ctrl+V)";case"download":return"⬇ image downloaded — attach it to your post";case"failed":return"couldn't capture image — opening text-only share"}}var q=e.i(55574);function A({archetypeKey:e}){let s=m[e]??m.optimist,a=[];for(let e=0;e<8;e++){let r=s[e]??"........";for(let s=0;s<8;s++){let i=r[s]??".",o="px";"o"===i?o+=" on":"p"===i?o+=" p":"g"===i?o+=" g":"d"===i&&(o+=" d"),a.push((0,t.jsx)("div",{className:o},`${e}-${s}`))}}return(0,t.jsx)("div",{className:"sigil",children:a})}let E="npx -y failproofai audit · @failproofai",R="npx -y failproofai audit · @Failproof AI",L=[({score:e,arch:t})=>`my agent has a personality and it's ${t}. did not see that coming.
2
2
 
3
3
  ran a failproof audit, scored ${e}/100, all local. find out what yours is → ${E}`,({score:e,arch:t})=>`spent 30 seconds auditing my agent. learned more about it than i did all month.
4
4
 
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,{otherChunks:["static/chunks/1c6aptmytnu6q.js","static/chunks/2yuzx8716maf0.js","static/chunks/3i8rg2fv9nd6e.js","static/chunks/06jxjnw8bfczc.js"],runtimeModuleIds:[94553]}]),(()=>{let e;if(!Array.isArray(globalThis.TURBOPACK))return;var t,r=function(){if(null!=self.TURBOPACK_ASSET_SUFFIX)return self.TURBOPACK_ASSET_SUFFIX;let e=document?.currentScript?.getAttribute?.("src")??"",t=e.indexOf("?");return t>=0?e.slice(t):""}(),n=((t=n||{})[t.Runtime=0]="Runtime",t[t.Parent=1]="Parent",t[t.Update=2]="Update",t);let o=new WeakMap;function l(e,t){this.m=e,this.e=t}let i=l.prototype,u=Object.prototype.hasOwnProperty,s="u">typeof Symbol&&Symbol.toStringTag;function c(e,t,r){u.call(e,t)||Object.defineProperty(e,t,r)}function a(e,t){let r=e[t];return r||(r=f(t),e[t]=r),r}function f(e){return{exports:{},error:void 0,id:e,namespaceObject:void 0}}function p(e,t,r){c(e,"__esModule",{value:!0}),s&&c(e,s,{value:"Module"});let n=0;for(;n<t.length;){let r=t[n++],o=t[n++];if("number"==typeof o)if(0===o)c(e,r,{value:t[n++],enumerable:!0,writable:!1});else throw Error(`unexpected tag: ${o}`);else"function"==typeof t[n]?c(e,r,{get:o,set:t[n++],enumerable:!0}):c(e,r,{get:o,enumerable:!0})}r||Object.seal(e)}function h(e,t){(null!=t?a(this.c,t):this.m).exports=e}i.s=function(e,t,r){let n,o;null!=t?o=(n=a(this.c,t)).exports:(n=this.m,o=this.e),n.namespaceObject=o,p(o,e,r)},i.j=function(e,t){let r,n;null!=t?n=(r=a(this.c,t)).exports:(r=this.m,n=this.e);let l=function(e,t){let r=o.get(e);if(!r){o.set(e,r=[]);let n=e=>{if("default"!==e){for(let t of r)if(u.call(t,e))return t}};e.exports=e.namespaceObject=new Proxy(t,{get(e,t){if(u.call(e,t)||"default"===t||"__esModule"===t)return Reflect.get(e,t);let r=n(t);return r&&Reflect.get(r,t)},set:()=>!1,defineProperty:()=>!1,deleteProperty:()=>!1,has:(e,t)=>!!Reflect.has(e,t)||"default"!==t&&"__esModule"!==t&&void 0!==n(t),ownKeys(e){let t=Reflect.ownKeys(e);for(let e of r)for(let r of Reflect.ownKeys(e))"default"===r||t.includes(r)||t.push(r);return t},getOwnPropertyDescriptor(e,t){let r=Reflect.getOwnPropertyDescriptor(e,t);if(r||"default"===t||"__esModule"===t)return r;let o=n(t);if(o)return{enumerable:!0,configurable:!0,get:()=>Reflect.get(o,t)}}})}return r}(r,n);"object"==typeof e&&null!==e&&l.push(e)},i.v=h,i.n=function(e,t){let r;(r=null!=t?a(this.c,t):this.m).exports=r.namespaceObject=e};let d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,m=[null,d({}),d([]),d(d)];function y(e,t,r){let n=[],o=-1;for(let t=e;("object"==typeof t||"function"==typeof t)&&!m.includes(t);t=d(t))for(let r of Object.getOwnPropertyNames(t))n.push(r,function(e,t){return()=>e[t]}(e,r)),-1===o&&"default"===r&&(o=n.length-1);return r&&o>=0||(o>=0?n.splice(o,1,0,e):n.push("default",0,e)),p(t,n),t}function g(e){let t=K(e,this.m);if(t.namespaceObject)return t.namespaceObject;let r=t.exports;return t.namespaceObject=y(r,"function"==typeof r?function(...e){return r.apply(this,e)}:Object.create(null),r&&r.__esModule)}function b(e){let t=e.indexOf("#");-1!==t&&(e=e.substring(0,t));let r=e.indexOf("?");return -1!==r&&(e=e.substring(0,r)),e}i.i=g,i.A=function(e){return this.r(e)(g.bind(this))},i.t="function"==typeof require?require:function(){throw Error("Unexpected use of runtime require")},i.r=function(e){return K(e,this.m).exports},i.f=function(e){function t(t){if(t=b(t),u.call(e,t))return e[t].module();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r}return t.keys=()=>Object.keys(e),t.resolve=t=>{if(t=b(t),u.call(e,t))return e[t].id();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r},t.import=async e=>await t(e),t};let O=function(e){let t=new URL(e,"x:/"),r={};for(let e in t)r[e]=t[e];for(let t in r.href=e,r.pathname=e.replace(/[?#].*/,""),r.origin=r.protocol="",r.toString=r.toJSON=(...t)=>e,r)Object.defineProperty(this,t,{enumerable:!0,configurable:!0,value:r[t]})};function w(e,t){throw Error(`Invariant: ${t(e)}`)}O.prototype=URL.prototype,i.U=O,i.z=function(e){throw Error("dynamic usage of require is not supported")},i.g=globalThis;let R=l.prototype,k="string"==typeof TURBOPACK_CHUNK_BASE_PATH?TURBOPACK_CHUNK_BASE_PATH:"/_next/",U=new Map;i.M=U;let v=new Map,_=new Map,P=new Map;async function j(e,t,r){let n;if("string"==typeof r)return function(e,t,r){return A(e,t,r)}(e,t,E(r));let o=r.included||[],l=o.map(e=>!!U.has(e)||v.get(e));if(l.length>0&&l.every(e=>e))return void await Promise.all(l);for(let l of(n=A(e,t,E(r.path)),o))v.has(l)||v.set(l,n);await n}R.l=function(e){return j(n.Parent,this.m.id,e)};let C=Promise.resolve(void 0),$=new WeakMap;function A(t,r,o){let l=e.loadChunkCached(t,o),i=$.get(l);if(void 0===i){let e=$.set.bind($,l,C);i=l.then(e).catch(e=>{let l;switch(t){case n.Runtime:l=`as a runtime dependency of chunk ${r}`;break;case n.Parent:l=`from module ${r}`;break;case n.Update:l="from an HMR update";break;default:w(t,e=>`Unknown source type: ${e}`)}let i=Error(`Failed to load chunk ${o} ${l}${e?`: ${e}`:""}`,e?{cause:e}:void 0);throw i.name="ChunkLoadError",i}),$.set(l,i)}return i}R.L=function(e){var t,r;return t=n.Parent,r=this.m.id,A(t,r,e)};R.R=function(e){let t=this.r(e);return t?.default??t},R.P=function(e){return`/ROOT/${e??""}`},R.F=function(e){return e?`file:///ROOT/${e.split("/").map(encodeURIComponent).join("/")}`:"file:///ROOT/"},R.q=function(e,t){h.call(this,`${e}${r}`,t)};let T=/[^A-Za-z0-9\-_.!~*'()/]/;function E(e,t=k){let n=T.test(e)?e.split("/").map(encodeURIComponent).join("/"):e;return`${t}${n}${r}`}function S(e,t){let r,n=e.indexOf("?");if(-1!==n)r=n;else{let t=e.indexOf("#");r=-1!==t?t:e.length}return r>=t.length&&e.startsWith(t,r-t.length)}R.b=k,R.X=r,R.h=E;function x(e){return S(e,".css")}let M={};i.c=M;let K=(e,t)=>{let r=M[e];if(r){if(r.error)throw r.error;return r}return N(e,n.Parent,t.id)};function N(e,t,r){let n=U.get(e);if("function"!=typeof n)throw Error(function(e,t,r){let n;switch(t){case 0:n=`as a runtime entry of chunk ${r}`;break;case 1:n=`because it was required from module ${r}`;break;case 2:n="because of an HMR update";break;default:w(t,e=>`Unknown source type: ${e}`)}return`Module ${e} was instantiated ${n}, but the module factory is not available.`}(e,t,r));let o=f(e),i=o.exports;M[e]=o;let u=new l(o,i);try{n(u,o,i)}catch(e){throw o.error=e,e}return o.namespaceObject&&o.exports!==o.namespaceObject&&y(o.exports,o.namespaceObject),o}function B(t){let r;if(!Array.isArray(t))return e.registerChunk(void 0,t);let n=function(e){if("string"==typeof e)return e;if(e)return{src:e.getAttribute("src")};if("u">typeof TURBOPACK_NEXT_CHUNK_URLS)return{src:TURBOPACK_NEXT_CHUNK_URLS.pop()};throw Error("chunk path empty but not in a worker")}(t[0]);return 2===t.length?r=t[1]:(r=void 0,!function(e,t){let r=1;for(;r<e.length;){let n,o=r+1;for(;o<e.length&&"function"!=typeof e[o];)o++;if(o===e.length)throw Error("malformed chunk format, expected a factory function");let l=e[o];for(let l=r;l<o;l++){let r=e[l],o=t.get(r);if(o){n=o;break}}let i=n??l,u=!1;for(let n=r;n<o;n++){let r=e[n];t.has(r)||(u||(i===l&&Object.defineProperty(l,"name",{value:"module evaluation"}),u=!0),t.set(r,i))}r=o+1}}(t,U)),e.registerChunk(n,r)}let L=new Map;function I(e){let t=L.get(e);if(!t){let r,n;t={resolved:!1,loadingStarted:!1,retryAttempts:0,promise:new Promise((e,t)=>{r=e,n=t}),resolve:()=>{t.resolved=!0,r()},reject:n},L.set(e,t)}return t}function q(e,t,r,n,o){!(null==n||n instanceof DOMException&&"NetworkError"===n.name)||r.retryAttempts>=1||L.get(t)!==r?(L.get(t)===r&&L.delete(t),r.reject(n)):(r.retryAttempts++,setTimeout(()=>{r.resolved||L.get(t)!==r||(o?o():(r.loadingStarted=!1,H(e,t)))},200+Math.floor(401*Math.random())))}function H(e,t){let r=I(t);if(r.loadingStarted)return r.promise;if(e===n.Runtime)return r.loadingStarted=!0,x(t)&&r.resolve(),r.promise;if("function"==typeof importScripts)if(x(t));else if(S(t,".js")){self.TURBOPACK_NEXT_CHUNK_URLS.push(t);try{importScripts(t)}catch(n){q(e,t,r,n)}}else throw Error(`can't infer type of chunk from URL ${t} in worker`);else{let n=decodeURI(t);if(x(t))if(document.querySelectorAll(`link[rel=stylesheet][href="${t}"],link[rel=stylesheet][href^="${t}?"],link[rel=stylesheet][href="${n}"],link[rel=stylesheet][href^="${n}?"]`).length>0)r.resolve();else{let n=()=>{let o=document.createElement("link");return o.rel="stylesheet",o.crossOrigin=null,o.href=t,o.onerror=()=>{let l=document.createComment("");o.replaceWith(l),q(e,t,r,void 0,()=>l.replaceWith(n()))},o.onload=()=>{r.resolve()},o};document.head.appendChild(n())}else if(S(t,".js")){let o=document.querySelectorAll(`script[src="${t}"],script[src^="${t}?"],script[src="${n}"],script[src^="${n}?"]`);if(o.length>0)for(let n of Array.from(o))n.addEventListener("error",()=>{n.remove(),q(e,t,r)},{once:!0});else{let n=document.createElement("script");n.crossOrigin=null,n.src=t,n.onerror=()=>{n.remove(),q(e,t,r)},document.head.appendChild(n)}}else throw Error(`can't infer type of chunk from URL ${t}`)}return r.loadingStarted=!0,r.promise}e={async registerChunk(e,t){let r;if(null!=e&&(r=function(e){if("string"==typeof e)return e;let t=decodeURIComponent(e.src.replace(/[?#].*$/,""));return t.startsWith(k)?t.slice(k.length):t}(e),I("string"==typeof e?E(e):e.src).resolve()),null!=t){for(let e of t.otherChunks)I(E("string"==typeof e?e:e.path));if(await Promise.all(t.otherChunks.map(e=>{var t;return t=r,j(n.Runtime,t,e)})),t.runtimeModuleIds.length>0)for(let e of t.runtimeModuleIds)!function(e,t){let r=M[t];if(r){if(r.error)throw r.error;return}N(t,n.Runtime,e)}(r,e)}},loadChunkCached:(e,t)=>H(e,t)};var F=globalThis.TURBOPACK;globalThis.TURBOPACK={push:B},F.forEach(B)})();
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,{otherChunks:["static/chunks/1c6aptmytnu6q.js","static/chunks/2yuzx8716maf0.js","static/chunks/3i8rg2fv9nd6e.js","static/chunks/0542cuk_va8g1.js"],runtimeModuleIds:[94553]}]),(()=>{let e;if(!Array.isArray(globalThis.TURBOPACK))return;var t,r=function(){if(null!=self.TURBOPACK_ASSET_SUFFIX)return self.TURBOPACK_ASSET_SUFFIX;let e=document?.currentScript?.getAttribute?.("src")??"",t=e.indexOf("?");return t>=0?e.slice(t):""}(),n=((t=n||{})[t.Runtime=0]="Runtime",t[t.Parent=1]="Parent",t[t.Update=2]="Update",t);let o=new WeakMap;function l(e,t){this.m=e,this.e=t}let i=l.prototype,u=Object.prototype.hasOwnProperty,s="u">typeof Symbol&&Symbol.toStringTag;function c(e,t,r){u.call(e,t)||Object.defineProperty(e,t,r)}function a(e,t){let r=e[t];return r||(r=f(t),e[t]=r),r}function f(e){return{exports:{},error:void 0,id:e,namespaceObject:void 0}}function p(e,t,r){c(e,"__esModule",{value:!0}),s&&c(e,s,{value:"Module"});let n=0;for(;n<t.length;){let r=t[n++],o=t[n++];if("number"==typeof o)if(0===o)c(e,r,{value:t[n++],enumerable:!0,writable:!1});else throw Error(`unexpected tag: ${o}`);else"function"==typeof t[n]?c(e,r,{get:o,set:t[n++],enumerable:!0}):c(e,r,{get:o,enumerable:!0})}r||Object.seal(e)}function h(e,t){(null!=t?a(this.c,t):this.m).exports=e}i.s=function(e,t,r){let n,o;null!=t?o=(n=a(this.c,t)).exports:(n=this.m,o=this.e),n.namespaceObject=o,p(o,e,r)},i.j=function(e,t){let r,n;null!=t?n=(r=a(this.c,t)).exports:(r=this.m,n=this.e);let l=function(e,t){let r=o.get(e);if(!r){o.set(e,r=[]);let n=e=>{if("default"!==e){for(let t of r)if(u.call(t,e))return t}};e.exports=e.namespaceObject=new Proxy(t,{get(e,t){if(u.call(e,t)||"default"===t||"__esModule"===t)return Reflect.get(e,t);let r=n(t);return r&&Reflect.get(r,t)},set:()=>!1,defineProperty:()=>!1,deleteProperty:()=>!1,has:(e,t)=>!!Reflect.has(e,t)||"default"!==t&&"__esModule"!==t&&void 0!==n(t),ownKeys(e){let t=Reflect.ownKeys(e);for(let e of r)for(let r of Reflect.ownKeys(e))"default"===r||t.includes(r)||t.push(r);return t},getOwnPropertyDescriptor(e,t){let r=Reflect.getOwnPropertyDescriptor(e,t);if(r||"default"===t||"__esModule"===t)return r;let o=n(t);if(o)return{enumerable:!0,configurable:!0,get:()=>Reflect.get(o,t)}}})}return r}(r,n);"object"==typeof e&&null!==e&&l.push(e)},i.v=h,i.n=function(e,t){let r;(r=null!=t?a(this.c,t):this.m).exports=r.namespaceObject=e};let d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,m=[null,d({}),d([]),d(d)];function y(e,t,r){let n=[],o=-1;for(let t=e;("object"==typeof t||"function"==typeof t)&&!m.includes(t);t=d(t))for(let r of Object.getOwnPropertyNames(t))n.push(r,function(e,t){return()=>e[t]}(e,r)),-1===o&&"default"===r&&(o=n.length-1);return r&&o>=0||(o>=0?n.splice(o,1,0,e):n.push("default",0,e)),p(t,n),t}function g(e){let t=K(e,this.m);if(t.namespaceObject)return t.namespaceObject;let r=t.exports;return t.namespaceObject=y(r,"function"==typeof r?function(...e){return r.apply(this,e)}:Object.create(null),r&&r.__esModule)}function b(e){let t=e.indexOf("#");-1!==t&&(e=e.substring(0,t));let r=e.indexOf("?");return -1!==r&&(e=e.substring(0,r)),e}i.i=g,i.A=function(e){return this.r(e)(g.bind(this))},i.t="function"==typeof require?require:function(){throw Error("Unexpected use of runtime require")},i.r=function(e){return K(e,this.m).exports},i.f=function(e){function t(t){if(t=b(t),u.call(e,t))return e[t].module();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r}return t.keys=()=>Object.keys(e),t.resolve=t=>{if(t=b(t),u.call(e,t))return e[t].id();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r},t.import=async e=>await t(e),t};let O=function(e){let t=new URL(e,"x:/"),r={};for(let e in t)r[e]=t[e];for(let t in r.href=e,r.pathname=e.replace(/[?#].*/,""),r.origin=r.protocol="",r.toString=r.toJSON=(...t)=>e,r)Object.defineProperty(this,t,{enumerable:!0,configurable:!0,value:r[t]})};function w(e,t){throw Error(`Invariant: ${t(e)}`)}O.prototype=URL.prototype,i.U=O,i.z=function(e){throw Error("dynamic usage of require is not supported")},i.g=globalThis;let k=l.prototype,R="string"==typeof TURBOPACK_CHUNK_BASE_PATH?TURBOPACK_CHUNK_BASE_PATH:"/_next/",U=new Map;i.M=U;let v=new Map,_=new Map,P=new Map;async function C(e,t,r){let n;if("string"==typeof r)return function(e,t,r){return A(e,t,r)}(e,t,E(r));let o=r.included||[],l=o.map(e=>!!U.has(e)||v.get(e));if(l.length>0&&l.every(e=>e))return void await Promise.all(l);for(let l of(n=A(e,t,E(r.path)),o))v.has(l)||v.set(l,n);await n}k.l=function(e){return C(n.Parent,this.m.id,e)};let j=Promise.resolve(void 0),$=new WeakMap;function A(t,r,o){let l=e.loadChunkCached(t,o),i=$.get(l);if(void 0===i){let e=$.set.bind($,l,j);i=l.then(e).catch(e=>{let l;switch(t){case n.Runtime:l=`as a runtime dependency of chunk ${r}`;break;case n.Parent:l=`from module ${r}`;break;case n.Update:l="from an HMR update";break;default:w(t,e=>`Unknown source type: ${e}`)}let i=Error(`Failed to load chunk ${o} ${l}${e?`: ${e}`:""}`,e?{cause:e}:void 0);throw i.name="ChunkLoadError",i}),$.set(l,i)}return i}k.L=function(e){var t,r;return t=n.Parent,r=this.m.id,A(t,r,e)};k.R=function(e){let t=this.r(e);return t?.default??t},k.P=function(e){return`/ROOT/${e??""}`},k.F=function(e){return e?`file:///ROOT/${e.split("/").map(encodeURIComponent).join("/")}`:"file:///ROOT/"},k.q=function(e,t){h.call(this,`${e}${r}`,t)};let T=/[^A-Za-z0-9\-_.!~*'()/]/;function E(e,t=R){let n=T.test(e)?e.split("/").map(encodeURIComponent).join("/"):e;return`${t}${n}${r}`}function S(e,t){let r,n=e.indexOf("?");if(-1!==n)r=n;else{let t=e.indexOf("#");r=-1!==t?t:e.length}return r>=t.length&&e.startsWith(t,r-t.length)}k.b=R,k.X=r,k.h=E;function M(e){return S(e,".css")}let x={};i.c=x;let K=(e,t)=>{let r=x[e];if(r){if(r.error)throw r.error;return r}return N(e,n.Parent,t.id)};function N(e,t,r){let n=U.get(e);if("function"!=typeof n)throw Error(function(e,t,r){let n;switch(t){case 0:n=`as a runtime entry of chunk ${r}`;break;case 1:n=`because it was required from module ${r}`;break;case 2:n="because of an HMR update";break;default:w(t,e=>`Unknown source type: ${e}`)}return`Module ${e} was instantiated ${n}, but the module factory is not available.`}(e,t,r));let o=f(e),i=o.exports;x[e]=o;let u=new l(o,i);try{n(u,o,i)}catch(e){throw o.error=e,e}return o.namespaceObject&&o.exports!==o.namespaceObject&&y(o.exports,o.namespaceObject),o}function B(t){let r;if(!Array.isArray(t))return e.registerChunk(void 0,t);let n=function(e){if("string"==typeof e)return e;if(e)return{src:e.getAttribute("src")};if("u">typeof TURBOPACK_NEXT_CHUNK_URLS)return{src:TURBOPACK_NEXT_CHUNK_URLS.pop()};throw Error("chunk path empty but not in a worker")}(t[0]);return 2===t.length?r=t[1]:(r=void 0,!function(e,t){let r=1;for(;r<e.length;){let n,o=r+1;for(;o<e.length&&"function"!=typeof e[o];)o++;if(o===e.length)throw Error("malformed chunk format, expected a factory function");let l=e[o];for(let l=r;l<o;l++){let r=e[l],o=t.get(r);if(o){n=o;break}}let i=n??l,u=!1;for(let n=r;n<o;n++){let r=e[n];t.has(r)||(u||(i===l&&Object.defineProperty(l,"name",{value:"module evaluation"}),u=!0),t.set(r,i))}r=o+1}}(t,U)),e.registerChunk(n,r)}let L=new Map;function I(e){let t=L.get(e);if(!t){let r,n;t={resolved:!1,loadingStarted:!1,retryAttempts:0,promise:new Promise((e,t)=>{r=e,n=t}),resolve:()=>{t.resolved=!0,r()},reject:n},L.set(e,t)}return t}function q(e,t,r,n,o){!(null==n||n instanceof DOMException&&"NetworkError"===n.name)||r.retryAttempts>=1||L.get(t)!==r?(L.get(t)===r&&L.delete(t),r.reject(n)):(r.retryAttempts++,setTimeout(()=>{r.resolved||L.get(t)!==r||(o?o():(r.loadingStarted=!1,H(e,t)))},200+Math.floor(401*Math.random())))}function H(e,t){let r=I(t);if(r.loadingStarted)return r.promise;if(e===n.Runtime)return r.loadingStarted=!0,M(t)&&r.resolve(),r.promise;if("function"==typeof importScripts)if(M(t));else if(S(t,".js")){self.TURBOPACK_NEXT_CHUNK_URLS.push(t);try{importScripts(t)}catch(n){q(e,t,r,n)}}else throw Error(`can't infer type of chunk from URL ${t} in worker`);else{let n=decodeURI(t);if(M(t))if(document.querySelectorAll(`link[rel=stylesheet][href="${t}"],link[rel=stylesheet][href^="${t}?"],link[rel=stylesheet][href="${n}"],link[rel=stylesheet][href^="${n}?"]`).length>0)r.resolve();else{let n=()=>{let o=document.createElement("link");return o.rel="stylesheet",o.crossOrigin=null,o.href=t,o.onerror=()=>{let l=document.createComment("");o.replaceWith(l),q(e,t,r,void 0,()=>l.replaceWith(n()))},o.onload=()=>{r.resolve()},o};document.head.appendChild(n())}else if(S(t,".js")){let o=document.querySelectorAll(`script[src="${t}"],script[src^="${t}?"],script[src="${n}"],script[src^="${n}?"]`);if(o.length>0)for(let n of Array.from(o))n.addEventListener("error",()=>{n.remove(),q(e,t,r)},{once:!0});else{let n=document.createElement("script");n.crossOrigin=null,n.src=t,n.onerror=()=>{n.remove(),q(e,t,r)},document.head.appendChild(n)}}else throw Error(`can't infer type of chunk from URL ${t}`)}return r.loadingStarted=!0,r.promise}e={async registerChunk(e,t){let r;if(null!=e&&(r=function(e){if("string"==typeof e)return e;let t=decodeURIComponent(e.src.replace(/[?#].*$/,""));return t.startsWith(R)?t.slice(R.length):t}(e),I("string"==typeof e?E(e):e.src).resolve()),null!=t){for(let e of t.otherChunks)I(E("string"==typeof e?e:e.path));if(await Promise.all(t.otherChunks.map(e=>{var t;return t=r,C(n.Runtime,t,e)})),t.runtimeModuleIds.length>0)for(let e of t.runtimeModuleIds)!function(e,t){let r=x[t];if(r){if(r.error)throw r.error;return}N(t,n.Runtime,e)}(r,e)}},loadChunkCached:(e,t)=>H(e,t)};var F=globalThis.TURBOPACK;globalThis.TURBOPACK={push:B},F.forEach(B)})();
@@ -55,6 +55,7 @@ import {
55
55
  baseUrlWithoutQuery,
56
56
  inspectJevConfig,
57
57
  looksLikeCredential,
58
+ parseJevMode,
58
59
  readJevConfigForUpdate,
59
60
  type JevConfig,
60
61
  type JevProviderKind,
@@ -307,7 +308,6 @@ function routingFromRaw(raw: Record<string, unknown> | null): {
307
308
  const provider = (JEV_PROVIDER_KINDS as readonly string[]).includes(providerRaw)
308
309
  ? (providerRaw as JevProviderKind)
309
310
  : null;
310
- const modeRaw = raw?.mode;
311
311
  return {
312
312
  provider,
313
313
  baseUrl: asString(raw?.baseUrl),
@@ -315,7 +315,7 @@ function routingFromRaw(raw: Record<string, unknown> | null): {
315
315
  // refused file may be a pasted key, and is not shown.
316
316
  accountId: CLOUDFLARE_ACCOUNT_ID_RE.test(asString(raw?.accountId)) ? asString(raw?.accountId) : "",
317
317
  model: asString(raw?.model),
318
- mode: modeRaw === "off" || modeRaw === "shadow" || modeRaw === "enforce" ? modeRaw : DEFAULT_JEV_MODE,
318
+ mode: parseJevMode(raw?.mode) ?? DEFAULT_JEV_MODE,
319
319
  };
320
320
  }
321
321
 
@@ -10,7 +10,7 @@
10
10
  * `writeJsonAtomically` the CLI's `jev setup` calls, with the same
11
11
  * `{ mode: 0o600, dirMode: 0o700 }`, after the same `validateJevConfig` the
12
12
  * loader itself runs. Nothing here re-states a rule that lives in
13
- * `jev-config.ts`: not the URL scheme, not "plain http only in shadow mode",
13
+ * `jev-config.ts`: not the URL scheme, not "plain http only in observe mode",
14
14
  * not "cloudflare needs an account id". A second copy of those rules is how the
15
15
  * dashboard ends up writing a file the hooks then refuse — the exact failure
16
16
  * mode this module exists to avoid.
@@ -112,6 +112,7 @@ import {
112
112
  baseUrlWithoutQuery,
113
113
  endpointGivenAsBase,
114
114
  jevConfigPath,
115
+ parseJevMode,
115
116
  providerHostConflict,
116
117
  readJevConfigFileForUpdate,
117
118
  validateApiKey,
@@ -134,7 +135,7 @@ export interface JevConfigInput {
134
135
  baseUrl: string;
135
136
  /** Cloudflare only. */
136
137
  accountId: string;
137
- /** "off" | "shadow" | "enforce". */
138
+ /** "off" | "observe" | "enforce". */
138
139
  mode: string;
139
140
  /** "" keeps the key where it is: the stored one, or the environment's. */
140
141
  token: string;
@@ -303,8 +304,9 @@ export async function saveJevConfigAction(input: JevConfigInput): Promise<JevWri
303
304
 
304
305
  // Refused, as `setJevModeAction` and `jev setup --mode` refuse it — not
305
306
  // skipped, which kept the old mode or wrote none (and none loads as enforce).
306
- if (input.mode !== "off" && input.mode !== "shadow" && input.mode !== "enforce") {
307
- return { ok: false, problem: 'mode must be "off", "shadow" or "enforce".' };
307
+ const mode = parseJevMode(input.mode);
308
+ if (mode === null) {
309
+ return { ok: false, problem: 'mode must be "off", "observe" or "enforce".' };
308
310
  }
309
311
 
310
312
  const baseUrl = input.baseUrl.trim();
@@ -370,7 +372,7 @@ export async function saveJevConfigAction(input: JevConfigInput): Promise<JevWri
370
372
  delete next.accountId;
371
373
  }
372
374
 
373
- next.mode = input.mode;
375
+ next.mode = mode;
374
376
 
375
377
  // Where the key may travel. Unchanged provider AND unchanged origin, from a
376
378
  // file only its owner could have written — anything else asks again.
@@ -459,7 +461,7 @@ export async function saveJevConfigAction(input: JevConfigInput): Promise<JevWri
459
461
  }
460
462
 
461
463
  /**
462
- * Switch Jev's mode — `off`, `shadow` or `enforce` — and change NOTHING else.
464
+ * Switch Jev's mode — `off`, `observe` or `enforce` — and change NOTHING else.
463
465
  *
464
466
  * This is the on/off switch for FailproofAI Cloud's Jev, whose `jev.json` the
465
467
  * page must not delete: its endpoint and key are not this page's to re-enter,
@@ -480,11 +482,12 @@ export async function saveJevConfigAction(input: JevConfigInput): Promise<JevWri
480
482
  * the endpoint it names, and re-saving it at 0600 would start trusting that
481
483
  * endpoint. Jev is already off for such a file; the page shows why and how.
482
484
  */
483
- export async function setJevModeAction(mode: string): Promise<JevWriteResult> {
485
+ export async function setJevModeAction(requested: string): Promise<JevWriteResult> {
484
486
  const refusal = await crossOriginRefusal();
485
487
  if (refusal) return { ok: false, problem: refusal };
486
- if (mode !== "off" && mode !== "shadow" && mode !== "enforce") {
487
- return { ok: false, problem: 'mode must be "off", "shadow" or "enforce".' };
488
+ const mode = parseJevMode(requested);
489
+ if (mode === null) {
490
+ return { ok: false, problem: 'mode must be "off", "observe" or "enforce".' };
488
491
  }
489
492
 
490
493
  const existingFile = readJevConfigFileForUpdate();
@@ -7,7 +7,7 @@
7
7
  * Only the rows where Jev changed or could have changed something get a pill:
8
8
  * a clear (a regex deny Jev overruled), a fallback (Jev's answer was not used —
9
9
  * unavailable, truncated or mismatched — and the regex policies decided alone),
10
- * and a shadow-mode row where Jev disagreed with what was enforced. A fallback
10
+ * and an observe-mode row where Jev disagreed with what was enforced. A fallback
11
11
  * where Jev did answer (the call was truncated to fit the envelope) and its
12
12
  * unapplied verdict was stricter than what was enforced gets a louder fallback
13
13
  * pill; the collector ships that row on its own for the same reason.
@@ -26,16 +26,16 @@ const SEVERITY: Record<string, number> = { allow: 0, instruct: 1, deny: 2 };
26
26
  /** Which pill a row gets, if any. Exported for tests. */
27
27
  export function jevPillKind(
28
28
  item: JevRow,
29
- ): "cleared" | "would-clear" | "fallback" | "fallback-stricter" | "shadow-stricter" | null {
29
+ ): "cleared" | "would-clear" | "fallback" | "fallback-stricter" | "observe-stricter" | null {
30
30
  const e = sanitizeJevActivity(item);
31
31
  const outcome = jevOutcome(e);
32
32
  if (outcome === null || outcome === "not-consulted" || outcome === "no-request") return null;
33
33
  const jevWasStricter = () => (SEVERITY[e.jevDecision ?? "allow"] ?? 0) > (SEVERITY[item.decision ?? "allow"] ?? 0);
34
34
  if (outcome === "fallback") return e.jevDecision !== undefined && jevWasStricter() ? "fallback-stricter" : "fallback";
35
35
  const cleared = (e.jevCleared ?? []).length > 0;
36
- if (e.jevMode === "shadow") {
36
+ if (e.jevMode === "observe") {
37
37
  if (cleared) return "would-clear";
38
- return jevWasStricter() ? "shadow-stricter" : null;
38
+ return jevWasStricter() ? "observe-stricter" : null;
39
39
  }
40
40
  return cleared ? "cleared" : null;
41
41
  }
@@ -47,13 +47,13 @@ const PILLS = {
47
47
  className: "border-sky-500/40 bg-sky-500/10 text-sky-600 dark:text-sky-400",
48
48
  },
49
49
  "would-clear": {
50
- label: "jev shadow",
51
- title: "Shadow mode: Jev would have cleared a block here; the regex result was enforced",
50
+ label: "jev observe",
51
+ title: "Observe mode: Jev would have cleared a block here; the regex result was enforced",
52
52
  className: "border-sky-500/30 bg-sky-500/5 text-sky-600/80 dark:text-sky-400/80",
53
53
  },
54
- "shadow-stricter": {
55
- label: "jev shadow",
56
- title: "Shadow mode: Jev would have been stricter here; the regex result was enforced",
54
+ "observe-stricter": {
55
+ label: "jev observe",
56
+ title: "Observe mode: Jev would have been stricter here; the regex result was enforced",
57
57
  className: "border-sky-500/30 bg-sky-500/5 text-sky-600/80 dark:text-sky-400/80",
58
58
  },
59
59
  "fallback-stricter": {
@@ -68,7 +68,7 @@ const PILLS = {
68
68
  },
69
69
  } as const;
70
70
 
71
- /** Marks a row where Jev cleared, fell back, or (in shadow mode) disagreed. */
71
+ /** Marks a row where Jev cleared, fell back, or (in observe mode) disagreed. */
72
72
  export function JevPill({ item }: { item: JevRow }) {
73
73
  const kind = jevPillKind(item);
74
74
  if (!kind) return null;
@@ -45,7 +45,7 @@
45
45
  * and a save leaves whatever is stored alone.
46
46
  *
47
47
  * Client-side validation here is a convenience only. Every rule — the URL
48
- * scheme, plain http being refused outside shadow mode, cloudflare's account id
48
+ * scheme, plain http being refused outside observe mode, cloudflare's account id
49
49
  * — is enforced server-side by the same `validateJevConfig` the loader runs.
50
50
  *
51
51
  * ## FailproofAI Cloud
@@ -53,7 +53,7 @@
53
53
  * When `jev.json` names the FailproofAI Cloud provider, the endpoint and the
54
54
  * key are not this page's to edit: both come from the machine's connection
55
55
  * (`config --token`). So the form is replaced by the two controls that are
56
- * the owner's — an on/off switch and shadow/enforce — both through
56
+ * the owner's — an on/off switch and observe/enforce — both through
57
57
  * `setJevModeAction`, which rewrites `mode` and nothing else. "Off" there keeps
58
58
  * the file (`mode: "off"`): deleting it would leave nothing on this page to
59
59
  * switch back on — the only way to get the file back would be re-running
@@ -87,7 +87,7 @@ const PROVIDERS = [
87
87
 
88
88
  const MODES = [
89
89
  { value: "enforce", label: "enforce — jev's verdict counts" },
90
- { value: "shadow", label: "shadow — log only, regex decides" },
90
+ { value: "observe", label: "observe — log only, regex decides" },
91
91
  { value: "off", label: "off — keep this config, don't ask jev" },
92
92
  ] as const;
93
93
 
@@ -279,10 +279,10 @@ export default function JevPanel({ initial }: { initial: JevSettingsView | null
279
279
  }, [form, token]);
280
280
 
281
281
  /**
282
- * The FailproofAI Cloud switch: `off`, `shadow` or `enforce`, and nothing
282
+ * The FailproofAI Cloud switch: `off`, `observe` or `enforce`, and nothing
283
283
  * else about the file changes (see `setJevModeAction`).
284
284
  */
285
- const onMode = useCallback(async (mode: "off" | "shadow" | "enforce") => {
285
+ const onMode = useCallback(async (mode: "off" | "observe" | "enforce") => {
286
286
  setBusy(true);
287
287
  setProblem(null);
288
288
  try {
@@ -372,8 +372,8 @@ export default function JevPanel({ initial }: { initial: JevSettingsView | null
372
372
  </span>
373
373
  <span className="set-dim">
374
374
  {view?.on
375
- ? view.mode === "shadow"
376
- ? "shadow: jev's answers are logged, the regex result is what gets enforced."
375
+ ? view.mode === "observe"
376
+ ? "observe: jev's answers are logged, the regex result is what gets enforced."
377
377
  : "enforce: jev's answers can clear a reviewable deny."
378
378
  : cloudRoute
379
379
  ? "through FailproofAI Cloud, on your org's plan — no endpoint or token of your own."
@@ -483,9 +483,9 @@ export default function JevPanel({ initial }: { initial: JevSettingsView | null
483
483
  <select
484
484
  id="jev-cloud-mode"
485
485
  className="set-select"
486
- value={view?.mode === "enforce" ? "enforce" : "shadow"}
486
+ value={view?.mode === "enforce" ? "enforce" : "observe"}
487
487
  disabled={busy || view?.mode === "off"}
488
- onChange={(e) => void onMode(e.target.value === "enforce" ? "enforce" : "shadow")}
488
+ onChange={(e) => void onMode(e.target.value === "enforce" ? "enforce" : "observe")}
489
489
  >
490
490
  {MODES.filter((m) => m.value !== "off").map((m) => (
491
491
  <option key={m.value} value={m.value}>
@@ -503,7 +503,7 @@ export default function JevPanel({ initial }: { initial: JevSettingsView | null
503
503
  type="button"
504
504
  className="btn btn-press"
505
505
  disabled={busy}
506
- onClick={() => void onMode(view?.mode === "off" ? "shadow" : "off")}
506
+ onClick={() => void onMode(view?.mode === "off" ? "observe" : "off")}
507
507
  >
508
508
  {busy ? "[ switching… ]" : view?.mode === "off" ? "[ turn jev on ]" : "[ turn jev off ]"}
509
509
  </button>
@@ -533,7 +533,7 @@ export default function JevPanel({ initial }: { initial: JevSettingsView | null
533
533
  label="endpoint url"
534
534
  hint={[
535
535
  form.provider === "custom"
536
- ? "required — https, or http to localhost in shadow mode"
536
+ ? "required — https, or http to localhost in observe mode"
537
537
  : "leave blank for the provider's own api",
538
538
  // The stored query string is not sent to this page (see
539
539
  // `baseUrlView` in `get-jev-config.ts`), so the field holds the URL
@@ -16,6 +16,8 @@
16
16
 
17
17
  ### Changed
18
18
 
19
+ - `fp guardrails summary` shows how many machines run Jev in each mode, reading the summary's
20
+ `jev.machines.observe` and `jev.machines.enforce`.
19
21
  - `fp policies publish` (and `policies compose --publish`) refuses a source carrying Jev
20
22
  fields a cloud policy never reads — a `semanticPolicies.add(...)` call, or a registration
21
23
  declaring `authority: "reviewable"` — before anything is sent (exit 1, `--no-verify` does
@@ -6217,6 +6217,22 @@ def render_deploy_plan(plan: Any, *, applied: bool = False) -> None:
6217
6217
  _stdout.print(); _stdout.print(Padding(card, (0, 0, 0, 2))); _stdout.print()
6218
6218
 
6219
6219
 
6220
+ def jev_machine_counts(summary: dict) -> tuple:
6221
+ """``(observe, enforce)`` machines running Jev, from the summary's ``jev.machines``.
6222
+
6223
+ ``(0, 0)`` when the server says nothing about Jev.
6224
+ """
6225
+ jev = summary.get("jev") if isinstance(summary, dict) else None
6226
+ machines = jev.get("machines") if isinstance(jev, dict) else None
6227
+ if not isinstance(machines, dict):
6228
+ return 0, 0
6229
+
6230
+ def count(v) -> int:
6231
+ return v if isinstance(v, int) and not isinstance(v, bool) and v > 0 else 0
6232
+
6233
+ return count(machines.get("observe")), count(machines.get("enforce"))
6234
+
6235
+
6220
6236
  def render_guardrails(summary: dict, timeline: Optional[dict] = None) -> None:
6221
6237
  """``fp guardrails`` — what actually happened, as opposed to what was intended."""
6222
6238
  totals = summary.get("totals") or {}
@@ -6230,6 +6246,16 @@ def render_guardrails(summary: dict, timeline: Optional[dict] = None) -> None:
6230
6246
  stat.append(" machines enforcing", style=theme.LABEL)
6231
6247
  body = [stat]
6232
6248
 
6249
+ observe, enforce = jev_machine_counts(summary)
6250
+ if observe or enforce:
6251
+ jev = Text()
6252
+ jev.append("jev ", style=theme.LABEL)
6253
+ jev.append(str(observe), style="bold white")
6254
+ jev.append(" observe ", style=theme.LABEL)
6255
+ jev.append(str(enforce), style="bold white")
6256
+ jev.append(" enforce", style=theme.LABEL)
6257
+ body.append(jev)
6258
+
6233
6259
  if timeline:
6234
6260
  # Every source, summed — a sparkline drawn from series[0] alone sat
6235
6261
  # beside a headline number computed from ALL sources, so the shape and