thumbgate 1.15.0 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +6 -6
- package/.claude-plugin/plugin.json +3 -3
- package/.well-known/llms.txt +5 -5
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +59 -35
- package/adapters/chatgpt/openapi.yaml +118 -2
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +210 -84
- package/adapters/opencode/opencode.json +1 -1
- package/bench/prompt-eval-suite.json +5 -1
- package/bin/cli.js +157 -8
- package/config/evals/agent-safety-eval.json +338 -22
- package/config/gates/routine.json +43 -0
- package/config/github-about.json +3 -3
- package/config/model-candidates.json +131 -0
- package/openapi/openapi.yaml +118 -2
- package/package.json +57 -49
- package/public/blog.html +7 -7
- package/public/codex-plugin.html +6 -6
- package/public/compare.html +29 -23
- package/public/dashboard.html +82 -10
- package/public/guide.html +28 -28
- package/public/index.html +216 -98
- package/public/learn.html +50 -22
- package/public/lessons.html +1 -1
- package/public/numbers.html +17 -17
- package/public/pro.html +82 -18
- package/scripts/agent-audit-trace.js +55 -0
- package/scripts/agent-memory-lifecycle.js +96 -0
- package/scripts/agent-readiness-plan.js +118 -0
- package/scripts/agentic-data-pipeline.js +21 -1
- package/scripts/agents-sdk-sandbox-plan.js +57 -0
- package/scripts/ai-org-governance.js +98 -0
- package/scripts/ai-search-distribution.js +43 -0
- package/scripts/artifact-agent-plan.js +81 -0
- package/scripts/billing.js +27 -8
- package/scripts/cli-schema.js +18 -2
- package/scripts/code-mode-mcp-plan.js +71 -0
- package/scripts/context-engine.js +1 -2
- package/scripts/context-manager.js +4 -1
- package/scripts/dashboard-render-spec.js +1 -1
- package/scripts/dashboard.js +275 -9
- package/scripts/decision-journal.js +13 -3
- package/scripts/document-workflow-governance.js +62 -0
- package/scripts/enterprise-agent-rollout.js +34 -0
- package/scripts/experience-replay-governance.js +69 -0
- package/scripts/export-hf-dataset.js +1 -1
- package/scripts/feedback-loop.js +92 -4
- package/scripts/feedback-to-rules.js +17 -23
- package/scripts/gates-engine.js +4 -6
- package/scripts/growth-campaigns.js +49 -0
- package/scripts/harness-selector.js +16 -4
- package/scripts/hybrid-supervisor-agent.js +64 -0
- package/scripts/inference-cache-policy.js +72 -0
- package/scripts/inference-economics.js +53 -0
- package/scripts/internal-agent-bootstrap.js +12 -2
- package/scripts/knowledge-layer-plan.js +108 -0
- package/scripts/lesson-inference.js +183 -44
- package/scripts/lesson-search.js +4 -1
- package/scripts/llm-client.js +157 -26
- package/scripts/mailer/resend-mailer.js +112 -1
- package/scripts/mcp-transport-strategy.js +66 -0
- package/scripts/memory-store-governance.js +60 -0
- package/scripts/meta-agent-loop.js +7 -13
- package/scripts/model-access-eligibility.js +38 -0
- package/scripts/model-migration-readiness.js +55 -0
- package/scripts/operational-integrity.js +96 -3
- package/scripts/otel-declarative-config.js +56 -0
- package/scripts/perplexity-client.js +1 -1
- package/scripts/post-training-governance.js +34 -0
- package/scripts/private-core-boundary.js +72 -0
- package/scripts/production-agent-readiness.js +40 -0
- package/scripts/prompt-eval.js +564 -32
- package/scripts/prompt-programs.js +93 -0
- package/scripts/provider-action-normalizer.js +585 -0
- package/scripts/scaling-law-claims.js +60 -0
- package/scripts/security-scanner.js +1 -1
- package/scripts/self-distill-agent.js +7 -32
- package/scripts/seo-gsd.js +232 -55
- package/scripts/skill-rag-router.js +53 -0
- package/scripts/spec-gate.js +1 -1
- package/scripts/student-consistent-training.js +73 -0
- package/scripts/synthetic-data-provenance.js +98 -0
- package/scripts/task-context-result.js +81 -0
- package/scripts/telemetry-analytics.js +149 -0
- package/scripts/thompson-sampling.js +2 -2
- package/scripts/token-savings.js +7 -6
- package/scripts/token-tco.js +46 -0
- package/scripts/tool-registry.js +63 -3
- package/scripts/verification-loop.js +10 -1
- package/scripts/verifier-scoring.js +71 -0
- package/scripts/workflow-sentinel.js +284 -28
- package/scripts/workspace-agent-routines.js +118 -0
- package/src/api/server.js +381 -120
- package/scripts/analytics-report.js +0 -328
- package/scripts/autonomous-workflow.js +0 -377
- package/scripts/billing-setup.js +0 -109
- package/scripts/creator-campaigns.js +0 -239
- package/scripts/cross-encoder-reranker.js +0 -235
- package/scripts/daemon-manager.js +0 -108
- package/scripts/decision-trace.js +0 -354
- package/scripts/delegation-runtime.js +0 -896
- package/scripts/dispatch-brief.js +0 -159
- package/scripts/distribution-surfaces.js +0 -110
- package/scripts/feedback-history-distiller.js +0 -382
- package/scripts/funnel-analytics.js +0 -35
- package/scripts/history-distiller.js +0 -200
- package/scripts/hosted-job-launcher.js +0 -256
- package/scripts/intent-router.js +0 -392
- package/scripts/lesson-reranker.js +0 -263
- package/scripts/lesson-retrieval.js +0 -148
- package/scripts/managed-lesson-agent.js +0 -183
- package/scripts/operational-dashboard.js +0 -103
- package/scripts/operational-summary.js +0 -129
- package/scripts/operator-artifacts.js +0 -608
- package/scripts/optimize-context.js +0 -17
- package/scripts/org-dashboard.js +0 -206
- package/scripts/partner-orchestration.js +0 -146
- package/scripts/predictive-insights.js +0 -356
- package/scripts/pulse.js +0 -80
- package/scripts/reflector-agent.js +0 -221
- package/scripts/sales-pipeline.js +0 -681
- package/scripts/session-episode-store.js +0 -329
- package/scripts/session-health-sensor.js +0 -242
- package/scripts/session-report.js +0 -120
- package/scripts/swarm-coordinator.js +0 -81
- package/scripts/tool-kpi-tracker.js +0 -12
- package/scripts/webhook-delivery.js +0 -62
- package/scripts/workflow-sprint-intake.js +0 -475
package/public/learn.html
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Learn — AI Agent Safety, Pre-Action
|
|
6
|
+
<title>Learn — AI Agent Safety, Pre-Action Checks, and Vibe Coding Guardrails</title>
|
|
7
7
|
<script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
|
|
8
|
-
<meta name="description" content="Practical guides for stopping AI coding agent mistakes. Learn about pre-action
|
|
9
|
-
<meta name="keywords" content="AI agent safety, pre-action
|
|
8
|
+
<meta name="description" content="Practical guides for stopping AI coding agent mistakes. Learn about pre-action checks, MCP guardrails, feedback-driven enforcement, and vibe coding safety for Claude Code, Cursor, Codex, and more.">
|
|
9
|
+
<meta name="keywords" content="AI agent safety, pre-action checks, vibe coding guardrails, Claude Code mistakes, Cursor agent memory, MCP server hooks, AI coding agent feedback, ThumbGate guides">
|
|
10
10
|
<meta property="og:title" content="Learn — AI Agent Safety Guides by ThumbGate">
|
|
11
|
-
<meta property="og:description" content="Practical guides for stopping AI coding agent mistakes with pre-action
|
|
11
|
+
<meta property="og:description" content="Practical guides for stopping AI coding agent mistakes with pre-action checks and feedback-driven enforcement.">
|
|
12
12
|
<meta property="og:type" content="website">
|
|
13
13
|
<meta property="og:url" content="https://thumbgate-production.up.railway.app/learn">
|
|
14
14
|
<link rel="canonical" href="https://thumbgate-production.up.railway.app/learn">
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@context": "https://schema.org",
|
|
21
21
|
"@type": "CollectionPage",
|
|
22
22
|
"name": "ThumbGate Learning Hub",
|
|
23
|
-
"description": "Practical guides for AI coding agent safety, pre-action
|
|
23
|
+
"description": "Practical guides for AI coding agent safety, pre-action checks, and vibe coding guardrails.",
|
|
24
24
|
"url": "https://thumbgate-production.up.railway.app/learn",
|
|
25
25
|
"dateModified": "2026-04-20",
|
|
26
26
|
"author": {
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
{
|
|
56
56
|
"@type": "ListItem",
|
|
57
57
|
"position": 3,
|
|
58
|
-
"url": "https://thumbgate-production.up.railway.app/learn/mcp-pre-action-
|
|
59
|
-
"name": "MCP Pre-Action
|
|
58
|
+
"url": "https://thumbgate-production.up.railway.app/learn/mcp-pre-action-checks-explained",
|
|
59
|
+
"name": "MCP Pre-Action Checks Explained"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"@type": "ListItem",
|
|
@@ -73,38 +73,50 @@
|
|
|
73
73
|
{
|
|
74
74
|
"@type": "ListItem",
|
|
75
75
|
"position": 6,
|
|
76
|
-
"url": "https://thumbgate
|
|
76
|
+
"url": "https://thumbgate.ai/guides/stop-repeated-ai-agent-mistakes",
|
|
77
77
|
"name": "How to Stop AI Coding Agents From Repeating Mistakes"
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"@type": "ListItem",
|
|
81
81
|
"position": 7,
|
|
82
|
-
"url": "https://thumbgate
|
|
82
|
+
"url": "https://thumbgate.ai/guides/cursor-agent-guardrails",
|
|
83
83
|
"name": "Cursor Guardrails That Block Repeated Mistakes"
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"@type": "ListItem",
|
|
87
87
|
"position": 8,
|
|
88
|
-
"url": "https://thumbgate
|
|
88
|
+
"url": "https://thumbgate.ai/guides/codex-cli-guardrails",
|
|
89
89
|
"name": "Codex CLI Guardrails That Actually Enforce"
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
"@type": "ListItem",
|
|
93
93
|
"position": 9,
|
|
94
|
-
"url": "https://thumbgate
|
|
94
|
+
"url": "https://thumbgate.ai/guides/gemini-cli-feedback-memory",
|
|
95
95
|
"name": "Gemini CLI Feedback Memory That Leads to Enforcement"
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"@type": "ListItem",
|
|
99
99
|
"position": 10,
|
|
100
|
-
"url": "https://thumbgate
|
|
100
|
+
"url": "https://thumbgate.ai/guides/browser-automation-safety",
|
|
101
101
|
"name": "Browser Automation Safety for AI Agents"
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"@type": "ListItem",
|
|
105
105
|
"position": 11,
|
|
106
|
-
"url": "https://thumbgate
|
|
106
|
+
"url": "https://thumbgate.ai/guides/native-messaging-host-security",
|
|
107
107
|
"name": "Native Messaging Host Security"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"@type": "ListItem",
|
|
111
|
+
"position": 12,
|
|
112
|
+
"url": "https://thumbgate.ai/guides/ai-search-topical-presence",
|
|
113
|
+
"name": "AI Search Topical Presence"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"@type": "ListItem",
|
|
117
|
+
"position": 13,
|
|
118
|
+
"url": "https://thumbgate.ai/guides/relational-knowledge-ai-recommendations",
|
|
119
|
+
"name": "Relational Knowledge in AI Recommendations"
|
|
108
120
|
}
|
|
109
121
|
]
|
|
110
122
|
}
|
|
@@ -215,10 +227,10 @@
|
|
|
215
227
|
<div class="article-grid">
|
|
216
228
|
<a href="/learn/stop-ai-agent-force-push" class="article-card">
|
|
217
229
|
<h3>How to Stop AI Agents From Force-Pushing to Main</h3>
|
|
218
|
-
<p>Your agent just ran git push --force on main. Again. Here is how to make that physically impossible with a pre-action
|
|
230
|
+
<p>Your agent just ran git push --force on main. Again. Here is how to make that physically impossible with a pre-action check that takes two minutes to set up.</p>
|
|
219
231
|
<span class="article-tag">Claude Code</span>
|
|
220
232
|
<span class="article-tag">Git Safety</span>
|
|
221
|
-
<span class="article-tag">Pre-Action
|
|
233
|
+
<span class="article-tag">Pre-Action Checks</span>
|
|
222
234
|
</a>
|
|
223
235
|
|
|
224
236
|
<a href="/learn/vibe-coding-safety-net" class="article-card">
|
|
@@ -229,16 +241,16 @@
|
|
|
229
241
|
<span class="article-tag">MCP</span>
|
|
230
242
|
</a>
|
|
231
243
|
|
|
232
|
-
<a href="/learn/mcp-pre-action-
|
|
233
|
-
<h3>MCP Pre-Action
|
|
234
|
-
<p>What pre-action
|
|
244
|
+
<a href="/learn/mcp-pre-action-checks-explained" class="article-card">
|
|
245
|
+
<h3>MCP Pre-Action Checks Explained</h3>
|
|
246
|
+
<p>What pre-action checks are, how they differ from prompt rules, and why enforcement beats instructions. A technical deep-dive for developers building on the Model Context Protocol.</p>
|
|
235
247
|
<span class="article-tag">MCP</span>
|
|
236
248
|
<span class="article-tag">PreToolUse</span>
|
|
237
249
|
<span class="article-tag">Technical</span>
|
|
238
250
|
</a>
|
|
239
251
|
<a href="/learn/agent-harness-pattern" class="article-card">
|
|
240
252
|
<h3>The Agent Harness Pattern: Why Your AI Needs a Seatbelt</h3>
|
|
241
|
-
<p>Tsinghua researchers formalized agent harnesses as first-class objects with contracts, verification
|
|
253
|
+
<p>Tsinghua researchers formalized agent harnesses as first-class objects with contracts, verification checks, and durable state. ThumbGate implements this pattern in production today.</p>
|
|
242
254
|
<span class="article-tag">Research</span>
|
|
243
255
|
<span class="article-tag">Agent Harness</span>
|
|
244
256
|
<span class="article-tag">NLAH</span>
|
|
@@ -256,6 +268,22 @@
|
|
|
256
268
|
<h2>Popular buyer questions</h2>
|
|
257
269
|
<p class="section-intro">These are the high-intent guides for buyers who already know the pain and want to understand where ThumbGate fits fast.</p>
|
|
258
270
|
<div class="article-grid">
|
|
271
|
+
<a href="/guides/ai-search-topical-presence" class="article-card">
|
|
272
|
+
<h3>AI Search Topical Presence</h3>
|
|
273
|
+
<p>Why AI assistants recommend the tools they repeatedly see tied to a buyer problem, and how ThumbGate builds that association with proof-backed pages.</p>
|
|
274
|
+
<span class="article-tag">AI Search</span>
|
|
275
|
+
<span class="article-tag">Topical Presence</span>
|
|
276
|
+
<span class="article-tag">Recommendation</span>
|
|
277
|
+
</a>
|
|
278
|
+
|
|
279
|
+
<a href="/guides/relational-knowledge-ai-recommendations" class="article-card">
|
|
280
|
+
<h3>Relational Knowledge in AI Recommendations</h3>
|
|
281
|
+
<p>How stored brand-to-problem associations shape AI answers, and why ThumbGate should own the pre-action-checks category in those retrieval paths.</p>
|
|
282
|
+
<span class="article-tag">Relational Knowledge</span>
|
|
283
|
+
<span class="article-tag">AI Answers</span>
|
|
284
|
+
<span class="article-tag">GEO</span>
|
|
285
|
+
</a>
|
|
286
|
+
|
|
259
287
|
<a href="/guides/stop-repeated-ai-agent-mistakes" class="article-card">
|
|
260
288
|
<h3>How to Stop AI Coding Agents From Repeating Mistakes</h3>
|
|
261
289
|
<p>The fastest explanation of why memory alone is not enough when your agent keeps making the same bad move twice.</p>
|
|
@@ -282,7 +310,7 @@
|
|
|
282
310
|
|
|
283
311
|
<a href="/guides/gemini-cli-feedback-memory" class="article-card">
|
|
284
312
|
<h3>Gemini CLI Feedback Memory That Leads to Enforcement</h3>
|
|
285
|
-
<p>A memory-first buyer path for Gemini CLI users who will eventually care about
|
|
313
|
+
<p>A memory-first buyer path for Gemini CLI users who will eventually care about checks, proof, and operational control.</p>
|
|
286
314
|
<span class="article-tag">Gemini</span>
|
|
287
315
|
<span class="article-tag">Memory</span>
|
|
288
316
|
<span class="article-tag">Enforcement</span>
|
|
@@ -306,10 +334,10 @@
|
|
|
306
334
|
|
|
307
335
|
<a href="/guides/autoresearch-agent-safety" class="article-card">
|
|
308
336
|
<h3>Autoresearch Agent Safety for Self-Improving Coding Agents</h3>
|
|
309
|
-
<p>The control-plane story for benchmark-search loops that need holdout tests, proof trails, and reward-hacking
|
|
337
|
+
<p>The control-plane story for benchmark-search loops that need holdout tests, proof trails, and reward-hacking checks.</p>
|
|
310
338
|
<span class="article-tag">Autoresearch</span>
|
|
311
339
|
<span class="article-tag">Holdout Proof</span>
|
|
312
|
-
<span class="article-tag">
|
|
340
|
+
<span class="article-tag">Checks</span>
|
|
313
341
|
</a>
|
|
314
342
|
</div>
|
|
315
343
|
|
package/public/lessons.html
CHANGED
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
<div style="margin:32px 0 24px;padding:24px;background:linear-gradient(135deg,rgba(167,139,250,0.08),rgba(34,211,238,0.05));border:1px solid rgba(167,139,250,0.2);border-radius:12px;">
|
|
226
226
|
<h1 style="font-size:22px;font-weight:700;margin-bottom:8px;letter-spacing:-0.02em;">📚 Lessons Learned</h1>
|
|
227
227
|
<p style="font-size:12px;color:var(--text-muted);margin-bottom:8px;">Updated: <time datetime="2026-04-20">2026-04-20</time> · by <a href="https://github.com/IgorGanapolsky" style="color:inherit;">Igor Ganapolsky</a></p>
|
|
228
|
-
<p style="font-size:14px;color:var(--text-muted);line-height:1.6;max-width:700px;">See what ThumbGate learned from your feedback, which failure patterns keep repeating, and how many actions the
|
|
228
|
+
<p style="font-size:14px;color:var(--text-muted);line-height:1.6;max-width:700px;">See what ThumbGate learned from your feedback, which failure patterns keep repeating, and how many actions the approval layer actually blocked. <span style="color:var(--purple);font-weight:600;">This view separates repeated failures from recorded gate blocks so the proof stays honest.</span></p>
|
|
229
229
|
<div style="display:flex;gap:16px;margin-top:12px;font-size:12px;color:var(--text-muted);">
|
|
230
230
|
<span>📋 <strong style="color:var(--text);">Active Rules</strong> — what was learned</span>
|
|
231
231
|
<span>📊 <strong style="color:var(--text);">Timeline</strong> — when it was learned</span>
|
package/public/numbers.html
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<meta name="generator" content="ThumbGate">
|
|
7
7
|
<meta name="author" content="Igor Ganapolsky">
|
|
8
8
|
<title>ThumbGate — The Numbers | Live First-Party Data</title>
|
|
9
|
-
<meta name="description" content="ThumbGate's live operational numbers: active pre-action
|
|
9
|
+
<meta name="description" content="ThumbGate's live operational numbers: active pre-action checks, AI agent actions blocked, estimated LLM tokens and dollars saved, and the Bayes error rate of our intervention scorer. First-party data, regenerated on every release.">
|
|
10
10
|
<meta property="og:title" content="ThumbGate — The Numbers">
|
|
11
|
-
<meta property="og:description" content="Live first-party operational metrics:
|
|
11
|
+
<meta property="og:description" content="Live first-party operational metrics: checks, blocks, token savings, and scorer calibration. Regenerated on every release.">
|
|
12
12
|
<meta property="og:type" content="website">
|
|
13
13
|
<meta property="og:url" content="https://thumbgate-production.up.railway.app/numbers">
|
|
14
14
|
<meta name="twitter:card" content="summary_large_image">
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@context": "https://schema.org",
|
|
46
46
|
"@type": "Dataset",
|
|
47
47
|
"name": "ThumbGate Live Operational Metrics",
|
|
48
|
-
"description": "First-party operational metrics from the ThumbGate pre-action
|
|
48
|
+
"description": "First-party operational metrics from the ThumbGate pre-action check runtime: active checks, blocked AI agent actions, estimated token savings, and Bayes error rate of the intervention scorer.",
|
|
49
49
|
"url": "https://thumbgate-production.up.railway.app/numbers",
|
|
50
50
|
"license": "https://opensource.org/licenses/MIT",
|
|
51
51
|
"creator": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dateModified": "2026-04-20",
|
|
61
61
|
"datePublished": "2026-04-20",
|
|
62
62
|
"keywords": [
|
|
63
|
-
"AI agent
|
|
63
|
+
"AI agent checks",
|
|
64
64
|
"LLM token savings",
|
|
65
65
|
"prevention rules",
|
|
66
66
|
"Bayes error rate",
|
|
@@ -192,31 +192,31 @@
|
|
|
192
192
|
<p class="subtitle">Live first-party operational data from the ThumbGate runtime. No surveys, no projections — counts pulled from the same local scripts that power the CLI and dashboard.</p>
|
|
193
193
|
<div class="freshness">Updated: 2026-04-20 · Version 1.12.2</div>
|
|
194
194
|
|
|
195
|
-
<h2>
|
|
195
|
+
<h2>Check enforcement</h2>
|
|
196
196
|
<div class="stats-grid">
|
|
197
197
|
<div class="stat-card">
|
|
198
|
-
<div class="stat-label">Active
|
|
198
|
+
<div class="stat-label">Active checks</div>
|
|
199
199
|
<div class="stat-value">52</div>
|
|
200
200
|
<div class="stat-sub">33 manual · 19 auto-promoted</div>
|
|
201
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/
|
|
201
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/check-stats.js">source: check-stats.js</a>
|
|
202
202
|
</div>
|
|
203
203
|
<div class="stat-card">
|
|
204
204
|
<div class="stat-label">Actions blocked</div>
|
|
205
205
|
<div class="stat-value">0</div>
|
|
206
|
-
<div class="stat-sub">repeat AI mistakes prevented at the
|
|
207
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/
|
|
206
|
+
<div class="stat-sub">repeat AI mistakes prevented at the check</div>
|
|
207
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/check-stats.js">source: check-stats.js</a>
|
|
208
208
|
</div>
|
|
209
209
|
<div class="stat-card">
|
|
210
210
|
<div class="stat-label">Actions warned</div>
|
|
211
211
|
<div class="stat-value">455</div>
|
|
212
212
|
<div class="stat-sub">soft interventions; not blocks</div>
|
|
213
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/
|
|
213
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/check-stats.js">source: check-stats.js</a>
|
|
214
214
|
</div>
|
|
215
215
|
<div class="stat-card">
|
|
216
|
-
<div class="stat-label">Top blocked
|
|
216
|
+
<div class="stat-label">Top blocked check</div>
|
|
217
217
|
<div class="stat-value" style="font-size:1.1rem;">local-only-git-writes (0 blocks)</div>
|
|
218
218
|
<div class="stat-sub">highest-occurrence prevention rule</div>
|
|
219
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/
|
|
219
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/check-stats.js">source: check-stats.js</a>
|
|
220
220
|
</div>
|
|
221
221
|
</div>
|
|
222
222
|
|
|
@@ -226,7 +226,7 @@
|
|
|
226
226
|
<div class="stat-label">Estimated hours saved</div>
|
|
227
227
|
<div class="stat-value">113.8</div>
|
|
228
228
|
<div class="stat-sub">~15 min per blocked mistake × blocks+warns</div>
|
|
229
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/
|
|
229
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/check-stats.js">source: check-stats.js</a>
|
|
230
230
|
</div>
|
|
231
231
|
<div class="stat-card">
|
|
232
232
|
<div class="stat-label">Estimated LLM dollars saved</div>
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
<div class="stat-label">Scorer Bayes error</div>
|
|
245
245
|
<div class="stat-value">1.5%</div>
|
|
246
246
|
<div class="stat-sub">irreducible error given current feature set</div>
|
|
247
|
-
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/bayes-optimal-
|
|
247
|
+
<a class="stat-source" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/scripts/bayes-optimal-check.js">source: bayes-optimal-check.js</a>
|
|
248
248
|
</div>
|
|
249
249
|
</div>
|
|
250
250
|
|
|
@@ -252,8 +252,8 @@
|
|
|
252
252
|
<div class="method">
|
|
253
253
|
<p><strong>Where the numbers come from.</strong> This page is regenerated from local scripts — no survey data, no hand-edited figures, no third-party attribution. Every number on this page is produced by code in the public <a href="https://github.com/IgorGanapolsky/ThumbGate">ThumbGate repo</a>.</p>
|
|
254
254
|
<ul>
|
|
255
|
-
<li><strong>Active
|
|
256
|
-
<li><strong>Actions blocked/warned</strong> — sum of <code>occurrences</code> across
|
|
255
|
+
<li><strong>Active checks</strong> — union of shipped default rules and the auto-promotion ledger (auto).</li>
|
|
256
|
+
<li><strong>Actions blocked/warned</strong> — sum of <code>occurrences</code> across checks with the corresponding action.</li>
|
|
257
257
|
<li><strong>Hours saved</strong> — conservative 15-minute/incident estimate for debugging a repeated AI mistake × (blocks + warns).</li>
|
|
258
258
|
<li><strong>Dollars saved</strong> — blended per-call token estimate (2k input + 600 output) × blocks × 2026-04-15 Anthropic + OpenAI list prices. See <code>scripts/token-savings.js</code> for the full price snapshot.</li>
|
|
259
259
|
<li><strong>Bayes error rate</strong> — irreducible classifier error of the current risk scorer given its feature set. High values mean "add features, don't tune thresholds."</li>
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
|
|
264
264
|
<div class="cta">
|
|
265
265
|
<a href="https://www.npmjs.com/package/thumbgate">Install ThumbGate — npx thumbgate init</a>
|
|
266
|
-
<div class="footer-note">Prefer the raw feed? See <a href="https://github.com/IgorGanapolsky/ThumbGate">GitHub</a> or run <code>npm run
|
|
266
|
+
<div class="footer-note">Prefer the raw feed? See <a href="https://github.com/IgorGanapolsky/ThumbGate">GitHub</a> or run <code>npm run check:stats</code> locally.</div>
|
|
267
267
|
<div class="footer-note">Generated at 2026-04-20T21:45:34.500Z UTC.</div>
|
|
268
268
|
</div>
|
|
269
269
|
</main>
|
package/public/pro.html
CHANGED
|
@@ -7,14 +7,14 @@ __GOOGLE_SITE_VERIFICATION_META__
|
|
|
7
7
|
<title>ThumbGate Pro | Personal local dashboard and proof for AI agent reliability</title>
|
|
8
8
|
<meta name="description" content="ThumbGate Pro is the paid lane for individual operators who want a personal local dashboard, DPO export, review-ready evidence, and founder support for risky AI coding workflows.">
|
|
9
9
|
<meta property="og:title" content="ThumbGate Pro | Personal local dashboard and proof for AI agent reliability">
|
|
10
|
-
<meta property="og:description" content="Move from free local
|
|
10
|
+
<meta property="og:description" content="Move from free local checks to a paid operator workflow with a personal local dashboard, DPO export, and review-ready evidence for repeated AI coding failures.">
|
|
11
11
|
<meta property="og:type" content="website">
|
|
12
12
|
<meta property="og:url" content="__APP_ORIGIN__/pro">
|
|
13
13
|
<link rel="canonical" href="__APP_ORIGIN__/pro">
|
|
14
14
|
<link rel="icon" type="image/png" href="/thumbgate-icon.png">
|
|
15
15
|
<link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
|
|
16
16
|
<meta property="og:image" content="/og.png">
|
|
17
|
-
<meta name="keywords" content="ThumbGate Pro, AI agent reliability, pre-action
|
|
17
|
+
<meta name="keywords" content="ThumbGate Pro, AI agent reliability, pre-action checks, DPO export, local dashboard, review-ready evidence, Claude Code reliability, Codex reliability, Cursor reliability">
|
|
18
18
|
|
|
19
19
|
<script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
|
|
20
20
|
__GA_BOOTSTRAP__
|
|
@@ -50,7 +50,7 @@ __GA_BOOTSTRAP__
|
|
|
50
50
|
},
|
|
51
51
|
"featureList": [
|
|
52
52
|
"Personal local dashboard",
|
|
53
|
-
"Visual
|
|
53
|
+
"Visual check debugger",
|
|
54
54
|
"DPO export from real thumbs-down corrections",
|
|
55
55
|
"Auto-connect running agents after activation",
|
|
56
56
|
"Founder support on risky workflows",
|
|
@@ -87,7 +87,7 @@ __GA_BOOTSTRAP__
|
|
|
87
87
|
"name": "How is Pro different from the free install?",
|
|
88
88
|
"acceptedAnswer": {
|
|
89
89
|
"@type": "Answer",
|
|
90
|
-
"text": "Free keeps the local recall,
|
|
90
|
+
"text": "Free keeps the local recall, checks, and MCP workflow. Pro adds a personal local dashboard, DPO export, auto-connect for running agents, and founder support for risky workflows."
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
{
|
|
@@ -808,7 +808,7 @@ __GA_BOOTSTRAP__
|
|
|
808
808
|
<h1>One correction protects every agent on your team.</h1>
|
|
809
809
|
<p style="font-size:13px;opacity:0.8;margin-bottom:0.5rem;">Updated: <time datetime="2026-04-20">2026-04-20</time> · by <a href="https://github.com/IgorGanapolsky" style="color:inherit;">Igor Ganapolsky</a></p>
|
|
810
810
|
<p>ThumbGate prevents unsafe AI agent actions before they hit shared repos, CI pipelines, and production. When one developer flags a bad pattern, every agent on the team is permanently blocked from repeating it.</p>
|
|
811
|
-
<p>Open-source core for individuals. Team plan for shared enforcement, CI
|
|
811
|
+
<p>Open-source core for individuals. Team plan for shared enforcement, CI checks, approval policies, and audit trails across your engineering org.</p>
|
|
812
812
|
<div class="hero-proof">
|
|
813
813
|
<div class="proof-pill">Personal local dashboard</div>
|
|
814
814
|
<div class="proof-pill">DPO export from real corrections</div>
|
|
@@ -820,14 +820,14 @@ __GA_BOOTSTRAP__
|
|
|
820
820
|
<a class="btn-secondary btn-demo" href="/dashboard?utm_source=website&utm_medium=pro_page&utm_campaign=pro_pack">Open dashboard demo</a>
|
|
821
821
|
<a class="btn-ghost btn-free-path" href="/guide?utm_source=website&utm_medium=pro_page&utm_campaign=free_install">Stay on Free and install locally</a>
|
|
822
822
|
</div>
|
|
823
|
-
<p class="hero-note"><strong>Honest split:</strong> if local recall and
|
|
823
|
+
<p class="hero-note"><strong>Honest split:</strong> if local recall and checks are enough, stay on Free. Go Pro when you want your own dashboard, DPO training data export, and proof you can show on the next risky workflow review.</p>
|
|
824
824
|
</div>
|
|
825
825
|
|
|
826
826
|
<div class="panel hero-aside">
|
|
827
827
|
<div class="aside-card">
|
|
828
828
|
<div class="aside-kicker">What you are buying</div>
|
|
829
829
|
<h2>A faster operator loop</h2>
|
|
830
|
-
<p>See every blocked action, the
|
|
830
|
+
<p>See every blocked action, the check that fired, the lesson behind it, and the export path that turns real thumbs-downs into reusable DPO pairs.</p>
|
|
831
831
|
<div class="price-stack">
|
|
832
832
|
<div class="price-line">
|
|
833
833
|
<div>
|
|
@@ -849,7 +849,7 @@ __GA_BOOTSTRAP__
|
|
|
849
849
|
<div class="aside-card">
|
|
850
850
|
<div class="aside-kicker">Proof-backed, not vibes</div>
|
|
851
851
|
<h3>Specific paid outcomes</h3>
|
|
852
|
-
<p>Visual
|
|
852
|
+
<p>Visual check debugger, DPO export, auto-connect after activation, Model Hardening Advisor, and founder support for the risky flow you need to harden first.</p>
|
|
853
853
|
</div>
|
|
854
854
|
|
|
855
855
|
<div class="aside-card">
|
|
@@ -887,7 +887,7 @@ __GA_BOOTSTRAP__
|
|
|
887
887
|
</a>
|
|
888
888
|
<a href="/dashboard?utm_source=website&utm_medium=pro_page_proof&utm_campaign=pro_pack">
|
|
889
889
|
<strong>Live dashboard demo</strong>
|
|
890
|
-
<span>Inspect lessons,
|
|
890
|
+
<span>Inspect lessons, checks, and blocked actions before you buy.</span>
|
|
891
891
|
</a>
|
|
892
892
|
</div>
|
|
893
893
|
</div>
|
|
@@ -901,9 +901,9 @@ __GA_BOOTSTRAP__
|
|
|
901
901
|
<div class="grid-3">
|
|
902
902
|
<div class="feature-card">
|
|
903
903
|
<h3>Debug the exact block in minutes</h3>
|
|
904
|
-
<p>The visual
|
|
904
|
+
<p>The visual check debugger shows every blocked action and the check that fired, so you stop guessing whether the Reliability Gateway is actually working.</p>
|
|
905
905
|
<ul>
|
|
906
|
-
<li>See the
|
|
906
|
+
<li>See the check, evidence, and lesson behind each deny.</li>
|
|
907
907
|
<li>Trust the system faster on deploys, migrations, and CI.</li>
|
|
908
908
|
</ul>
|
|
909
909
|
</div>
|
|
@@ -930,12 +930,12 @@ __GA_BOOTSTRAP__
|
|
|
930
930
|
<section class="section">
|
|
931
931
|
<div class="container">
|
|
932
932
|
<div class="section-label">Honest packaging</div>
|
|
933
|
-
<h2 class="section-title">Stay on Free when recall and
|
|
933
|
+
<h2 class="section-title">Stay on Free when recall and checks are enough. Go Pro when you need proof and operator speed.</h2>
|
|
934
934
|
<div class="split-grid">
|
|
935
935
|
<div class="split-card free">
|
|
936
936
|
<div class="split-kicker">Stay on Free</div>
|
|
937
937
|
<h3>The local install is still the right first step</h3>
|
|
938
|
-
<p>If you only need local recall, Pre-Action
|
|
938
|
+
<p>If you only need local recall, Pre-Action Checks, MCP setup, and a way to stop repeated mistakes on one machine, keep the free install and move fast.</p>
|
|
939
939
|
<ul>
|
|
940
940
|
<li>Local-first recall, lessons, and enforcement.</li>
|
|
941
941
|
<li>No cloud account required.</li>
|
|
@@ -963,14 +963,14 @@ __GA_BOOTSTRAP__
|
|
|
963
963
|
<h3>ThumbGate Team — Agent Governance</h3>
|
|
964
964
|
<div class="price">$49<span>/seat/mo</span></div>
|
|
965
965
|
<div class="annual">Billed monthly or annually · Starts with a 30-min pilot call</div>
|
|
966
|
-
<p class="pricing-note">Shared enforcement memory, CI
|
|
966
|
+
<p class="pricing-note">Shared enforcement memory, CI checks, approval policies, sandbox routing, and a full audit trail of every blocked agent action across your team.</p>
|
|
967
967
|
<ul>
|
|
968
968
|
<li><strong>Shared enforcement</strong> — one developer's correction blocks that pattern for every agent on the team.</li>
|
|
969
|
-
<li><strong>CI
|
|
969
|
+
<li><strong>CI check integration</strong> — block unsafe merges, enforce test requirements, prevent PRs with unresolved threads.</li>
|
|
970
970
|
<li><strong>Approval policies</strong> — require human sign-off for high-risk actions (production deploys, schema migrations, destructive SQL).</li>
|
|
971
971
|
<li><strong>Audit trail</strong> — every blocked action logged with timestamp, agent, context, and the rule that fired.</li>
|
|
972
972
|
<li><strong>Sandbox routing</strong> — route risky agent runs into isolated execution environments.</li>
|
|
973
|
-
<li><strong>Org dashboard</strong> — active agents,
|
|
973
|
+
<li><strong>Org dashboard</strong> — active agents, check hit rates, risk scores, and proof-backed team metrics.</li>
|
|
974
974
|
</ul>
|
|
975
975
|
<div class="pricing-actions">
|
|
976
976
|
<a class="btn-primary" href="/#workflow-sprint-intake">Book a Team Pilot Call</a>
|
|
@@ -991,7 +991,7 @@ __GA_BOOTSTRAP__
|
|
|
991
991
|
<div class="team-card">
|
|
992
992
|
<div class="section-label" style="text-align:left;margin-bottom:8px;">Free path</div>
|
|
993
993
|
<h3>Prefer the local install first?</h3>
|
|
994
|
-
<p class="comparison-note">Install with <code style="font-family:var(--mono);color:var(--cyan);">npx thumbgate init</code>, keep the free local
|
|
994
|
+
<p class="comparison-note">Install with <code style="font-family:var(--mono);color:var(--cyan);">npx thumbgate init</code>, keep the free local checks, and come back to Pro once the workflow owner asks for your own dashboard, exports, or review-ready proof.</p>
|
|
995
995
|
</div>
|
|
996
996
|
</div>
|
|
997
997
|
</div>
|
|
@@ -1004,7 +1004,7 @@ __GA_BOOTSTRAP__
|
|
|
1004
1004
|
<div class="faq-list">
|
|
1005
1005
|
<div class="faq-item open">
|
|
1006
1006
|
<button class="faq-q" type="button" onclick="toggleFaq(this)" onkeydown="handleFaqKeydown(event)" aria-expanded="true">How is Pro different from the free install?</button>
|
|
1007
|
-
<div class="faq-a">Free keeps the local recall, Pre-Action
|
|
1007
|
+
<div class="faq-a">Free keeps the local recall, Pre-Action Checks, and MCP setup. Pro adds the personal local dashboard, DPO export, auto-connect after activation, and founder support when one risky workflow keeps repeating the same failure mode.</div>
|
|
1008
1008
|
</div>
|
|
1009
1009
|
<div class="faq-item">
|
|
1010
1010
|
<button class="faq-q" type="button" onclick="toggleFaq(this)" onkeydown="handleFaqKeydown(event)" aria-expanded="false">Does Pro require a cloud account?</button>
|
|
@@ -1050,6 +1050,46 @@ __GA_BOOTSTRAP__
|
|
|
1050
1050
|
|
|
1051
1051
|
<script src="/js/buyer-intent.js"></script>
|
|
1052
1052
|
<script>
|
|
1053
|
+
function readMarketingParam(name) {
|
|
1054
|
+
var params = new URLSearchParams(window.location.search);
|
|
1055
|
+
return params.get(name);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
function sendFirstPartyTelemetry(eventType, props) {
|
|
1059
|
+
var payload = Object.assign({
|
|
1060
|
+
eventType: eventType,
|
|
1061
|
+
clientType: 'web',
|
|
1062
|
+
acquisitionId: serverAcquisitionId,
|
|
1063
|
+
visitorId: serverVisitorId,
|
|
1064
|
+
sessionId: serverSessionId,
|
|
1065
|
+
source: readMarketingParam('utm_source') || readMarketingParam('source') || 'website',
|
|
1066
|
+
utmSource: readMarketingParam('utm_source') || 'website',
|
|
1067
|
+
utmMedium: readMarketingParam('utm_medium') || 'pro_page',
|
|
1068
|
+
utmCampaign: readMarketingParam('utm_campaign') || 'pro_pack',
|
|
1069
|
+
utmContent: readMarketingParam('utm_content'),
|
|
1070
|
+
utmTerm: readMarketingParam('utm_term'),
|
|
1071
|
+
creator: readMarketingParam('creator') || readMarketingParam('creator_handle'),
|
|
1072
|
+
community: readMarketingParam('community') || readMarketingParam('subreddit'),
|
|
1073
|
+
postId: readMarketingParam('post_id'),
|
|
1074
|
+
commentId: readMarketingParam('comment_id'),
|
|
1075
|
+
campaignVariant: readMarketingParam('campaign_variant'),
|
|
1076
|
+
offerCode: readMarketingParam('offer_code'),
|
|
1077
|
+
page: '/pro',
|
|
1078
|
+
landingPath: '/pro'
|
|
1079
|
+
}, props || {});
|
|
1080
|
+
var body = JSON.stringify(payload);
|
|
1081
|
+
if (navigator.sendBeacon) {
|
|
1082
|
+
navigator.sendBeacon('/v1/telemetry/ping', new Blob([body], { type: 'application/json' }));
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
fetch('/v1/telemetry/ping', {
|
|
1086
|
+
method: 'POST',
|
|
1087
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1088
|
+
body: body,
|
|
1089
|
+
keepalive: true,
|
|
1090
|
+
}).catch(function() {});
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1053
1093
|
function initializeBuyerIntent() {
|
|
1054
1094
|
globalThis.ThumbGateBuyerIntent.initializeBuyerIntent({
|
|
1055
1095
|
page: 'pro',
|
|
@@ -1066,6 +1106,11 @@ function trackClick(selector, eventName, props) {
|
|
|
1066
1106
|
document.querySelectorAll(selector).forEach(function(el) {
|
|
1067
1107
|
el.addEventListener('click', function() {
|
|
1068
1108
|
if (typeof plausible === 'function') plausible(eventName, { props: props || {} });
|
|
1109
|
+
sendFirstPartyTelemetry(eventName, Object.assign({}, props || {}, {
|
|
1110
|
+
ctaId: (props && props.ctaId) || eventName,
|
|
1111
|
+
ctaPlacement: (props && props.ctaPlacement) || 'pro_page',
|
|
1112
|
+
planId: (props && props.planId) || null,
|
|
1113
|
+
}));
|
|
1069
1114
|
});
|
|
1070
1115
|
});
|
|
1071
1116
|
}
|
|
@@ -1087,6 +1132,25 @@ trackClick('.btn-demo', 'pro_demo_click', { page: 'pro' });
|
|
|
1087
1132
|
trackClick('.btn-free-path', 'pro_free_path_click', { page: 'pro' });
|
|
1088
1133
|
trackClick('.proof-links a', 'pro_proof_click', { page: 'pro' });
|
|
1089
1134
|
initializeBuyerIntent();
|
|
1135
|
+
globalThis.buyerJourney = globalThis.ThumbGateBuyerIntent.initializeBehaviorAnalytics({
|
|
1136
|
+
pageType: 'marketing',
|
|
1137
|
+
pagePath: '/pro',
|
|
1138
|
+
landingPath: '/pro',
|
|
1139
|
+
sendTelemetry: sendFirstPartyTelemetry,
|
|
1140
|
+
emailSelector: '[data-buyer-email]',
|
|
1141
|
+
sections: [
|
|
1142
|
+
{ selector: '.hero', sectionId: 'hero', sectionLabel: 'Hero' },
|
|
1143
|
+
{ selector: '#proof', sectionId: 'proof', sectionLabel: 'Proof' },
|
|
1144
|
+
{ selector: '#why-pay', sectionId: 'why_pay', sectionLabel: 'Why Pay' },
|
|
1145
|
+
{ selector: '#pricing', sectionId: 'pricing', sectionLabel: 'Pricing' },
|
|
1146
|
+
{ selector: '#faq', sectionId: 'faq', sectionLabel: 'FAQ' }
|
|
1147
|
+
],
|
|
1148
|
+
ctaImpressions: [
|
|
1149
|
+
{ selector: '.btn-pro-checkout', ctaId: 'pro_checkout', ctaPlacement: 'pro_page', planId: 'pro' },
|
|
1150
|
+
{ selector: '.btn-demo', ctaId: 'pro_demo', ctaPlacement: 'pro_page', planId: 'proof' },
|
|
1151
|
+
{ selector: '.btn-free-path', ctaId: 'pro_free_path', ctaPlacement: 'pro_page', planId: 'free' }
|
|
1152
|
+
]
|
|
1153
|
+
});
|
|
1090
1154
|
|
|
1091
1155
|
document.querySelectorAll('.faq-q').forEach(function(el) {
|
|
1092
1156
|
el.addEventListener('click', function() {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function buildAgentAuditSpan(input = {}) {
|
|
4
|
+
return {
|
|
5
|
+
runId: input.runId || null,
|
|
6
|
+
spanId: input.spanId || null,
|
|
7
|
+
parentSpanId: input.parentSpanId || null,
|
|
8
|
+
stage: input.stage || 'unknown',
|
|
9
|
+
promptHash: input.promptHash || null,
|
|
10
|
+
model: input.model || null,
|
|
11
|
+
reasoningSummary: input.reasoningSummary || null,
|
|
12
|
+
dataAccessed: Array.isArray(input.dataAccessed) ? input.dataAccessed : [],
|
|
13
|
+
toolsUsed: Array.isArray(input.toolsUsed) ? input.toolsUsed : [],
|
|
14
|
+
decision: input.decision || null,
|
|
15
|
+
evidenceIds: Array.isArray(input.evidenceIds) ? input.evidenceIds : [],
|
|
16
|
+
safetyEvents: Array.isArray(input.safetyEvents) ? input.safetyEvents : [],
|
|
17
|
+
cost: {
|
|
18
|
+
inputTokens: Number(input.inputTokens || 0),
|
|
19
|
+
outputTokens: Number(input.outputTokens || 0),
|
|
20
|
+
latencyMs: Number(input.latencyMs || 0),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function evaluateAgentAuditTrace(trace = {}) {
|
|
26
|
+
const spans = Array.isArray(trace.spans) ? trace.spans : [];
|
|
27
|
+
const issues = [];
|
|
28
|
+
|
|
29
|
+
if (!trace.runId) issues.push('missing_run_id');
|
|
30
|
+
if (spans.length === 0) issues.push('missing_spans');
|
|
31
|
+
if (!spans.some((span) => span.stage === 'input')) issues.push('missing_input_span');
|
|
32
|
+
if (!spans.some((span) => span.stage === 'decision')) issues.push('missing_decision_span');
|
|
33
|
+
if (spans.some((span) => !span.promptHash && span.stage === 'input')) issues.push('input_prompt_hash_required');
|
|
34
|
+
if (spans.some((span) => span.toolsUsed?.length && !span.evidenceIds?.length)) issues.push('tool_span_requires_evidence_ids');
|
|
35
|
+
if (spans.some((span) => span.dataAccessed?.length && !span.evidenceIds?.length)) issues.push('data_access_requires_evidence_ids');
|
|
36
|
+
|
|
37
|
+
const totalTokens = spans.reduce((sum, span) => sum + (span.cost?.inputTokens || 0) + (span.cost?.outputTokens || 0), 0);
|
|
38
|
+
const totalLatencyMs = spans.reduce((sum, span) => sum + (span.cost?.latencyMs || 0), 0);
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
decision: issues.length ? 'warn' : 'allow',
|
|
42
|
+
issues,
|
|
43
|
+
totals: {
|
|
44
|
+
spans: spans.length,
|
|
45
|
+
totalTokens,
|
|
46
|
+
totalLatencyMs,
|
|
47
|
+
safetyEvents: spans.reduce((sum, span) => sum + (span.safetyEvents?.length || 0), 0),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
buildAgentAuditSpan,
|
|
54
|
+
evaluateAgentAuditTrace,
|
|
55
|
+
};
|