thumbgate 1.27.17 → 1.27.19

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 (107) hide show
  1. package/.claude-plugin/marketplace.json +85 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.well-known/mcp/server-card.json +1 -1
  4. package/README.md +33 -5
  5. package/adapters/chatgpt/openapi.yaml +1707 -0
  6. package/adapters/claude/.mcp.json +2 -2
  7. package/adapters/codex/config.toml +2 -2
  8. package/adapters/mcp/server-stdio.js +1 -1
  9. package/adapters/opencode/opencode.json +1 -1
  10. package/bin/cli.js +63 -54
  11. package/bin/postinstall.js +23 -14
  12. package/config/post-deploy-marketing-pages.json +19 -0
  13. package/config/tessl-tiles.json +1 -3
  14. package/package.json +99 -229
  15. package/public/guide.html +0 -4
  16. package/public/index.html +28 -49
  17. package/public/learn.html +0 -8
  18. package/public/numbers.html +2 -2
  19. package/scripts/agent-readiness.js +0 -147
  20. package/scripts/bot-detection.js +61 -3
  21. package/scripts/cli-feedback.js +4 -14
  22. package/scripts/cli-schema.js +7 -0
  23. package/scripts/durability/step.js +3 -3
  24. package/scripts/feedback-loop.js +10 -32
  25. package/scripts/gates-engine.js +72 -1
  26. package/scripts/hook-runtime.js +2 -2
  27. package/scripts/license.js +10 -9
  28. package/scripts/llm-client.js +44 -260
  29. package/scripts/mcp-config.js +7 -1
  30. package/scripts/published-cli.js +0 -8
  31. package/scripts/seo-gsd.js +0 -5
  32. package/src/api/server.js +111 -35
  33. package/.claude/commands/dashboard.md +0 -15
  34. package/.claude/commands/thumbgate-blocked.md +0 -27
  35. package/.claude/commands/thumbgate-dashboard.md +0 -15
  36. package/.claude/commands/thumbgate-doctor.md +0 -30
  37. package/.claude/commands/thumbgate-guard.md +0 -36
  38. package/.claude/commands/thumbgate-protect.md +0 -30
  39. package/.claude/commands/thumbgate-rules.md +0 -30
  40. package/adapters/gcp/dfcx-webhook-gate.js +0 -295
  41. package/adapters/letta/README.md +0 -41
  42. package/adapters/letta/thumbgate-letta-adapter.js +0 -133
  43. package/adapters/policy-engine/ethicore-guardian-client.js +0 -68
  44. package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +0 -260
  45. package/bench/observability-eval-suite.json +0 -26
  46. package/bin/dashboard-cli.js +0 -7
  47. package/commands/dashboard.md +0 -15
  48. package/commands/thumbgate-dashboard.md +0 -15
  49. package/config/builtin-lessons.json +0 -23
  50. package/public/about.html +0 -162
  51. package/public/agent-manager.html +0 -179
  52. package/public/agents-cost-savings.html +0 -153
  53. package/public/ai-malpractice-prevention.html +0 -818
  54. package/public/assets/brand/github-social-preview.png +0 -0
  55. package/public/assets/brand/thumbgate-icon-512.png +0 -0
  56. package/public/assets/brand/thumbgate-icon-pro-512.png +0 -0
  57. package/public/assets/brand/thumbgate-icon-team-512.png +0 -0
  58. package/public/assets/brand/thumbgate-logo-1200x360.png +0 -0
  59. package/public/assets/brand/thumbgate-logo-transparent.svg +0 -22
  60. package/public/assets/brand/thumbgate-mark-inline-v3.svg +0 -19
  61. package/public/assets/brand/thumbgate-mark-pro.svg +0 -23
  62. package/public/assets/brand/thumbgate-mark-team.svg +0 -26
  63. package/public/assets/brand/thumbgate-mark.svg +0 -21
  64. package/public/assets/brand/thumbgate-wordmark.svg +0 -20
  65. package/public/assets/claude-thumbgate-statusbar.svg +0 -8
  66. package/public/assets/codex-thumbgate-statusbar-test.svg +0 -9
  67. package/public/assets/legal-intake-control-flow.svg +0 -66
  68. package/public/brand/thumbgate-mark.svg +0 -19
  69. package/public/brand/thumbgate-og.svg +0 -16
  70. package/public/chatgpt-app.html +0 -330
  71. package/public/codex-enterprise.html +0 -123
  72. package/public/js/buyer-intent.js +0 -672
  73. package/public/pricing.html +0 -399
  74. package/scripts/action-receipts.js +0 -324
  75. package/scripts/activation-quickstart.js +0 -187
  76. package/scripts/agent-operations-planner.js +0 -621
  77. package/scripts/ai-component-inventory.js +0 -367
  78. package/scripts/async-eval-observability.js +0 -236
  79. package/scripts/audit.js +0 -65
  80. package/scripts/aws-blocks-guardrails.js +0 -228
  81. package/scripts/bot-detector.js +0 -50
  82. package/scripts/classifier-routing.js +0 -130
  83. package/scripts/dashboard-chat.js +0 -332
  84. package/scripts/feedback-aggregate.js +0 -281
  85. package/scripts/feedback-sanitizer.js +0 -105
  86. package/scripts/hob-pack.js +0 -591
  87. package/scripts/hook-stop-anti-claim.js +0 -301
  88. package/scripts/install-shim.js +0 -87
  89. package/scripts/mcp-oauth.js +0 -293
  90. package/scripts/noop-detect.js +0 -285
  91. package/scripts/omlx-smoke.js +0 -192
  92. package/scripts/parallel-workflow-orchestrator.js +0 -293
  93. package/scripts/plan-gate.js +0 -243
  94. package/scripts/plausible-domain-config.js +0 -99
  95. package/scripts/qa-scenario-planner.js +0 -136
  96. package/scripts/repeat-metric.js +0 -137
  97. package/scripts/secret-fixture-tokens.js +0 -61
  98. package/scripts/secret-redaction.js +0 -166
  99. package/scripts/self-harness-optimizer.js +0 -141
  100. package/scripts/self-healing-check.js +0 -193
  101. package/scripts/silent-failure-cluster.js +0 -531
  102. package/scripts/statusline-cache-read.js +0 -57
  103. package/scripts/sync-telemetry-from-prod.js +0 -374
  104. package/scripts/tool-contract-validator.js +0 -76
  105. package/scripts/trajectory-scorer.js +0 -63
  106. package/scripts/verify-marketing-pages-deployed.js +0 -195
  107. package/scripts/visitor-journey.js +0 -172
