thumbgate 1.29.2 → 1.31.0

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 (111) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.well-known/mcp/server-card.json +1 -1
  3. package/README.md +54 -16
  4. package/adapters/claude/.mcp.json +2 -2
  5. package/adapters/forge/forge.yaml +3 -3
  6. package/adapters/mcp/server-stdio.js +143 -14
  7. package/adapters/opencode/opencode.json +1 -1
  8. package/bench/observability-eval-suite.json +2 -2
  9. package/bin/cli.js +154 -36
  10. package/config/evals/generation-quality-golden.json +95 -0
  11. package/config/evals/rag-answer-quality-golden.json +91 -0
  12. package/config/evals/retrieval-hybrid-ablation.json +66 -0
  13. package/config/evals/retrieval-ranking-golden.json +522 -0
  14. package/config/gates/default.json +217 -50
  15. package/config/mcp-allowlists.json +215 -185
  16. package/config/model-tiers.json +7 -2
  17. package/config/post-deploy-marketing-pages.json +26 -1
  18. package/glama.json +6 -0
  19. package/package.json +94 -11
  20. package/public/architecture.html +130 -0
  21. package/public/assets/diagrams/agent-integration.png +0 -0
  22. package/public/assets/diagrams/before-after.svg +22 -0
  23. package/public/assets/diagrams/decision.svg +36 -0
  24. package/public/assets/diagrams/feedback-pipeline.png +0 -0
  25. package/public/assets/diagrams/hero-thumbs.svg +68 -0
  26. package/public/assets/diagrams/loop.svg +40 -0
  27. package/public/assets/diagrams/plugin-topology.png +0 -0
  28. package/public/assets/diagrams/pre-action-gate-loop.svg +59 -0
  29. package/public/assets/diagrams/self-improving-thumbs-loop.svg +105 -0
  30. package/public/assets/diagrams/stack.svg +18 -0
  31. package/public/assets/diagrams/thumbgate-architecture.png +0 -0
  32. package/public/case-studies.html +151 -0
  33. package/public/compare.html +1 -0
  34. package/public/dashboard.html +126 -28
  35. package/public/eval-scorecard.html +195 -0
  36. package/public/eval-scorecard.json +18 -0
  37. package/public/evaluations.html +168 -0
  38. package/public/index.html +143 -13
  39. package/public/numbers.html +3 -2
  40. package/public/pricing.html +143 -30
  41. package/public/whitepaper.html +189 -0
  42. package/scripts/a-plus-evidence-scorecard.js +303 -0
  43. package/scripts/activation-quickstart.js +1 -0
  44. package/scripts/agent-outcome-monitor.js +71 -1
  45. package/scripts/async-eval-observability.js +36 -11
  46. package/scripts/audit-trail.js +37 -1
  47. package/scripts/auto-promote-gates.js +149 -34
  48. package/scripts/billing.js +3 -1
  49. package/scripts/claude-feedback-sync.js +3 -2
  50. package/scripts/cli-feedback.js +13 -7
  51. package/scripts/colbert-style-maxsim.js +236 -0
  52. package/scripts/cross-encoder-reranker.js +359 -126
  53. package/scripts/dashboard-chat.js +350 -17
  54. package/scripts/document-intake.js +283 -7
  55. package/scripts/eval-quality-suite.js +204 -0
  56. package/scripts/feedback-aggregate.js +5 -2
  57. package/scripts/feedback-loop.js +359 -189
  58. package/scripts/feedback-paths.js +32 -13
  59. package/scripts/feedback-quality.js +53 -0
  60. package/scripts/filesystem-search.js +17 -7
  61. package/scripts/gates-engine.js +98 -4
  62. package/scripts/generate-case-study-outreach.js +253 -0
  63. package/scripts/generate-eval-scorecard.js +276 -0
  64. package/scripts/growth-campaigns.js +183 -0
  65. package/scripts/harness-tool-names.js +70 -0
  66. package/scripts/hook-runtime.js +10 -3
  67. package/scripts/jsonl-watcher.js +1 -0
  68. package/scripts/lesson-db.js +16 -5
  69. package/scripts/lesson-embedding-index.js +67 -20
  70. package/scripts/lesson-embedding-maintenance.js +177 -0
  71. package/scripts/lesson-inference.js +23 -4
  72. package/scripts/lesson-reranker.js +55 -9
  73. package/scripts/lesson-retrieval.js +375 -32
  74. package/scripts/lesson-search.js +48 -11
  75. package/scripts/llm-client.js +304 -15
  76. package/scripts/mcp-config.js +26 -5
  77. package/scripts/mcp-oauth.js +37 -2
  78. package/scripts/model-eval.js +308 -0
  79. package/scripts/model-tier-router.js +593 -0
  80. package/scripts/parallel-workflow-orchestrator.js +86 -22
  81. package/scripts/pragmatic-hybrid-search.js +379 -0
  82. package/scripts/published-cli.js +11 -1
  83. package/scripts/rag-document-pipeline.js +461 -0
  84. package/scripts/rag-structured-output.js +441 -0
  85. package/scripts/ragas-style-metrics.js +351 -0
  86. package/scripts/refresh-proof-pack.js +261 -0
  87. package/scripts/request-envelope.js +178 -0
  88. package/scripts/rerank-pipeline.js +370 -0
  89. package/scripts/rerank-quality-eval.js +155 -0
  90. package/scripts/retrieval-hybrid-ablation.js +120 -0
  91. package/scripts/retrieval-quality-tier.js +118 -0
  92. package/scripts/risk-scorer.js +144 -15
  93. package/scripts/secret-scanner.js +395 -4
  94. package/scripts/self-distill-agent.js +7 -1
  95. package/scripts/self-healing-check.js +25 -0
  96. package/scripts/skill-packs.js +183 -0
  97. package/scripts/slow-loop.js +72 -0
  98. package/scripts/statusline-links.js +1 -1
  99. package/scripts/statusline-local-stats.js +1 -1
  100. package/scripts/statusline.sh +8 -1
  101. package/scripts/telemetry-analytics.js +13 -1
  102. package/scripts/thumbgate-bench.js +13 -0
  103. package/scripts/thumbgate-search.js +98 -6
  104. package/scripts/tier-budget-guard.js +186 -0
  105. package/scripts/tool-kpi-tracker.js +124 -0
  106. package/scripts/tool-registry.js +95 -1
  107. package/scripts/vector-store.js +108 -4
  108. package/scripts/verify-marketing-pages-deployed.js +85 -3
  109. package/server.json +44 -0
  110. package/smithery.yaml +17 -0
  111. package/src/api/server.js +424 -99