@@ -1,818 +0,0 @@
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
- <title>Pre-Execution Controls for Legal AI Agents - ThumbGate</title>
7
- <script defer data-domain="thumbgate.ai" src="https://plausible.io/js/script.js"></script>
8
- <meta name="description" content="Pre-execution controls for law-firm AI agents: block unauthorized advice, conflict-check failures, privilege leaks, and unapproved model calls before an agent acts.">
9
- <meta property="og:title" content="Pre-Execution Controls for Legal AI Agents">
10
- <meta property="og:description" content="ThumbGate preloads firm-approved ground truth, checks legal AI actions before execution, and records audit evidence for law-firm innovation, risk, and pricing teams.">
11
- <meta property="og:type" content="article">
12
- <meta property="og:image" content="https://thumbgate.ai/og.png">
13
- <link rel="canonical" href="https://thumbgate.ai/ai-malpractice-prevention">
14
- <script type="application/ld+json">
15
- {
16
- "@context": "https://schema.org",
17
- "@type": "TechArticle",
18
- "headline": "Pre-Execution Controls for Legal AI Agents",
19
- "description": "ThumbGate is a pre-execution control layer for law-firm AI intake workflows. It can preload firm-approved ground truth, evaluate proposed agent actions before execution, and produce audit evidence for human review.",
20
- "datePublished": "2026-05-21",
21
- "dateModified": "2026-05-25",
22
- "author": { "@type": "Person", "name": "Igor Ganapolsky", "url": "https://github.com/IgorGanapolsky" },
23
- "publisher": { "@type": "Organization", "name": "ThumbGate", "url": "https://thumbgate.ai" },
24
- "about": [
25
- { "@type": "Thing", "name": "Legal AI Governance" },
26
- { "@type": "Thing", "name": "Unauthorized Practice of Law" },
27
- { "@type": "Thing", "name": "Attorney-Client Privilege" },
28
- { "@type": "Thing", "name": "ABA Formal Opinion 512" },
29
- { "@type": "Thing", "name": "Conflict of Interest Check" }
30
- ]
31
- }
32
- </script>
33
- <style>
34
- *, *::before, *::after { box-sizing: border-box; }
35
- :root {
36
- --bg: #08090b;
37
- --panel: #14161a;
38
- --panel-2: #1b1f26;
39
- --line: #2c313a;
40
- --text: #f2f4f8;
41
- --muted: #a7afbd;
42
- --soft: #d8deea;
43
- --blue: #62a4ff;
44
- --cyan: #2dd4bf;
45
- --amber: #f2bd5b;
46
- --red: #fb7185;
47
- --green: #72e3a5;
48
- }
49
- body {
50
- margin: 0;
51
- font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
52
- background: var(--bg);
53
- color: var(--text);
54
- line-height: 1.58;
55
- }
56
- a { color: var(--blue); }
57
- nav {
58
- display: flex;
59
- align-items: center;
60
- gap: 1.1rem;
61
- flex-wrap: wrap;
62
- padding: 0.9rem clamp(1rem, 3vw, 2.25rem);
63
- border-bottom: 1px solid var(--line);
64
- background: rgba(8, 9, 11, 0.94);
65
- position: sticky;
66
- top: 0;
67
- z-index: 10;
68
- }
69
- nav a { color: var(--muted); text-decoration: none; font-size: 0.9rem; }
70
- nav .brand { color: var(--text); font-weight: 850; }
71
- .wrap { max-width: 1120px; margin: 0 auto; padding: 0 clamp(1rem, 3vw, 2rem); }
72
- .hero {
73
- min-height: calc(100vh - 68px);
74
- display: grid;
75
- grid-template-columns: minmax(0, 1fr) minmax(320px, 0.9fr);
76
- gap: clamp(2rem, 5vw, 4rem);
77
- align-items: center;
78
- padding: clamp(3rem, 6vw, 5rem) 0 2.2rem;
79
- }
80
- .eyebrow {
81
- display: inline-flex;
82
- color: var(--cyan);
83
- border: 1px solid rgba(45, 212, 191, 0.24);
84
- background: rgba(45, 212, 191, 0.08);
85
- padding: 0.34rem 0.72rem;
86
- border-radius: 999px;
87
- font-size: 0.76rem;
88
- font-weight: 850;
89
- letter-spacing: 0.08em;
90
- text-transform: uppercase;
91
- }
92
- h1 {
93
- font-size: clamp(2.25rem, 4.1vw, 3.65rem);
94
- line-height: 1.03;
95
- letter-spacing: 0;
96
- margin: 1.1rem 0 1rem;
97
- max-width: 800px;
98
- }
99
- .lead {
100
- color: var(--soft);
101
- font-size: clamp(1.05rem, 1.65vw, 1.24rem);
102
- max-width: 760px;
103
- margin: 0 0 1.4rem;
104
- }
105
- .hero-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin: 1.4rem 0; }
106
- .cta {
107
- display: inline-flex;
108
- align-items: center;
109
- justify-content: center;
110
- min-height: 48px;
111
- padding: 0.78rem 1.05rem;
112
- border-radius: 8px;
113
- background: var(--blue);
114
- color: #06111f;
115
- text-decoration: none;
116
- font-weight: 850;
117
- }
118
- .ghost { color: var(--soft); text-decoration: none; border-bottom: 1px solid var(--line); padding-bottom: 0.1rem; }
119
- .proof-row {
120
- display: grid;
121
- grid-template-columns: repeat(3, minmax(0, 1fr));
122
- gap: 0.75rem;
123
- margin-top: 1.2rem;
124
- max-width: 820px;
125
- }
126
- .proof {
127
- border: 1px solid var(--line);
128
- border-radius: 8px;
129
- padding: 0.82rem;
130
- background: rgba(255, 255, 255, 0.03);
131
- min-height: 92px;
132
- }
133
- .proof strong { display: block; color: var(--text); font-size: 0.94rem; }
134
- .proof span { color: var(--muted); font-size: 0.85rem; }
135
- .trust-strip {
136
- display: grid;
137
- grid-template-columns: repeat(4, minmax(0, 1fr));
138
- gap: 0.7rem;
139
- margin: 1.2rem 0 0;
140
- max-width: 920px;
141
- }
142
- .trust-item {
143
- border: 1px solid rgba(98, 164, 255, 0.24);
144
- border-radius: 8px;
145
- background: rgba(98, 164, 255, 0.07);
146
- padding: 0.72rem;
147
- color: var(--soft);
148
- font-size: 0.82rem;
149
- font-weight: 750;
150
- }
151
- .control-flow {
152
- border: 1px solid #343a46;
153
- background: #101318;
154
- border-radius: 8px;
155
- box-shadow: 0 24px 80px rgba(0, 0, 0, 0.34);
156
- padding: 1rem;
157
- }
158
- .flow-asset {
159
- display: block;
160
- width: 100%;
161
- height: auto;
162
- border: 1px solid var(--line);
163
- border-radius: 8px;
164
- margin: 0 0 0.9rem;
165
- background: #08090b;
166
- }
167
- .control-flow h2 { font-size: 1rem; margin: 0 0 0.85rem; color: var(--soft); }
168
- .flow-step {
169
- display: grid;
170
- grid-template-columns: 34px minmax(0, 1fr);
171
- gap: 0.8rem;
172
- align-items: start;
173
- border: 1px solid var(--line);
174
- border-radius: 8px;
175
- background: var(--panel);
176
- padding: 0.88rem;
177
- margin: 0.72rem 0;
178
- }
179
- .num {
180
- width: 34px;
181
- height: 34px;
182
- display: grid;
183
- place-items: center;
184
- border-radius: 8px;
185
- font-weight: 850;
186
- color: #06111f;
187
- background: var(--cyan);
188
- }
189
- .flow-step h3 { margin: 0 0 0.24rem; font-size: 0.98rem; }
190
- .flow-step p { margin: 0; color: var(--muted); font-size: 0.9rem; }
191
- .blocked { border-color: rgba(251, 113, 133, 0.55); background: rgba(251, 113, 133, 0.08); }
192
- .blocked .num { background: var(--red); color: #19070a; }
193
- .cleared { border-color: rgba(114, 227, 165, 0.42); background: rgba(114, 227, 165, 0.08); }
194
- .cleared .num { background: var(--green); color: #06120b; }
195
- main section {
196
- border-top: 1px solid var(--line);
197
- padding: clamp(2.35rem, 5vw, 4rem) 0;
198
- }
199
- h2 {
200
- font-size: clamp(1.75rem, 2.8vw, 2.5rem);
201
- line-height: 1.15;
202
- margin: 0 0 0.75rem;
203
- letter-spacing: 0;
204
- }
205
- .section-lead { color: var(--muted); font-size: 1.05rem; max-width: 820px; margin: 0 0 1.35rem; }
206
- .grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
207
- .two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
208
- .card {
209
- border: 1px solid var(--line);
210
- background: var(--panel);
211
- border-radius: 8px;
212
- padding: 1rem;
213
- }
214
- .card h3 { margin: 0 0 0.5rem; font-size: 1.04rem; color: var(--text); }
215
- .card p, .card li { color: var(--muted); margin: 0.42rem 0; }
216
- .tag {
217
- display: inline-flex;
218
- color: #071116;
219
- background: var(--cyan);
220
- border-radius: 6px;
221
- padding: 0.14rem 0.45rem;
222
- font-size: 0.72rem;
223
- font-weight: 850;
224
- margin-bottom: 0.62rem;
225
- }
226
- .amber { background: var(--amber); }
227
- .red { background: var(--red); color: #19070a; }
228
- .blue { background: var(--blue); color: #06111f; }
229
- .green { background: var(--green); color: #06120b; }
230
- .matrix { width: 100%; border-collapse: collapse; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
231
- .matrix th, .matrix td {
232
- padding: 0.82rem;
233
- border-bottom: 1px solid var(--line);
234
- vertical-align: top;
235
- text-align: left;
236
- }
237
- .matrix th { color: var(--cyan); background: #11151b; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }
238
- .matrix td { color: var(--muted); }
239
- .callout {
240
- background: #f2f4f8;
241
- color: #111827;
242
- border-radius: 8px;
243
- padding: clamp(1.2rem, 3vw, 1.8rem);
244
- }
245
- .callout p, .callout li { color: #344054; }
246
- .callout .cta { background: #111827; color: #fff; }
247
- .footer {
248
- color: var(--muted);
249
- padding: 2.2rem 0 4rem;
250
- border-top: 1px solid var(--line);
251
- }
252
- @media (max-width: 880px) {
253
- .hero, .grid, .two, .proof-row, .trust-strip { grid-template-columns: 1fr; }
254
- .hero { min-height: auto; padding-top: 2.4rem; }
255
- nav { position: static; }
256
- }
257
- @media (max-width: 700px) {
258
- .matrix, .matrix tbody, .matrix tr, .matrix td { display: block; width: 100%; }
259
- .matrix { border: 0; }
260
- .matrix thead { display: none; }
261
- .matrix tr {
262
- border: 1px solid var(--line);
263
- border-radius: 8px;
264
- margin-bottom: 0.85rem;
265
- background: var(--panel);
266
- overflow: hidden;
267
- }
268
- .matrix td { border-bottom: 1px solid var(--line); padding: 0.75rem 0.9rem; }
269
- .matrix td:last-child { border-bottom: 0; }
270
- .matrix td::before {
271
- display: block;
272
- color: var(--cyan);
273
- font-size: 0.72rem;
274
- font-weight: 850;
275
- letter-spacing: 0.06em;
276
- margin-bottom: 0.25rem;
277
- text-transform: uppercase;
278
- }
279
- .matrix td:nth-child(1)::before { content: "Buyer question"; }
280
- .matrix td:nth-child(2)::before { content: "Pilot answer"; }
281
- .matrix td:nth-child(3)::before { content: "Evidence to bring"; }
282
- }
283
- .demo-result { margin-top:1rem; padding:1rem; border-radius:8px; font-size:0.95rem; }
284
- .demo-blocked { background:rgba(248,113,113,0.1); border:1px solid var(--red); }
285
- .demo-cleared { background:rgba(52,211,153,0.1); border:1px solid var(--green); }
286
- .audit-log { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size:0.85rem; background:#0f0f11; padding:0.75rem; border-radius:6px; margin-top:0.75rem; white-space:pre-wrap; color:var(--soft); }
287
- </style>
288
- </head>
289
- <body>
290
- <nav>
291
- <a href="/ai-malpractice-prevention" class="brand">ThumbGate</a>
292
- <a href="/agent-manager">Agent Manager</a>
293
- <a href="/agents-cost-savings">FinOps for Agents</a>
294
- <a href="/dashboard">Dashboard demo</a>
295
- <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub</a>
296
- </nav>
297
-
298
- <div class="wrap">
299
- <header class="hero">
300
- <div>
301
- <div style="display: inline-block; border-left: 3px solid #fbbf24; background: rgba(251, 191, 36, 0.08); padding: 0.7rem 1rem; margin-bottom: 1.25rem; border-radius: 0 6px 6px 0; max-width: 760px;">
302
- <strong style="color: #fbbf24; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; display: block; margin-bottom: 0.25rem;">Why this matters now &mdash; 2026</strong>
303
- <span style="color: var(--text); font-size: 0.95rem; line-height: 1.55;">Sullivan &amp; Cromwell apologized to a federal judge for AI-hallucinated citations &mdash; despite policies, mandatory training, and verification requirements. Gordon Rees did the same on a bankruptcy filing. The <a href="https://www.damiencharlotin.com/hallucinations/" target="_blank" rel="noopener" style="color: #fbbf24">public hallucination-cases database</a> now catalogs <strong>1,369+ rulings</strong>. The firms with policies still got sanctioned. <em>Policies are not enforcement.</em> A runtime gate is.</span>
304
- </div>
305
- <span class="eyebrow">Pre-read for law-firm AI governance pilots</span>
306
- <h1>Pre-execution controls for legal AI agents.</h1>
307
- <p class="lead">Block unauthorized advice, conflict-check failures, privilege leaks, and unapproved model calls before an intake agent replies, fetches records, schedules a meeting, or sends data outside the firm's approved boundary.</p>
308
- <p style="color: var(--soft); font-size: 0.98rem; max-width: 760px; margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-left: 3px solid var(--green); background: rgba(114, 227, 165, 0.06); border-radius: 0 6px 6px 0;">
309
- <strong style="color: var(--green)">Predictability you can put in front of a client.</strong>
310
- Pre-execution controls aren't just defensive &mdash; they make agentic-AI deployment <em>predictable enough to sell</em>. Innovation teams at law firms have always had to choose between speed and certainty. The runtime gate lets you have both: the agent moves at machine speed, the gate enforces firm-specific policy deterministically, and every decision ships an audit log your pricing partners can underwrite. <strong style="color: var(--soft)">Predictability. Insights. Value.</strong> The three things your innovation team already promises clients &mdash; extended to the agentic surface.
311
- </p>
312
- <p style="color: var(--soft); font-size: 0.95rem; max-width: 760px; margin: 0 0 1rem; padding: 0.55rem 0.85rem; border-left: 3px solid var(--cyan); background: rgba(45, 212, 191, 0.05); border-radius: 0 6px 6px 0;">
313
- <strong style="color: var(--cyan)">The gate learns from your attorneys.</strong>
314
- Every 👍 / 👎 an attorney logs on an AI answer becomes a lesson in your firm's local DB. Recurring patterns promote to deterministic rules. The next time a similar action is proposed, the rule fires before any human is asked to approve.
315
- <a href="/learn/feedback-loop-vs-decision-layer" style="color: var(--cyan); white-space: nowrap;">How the feedback loop works &rarr;</a>
316
- </p>
317
- <p style="color: var(--soft); font-size: 0.95rem; max-width: 760px; margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-left: 3px solid #a78bfa; background: rgba(167, 139, 250, 0.06); border-radius: 0 6px 6px 0;">
318
- <strong style="color: #a78bfa">No public-facing chatbot? You still have the risk surface.</strong>
319
- Most BigLaw firms don't take client intake through a chatbot &mdash; but their associates already paste matter context into Claude, Cursor, Codex, and internal LLM gateways every day. The risk isn't a bot giving public advice; it's <em>internal</em> agent use the firm can't see. ThumbGate sits between each agent and its next action, captures attorney 👍/👎 on every output, and produces a <strong style="color: var(--soft)">searchable audit log + RAG of every gated detection</strong> &mdash; queryable by ethics, risk, and innovation owners. Your conflicts DB and document systems stay where they are; we instrument what the agents inside the firm are about to do.
320
- </p>
321
- <p style="color: var(--soft); font-size: 0.95rem; max-width: 760px; margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-left: 3px solid #f59e0b; background: rgba(245, 158, 11, 0.06); border-radius: 0 6px 6px 0;">
322
- <strong style="color: #f59e0b">Already piloting an AI case tool? It makes agents capable &mdash; ThumbGate makes them auditable.</strong>
323
- Litigation &amp; arbitration teams and in-house counsel are adopting AI case-intelligence and drafting copilots that touch privileged correspondence, pleadings, and matter files. Those tools make the agent <em>capable</em>; they don't give risk, ethics, and innovation owners a control point or a defensible record of what the agent was about to do. ThumbGate is the governance layer <em>around</em> them &mdash; a deterministic gate on the next action, attorney 👍/👎 promoted to firm rules, and an exportable audit trail &mdash; the evidence procurement (and your professional-liability review) actually ask for before agents run on multi-million-dollar matters.
324
- </p>
325
- <div class="hero-actions">
326
- <a class="cta" href="mailto:iganapolsky@gmail.com?subject=ThumbGate%2025-minute%20legal%20AI%20pilot%20walkthrough&amp;body=Hi%20Igor%2C%0A%0AWe%27d%20like%20to%20review%20the%2025-minute%20ThumbGate%20legal%20AI%20intake%20pilot.%20Please%20send%20the%20meeting%20invite%20and%20demo%20materials.%0A%0ABest%2C">Book a 25-minute pilot walkthrough</a>
327
- <a class="ghost" href="#live-gate-demos">Try the live gates &rarr;</a>
328
- <a class="ghost" href="#demo">View the 25-minute demo plan</a>
329
- </div>
330
- <p style="font-size: 0.85rem; color: var(--muted); margin: -0.5rem 0 1.2rem; max-width: 760px;">
331
- Button not opening your mail client? <button type="button" onclick="__thumbgateCopyPilotEmail(this)" style="padding:0.35rem 0.7rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:5px; cursor:pointer; vertical-align: baseline;">Copy the email instead</button> or write to <span style="color: var(--text); user-select: all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;">iganapolsky@gmail.com</span> directly.
332
- </p>
333
- <div class="proof-row" aria-label="Key proof points">
334
- <div class="proof"><strong>Preloaded controls</strong><span>Firm policy, approved disclaimers, adverse-party lists, routing rules, and model endpoint allowlists.</span></div>
335
- <div class="proof"><strong>Pre-action checks</strong><span>Controls run before the agent replies, fetches records, schedules intake, or calls an external model.</span></div>
336
- <div class="proof"><strong>Reviewable evidence</strong><span>Every block, warning, override, and handoff becomes a structured audit event.</span></div>
337
- </div>
338
- <div class="trust-strip" aria-label="Trust and deployment assumptions">
339
- <div class="trust-item">Local-first enforcement option</div>
340
- <div class="trust-item">Works around Azure OpenAI, Claude, Gemini, and internal tools</div>
341
- <div class="trust-item">ABA Formal Opinion 512 mapped to reviewable controls</div>
342
- <div class="trust-item">No guaranteed-malpractice-prevention claim</div>
343
- </div>
344
- </div>
345
-
346
- <aside class="control-flow" aria-label="ThumbGate pre-action control flow">
347
- <img class="flow-asset" src="/assets/legal-intake-control-flow.svg" alt="Diagram of the ThumbGate legal intake pre-action control flow">
348
- <h2>What the demo should show</h2>
349
- <div class="flow-step">
350
- <span class="num">1</span>
351
- <div>
352
- <h3>Prospect asks a risky intake question</h3>
353
- <p>"Can I sue my former employer in Florida if they changed my commission plan?"</p>
354
- </div>
355
- </div>
356
- <div class="flow-step blocked">
357
- <span class="num">2</span>
358
- <div>
359
- <h3>Advice-shaped response is stopped</h3>
360
- <p>Legal conclusion plus jurisdictional recommendation is routed to attorney review before delivery.</p>
361
- </div>
362
- </div>
363
- <div class="flow-step cleared">
364
- <span class="num">3</span>
365
- <div>
366
- <h3>Safe handoff is allowed</h3>
367
- <p>The agent collects neutral routing details and schedules review without creating reliance.</p>
368
- </div>
369
- </div>
370
- <div class="flow-step">
371
- <span class="num">4</span>
372
- <div>
373
- <h3>Audit event is exportable</h3>
374
- <p>Rule version, source policy, proposed action, outcome, reviewer, and timestamp are preserved.</p>
375
- </div>
376
- </div>
377
- </aside>
378
- </header>
379
-
380
- <main>
381
- <section>
382
- <h2>Why this is credible now.</h2>
383
- <p class="section-lead">The market is not waiting for perfect AI. Large firms are adopting legal AI while ethics, security, and innovation teams are still formalizing the controls around it. ThumbGate fits that gap: it is not another research assistant; it is a control point around the assistants and agents a firm already wants to evaluate. Governance has to live outside the model's context window. If the agent can reason around the rule, it is not really a rule.</p>
384
- <div class="grid">
385
- <div class="card">
386
- <span class="tag blue">Governance</span>
387
- <h3>ABA Formal Opinion 512 maps cleanly to controls</h3>
388
- <p>Competence, confidentiality, supervision, verification, communication, and reasonable fees become concrete checks and review records.</p>
389
- </div>
390
- <div class="card">
391
- <span class="tag amber">Adoption</span>
392
- <h3>AI is entering normal workflows</h3>
393
- <p>The practical buyer question is no longer "will lawyers use AI?" It is "which actions can an agent take without review?"</p>
394
- </div>
395
- <div class="card">
396
- <span class="tag green">Positioning</span>
397
- <h3>Vendor-neutral by design</h3>
398
- <p>The pilot can sit around internal tools, Azure OpenAI, Claude, Gemini, document systems, or purpose-built legal AI products.</p>
399
- </div>
400
- </div>
401
- </section>
402
-
403
- <section>
404
- <h2>The pilot is an AI-SDLC control layer, not a chatbot demo.</h2>
405
- <p class="section-lead">The strongest buyer framing is simple: the firm may already have agents, copilots, research tools, and intake experiments. What it still needs is the system around those agents: triggers, isolated runs, approved context, visibility, and controls that live outside the model prompt.</p>
406
- <div class="grid">
407
- <div class="card">
408
- <span class="tag blue">Trigger</span>
409
- <h3>Define what starts legal AI work</h3>
410
- <p>A pilot run should begin from a scoped intake event, not an open-ended prompt. The event carries practice area, jurisdiction, allowed tools, reviewer role, and done criteria.</p>
411
- </div>
412
- <div class="card">
413
- <span class="tag amber">Context</span>
414
- <h3>Load only approved firm ground truth</h3>
415
- <p>Disclaimers, adverse-party fixtures, model allowlists, routing policy, and supervision rules should be versioned inputs, not improvised chat context.</p>
416
- </div>
417
- <div class="card">
418
- <span class="tag green">Controls</span>
419
- <h3>Block before the action happens</h3>
420
- <p>Pre-action gates stop advice-shaped replies, conflict-precheck bypass, and confidential egress before the agent sends, fetches, schedules, or calls out.</p>
421
- </div>
422
- </div>
423
- <div class="callout" style="margin-top:1rem;">
424
- <p><strong>Executive takeaway:</strong> ThumbGate does not ask a law firm to trust a bigger prompt. It gives risk, innovation, and security teams a reviewable control point between the agent and the next privileged action.</p>
425
- <p><a href="/learn/background-agent-control-layer">Read the background-agent control-layer brief &rarr;</a></p>
426
- </div>
427
- </section>
428
-
429
- <section>
430
- <h2>Yes, the pilot can start with preloaded ground truth.</h2>
431
- <p class="section-lead">The first pilot should not ask the model to discover the firm's risk posture. ThumbGate should load the approved rule pack before the first intake simulation, then prove that the agent is physically stopped when a proposed action violates that pack.</p>
432
- <div class="grid">
433
- <div class="card">
434
- <span class="tag green">Inputs</span>
435
- <h3>Firm-approved source material</h3>
436
- <p>Disclaimers, intake scripts, escalation rules, practice-area boundaries, jurisdiction notes, model endpoint policy, retention rules, and reviewer roles.</p>
437
- </div>
438
- <div class="card">
439
- <span class="tag amber">Fixtures</span>
440
- <h3>Adverse-party and matter examples</h3>
441
- <p>A synthetic adverse-party list and red-team intake transcripts let the demo show conflict stops without exposing privileged or client data.</p>
442
- </div>
443
- <div class="card">
444
- <span class="tag blue">Outputs</span>
445
- <h3>Deterministic control evidence</h3>
446
- <p>Each demo decision shows the matched rule, proposed action, allowed or blocked outcome, reviewer path, timestamp, and exportable audit record.</p>
447
- </div>
448
- </div>
449
- </section>
450
-
451
- <section>
452
- <h2>Three failure modes the pilot should control.</h2>
453
- <div class="grid">
454
- <div class="card">
455
- <span class="tag red">UPL</span>
456
- <h3>Unauthorized-practice risk</h3>
457
- <p>Block outcome predictions, jurisdictional recommendations, and advice-shaped responses from non-attorney intake agents. Allow neutral collection and attorney handoff.</p>
458
- </div>
459
- <div class="card">
460
- <span class="tag amber">Conflicts</span>
461
- <h3>Conflict preconditions</h3>
462
- <p>Require configured adverse-party clearance before the agent continues intake or requests sensitive matter facts.</p>
463
- </div>
464
- <div class="card">
465
- <span class="tag blue">Privilege</span>
466
- <h3>Confidentiality and egress</h3>
467
- <p>Block or reroute outbound calls that include privileged markers, matter identifiers, or firm-classified confidential content.</p>
468
- </div>
469
- </div>
470
- </section>
471
-
472
- <section id="demo">
473
- <h2>25-minute walkthrough agenda.</h2>
474
- <p class="section-lead">The call should be visual. The goal is not to prove every enterprise feature. It is to show a repeatable mechanism the innovation team can explain internally.</p>
475
- <div class="two grid">
476
- <div class="card">
477
- <h3>Show these assets</h3>
478
- <ul>
479
- <li>One unsafe intake transcript and blocked response.</li>
480
- <li>One conflict-precheck stop before sensitive facts are collected.</li>
481
- <li>One egress block or safe in-tenant reroute.</li>
482
- <li>One audit export with rule version, source, outcome, and reviewer.</li>
483
- </ul>
484
- </div>
485
- <div class="card">
486
- <h3>Skip these on the first call</h3>
487
- <ul>
488
- <li>Broad platform tour.</li>
489
- <li>Pricing page or checkout flow.</li>
490
- <li>Unverified sanctions statistics.</li>
491
- <li>Claims about SOC 2, BAA, carrier discounts, or guaranteed malpractice prevention.</li>
492
- </ul>
493
- </div>
494
- </div>
495
- <div class="two grid" style="margin-top:1rem;">
496
- <div class="card">
497
- <h3>Suggested agenda</h3>
498
- <ul>
499
- <li>3 minutes: confirm the target workflow and risk owners.</li>
500
- <li>7 minutes: show blocked unauthorized-advice and conflict examples.</li>
501
- <li>7 minutes: show preloaded ground truth and audit evidence.</li>
502
- <li>5 minutes: discuss deployment boundary, data handling, and reviewer roles.</li>
503
- <li>3 minutes: agree on pilot inputs and next step.</li>
504
- </ul>
505
- </div>
506
- <div class="card">
507
- <h3>Recommended ask</h3>
508
- <p>Ask for one practice-area workflow, one approved disclaimer, one synthetic adverse-party fixture, one security contact, and permission to build a no-client-data pilot pack.</p>
509
- </div>
510
- </div>
511
- </section>
512
-
513
- <section>
514
- <h2>Procurement questions to answer early.</h2>
515
- <table class="matrix">
516
- <thead>
517
- <tr><th>Buyer question</th><th>Pilot answer</th><th>Evidence to bring</th></tr>
518
- </thead>
519
- <tbody>
520
- <tr><td>Will our data train models?</td><td>The pilot can run inside the firm's boundary. Hosted services should receive only counters and rule metadata unless explicitly approved.</td><td>Data-flow diagram, retention note, subprocessor list.</td></tr>
521
- <tr><td>Who can see privileged data?</td><td>Default pilot design keeps privileged payloads in the firm's environment, with access governed by their controls.</td><td>Architecture note and access-control assumptions.</td></tr>
522
- <tr><td>Can we reproduce a decision later?</td><td>Each event should preserve the rule version, source policy, proposed action, decision, reviewer, and timestamp.</td><td>Sample audit export.</td></tr>
523
- <tr><td>How do we tune false positives?</td><td>Use hard block, review queue, warning, and allow modes. Promote rules only after test examples and attorney approval.</td><td>Rule lifecycle and override examples.</td></tr>
524
- </tbody>
525
- </table>
526
- </section>
527
-
528
- <section>
529
- <div class="callout">
530
- <h2>Recommended 30-day pilot.</h2>
531
- <p>Start narrow: one intake channel, one practice-area workflow, one adverse-party fixture, one approved-model routing policy, and one audit export format.</p>
532
- <p>Deliverables: preloaded rule pack, demo agent, screenshot set, 60-second walkthrough clip, security data-flow note, pilot metrics, and a go/no-go rollout recommendation.</p>
533
- <p style="margin:1.2rem 0 0.6rem;color:var(--amber);font-size:1.1rem;font-weight:700;">Pilot setup fee: $2,500 &ndash; $7,500 flat (scope-dependent). No per-seat or per-query billing during the pilot.</p>
534
- <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:0.75rem;margin:1.4rem 0 1rem;">
535
- <div style="background:rgba(114,227,165,0.06);border-left:3px solid var(--green);padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
536
- <strong style="color:var(--green);font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What you walk away with</strong>
537
- <span style="font-size:0.9rem;color:var(--soft)">A searchable audit log + RAG of every gated detection over 30 days, broken down by rule, agent, and disposition. Defensible in front of your risk committee.</span>
538
- </div>
539
- <div style="background:rgba(251,191,36,0.06);border-left:3px solid #fbbf24;padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
540
- <strong style="color:#fbbf24;font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What we don't claim</strong>
541
- <span style="font-size:0.9rem;color:var(--soft)">Not SOC 2 today. Not BAA-ready as a blanket claim. No hallucination indemnity for third-party model output. Local-first deployment makes the pilot a no-client-data engagement.</span>
542
- </div>
543
- <div style="background:rgba(45,212,191,0.06);border-left:3px solid var(--cyan);padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
544
- <strong style="color:var(--cyan);font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What you bring</strong>
545
- <span style="font-size:0.9rem;color:var(--soft)">One named owner, one workflow you're already evaluating AI on, your approved disclaimer language, and read-only access to whichever conflicts DB you already run.</span>
546
- </div>
547
- </div>
548
- <div style="display:flex;gap:1rem;flex-wrap:wrap;margin-top:1rem;">
549
- <a class="cta" href="mailto:iganapolsky@gmail.com?subject=ThumbGate%2025-minute%20legal%20AI%20pilot%20walkthrough&amp;body=Hi%20Igor%2C%0A%0AWe%27d%20like%20to%20review%20the%2025-minute%20ThumbGate%20legal%20AI%20intake%20pilot.%20Please%20send%20the%20meeting%20invite%20and%20demo%20materials.%0A%0ABest%2C">Book a 25-minute pilot walkthrough</a>
550
- <a class="ghost" href="/dashboard">View the live dashboard demo</a>
551
- </div>
552
- <p style="font-size:0.85rem; color:var(--muted); margin:0.75rem 0 0;">
553
- Button not opening your mail client (common on Gmail Web / iPhone)? <button type="button" onclick="__thumbgateCopyPilotEmail(this)" style="padding:0.35rem 0.7rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:5px; cursor:pointer; vertical-align: baseline;">Copy the email instead</button> or write to <span style="color: var(--text); user-select: all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;">iganapolsky@gmail.com</span> directly.
554
- </p>
555
- </div>
556
- </section>
557
-
558
- <section id="live-gate-demos">
559
- <h2>Live gate demos &mdash; try them yourself</h2>
560
- <div style="border-left: 3px solid var(--cyan); background: rgba(34, 211, 238, 0.06); padding: 0.85rem 1.1rem; margin: 0 0 1.5rem; border-radius: 0 6px 6px 0;">
561
- <strong style="color: var(--cyan)">Monitor vs enforce.</strong> <span style="color: var(--text)">Agent observability tools log what your agent <em>did</em>. ThumbGate gates what your agent is <em>about to do</em> &mdash; runtime block before execution, not retrospective alert after the harm. SIEM ingestion is the audit trail. The PreToolUse hook is the prevention.</span>
562
- </div>
563
- <p style="color:var(--muted); margin-bottom:1.5rem">These simulators use the exact same deterministic PreToolUse logic that runs in production. No LLM calls on the enforcement path &mdash; just fast, auditable pattern matching.</p>
564
-
565
- <!-- UPL Gate Simulator -->
566
- <div class="card" style="margin-bottom:2rem">
567
- <h3 style="color:var(--cyan); margin-bottom:0.75rem">1. UPL Gate &mdash; advice-shaped output detector</h3>
568
- <p style="font-size:0.95rem; color:var(--muted)">Paste an <strong>advice-shaped response a bot would deliver to a client</strong> (not a client's question). The gate detects predictions, recommendations, or jurisdictional legal analysis from a non-attorney source and blocks delivery. The patterns it matches were promoted from attorney 👎 feedback.</p>
569
- <textarea id="upl-input" placeholder="E.g. 'Based on the facts you described, you likely have a strong claim for breach of contract and could recover significant damages.'" style="width:100%; height:90px; background:#0f0f11; color:var(--text); border:1px solid var(--line); border-radius:8px; padding:0.75rem; font-size:0.95rem; resize:vertical; margin:0.75rem 0"></textarea>
570
- <div style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center; margin-bottom:0.5rem">
571
- <button onclick="runUPLDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Run through UPL Gate</button>
572
- <button type="button" onclick="document.getElementById('upl-input').value='You have a strong case for wrongful termination. In my opinion, you should file in the Southern District of Florida.';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill sample &mdash; will BLOCK</button>
573
- <button type="button" onclick="document.getElementById('upl-input').value='I can schedule a 30-minute consultation with one of our employment attorneys. Would 2pm Thursday work?';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill sample &mdash; will CLEAR</button>
574
- </div>
575
- <div id="upl-result" class="demo-result" style="display:none"></div>
576
- </div>
577
-
578
- <!-- Conflict Check Simulator -->
579
- <div class="card" style="margin-bottom:2rem">
580
- <h3 style="color:var(--cyan); margin-bottom:0.75rem">2. Conflict Gate &mdash; adverse party clearance</h3>
581
- <p style="font-size:0.95rem; color:var(--muted)">Enter a prospective client or party name. <strong>In production this gate queries YOUR firm's existing conflicts DB</strong> (Intapp Open, IntelliPlan, Aderant, or a custom system) &mdash; not a vendor-hosted list. ThumbGate is the agent-side enforcement; your DB stays the source of truth. The sample list below is illustrative only.</p>
582
- <div style="display:flex; gap:0.75rem; align-items:flex-end; margin:0.75rem 0; flex-wrap:wrap">
583
- <div style="flex:1; min-width:240px">
584
- <label style="font-size:0.8rem; color:var(--muted); display:block; margin-bottom:0.25rem">Party / Company Name</label>
585
- <input id="conflict-input" type="text" placeholder="Latam Real Capital" value="Latam Real Capital S.A." style="width:100%; background:#0f0f11; color:var(--text); border:1px solid var(--line); border-radius:8px; padding:0.6rem; font-size:0.95rem">
586
- </div>
587
- <button onclick="runConflictDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem; white-space:nowrap">Check Against Adverse List</button>
588
- </div>
589
- <div style="display:flex; gap:0.5rem; flex-wrap:wrap; margin-bottom:0.5rem">
590
- <button type="button" onclick="document.getElementById('conflict-input').value='Latam Real Capital S.A.';" style="padding:0.4rem 0.8rem; font-size:0.8rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill &mdash; will BLOCK</button>
591
- <button type="button" onclick="document.getElementById('conflict-input').value='Acme Manufacturing LLC';" style="padding:0.4rem 0.8rem; font-size:0.8rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill &mdash; will CLEAR</button>
592
- </div>
593
- <div style="font-size:0.8rem; color:var(--muted); margin-bottom:0.5rem">Sample adverse list (synthetic, illustrative): Latam Real Capital S.A. (real estate #M-2847), Hospitalia Holdings (hospitality M&amp;A #M-2911), NovaIA Latam (AI venture #M-2755)</div>
594
- <div id="conflict-result" class="demo-result" style="display:none"></div>
595
- </div>
596
-
597
- <!-- Privilege Egress Simulator -->
598
- <div class="card">
599
- <h3 style="color:var(--cyan); margin-bottom:0.75rem">3. Egress Gate &mdash; privilege marker detector</h3>
600
- <p style="font-size:0.95rem; color:var(--muted)">Paste content an agent might try to send to an external LLM (e.g. deposition summary request). The gate blocks if it detects privilege markers. Markers are firm-defined and the list grows from attorney 👍/👎 on what the gate let through.</p>
601
- <textarea id="privilege-input" placeholder="Please summarize this deposition transcript. [Attorney Work Product - Matter M-2847 - Confidential]" style="width:100%; height:90px; background:#0f0f11; color:var(--text); border:1px solid var(--line); border-radius:8px; padding:0.75rem; font-size:0.95rem; resize:vertical; margin:0.75rem 0"></textarea>
602
- <div style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center; margin-bottom:0.5rem">
603
- <button onclick="runPrivilegeDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Attempt External LLM Call</button>
604
- <button type="button" onclick="document.getElementById('privilege-input').value='Please summarize this deposition transcript. [Attorney Work Product - Matter M-2847 - Confidential]';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill sample &mdash; will BLOCK</button>
605
- <button type="button" onclick="document.getElementById('privilege-input').value='Please summarize the public press release announcing the merger between Acme Corp and Foobar Inc.';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill sample &mdash; will CLEAR</button>
606
- </div>
607
- <div id="privilege-result" class="demo-result" style="display:none"></div>
608
- </div>
609
-
610
- <script>
611
- function escapeHtml(s) {
612
- return String(s).replace(/[&<>"']/g, function(c) {
613
- return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
614
- });
615
- }
616
- window.__thumbgateCopyPilotEmail = function(btn) {
617
- var body = "Hi Igor,\n\nWe'd like to review the 25-minute ThumbGate legal AI intake pilot. Please send the meeting invite and demo materials.\n\nBest,";
618
- var full = "To: iganapolsky@gmail.com\nSubject: ThumbGate 25-minute legal AI pilot walkthrough\n\n" + body;
619
- var done = function(label) {
620
- var orig = btn.dataset.origLabel || btn.textContent;
621
- btn.dataset.origLabel = orig;
622
- btn.textContent = label;
623
- setTimeout(function() { btn.textContent = orig; }, 2400);
624
- };
625
- if (navigator.clipboard && navigator.clipboard.writeText) {
626
- navigator.clipboard.writeText(full)
627
- .then(function() { done('Copied — paste into Gmail or any mail client'); })
628
- .catch(function() { done('Copy failed — email iganapolsky@gmail.com directly'); });
629
- } else {
630
- done('Email iganapolsky@gmail.com directly');
631
- }
632
- };
633
- // Produces the same JSON shape a production ThumbGate gate would stream to the firm's SIEM.
634
- // Includes ISO 27001 control mapping so procurement can map evidence to controls without translation.
635
- window.__thumbgateBuildAudit = function(args) {
636
- return {
637
- audit_id: args.audit_id,
638
- timestamp_iso: args.timestamp_iso,
639
- rule: { id: args.rule_id, version: args.rule_version, matched: args.matched },
640
- blocked_call: {
641
- agent: args.agent,
642
- input_excerpt: String(args.input || '').slice(0, 280),
643
- matter_context: args.matter_context
644
- },
645
- action: args.action,
646
- reviewer: null,
647
- iso_27001_controls: args.iso_controls,
648
- generated_by: 'ThumbGate PreToolUse Gate (sample export — production version streams to your SIEM)',
649
- sample_disclaimer: 'Synthetic audit record for evaluation. No real client data referenced.'
650
- };
651
- };
652
- window.__thumbgateDownloadAudit = function(payload, filename) {
653
- try {
654
- var json = JSON.stringify(payload, null, 2);
655
- var blob = new Blob([json], { type: 'application/json' });
656
- var url = URL.createObjectURL(blob);
657
- var a = document.createElement('a');
658
- a.href = url; a.download = filename;
659
- document.body.appendChild(a); a.click();
660
- document.body.removeChild(a);
661
- setTimeout(function() { URL.revokeObjectURL(url); }, 10000);
662
- } catch (e) { console.error('audit download failed', e); }
663
- };
664
- window.__thumbgateAuditRegistry = {};
665
- window.__thumbgateAuditByKey = function(key) {
666
- var entry = window.__thumbgateAuditRegistry[key];
667
- if (!entry) return;
668
- window.__thumbgateDownloadAudit(entry.payload, entry.filename);
669
- };
670
- window.__thumbgateAuditButton = function(key, payload, filename) {
671
- window.__thumbgateAuditRegistry[key] = { payload: payload, filename: filename };
672
- return '<button class="cta" style="margin-top:0.5rem; padding:0.45rem 0.9rem; font-size:0.82rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan)" ' +
673
- 'onclick="__thumbgateAuditByKey(\'' + key + '\')">' +
674
- 'Download audit JSON (sample) &darr;</button>';
675
- };
676
- function runUPLDemo() {
677
- var input = document.getElementById('upl-input').value.trim();
678
- var resultDiv = document.getElementById('upl-result');
679
- if (!input) { resultDiv.style.display = 'none'; return; }
680
- var advicePatterns = ['you have a strong case', 'likely to win', 'you should', 'recommend that you', 'based on the facts you described', 'in my opinion', 'the best course is', 'you are entitled to'];
681
- var lower = input.toLowerCase();
682
- var blocked = false;
683
- var reason = '';
684
- for (var i = 0; i < advicePatterns.length; i++) {
685
- if (lower.indexOf(advicePatterns[i]) !== -1) { blocked = true; reason = advicePatterns[i]; break; }
686
- }
687
- if (blocked) {
688
- var uplPayload = __thumbgateBuildAudit({
689
- audit_id: 'UPL-2847-20260526-091204',
690
- timestamp_iso: '2026-05-26T09:12:04Z',
691
- rule_id: 'UPL_RULE_05.5_ADVICE_SHAPE',
692
- rule_version: '3.2',
693
- matched: 'advice-shaped output from non-attorney source ("' + reason + '")',
694
- agent: 'website-intake-bot-v2',
695
- input: input,
696
- matter_context: 'New client intake (web)',
697
- action: 'REPLACE + LOG + NOTIFY_ATTORNEY',
698
- iso_controls: ['A.5.34 (Privacy & PII protection)', 'A.5.24 (Information security incident management)']
699
- });
700
- resultDiv.innerHTML =
701
- '<div class="demo-blocked">' +
702
- '<strong style="color:#f87171">BLOCKED &mdash; UPL Gate fired</strong><br>' +
703
- 'Detected advice-shaped pattern: "' + escapeHtml(reason) + '"<br><br>' +
704
- '<strong>Corrective action taken:</strong><br>' +
705
- 'Response replaced with: <em>"That\'s a legal question best answered by a licensed attorney. I can schedule a 30-minute consultation with one of our [practice area] attorneys &mdash; would [time] work for you?"</em><br><br>' +
706
- '<div class="audit-log">[2026-05-26 09:12:04] PreToolUse gate: UPL_RULE_05.5_ADVICE_SHAPE v3.2\nRule matched: advice-shaped output from non-attorney source\nAction: REPLACE + LOG + NOTIFY_ATTORNEY\nAudit ID: UPL-2847-20260526-091204\nMatter context: New client intake (web)\nAgent: website-intake-bot-v2</div>' +
707
- __thumbgateAuditButton('upl', uplPayload, 'ThumbGate-Audit-UPL-2847-2026-05-26.json') +
708
- '</div>';
709
- } else {
710
- resultDiv.innerHTML =
711
- '<div class="demo-cleared">' +
712
- '<strong style="color:#34d399">CLEARED &mdash; no UPL pattern detected</strong><br>' +
713
- 'Response would be delivered as-is. (In production this would still be logged for training.)' +
714
- '</div>';
715
- }
716
- resultDiv.style.display = 'block';
717
- }
718
-
719
- function runConflictDemo() {
720
- var party = document.getElementById('conflict-input').value.trim().toLowerCase();
721
- var resultDiv = document.getElementById('conflict-result');
722
- if (!party) { resultDiv.style.display = 'none'; return; }
723
- var adverseList = ['latam real capital', 'latam real', 'hospitalia holdings', 'hospitalia', 'novaia latam', 'novaia'];
724
- var isAdverse = adverseList.some(function(a) { return party.indexOf(a) !== -1; });
725
- if (isAdverse) {
726
- var conflictPayload = __thumbgateBuildAudit({
727
- audit_id: 'CONF-2911-20260526-091204',
728
- timestamp_iso: '2026-05-26T09:12:04Z',
729
- rule_id: 'CONFLICT_RULE_1.7_ADVERSE',
730
- rule_version: '4.1',
731
- matched: 'adverse-parties list match for "' + party + '"',
732
- agent: 'doc-fetch-agent-v1',
733
- input: party,
734
- matter_context: 'New M&A intake — preliminary conflict check',
735
- action: 'BLOCK + REDIRECT + LOG',
736
- iso_controls: ['A.5.10 (Acceptable use of information)', 'A.5.24 (Information security incident management)', 'A.8.10 (Information deletion)']
737
- });
738
- resultDiv.innerHTML =
739
- '<div class="demo-blocked">' +
740
- '<strong style="color:#f87171">BLOCKED &mdash; Conflict Gate fired</strong><br>' +
741
- '"' + escapeHtml(party) + '" matches adverse party in existing matter.<br><br>' +
742
- '<strong>Corrective action:</strong> Fetch blocked. Agent redirected to: <em>"This party appears as adverse in matter M-2847. Contact ethics screen lead before proceeding."</em><br><br>' +
743
- '<div class="audit-log">[2026-05-26 09:12:04] PreToolUse gate: CONFLICT_RULE_1.7_ADVERSE v4.1\nMatched: adverse-parties list\nAction: BLOCK + REDIRECT + LOG\nAudit ID: CONF-2911-20260526-091204\nRequesting matter: New M&amp;A intake\nAgent: doc-fetch-agent-v1</div>' +
744
- __thumbgateAuditButton('conflict', conflictPayload, 'ThumbGate-Audit-CONF-2911-2026-05-26.json') +
745
- '</div>';
746
- } else {
747
- resultDiv.innerHTML =
748
- '<div class="demo-cleared">' +
749
- '<strong style="color:#34d399">CLEARED &mdash; no conflict found</strong><br>' +
750
- 'Positive clearance recorded. Agent may proceed with intake.<br><br>' +
751
- '<div class="audit-log">[2026-05-26 09:12:04] PreToolUse gate: CONFLICT_RULE_1.7_ADVERSE v4.1\nResult: CLEAR (no match in adverse list)\nAction: ALLOW + LOG\nAudit ID: CONF-2912-20260526-091204</div>' +
752
- '</div>';
753
- }
754
- resultDiv.style.display = 'block';
755
- }
756
-
757
- function runPrivilegeDemo() {
758
- var input = document.getElementById('privilege-input').value.trim();
759
- var resultDiv = document.getElementById('privilege-result');
760
- if (!input) { resultDiv.style.display = 'none'; return; }
761
- var privMarkers = ['attorney work product', 'privileged', 'confidential - attorney client', 'matter m-', 'm-2847', 'm-2911'];
762
- var lower = input.toLowerCase();
763
- var blocked = false;
764
- var marker = '';
765
- for (var i = 0; i < privMarkers.length; i++) {
766
- if (lower.indexOf(privMarkers[i]) !== -1) { blocked = true; marker = privMarkers[i]; break; }
767
- }
768
- if (blocked) {
769
- var privilegePayload = __thumbgateBuildAudit({
770
- audit_id: 'PRIV-2755-20260526-091204',
771
- timestamp_iso: '2026-05-26T09:12:04Z',
772
- rule_id: 'EGRESS_RULE_1.6_PRIVILEGE',
773
- rule_version: '2.8',
774
- matched: 'privilege marker in outbound payload ("' + marker + '")',
775
- agent: 'brief-assistant-v3',
776
- input: input,
777
- matter_context: 'Outbound LLM call from attorney workspace',
778
- action: 'BLOCK + REDIRECT_TO_TENANT_LLM + LOG',
779
- iso_controls: ['A.5.34 (Privacy & PII protection)', 'A.5.14 (Information transfer)', 'A.8.24 (Use of cryptography)']
780
- });
781
- resultDiv.innerHTML =
782
- '<div class="demo-blocked">' +
783
- '<strong style="color:#f87171">BLOCKED &mdash; Egress Gate fired</strong><br>' +
784
- 'Detected privilege marker: "' + escapeHtml(marker) + '"<br><br>' +
785
- '<strong>Corrective action:</strong> Outbound call to external LLM blocked. Redirected to in-tenant Azure OpenAI (BAA-protected) or internal summarizer.<br><br>' +
786
- '<div class="audit-log">[2026-05-26 09:12:04] PreToolUse gate: EGRESS_RULE_1.6_PRIVILEGE v2.8\nRule matched: privilege marker in outbound payload\nAction: BLOCK + REDIRECT_TO_TENANT_LLM + LOG\nAudit ID: PRIV-2755-20260526-091204\nContent hash: sha256:7f3a... (truncated)\nAgent: brief-assistant-v3</div>' +
787
- __thumbgateAuditButton('privilege', privilegePayload, 'ThumbGate-Audit-PRIV-2755-2026-05-26.json') +
788
- '</div>';
789
- } else {
790
- resultDiv.innerHTML =
791
- '<div class="demo-cleared">' +
792
- '<strong style="color:#34d399">CLEARED &mdash; no privilege markers detected</strong><br>' +
793
- 'Content would be sent to external LLM (in production this would still trigger logging + optional human review flag).' +
794
- '</div>';
795
- }
796
- resultDiv.style.display = 'block';
797
- }
798
-
799
- // Keyboard support: Enter submits, Shift+Enter inserts newline
800
- var uplEl = document.getElementById('upl-input');
801
- if (uplEl) uplEl.addEventListener('keydown', function(e) {
802
- if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); runUPLDemo(); }
803
- });
804
- var privEl = document.getElementById('privilege-input');
805
- if (privEl) privEl.addEventListener('keydown', function(e) {
806
- if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); runPrivilegeDemo(); }
807
- });
808
- </script>
809
- </section>
810
- </main>
811
-
812
- <footer class="footer">
813
- <p>ThumbGate is a software control layer, not legal advice. This page is intended for pilot scoping with law-firm innovation, technology, risk, and pricing teams. Final policy choices should be reviewed by the firm's attorneys and security team.</p>
814
- </footer>
815
- </div>
816
- <script src="/js/buyer-intent.js"></script>
817
- </body>
818
- </html>