@@ -0,0 +1,168 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="generator" content="ThumbGate">
7
+ <meta name="author" content="Igor Ganapolsky">
8
+ <title>ThumbGate — How We Evaluate | Held-Out Metrics, Drift Gates, Error Analysis</title>
9
+ <meta name="description" content="ThumbGate's evaluation methodology, published including the numbers that don't flatter us: held-out lift over trivial baselines, dual IID/distribution-shift splits, trace-mined drift benchmarks, and the five evaluator bugs we found and fixed.">
10
+ <meta property="og:title" content="ThumbGate — How We Evaluate">
11
+ <meta property="og:description" content="Evaluation methodology with the unflattering numbers left in: +9.9 points held-out lift on familiar traffic, −10.5 on unseen action types. That asymmetry is why deterministic rules enforce and the model only triages.">
12
+ <meta property="og:type" content="article">
13
+ <meta property="og:url" content="https://thumbgate.ai/evaluations">
14
+ <meta name="twitter:card" content="summary_large_image">
15
+ <link rel="canonical" href="https://thumbgate.ai/evaluations">
16
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
17
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
18
+ <script defer data-domain="thumbgate.ai" src="https://plausible.io/js/script.js"></script>
19
+
20
+ <script type="application/ld+json">
21
+ {
22
+ "@context": "https://schema.org",
23
+ "@type": "TechArticle",
24
+ "headline": "How ThumbGate Evaluates Its Own Enforcement",
25
+ "description": "Held-out evaluation methodology for an AI-agent firewall: dual IID/distribution-shift splits, lift over trivial baselines, trace-mined drift benchmarks, published-artifact verification, and the error analysis behind them.",
26
+ "url": "https://thumbgate.ai/evaluations",
27
+ "dateModified": "2026-07-29",
28
+ "author": {
29
+ "@type": "Person",
30
+ "name": "Igor Ganapolsky",
31
+ "url": "https://github.com/IgorGanapolsky",
32
+ "sameAs": [
33
+ "https://github.com/IgorGanapolsky",
34
+ "https://www.linkedin.com/in/igorganapolsky"
35
+ ]
36
+ }
37
+ }
38
+ </script>
39
+
40
+ <style>
41
+ :root {
42
+ --bg: #0b0f14; --panel: #111823; --border: #1e2a3a; --text: #e6edf3;
43
+ --muted: #8b98a5; --cyan: #39c5cf; --green: #3fb950; --red: #f85149; --amber: #d29922;
44
+ }
45
+ * { margin: 0; padding: 0; box-sizing: border-box; }
46
+ body { background: var(--bg); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; }
47
+ nav { padding: 1rem 2rem; border-bottom: 1px solid var(--border); display: flex; gap: 1.5rem; align-items: center; flex-wrap: wrap; }
48
+ nav a { color: var(--muted); text-decoration: none; font-size: 0.9rem; }
49
+ nav a:hover { color: var(--cyan); }
50
+ nav .brand { color: var(--text); font-weight: 700; font-size: 1.05rem; text-decoration: none; }
51
+ .container { max-width: 880px; margin: 0 auto; padding: 2.5rem 1.5rem 4rem; }
52
+ h1 { font-size: 2rem; margin-bottom: 0.5rem; }
53
+ h2 { font-size: 1.35rem; margin: 2.5rem 0 0.75rem; color: var(--cyan); }
54
+ h3 { font-size: 1.05rem; margin: 1.5rem 0 0.5rem; }
55
+ p { margin: 0.75rem 0; color: var(--text); }
56
+ .subtitle { color: var(--muted); font-size: 1.05rem; }
57
+ .panel { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 1.25rem 1.5rem; margin: 1.25rem 0; }
58
+ table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: 0.92rem; }
59
+ th, td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); }
60
+ th { color: var(--muted); font-weight: 600; }
61
+ code { background: #0d1420; border: 1px solid var(--border); border-radius: 4px; padding: 0.1rem 0.35rem; font-size: 0.86em; color: var(--cyan); }
62
+ pre { background: #0d1420; border: 1px solid var(--border); border-radius: 8px; padding: 1rem; overflow-x: auto; font-size: 0.85rem; margin: 1rem 0; }
63
+ .good { color: var(--green); } .bad { color: var(--red); } .warn { color: var(--amber); }
64
+ .chart-caption { color: var(--muted); font-size: 0.85rem; margin-top: 0.4rem; }
65
+ ul { margin: 0.5rem 0 0.75rem 1.4rem; }
66
+ li { margin: 0.35rem 0; }
67
+ .footer-note { color: var(--muted); font-size: 0.85rem; margin-top: 2.5rem; text-align: center; }
68
+ .footer-note a { color: var(--cyan); text-decoration: none; }
69
+ .rule { border-left: 3px solid var(--cyan); padding: 0.6rem 1rem; background: var(--panel); margin: 1.25rem 0; font-weight: 600; }
70
+ </style>
71
+ </head>
72
+ <body>
73
+
74
+ <nav>
75
+ <a class="brand" href="/">ThumbGate</a>
76
+ <a href="/whitepaper">White paper</a>
77
+ <a href="/architecture">Architecture</a>
78
+ <a href="/eval-scorecard">Scorecard</a>
79
+ <a href="/evaluations">Evaluations</a>
80
+ <a href="/case-studies">Case studies</a>
81
+ <a href="/numbers">Numbers</a>
82
+ <a href="/pricing">Pricing</a>
83
+ </nav>
84
+
85
+ <main class="container">
86
+ <h1>How We Evaluate</h1>
87
+ <p class="subtitle">The methodology behind ThumbGate's enforcement quality — published with the numbers that don't flatter us left in. Every figure on this page is reproducible from the open-source repo with one command.</p>
88
+
89
+ <h2>The headline we retired</h2>
90
+ <p>ThumbGate's learned risk model used to report one quality figure: <code>trainingAccuracy: 0.820</code> — measured on the same rows it trained on, against a corpus where answering "risky" unconditionally scores 71.1%. That is an 11-point in-sample lift presented as an 82-point achievement, and it said nothing about generalization at all.</p>
91
+ <p>We replaced it with held-out evaluation under two different splits, and we publish both results — including the one that inverts.</p>
92
+
93
+ <h2>The result, honestly</h2>
94
+ <div class="panel">
95
+ <svg viewBox="0 0 640 260" role="img" aria-label="Bar chart: accuracy lift over the majority baseline. In-sample plus 10.9 points, held-out IID plus 9.9 points, held-out novel-context minus 10.5 points.">
96
+ <line x1="60" y1="130" x2="620" y2="130" stroke="#1e2a3a" stroke-width="1"/>
97
+ <text x="30" y="40" fill="#8b98a5" font-size="11">+12</text>
98
+ <text x="30" y="134" fill="#8b98a5" font-size="11">0</text>
99
+ <text x="30" y="230" fill="#8b98a5" font-size="11">−12</text>
100
+ <rect x="90" y="48" width="120" height="82" fill="#d29922" rx="3"/>
101
+ <rect x="270" y="55" width="120" height="75" fill="#3fb950" rx="3"/>
102
+ <rect x="450" y="130" width="120" height="79" fill="#f85149" rx="3"/>
103
+ <text x="150" y="40" fill="#d29922" font-size="13" text-anchor="middle">+10.9</text>
104
+ <text x="330" y="47" fill="#3fb950" font-size="13" text-anchor="middle">+9.9</text>
105
+ <text x="510" y="225" fill="#f85149" font-size="13" text-anchor="middle">−10.5</text>
106
+ <text x="150" y="250" fill="#8b98a5" font-size="11" text-anchor="middle">in-sample (old headline)</text>
107
+ <text x="330" y="250" fill="#8b98a5" font-size="11" text-anchor="middle">held-out, familiar kinds</text>
108
+ <text x="510" y="250" fill="#8b98a5" font-size="11" text-anchor="middle">held-out, unseen kinds</text>
109
+ </svg>
110
+ <p class="chart-caption">Accuracy lift over the majority-class baseline, in points. 1,791 production rows, 12 independent group-aware stratified splits, mean across resamples. IID: +9.9 ± 1.7, AUC 0.887, 12/12 folds beat baseline. Novel-context: −10.5 ± 9.0, 1/12 folds, calibration error 0.31 vs 0.06.</p>
111
+ </div>
112
+ <p>On familiar traffic the model genuinely helps. On action types it has never seen, it is <span class="bad">worse than a constant classifier</span> — and unfamiliar actions are precisely the case a firewall exists for. That asymmetry is why <strong>deterministic rules enforce and the model only triages</strong>. We consider publishing that inversion more valuable than hiding it: it is the reason ThumbGate's blocking behaviour does not degrade with the model.</p>
113
+
114
+ <h2>The methodology</h2>
115
+ <table>
116
+ <tr><th>Practice</th><th>What it prevents</th></tr>
117
+ <tr><td>Lift vs the majority baseline, reported beside every accuracy</td><td>71% base-rate corpora making any model look strong</td></tr>
118
+ <tr><td>MCC + ROC-AUC + Brier + calibration error</td><td>accuracy hiding degenerate or miscalibrated behaviour</td></tr>
119
+ <tr><td>Dual holdouts: IID <em>and</em> whole-category (distribution shift)</td><td>quoting only the flattering generalization estimate</td></tr>
120
+ <tr><td>Group-aware splits keyed on the feature vector</td><td>duplicate inputs straddling folds and inflating scores</td></tr>
121
+ <tr><td>12 resamples, mean ± sd, paired t on shared folds</td><td>single lucky splits shipping as "improvements"</td></tr>
122
+ <tr><td>Per-fold vocabulary rebuild</td><td>held-out rows choosing the model's features (transductive fit)</td></tr>
123
+ </table>
124
+
125
+ <h2>The evaluation suites</h2>
126
+ <ul>
127
+ <li><strong>Model harness</strong> — <code>npm run eval:risk</code>: the resampling harness; <code>--json</code> emits the machine-readable report backing this page.</li>
128
+ <li><strong>Trace-mined drift benchmark</strong> — real production gate decisions, redacted, become 60 replayable cases across 12 gates; CI fails when any real command's verdict <em>moves</em>. Silent gate death is the signature of every bypass we have found.</li>
129
+ <li><strong>Evasion matrix</strong> — 14 dangerous commands × 9 canonicalization transforms; this is the suite that measured the 62 holes closed in v1.29.2.</li>
130
+ <li><strong>Published-artifact verification</strong> — the npm tarball itself is installed into a throwaway prefix and driven through its public hook contract twice daily. CI proving the <em>source</em> blocks something is a different claim from the artifact users receive blocking it.</li>
131
+ <li><strong>Decision canary</strong> — live decision-distribution drift: a gate going <em>silent</em>, a <em>spike</em> in blocks, or a gate appearing/disappearing.</li>
132
+ </ul>
133
+
134
+ <h2>The gates that block a release</h2>
135
+ <ul>
136
+ <li>A synthetic-fixture quality gate that separates <em>"the trainer broke"</em> from <em>"the data lacks signal"</em> — different problems, different fixes.</li>
137
+ <li>A <strong>pure-noise canary</strong>: a trainer that finds &gt;15 points of lift in random labels has labels leaking into features, and CI fails.</li>
138
+ <li><strong>Vacuity guards</strong>: a drift test that compared fewer than 20 cases fails; a single-class test fold refuses to report rather than emitting a meaningless pass. A check that cannot fail is treated as no check.</li>
139
+ <li>Non-significant improvements do not ship. Two candidate upgrades (a feature-diversity cap, Platt calibration) are implemented, tested, and <em>off</em> — paired t of −0.31 and −0.72.</li>
140
+ </ul>
141
+
142
+ <h2>Error analysis: the five bugs we found in our own evaluator</h2>
143
+ <p>The uncomfortable finding of this work: the evaluator was wrong more often than the model, and its errors all flattered us.</p>
144
+ <table>
145
+ <tr><th>Bug</th><th>Effect before the fix</th></tr>
146
+ <tr><td>Tied-hash rows straddling folds</td><td>test fold contained memorized rows</td></tr>
147
+ <tr><td>Cross-class duplicate leakage under label noise</td><td>same input in both folds with different labels</td></tr>
148
+ <tr><td>Group quota overshoot (one 655-row category)</td><td class="bad">novel-context result read +0.016; truth is −0.105</td></tr>
149
+ <tr><td>Vocabulary built before the split</td><td>held-out rows chose the model's features</td></tr>
150
+ <tr><td>Raw text in the split key</td><td>identical model inputs split across folds</td></tr>
151
+ </table>
152
+ <p>Three of the five were found by adversarial review <em>after</em> we had published numbers from the leaky evaluator. The corrected conclusion was stronger, not weaker — and the correction is documented in the repo, not overwritten.</p>
153
+
154
+ <div class="rule">The rule all of this enforces: no accuracy figure ships without the baseline it beats and the split it was measured on.</div>
155
+
156
+ <h2>Reproduce it</h2>
157
+ <p>Honest scoping: the measured corpus is <strong>private operator feedback telemetry</strong> and does not ship in the public repo. The exact machine-readable report behind the figures on this page is checked in with provenance at <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/evals/risk-model-report.json">evals/risk-model-report.json</a>. A clean clone gives you that report, the methodology write-up, the CI quality gate (synthetic fixtures / no private data), and the same harness to run against <em>your</em> feedback log. The figures on this page are first-party operator measurements documented in <a style="color:var(--cyan)" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/ML-EVALUATION.md">docs/ML-EVALUATION.md</a> — not a committed private corpus dump.</p>
158
+ <pre>git clone https://github.com/IgorGanapolsky/ThumbGate
159
+ cd ThumbGate &amp;&amp; npm ci
160
+ npm run test:risk-quality # CI quality gate — no private data needed
161
+ # Optional: re-run the harness on your own feedback log
162
+ node scripts/eval-risk-model.js --corpus &lt;your-own-feedback-log&gt; --resamples 12 --json</pre>
163
+ <p>Full methodology: <a style="color:var(--cyan)" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/ML-EVALUATION.md">docs/ML-EVALUATION.md</a> · case studies: <a style="color:var(--cyan)" href="/case-studies">/case-studies</a> · gate scorecard: <a style="color:var(--cyan)" href="/eval-scorecard">/eval-scorecard</a></p>
164
+
165
+ <p class="footer-note">ThumbGate is built in the open by <a href="https://github.com/IgorGanapolsky">Igor Ganapolsky</a>. This page reports first-party measurements only — no customer counts, no install volume, no revenue claims.</p>
166
+ </main>
167
+ </body>
168
+ </html>
package/public/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <meta name="generator" content="ThumbGate">
7
7
  <meta name="author" content="Igor Ganapolsky">
8
- <meta name="thumbgate-version" content="1.29.2">
8
+ <meta name="thumbgate-version" content="1.31.0">
9
9
  __GOOGLE_SITE_VERIFICATION_META__
10
10
  <link rel="icon" type="image/png" href="/thumbgate-icon.png">
11
11
  <link rel="canonical" href="__APP_ORIGIN__/">
@@ -39,7 +39,7 @@
39
39
  "applicationCategory": "DeveloperApplication",
40
40
  "operatingSystem": "macOS, Linux, Windows",
41
41
  "url": "__APP_ORIGIN__",
42
- "description": "Self-improving firewall for AI coding agents. ThumbGate captures feedback as local lessons, re-ranks relevant lessons for each action, promotes repeated negative patterns into warning or blocking gates, expires stale auto-promoted gates, and runs pre-action checks before shell, file, git, deploy, or API tool calls. Detected secret exfiltration and gate-bypass commands are denied by default; strict mode blocks matching destructive-action rules.",
42
+ "description": "Self-improving firewall for AI coding agents. ThumbGate captures feedback as local lessons, re-ranks relevant lessons for each action, promotes repeated negative patterns into warning or blocking gates, expires stale auto-promoted gates, and runs pre-action checks before shell, file, git, deploy, or API tool calls. Detected secret exfiltration and process-kill/environment-override self-disable commands (gate-process bypass) are denied by default; strict mode blocks matching destructive-action rules.",
43
43
  "codeRepository": "https://github.com/IgorGanapolsky/ThumbGate",
44
44
  "featureList": [
45
45
  "Pre-action PreToolUse checks for coding agents",
@@ -559,6 +559,104 @@
559
559
  h1 { font-size: 46px; }
560
560
  .checkout-card, .pro-card { padding: 22px 18px; }
561
561
  }
562
+
563
+ /* Visual-first conversion: thumbs + diagrams */
564
+ .hero-thumbs {
565
+ display: flex;
566
+ align-items: center;
567
+ justify-content: flex-start;
568
+ gap: 14px;
569
+ margin: 0 0 18px;
570
+ font-size: clamp(42px, 6vw, 64px);
571
+ line-height: 1;
572
+ filter: drop-shadow(0 0 28px rgba(34, 211, 238, 0.28));
573
+ }
574
+ .hero-thumbs span {
575
+ display: inline-flex;
576
+ width: 1.15em;
577
+ height: 1.15em;
578
+ align-items: center;
579
+ justify-content: center;
580
+ border-radius: 22%;
581
+ background: rgba(17, 23, 34, 0.9);
582
+ border: 1px solid rgba(39, 50, 70, 0.9);
583
+ }
584
+ .hero-thumbs .up { border-color: rgba(86, 227, 159, 0.55); box-shadow: 0 0 0 1px rgba(86, 227, 159, 0.12); }
585
+ .hero-thumbs .down { border-color: rgba(255, 100, 124, 0.55); box-shadow: 0 0 0 1px rgba(255, 100, 124, 0.12); }
586
+ .hero-visual {
587
+ margin: 22px 0 0;
588
+ border: 1px solid rgba(56, 215, 255, 0.22);
589
+ border-radius: 18px;
590
+ overflow: hidden;
591
+ background: #0a1018;
592
+ box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
593
+ }
594
+ .hero-visual img, .diagram-frame img {
595
+ display: block;
596
+ width: 100%;
597
+ height: auto;
598
+ }
599
+ .diagram-strip { padding: 56px 0 12px; }
600
+ .diagram-frame {
601
+ margin: 28px 0 0;
602
+ border: 1px solid rgba(56, 215, 255, 0.2);
603
+ border-radius: 20px;
604
+ overflow-x: auto;
605
+ overflow-y: hidden;
606
+ -webkit-overflow-scrolling: touch;
607
+ background: #0a0a0b;
608
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
609
+ }
610
+ .diagram-frame img {
611
+ min-width: 640px;
612
+ }
613
+ .hero-visual img {
614
+ min-width: 0;
615
+ }
616
+ @media (max-width: 720px) {
617
+ .diagram-frame img {
618
+ min-width: 720px;
619
+ }
620
+ .hero-visual {
621
+ margin-left: -4px;
622
+ margin-right: -4px;
623
+ }
624
+ }
625
+ .diagram-caption {
626
+ margin: 14px 0 0;
627
+ color: var(--muted);
628
+ font-size: 14px;
629
+ text-align: center;
630
+ }
631
+ .self-improve-callout {
632
+ margin: 28px 0 0;
633
+ padding: 20px 22px;
634
+ border: 1px solid rgba(86, 227, 159, 0.3);
635
+ border-radius: 14px;
636
+ background: rgba(86, 227, 159, 0.06);
637
+ color: #c5ceda;
638
+ font-size: 16px;
639
+ line-height: 1.55;
640
+ max-width: 820px;
641
+ }
642
+ .self-improve-callout strong { color: var(--green); }
643
+ .loop-step .thumb-icon {
644
+ display: inline-flex;
645
+ font-size: 28px;
646
+ line-height: 1;
647
+ margin-bottom: 4px;
648
+ }
649
+ .visual-pair {
650
+ display: grid;
651
+ grid-template-columns: 1.1fr 0.9fr;
652
+ gap: 18px;
653
+ margin-top: 28px;
654
+ align-items: stretch;
655
+ }
656
+ @media (max-width: 900px) {
657
+ .visual-pair { grid-template-columns: 1fr; }
658
+ .hero-thumbs { justify-content: center; }
659
+ }
562
660
  </style>
563
661
  </head>
564
662
  <body data-revenue-assist="off">
@@ -584,6 +682,7 @@
584
682
  <div class="shell hero-grid">
585
683
  <div class="hero-copy">
586
684
  <div class="eyebrow">Now live · Pre-action gates · Not a prompt · Not a postmortem</div>
685
+ <div class="hero-thumbs" aria-hidden="true"><span class="up">👍</span><span class="down">👎</span></div>
587
686
  <h1>Stop AI agent mistakes before they cost you.</h1>
588
687
  <p class="hero-lede">Hard allow/deny at the <strong>tool-call boundary</strong>. Audit entry written at decision time. Every approval teaches the next gate.</p>
589
688
  <p class="fit-line"><strong>Dual path (buy + book):</strong> <strong>$499 Diagnostic</strong> maps one expensive failure on Claude Code, Cursor, Codex, or similar agents and installs a hard gate with proof — or self-serve <strong>Pro at $19/mo</strong> if you already know the loop. Free local evaluate stays free.</p>
@@ -593,7 +692,11 @@
593
692
  <span class="spec-chip"><strong>Promote</strong> gates</span>
594
693
  <span class="spec-chip"><strong>Block</strong> next action</span>
595
694
  </div>
695
+ <figure class="hero-visual">
696
+ <img src="/assets/diagrams/hero-thumbs.svg" width="640" height="360" alt="ThumbGate: thumbs up and thumbs down become a pre-action gate that can ALLOW, WARN, or DENY before the tool call runs" loading="eager" decoding="async">
697
+ </figure>
596
698
  <a class="proof-link" href="#proof">See a strict-mode deny example ↓</a>
699
+ <a class="proof-link-secondary" href="#how-it-works" style="margin-left:14px;color:var(--cyan);font-weight:750;text-decoration:none">See how the self-improving loop works ↓</a>
597
700
  <p class="install-hint"><code>npx thumbgate init</code> free local evaluate · first hard gate usually minutes after install · <a href="/pricing">how we stack up</a></p>
598
701
  <p class="install-hint" id="thumbgate-dashboard-command" style="margin-top:10px;">Dashboard: <code>npx thumbgate dashboard --open</code> · <code>/thumbgate-dashboard</code> · bin <code>thumbgate-dashboard</code> if global · <a href="/dashboard#insights">demo</a></p>
599
702
  </div>
@@ -638,34 +741,60 @@
638
741
  </div>
639
742
  </section>
640
743
 
744
+ <section class="diagram-strip" id="before-after" aria-label="Before and after ThumbGate">
745
+ <div class="shell">
746
+ <div class="section-kicker">Why it’s called ThumbGate</div>
747
+ <h2 class="section-title">Thumbs teach. The gate enforces.</h2>
748
+ <div class="visual-pair">
749
+ <figure class="diagram-frame">
750
+ <img src="/assets/diagrams/before-after.svg" width="960" height="300" alt="Without ThumbGate the same AI agent mistake repeats. With ThumbGate one thumbs-down becomes a local pre-action gate that can refresh or expire." loading="lazy" decoding="async">
751
+ </figure>
752
+ <figure class="diagram-frame">
753
+ <img src="/assets/diagrams/loop.svg" width="960" height="300" alt="Agent proposes a tool, ThumbGate decides ALLOW WARN or DENY, thumbs feedback becomes a rule that closes the loop." loading="lazy" decoding="async">
754
+ </figure>
755
+ </div>
756
+ </div>
757
+ </section>
758
+
641
759
  <section id="how-it-works">
642
760
  <div class="shell">
643
761
  <div class="section-kicker">Self-improving product loop</div>
644
762
  <h2 class="section-title">Pre-action checks—and the systems that refine them.</h2>
645
- <p class="section-lede">No governance novel. Corrections become reviewable local lessons; relevant lessons are re-ranked; repeated negative patterns can become explicit gates; and the next action is checked before execution. <strong style="color:var(--text)">Click a step</strong> to see what happens under the hood.</p>
763
+ <p class="section-lede">Corrections become local lessons; repeated negatives become gates; the next action is checked before execution. <strong style="color:var(--text)">Click a step</strong> for the under-the-hood demo.</p>
764
+ <figure class="diagram-frame" style="margin-top:28px">
765
+ <img src="/assets/diagrams/self-improving-thumbs-loop.svg" width="1100" height="420" alt="Self-improving ThumbGate loop: thumbs up or thumbs down become a local lesson, then a prevention rule, then ALLOW WARN or DENY on the next tool call. The loop closes under your control without retraining the model." loading="lazy" decoding="async">
766
+ </figure>
767
+ <div class="self-improve-callout">
768
+ <strong>Is it really self-improving?</strong>
769
+ Yes — the control layer, not the LLM. 👍/👎 → local lesson → ranked rule → next tool call gated. No model retrain.
770
+ </div>
646
771
  <div class="loop" role="tablist" aria-label="Self-improving product loop — click a step for under-the-hood demo">
647
772
  <!-- Cards are divs (not <button>) so headings/chips stay valid HTML; browsers
648
773
  auto-close <button> around <h3>/<div>, which broke click targets. -->
649
774
  <div class="loop-step" role="tab" tabindex="0" id="loop-tab-1" data-loop-step="1" aria-selected="false" aria-controls="loop-panel" aria-expanded="false">
650
775
  <span class="loop-number">1</span>
776
+ <div class="thumb-icon" aria-hidden="true">👍👎</div>
651
777
  <h3>Capture feedback</h3>
652
- <p>Record explicit 👍 or 👎 feedback with the action and outcome context that made it useful or wrong.</p>
778
+ <p>Record explicit 👍 or 👎 with the action and outcome context.</p>
653
779
  <span class="loop-hint">Under the hood ↓</span>
654
780
  </div>
655
781
  <div class="loop-step" role="tab" tabindex="0" id="loop-tab-2" data-loop-step="2" aria-selected="false" aria-controls="loop-panel" aria-expanded="false">
656
782
  <span class="loop-number">2</span>
783
+ <div class="thumb-icon" aria-hidden="true">🧠</div>
657
784
  <h3>Remember locally</h3>
658
- <p>Store a reviewable lesson that survives sessions and model changes without sending the control history into model weights.</p>
785
+ <p>Store a reviewable lesson that survives sessions without writing into model weights.</p>
659
786
  <span class="loop-hint">Under the hood ↓</span>
660
787
  </div>
661
788
  <div class="loop-step" role="tab" tabindex="0" id="loop-tab-3" data-loop-step="3" aria-selected="false" aria-controls="loop-panel" aria-expanded="false">
662
789
  <span class="loop-number">3</span>
790
+ <div class="thumb-icon" aria-hidden="true">📈</div>
663
791
  <h3>Rank and refine</h3>
664
- <p>Re-rank relevant lessons for the action. Repeated negative patterns can promote from warnings to blocking gates; stale gates expire.</p>
792
+ <p>Re-rank lessons for the action. Repeated negatives can promote to blocking gates; stale gates expire.</p>
665
793
  <span class="loop-hint">Under the hood ↓</span>
666
794
  </div>
667
795
  <div class="loop-step" role="tab" tabindex="0" id="loop-tab-4" data-loop-step="4" aria-selected="false" aria-controls="loop-panel" aria-expanded="false">
668
796
  <span class="loop-number">4</span>
797
+ <div class="thumb-icon" aria-hidden="true">🛡️</div>
669
798
  <h3>Gate the next action</h3>
670
799
  <p>The action is allowed, warned, or denied before the tool proceeds.</p>
671
800
  <div class="decisions" aria-label="Possible decisions">
@@ -717,7 +846,7 @@
717
846
  <div class="shell">
718
847
  <div class="section-kicker">What the $499 enterprise gate buys</div>
719
848
  <h2 class="section-title">A managed gate for one painful workflow.</h2>
720
- <p class="section-lede">This is the enterprise entry offer for one workflow, not an org-wide hosted platform license.</p>
849
+ <p class="section-lede">Enterprise entry for one workflownot an org-wide platform license.</p>
721
850
  <div class="deliverables">
722
851
  <article class="deliverable">
723
852
  <h3>Failure map</h3>
@@ -760,9 +889,10 @@ next decision recorded before execution</pre>
760
889
  </div>
761
890
  </div>
762
891
  <div class="proof-copy">
763
- <p>Detected secret exfiltration and attempts to kill or bypass the gate process are denied by default. Matching destructive actions warn by default and deny in strict mode.</p>
764
- <p>The example shows the strict-mode decision the managed install would specify and test. It is not a claim that every free install blocks every risky command automatically.</p>
892
+ <p>Detected secret exfiltration and gate-process bypass attempts are denied by default (process-kill/environment-override self-disable floors). Matching destructive actions warn by default and deny in strict mode.</p>
893
+ <p>Managed strict-mode example—not a claim that every free install blocks every risky command automatically.</p>
765
894
  <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/VERIFICATION_EVIDENCE.md" target="_blank" rel="noopener">Read the test-backed verification evidence →</a>
895
+ <p style="margin-top:12px;"><a href="/whitepaper">White paper</a> · <a href="/eval-scorecard">Scorecard</a> · <a href="/architecture">Architecture</a> · <a href="/case-studies">Cases</a></p>
766
896
  </div>
767
897
  </div>
768
898
  </div>
@@ -801,7 +931,7 @@ next decision recorded before execution</pre>
801
931
  <div class="shell">
802
932
  <div class="section-kicker">Two cash paths</div>
803
933
  <h2 class="section-title">Start self-serve, or bring the failure that already cost you time.</h2>
804
- <p class="section-lede">Pro is the self-serve subscription for operators. The $499 enterprise gate is a managed install for one painful workflow—not another policy deck.</p>
934
+ <p class="section-lede">Pro is self-serve for operators. The $499 gate is a managed install for one painful workflow—not a policy deck.</p>
805
935
  <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:22px">
806
936
  <a class="nav-buy" href="/checkout/pro?utm_source=website&amp;utm_medium=homepage_final&amp;utm_campaign=pro_self_serve&amp;cta_id=final_pro_buy&amp;cta_placement=final&amp;plan_id=pro" data-offer-link data-cta-id="final_pro_buy">Start Pro — $19/mo</a>
807
937
  <a class="nav-enterprise" href="#enterprise-gate" data-offer-link data-cta-id="final_diagnostic_buy">Buy the $499 enterprise gate</a>
@@ -812,7 +942,7 @@ next decision recorded before execution</pre>
812
942
 
813
943
  <footer>
814
944
  <div class="shell footer-inner">
815
- <span>ThumbGate · MIT License · npm v1.29.2</span>
945
+ <span>ThumbGate · MIT License · npm v1.31.0</span>
816
946
  <div class="footer-links">
817
947
  <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub</a>
818
948
  <a href="/guide">Technical setup</a>
@@ -1019,7 +1149,7 @@ next decision recorded before execution</pre>
1019
1149
  'mode <span class="y">warn-by-default</span>\n' +
1020
1150
  'decision <span class="y">WARN</span>\n' +
1021
1151
  'note logged + flagged; tool may still proceed\n\n' +
1022
- 'secret exfil / gate-bypass floors → <span class="r">DENY</span> regardless',
1152
+ 'secret exfil / gate process bypass floors → <span class="r">DENY</span> regardless',
1023
1153
  bodyStrict:
1024
1154
  'proposed git push --force origin main\n' +
1025
1155
  'hook PreToolUse → gates-engine\n' +
@@ -1029,7 +1159,7 @@ next decision recorded before execution</pre>
1029
1159
  'next blocked before execution',
1030
1160
  facts: [
1031
1161
  'PreToolUse hooks check Bash / Edit / Write before the tool runs',
1032
- 'Outcomes: ALLOW, WARN, or DENY',
1162
+ 'Outcomes: allowed, warned, or denied (ALLOW / WARN / DENY)',
1033
1163
  'Default install is warn + audit; hard deny needs strict mode (plus secret floors)',
1034
1164
  ],
1035
1165
  honest: 'Default is not “block everything.” Default warns. Strict mode denies matching high-risk actions. Secrets/exfil still hard-deny.',
@@ -25,7 +25,7 @@
25
25
  "alternateName": "thumbgate",
26
26
  "applicationCategory": "DeveloperApplication",
27
27
  "operatingSystem": "Cross-platform, Node.js >=18.18.0",
28
- "softwareVersion": "1.29.2",
28
+ "softwareVersion": "1.31.0",
29
29
  "url": "https://thumbgate.ai/numbers",
30
30
  "dateModified": "2026-05-07",
31
31
  "creator": {
@@ -195,6 +195,7 @@
195
195
  <a href="/learn">Learn</a>
196
196
  <a href="/compare">Compare</a>
197
197
  <a href="/numbers">Numbers</a>
198
+ <a href="/evaluations">Evaluations</a>
198
199
  <a href="/dashboard">Dashboard</a>
199
200
  <a href="/pro">Pro</a>
200
201
  </nav>
@@ -202,7 +203,7 @@
202
203
  <main class="container">
203
204
  <h1>The Numbers</h1>
204
205
  <p class="subtitle">Generated first-party operational snapshot from the ThumbGate runtime. This is not customer traction, install volume, revenue, or proof that a configured gate has fired.</p>
205
- <div class="freshness">Updated: 2026-05-07 · Version 1.29.2</div>
206
+ <div class="freshness">Updated: 2026-05-07 · Version 1.31.0</div>
206
207
  <div class="truth-note"><strong>Read this first:</strong> configured checks are inventory. Recorded blocks and warnings are usage evidence. This snapshot currently reports 0 recorded hard-block event(s) and 0 recorded warning event(s).</div>
207
208
 
208
209
  <h2>Gate enforcement</h2>