thumbgate 1.27.18 → 1.27.20
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/commands/dashboard.md +15 -0
- package/.claude/commands/thumbgate-blocked.md +27 -0
- package/.claude/commands/thumbgate-dashboard.md +15 -0
- package/.claude/commands/thumbgate-doctor.md +30 -0
- package/.claude/commands/thumbgate-guard.md +36 -0
- package/.claude/commands/thumbgate-protect.md +30 -0
- package/.claude/commands/thumbgate-rules.md +30 -0
- package/.claude-plugin/plugin.json +4 -3
- package/.well-known/agentic-verify.txt +1 -0
- package/.well-known/llms.txt +33 -12
- package/.well-known/mcp/server-card.json +8 -8
- package/README.md +246 -30
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/gcp/dfcx-webhook-gate.js +295 -0
- package/adapters/gemini/function-declarations.json +1 -0
- package/adapters/letta/README.md +41 -0
- package/adapters/letta/thumbgate-letta-adapter.js +133 -0
- package/adapters/mcp/server-stdio.js +263 -11
- package/adapters/opencode/opencode.json +1 -1
- package/adapters/policy-engine/ethicore-guardian-client.js +68 -0
- package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +260 -0
- package/bench/observability-eval-suite.json +26 -0
- package/bench/thumbgate-bench.json +2 -2
- package/bin/cli.js +1456 -122
- package/bin/dashboard-cli.js +7 -0
- package/bin/postinstall.js +11 -27
- package/commands/dashboard.md +15 -0
- package/commands/thumbgate-dashboard.md +15 -0
- package/config/gate-classifier-routing.json +98 -0
- package/config/gate-templates.json +216 -0
- package/config/gates/claim-verification.json +12 -0
- package/config/gates/default.json +31 -2
- package/config/github-about.json +2 -2
- package/config/mcp-allowlists.json +23 -13
- package/config/merge-quality-checks.json +0 -1
- package/config/model-candidates.json +121 -6
- package/config/post-deploy-marketing-pages.json +80 -0
- package/config/tessl-tiles.json +1 -3
- package/openapi/openapi.yaml +12 -0
- package/package.json +225 -100
- package/public/about.html +162 -0
- package/public/agent-manager.html +179 -0
- package/public/agents-cost-savings.html +153 -0
- package/public/ai-malpractice-prevention.html +818 -0
- package/public/assets/brand/github-social-preview.png +0 -0
- package/public/assets/brand/thumbgate-icon-512.png +0 -0
- package/public/assets/brand/thumbgate-icon-pro-512.png +0 -0
- package/public/assets/brand/thumbgate-icon-team-512.png +0 -0
- package/public/assets/brand/thumbgate-logo-1200x360.png +0 -0
- package/public/assets/brand/thumbgate-logo-transparent.svg +28 -0
- package/public/assets/brand/thumbgate-mark-inline-v3.svg +18 -0
- package/public/assets/brand/thumbgate-mark-pro.svg +23 -0
- package/public/assets/brand/thumbgate-mark-team.svg +26 -0
- package/public/assets/brand/thumbgate-mark.svg +21 -0
- package/public/assets/brand/thumbgate-wordmark.svg +20 -0
- package/public/assets/claude-thumbgate-statusbar.svg +8 -0
- package/public/assets/codex-thumbgate-statusbar-test.svg +9 -0
- package/public/assets/legal-intake-control-flow.svg +66 -0
- package/public/blog.html +4 -4
- package/public/brand/thumbgate-mark.svg +19 -0
- package/public/brand/thumbgate-og.svg +16 -0
- package/public/chatgpt-app.html +330 -0
- package/public/codex-enterprise.html +123 -0
- package/public/codex-plugin.html +72 -20
- package/public/compare.html +31 -8
- package/public/dashboard.html +930 -166
- package/public/diagnostic.html +345 -0
- package/public/federal.html +2 -2
- package/public/guide.html +33 -13
- package/public/index.html +469 -111
- package/public/install.html +193 -0
- package/public/js/buyer-intent.js +672 -0
- package/public/learn.html +183 -18
- package/public/lessons.html +168 -10
- package/public/numbers.html +7 -7
- package/public/pricing.html +399 -0
- package/public/pro.html +34 -11
- package/scripts/action-receipts.js +324 -0
- package/scripts/activation-quickstart.js +187 -0
- package/scripts/agent-memory-lifecycle.js +211 -0
- package/scripts/agent-operations-planner.js +621 -0
- package/scripts/agent-readiness.js +20 -3
- package/scripts/agent-reward-model.js +53 -1
- package/scripts/ai-component-inventory.js +367 -0
- package/scripts/async-eval-observability.js +236 -0
- package/scripts/audit.js +65 -0
- package/scripts/auto-promote-gates.js +82 -10
- package/scripts/auto-wire-hooks.js +14 -0
- package/scripts/aws-blocks-guardrails.js +272 -0
- package/scripts/billing.js +93 -1
- package/scripts/bot-detection.js +61 -3
- package/scripts/build-metadata.js +50 -10
- package/scripts/classifier-routing.js +130 -0
- package/scripts/cli-feedback.js +4 -2
- package/scripts/cli-schema.js +97 -0
- package/scripts/cli-telemetry.js +6 -1
- package/scripts/commercial-offer.js +82 -2
- package/scripts/context-manager.js +74 -6
- package/scripts/dashboard-chat.js +332 -0
- package/scripts/dashboard.js +68 -2
- package/scripts/export-databricks-bundle.js +5 -1
- package/scripts/export-dpo-pairs.js +7 -2
- package/scripts/feedback-aggregate.js +281 -0
- package/scripts/feedback-loop.js +123 -1
- package/scripts/feedback-quality.js +87 -0
- package/scripts/feedback-sanitizer.js +105 -0
- package/scripts/filesystem-search.js +35 -10
- package/scripts/gate-stats.js +89 -0
- package/scripts/gates-engine.js +1176 -85
- package/scripts/gemini-embedding-policy.js +2 -1
- package/scripts/hook-runtime.js +20 -14
- package/scripts/hook-stop-anti-claim.js +301 -0
- package/scripts/hook-thumbgate-cache-updater.js +18 -2
- package/scripts/hybrid-feedback-context.js +142 -7
- package/scripts/install-shim.js +87 -0
- package/scripts/lesson-inference.js +8 -3
- package/scripts/lesson-search.js +17 -1
- package/scripts/license.js +10 -10
- package/scripts/llm-client.js +169 -4
- package/scripts/local-model-profile.js +15 -8
- package/scripts/mcp-config.js +7 -1
- package/scripts/mcp-oauth.js +293 -0
- package/scripts/memory-scope-readiness.js +159 -0
- package/scripts/meta-agent-loop.js +36 -0
- package/scripts/noop-detect.js +285 -0
- package/scripts/operational-integrity.js +39 -5
- package/scripts/oss-pr-opportunity-scout.js +35 -5
- package/scripts/parallel-workflow-orchestrator.js +293 -0
- package/scripts/plan-gate.js +243 -0
- package/scripts/plausible-domain-config.js +99 -0
- package/scripts/plausible-server-events.js +9 -6
- package/scripts/pro-local-dashboard.js +4 -4
- package/scripts/proxy-pointer-rag-guardrails.js +42 -1
- package/scripts/published-cli.js +0 -8
- package/scripts/qa-scenario-planner.js +136 -0
- package/scripts/rate-limiter.js +64 -13
- package/scripts/repeat-metric.js +137 -0
- package/scripts/secret-fixture-tokens.js +61 -0
- package/scripts/secret-redaction.js +166 -0
- package/scripts/secret-scanner.js +44 -5
- package/scripts/security-scanner.js +260 -10
- package/scripts/self-distill-agent.js +3 -1
- package/scripts/self-harness-optimizer.js +141 -0
- package/scripts/self-healing-check.js +193 -0
- package/scripts/self-protection.js +90 -0
- package/scripts/seo-gsd.js +916 -7
- package/scripts/silent-failure-cluster.js +531 -0
- package/scripts/statusline-cache-path.js +17 -2
- package/scripts/statusline-cache-read.js +57 -0
- package/scripts/statusline-local-stats.js +9 -1
- package/scripts/statusline-meta.js +28 -2
- package/scripts/statusline.sh +20 -4
- package/scripts/sync-telemetry-from-prod.js +374 -0
- package/scripts/telemetry-analytics.js +357 -0
- package/scripts/thompson-sampling.js +31 -10
- package/scripts/thumbgate-bench.js +16 -1
- package/scripts/thumbgate-search.js +85 -19
- package/scripts/tool-contract-validator.js +76 -0
- package/scripts/tool-registry.js +169 -1
- package/scripts/trajectory-scorer.js +63 -0
- package/scripts/vector-store.js +45 -0
- package/scripts/verify-marketing-pages-deployed.js +212 -0
- package/scripts/visitor-journey.js +172 -0
- package/scripts/workflow-sentinel.js +286 -53
- package/scripts/workspace-evolver.js +62 -2
- package/src/api/server.js +2683 -319
- package/.claude-plugin/marketplace.json +0 -85
- package/adapters/chatgpt/openapi.yaml +0 -1695
- package/scripts/bot-detector.js +0 -50
package/public/learn.html
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Learn — AI Agent Safety, Pre-Action Checks, and Vibe Coding Guardrails</title>
|
|
7
|
-
<script defer data-domain="thumbgate
|
|
7
|
+
<script defer data-domain="thumbgate.ai" src="https://plausible.io/js/script.js"></script>
|
|
8
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
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
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
|
-
<meta property="og:url" content="https://thumbgate
|
|
14
|
-
<link rel="canonical" href="https://thumbgate
|
|
13
|
+
<meta property="og:url" content="https://thumbgate.ai/learn">
|
|
14
|
+
<link rel="canonical" href="https://thumbgate.ai/learn">
|
|
15
15
|
<link rel="icon" type="image/png" href="/thumbgate-icon.png">
|
|
16
16
|
<link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
|
|
17
17
|
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@type": "CollectionPage",
|
|
22
22
|
"name": "ThumbGate Learning Hub",
|
|
23
23
|
"description": "Practical guides for AI coding agent safety, pre-action checks, and vibe coding guardrails.",
|
|
24
|
-
"url": "https://thumbgate
|
|
25
|
-
"dateModified": "2026-
|
|
24
|
+
"url": "https://thumbgate.ai/learn",
|
|
25
|
+
"dateModified": "2026-06-06",
|
|
26
26
|
"author": {
|
|
27
27
|
"@type": "Person",
|
|
28
28
|
"name": "Igor Ganapolsky",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"publisher": {
|
|
36
36
|
"@type": "Organization",
|
|
37
37
|
"name": "ThumbGate",
|
|
38
|
-
"url": "https://thumbgate
|
|
38
|
+
"url": "https://thumbgate.ai"
|
|
39
39
|
},
|
|
40
40
|
"mainEntity": {
|
|
41
41
|
"@type": "ItemList",
|
|
@@ -43,39 +43,81 @@
|
|
|
43
43
|
{
|
|
44
44
|
"@type": "ListItem",
|
|
45
45
|
"position": 1,
|
|
46
|
-
"url": "https://thumbgate
|
|
46
|
+
"url": "https://thumbgate.ai/learn/stop-ai-agent-force-push",
|
|
47
47
|
"name": "How to Stop AI Agents From Force-Pushing to Main"
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
"@type": "ListItem",
|
|
51
51
|
"position": 2,
|
|
52
|
-
"url": "https://thumbgate
|
|
52
|
+
"url": "https://thumbgate.ai/learn/vibe-coding-safety-net",
|
|
53
53
|
"name": "The Vibe Coding Safety Net You Are Missing"
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"@type": "ListItem",
|
|
57
57
|
"position": 3,
|
|
58
|
-
"url": "https://thumbgate
|
|
58
|
+
"url": "https://thumbgate.ai/learn/mcp-pre-action-checks-explained",
|
|
59
59
|
"name": "MCP Pre-Action Checks Explained"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"@type": "ListItem",
|
|
63
63
|
"position": 4,
|
|
64
|
-
"url": "https://thumbgate
|
|
64
|
+
"url": "https://thumbgate.ai/learn/agent-harness-pattern",
|
|
65
65
|
"name": "The Agent Harness Pattern: Why Your AI Needs a Seatbelt"
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
"@type": "ListItem",
|
|
69
69
|
"position": 5,
|
|
70
|
-
"url": "https://thumbgate
|
|
71
|
-
"name": "
|
|
70
|
+
"url": "https://thumbgate.ai/learn/background-agent-control-layer",
|
|
71
|
+
"name": "Background Agents Need a Control Layer Outside the Model"
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
"@type": "ListItem",
|
|
75
75
|
"position": 6,
|
|
76
|
+
"url": "https://thumbgate.ai/learn/ai-agent-persistent-memory",
|
|
77
|
+
"name": "How to Give Your AI Coding Agent Persistent Memory Across Sessions"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"@type": "ListItem",
|
|
81
|
+
"position": 7,
|
|
82
|
+
"url": "https://thumbgate.ai/learn/agentic-enterprise-context-brain",
|
|
83
|
+
"name": "Agentic Enterprise Context Brain: Memory Plus Enforcement"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"@type": "ListItem",
|
|
87
|
+
"position": 8,
|
|
88
|
+
"url": "https://thumbgate.ai/learn/deterministic-agent-workflows",
|
|
89
|
+
"name": "Deterministic Agent Workflows Need Runtime Gates"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"@type": "ListItem",
|
|
93
|
+
"position": 9,
|
|
94
|
+
"url": "https://thumbgate.ai/learn/codex-role-plugins-need-governance",
|
|
95
|
+
"name": "Codex Role Plugins Need Pre-Action Governance"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"@type": "ListItem",
|
|
99
|
+
"position": 10,
|
|
100
|
+
"url": "https://thumbgate.ai/learn/agentic-os-team-governance",
|
|
101
|
+
"name": "Agentic OS Team Governance: Three Tiers Plus Gates"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"@type": "ListItem",
|
|
105
|
+
"position": 11,
|
|
106
|
+
"url": "https://thumbgate.ai/learn/cost-aware-agent-gate-routing",
|
|
107
|
+
"name": "Cost-Aware Agent Gate Routing"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"@type": "ListItem",
|
|
111
|
+
"position": 12,
|
|
76
112
|
"url": "https://thumbgate.ai/learn/from-prototype-to-production",
|
|
77
113
|
"name": "From git init to v1.17.0 in 70 days: an honest ThumbGate build log"
|
|
78
114
|
},
|
|
115
|
+
{
|
|
116
|
+
"@type": "ListItem",
|
|
117
|
+
"position": 13,
|
|
118
|
+
"url": "https://thumbgate.ai/learn/pretix-stripe-connect-marketplaces",
|
|
119
|
+
"name": "Building a Pretix + Stripe Connect Plugin for Live-Music Venues"
|
|
120
|
+
},
|
|
79
121
|
{
|
|
80
122
|
"@type": "ListItem",
|
|
81
123
|
"position": 7,
|
|
@@ -103,38 +145,56 @@
|
|
|
103
145
|
{
|
|
104
146
|
"@type": "ListItem",
|
|
105
147
|
"position": 10,
|
|
148
|
+
"url": "https://thumbgate.ai/guides/hermes-agent-guardrails",
|
|
149
|
+
"name": "Hermes Agent Guardrails for Self-Improving Agents"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"@type": "ListItem",
|
|
153
|
+
"position": 11,
|
|
154
|
+
"url": "https://thumbgate.ai/guides/agent-context-governance",
|
|
155
|
+
"name": "Agent Context Governance for Long-Running Agents"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"@type": "ListItem",
|
|
159
|
+
"position": 12,
|
|
106
160
|
"url": "https://thumbgate.ai/guides/roo-code-alternative-cline",
|
|
107
161
|
"name": "Roo Code Alternative: Migrating to Cline with Portable Lesson Memory"
|
|
108
162
|
},
|
|
109
163
|
{
|
|
110
164
|
"@type": "ListItem",
|
|
111
|
-
"position":
|
|
165
|
+
"position": 13,
|
|
112
166
|
"url": "https://thumbgate.ai/guides/browser-automation-safety",
|
|
113
167
|
"name": "Browser Automation Safety for AI Agents"
|
|
114
168
|
},
|
|
115
169
|
{
|
|
116
170
|
"@type": "ListItem",
|
|
117
|
-
"position":
|
|
171
|
+
"position": 14,
|
|
118
172
|
"url": "https://thumbgate.ai/guides/native-messaging-host-security",
|
|
119
173
|
"name": "Native Messaging Host Security"
|
|
120
174
|
},
|
|
121
175
|
{
|
|
122
176
|
"@type": "ListItem",
|
|
123
|
-
"position":
|
|
177
|
+
"position": 15,
|
|
124
178
|
"url": "https://thumbgate.ai/guides/ai-search-topical-presence",
|
|
125
179
|
"name": "AI Search Topical Presence"
|
|
126
180
|
},
|
|
127
181
|
{
|
|
128
182
|
"@type": "ListItem",
|
|
129
|
-
"position":
|
|
183
|
+
"position": 16,
|
|
130
184
|
"url": "https://thumbgate.ai/guides/relational-knowledge-ai-recommendations",
|
|
131
185
|
"name": "Relational Knowledge in AI Recommendations"
|
|
132
186
|
},
|
|
133
187
|
{
|
|
134
188
|
"@type": "ListItem",
|
|
135
|
-
"position":
|
|
189
|
+
"position": 17,
|
|
136
190
|
"url": "https://thumbgate.ai/guides/ai-deployment-readiness",
|
|
137
191
|
"name": "AI Deployment Readiness Before Production Rollout"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"@type": "ListItem",
|
|
195
|
+
"position": 18,
|
|
196
|
+
"url": "https://thumbgate.ai/guides/database-agent-safety",
|
|
197
|
+
"name": "Database Safety for AI Agents"
|
|
138
198
|
}
|
|
139
199
|
]
|
|
140
200
|
}
|
|
@@ -230,7 +290,7 @@
|
|
|
230
290
|
<body>
|
|
231
291
|
|
|
232
292
|
<nav>
|
|
233
|
-
<a href="/" class="brand"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
|
|
293
|
+
<a href="/" class="brand"><img src="/assets/brand/thumbgate-mark-inline-v3.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
|
|
234
294
|
<a href="/guide">Setup Guide</a>
|
|
235
295
|
<a href="/learn">Learn</a>
|
|
236
296
|
<a href="/dashboard">Dashboard</a>
|
|
@@ -297,6 +357,14 @@
|
|
|
297
357
|
<span class="article-tag">Shared Memory</span>
|
|
298
358
|
</a>
|
|
299
359
|
|
|
360
|
+
<a href="/learn/background-agent-control-layer" class="article-card">
|
|
361
|
+
<h3>Background Agents Need a Control Layer Outside the Model</h3>
|
|
362
|
+
<p>Agents can produce work. Production teams still need triggers, isolated runs, context, visibility, and controls. This is where ThumbGate fits in the AI-SDLC stack.</p>
|
|
363
|
+
<span class="article-tag">Background Agents</span>
|
|
364
|
+
<span class="article-tag">AI-SDLC</span>
|
|
365
|
+
<span class="article-tag">Controls</span>
|
|
366
|
+
</a>
|
|
367
|
+
|
|
300
368
|
<a href="/learn/claude-code-goal-with-rubrics" class="article-card">
|
|
301
369
|
<h3>Claude Code /goal vs Todo: The 4-Field Pattern That Actually Holds</h3>
|
|
302
370
|
<p>Treating /goal like a todo wastes the command. The 4-field pattern (clear goal, measurable success, shown proof, hard limits) is the same shape as a ThumbGate rubric. Pair them and the agent cannot fake completion.</p>
|
|
@@ -313,6 +381,46 @@
|
|
|
313
381
|
<span class="article-tag">Session Persistence</span>
|
|
314
382
|
</a>
|
|
315
383
|
|
|
384
|
+
<a href="/learn/agentic-enterprise-context-brain" class="article-card">
|
|
385
|
+
<h3>Agentic Enterprise Context Brain: Memory Plus Enforcement</h3>
|
|
386
|
+
<p>Enterprise agents need a context brain, but memory alone does not stop a repeated bad action. This guide turns facts, trust scores, prior failures, approvals, and evidence into pre-action gates.</p>
|
|
387
|
+
<span class="article-tag">Agentic Enterprise</span>
|
|
388
|
+
<span class="article-tag">Memory OS</span>
|
|
389
|
+
<span class="article-tag">Enforcement</span>
|
|
390
|
+
</a>
|
|
391
|
+
|
|
392
|
+
<a href="/learn/deterministic-agent-workflows" class="article-card">
|
|
393
|
+
<h3>Deterministic Agent Workflows Need Runtime Gates</h3>
|
|
394
|
+
<p>Claude Code workflows make orchestration scriptable and reviewable. ThumbGate adds the missing trust layer: run contracts, proof gates, and repeat-failure blocks before each tool call executes.</p>
|
|
395
|
+
<span class="article-tag">Claude Code</span>
|
|
396
|
+
<span class="article-tag">Workflows</span>
|
|
397
|
+
<span class="article-tag">Proof Gates</span>
|
|
398
|
+
</a>
|
|
399
|
+
|
|
400
|
+
<a href="/learn/codex-role-plugins-need-governance" class="article-card">
|
|
401
|
+
<h3>Codex Role Plugins Need Pre-Action Governance</h3>
|
|
402
|
+
<p>Codex plugins, Sites, and annotations move agent work into sales, analytics, design, finance, and documents. ThumbGate gates role-specific writes before they publish, share, or update business systems.</p>
|
|
403
|
+
<span class="article-tag">Codex Plugins</span>
|
|
404
|
+
<span class="article-tag">Sites</span>
|
|
405
|
+
<span class="article-tag">Governance</span>
|
|
406
|
+
</a>
|
|
407
|
+
|
|
408
|
+
<a href="/learn/agentic-os-team-governance" class="article-card">
|
|
409
|
+
<h3>Agentic OS Team Governance: Three Tiers Plus Gates</h3>
|
|
410
|
+
<p>A team Agentic OS needs human-editable source of truth, agent-operating files, git backup, permission mirroring, and memory scope. ThumbGate turns that architecture into runtime checks.</p>
|
|
411
|
+
<span class="article-tag">Agentic OS</span>
|
|
412
|
+
<span class="article-tag">Team Memory</span>
|
|
413
|
+
<span class="article-tag">Enterprise</span>
|
|
414
|
+
</a>
|
|
415
|
+
|
|
416
|
+
<a href="/learn/cost-aware-agent-gate-routing" class="article-card">
|
|
417
|
+
<h3>Cost-Aware Agent Gate Routing</h3>
|
|
418
|
+
<p>Use deterministic rules, semantic cache, local classifiers, local semantic recall, LLM judges, and human review in the right order so governance stays fast enough to leave on.</p>
|
|
419
|
+
<span class="article-tag">Semantic Cache</span>
|
|
420
|
+
<span class="article-tag">Rubrics</span>
|
|
421
|
+
<span class="article-tag">Cost Control</span>
|
|
422
|
+
</a>
|
|
423
|
+
|
|
316
424
|
<a href="/learn/from-prototype-to-production" class="article-card">
|
|
317
425
|
<h3>From git init to v1.17.0 in 70 days: an honest ThumbGate build log</h3>
|
|
318
426
|
<p>70 days, 112 commits, 17 minor releases, 6k npm downloads, $0 cold-traffic revenue. The unedited story of taking ThumbGate from a one-line repo init to live production — including the part that's still broken.</p>
|
|
@@ -320,11 +428,27 @@
|
|
|
320
428
|
<span class="article-tag">Indie SaaS</span>
|
|
321
429
|
<span class="article-tag">Shipping in Public</span>
|
|
322
430
|
</a>
|
|
431
|
+
|
|
432
|
+
<a href="/learn/pretix-stripe-connect-marketplaces" class="article-card">
|
|
433
|
+
<h3>Building a Pretix + Stripe Connect Plugin for Live-Music Venues</h3>
|
|
434
|
+
<p>How to design a multi-venue Stripe Connect ticketing plugin on Pretix, keeping venues as Merchant of Record without messy platform-fee tax reporting.</p>
|
|
435
|
+
<span class="article-tag">Stripe Connect</span>
|
|
436
|
+
<span class="article-tag">Pretix</span>
|
|
437
|
+
<span class="article-tag">Case Study</span>
|
|
438
|
+
</a>
|
|
323
439
|
</div>
|
|
324
440
|
|
|
325
441
|
<h2>Popular buyer questions</h2>
|
|
326
442
|
<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>
|
|
327
443
|
<div class="article-grid">
|
|
444
|
+
<a href="/guides/database-agent-safety" class="article-card">
|
|
445
|
+
<h3>Database Safety for AI Agents</h3>
|
|
446
|
+
<p>Block hallucinated SQL writes, migrations, role grants, and production database changes before an agent can touch live data.</p>
|
|
447
|
+
<span class="article-tag">Database</span>
|
|
448
|
+
<span class="article-tag">SQL</span>
|
|
449
|
+
<span class="article-tag">Production Safety</span>
|
|
450
|
+
</a>
|
|
451
|
+
|
|
328
452
|
<a href="/guides/ai-deployment-readiness" class="article-card">
|
|
329
453
|
<h3>AI Deployment Readiness Before Production Rollout</h3>
|
|
330
454
|
<p>Use one priority workflow to map tools, data, controls, pre-action gates, and proof before an AI deployment team ships into production.</p>
|
|
@@ -341,6 +465,22 @@
|
|
|
341
465
|
<span class="article-tag">Recommendation</span>
|
|
342
466
|
</a>
|
|
343
467
|
|
|
468
|
+
<a href="/guides/agentic-web-governance" class="article-card">
|
|
469
|
+
<h3>Agentic Web Governance</h3>
|
|
470
|
+
<p>Bots already outnumber humans in HTML requests. ThumbGate turns that agentic-web shift into pre-action governance before AI agents touch real systems.</p>
|
|
471
|
+
<span class="article-tag">Agentic Web</span>
|
|
472
|
+
<span class="article-tag">AI Search</span>
|
|
473
|
+
<span class="article-tag">Governance</span>
|
|
474
|
+
</a>
|
|
475
|
+
|
|
476
|
+
<a href="/guides/vllm-serving-guardrails" class="article-card">
|
|
477
|
+
<h3>vLLM Serving Guardrails</h3>
|
|
478
|
+
<p>Gate self-hosted inference changes before agents route production work through PagedAttention, batching, prefix-cache, or model-swap optimizations.</p>
|
|
479
|
+
<span class="article-tag">vLLM</span>
|
|
480
|
+
<span class="article-tag">LLM Serving</span>
|
|
481
|
+
<span class="article-tag">Runtime Safety</span>
|
|
482
|
+
</a>
|
|
483
|
+
|
|
344
484
|
<a href="/guides/relational-knowledge-ai-recommendations" class="article-card">
|
|
345
485
|
<h3>Relational Knowledge in AI Recommendations</h3>
|
|
346
486
|
<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>
|
|
@@ -381,6 +521,30 @@
|
|
|
381
521
|
<span class="article-tag">Enforcement</span>
|
|
382
522
|
</a>
|
|
383
523
|
|
|
524
|
+
<a href="/guides/hermes-agent-guardrails" class="article-card">
|
|
525
|
+
<h3>Hermes Agent Guardrails for Self-Improving Agents</h3>
|
|
526
|
+
<p>Hermes-style agents bring persistent memory, generated skills, gateways, automations, and sandboxes. ThumbGate adds the pre-action firewall before those agents touch real systems.</p>
|
|
527
|
+
<span class="article-tag">Hermes Agent</span>
|
|
528
|
+
<span class="article-tag">Persistent Agents</span>
|
|
529
|
+
<span class="article-tag">Execution Firewall</span>
|
|
530
|
+
</a>
|
|
531
|
+
|
|
532
|
+
<a href="/guides/safe-self-evolution" class="article-card">
|
|
533
|
+
<h3>Safe Self-Evolution: Prompt Optimization without Regression</h3>
|
|
534
|
+
<p>Hermes-style autonomous agents learn by observing failures and rewriting skills. ThumbGate introduces Safe Self-Evolution: weakness mining, automated prompt optimization, verification suites, and atomic git rollbacks.</p>
|
|
535
|
+
<span class="article-tag">Self-Evolution</span>
|
|
536
|
+
<span class="article-tag">Harness Optimizer</span>
|
|
537
|
+
<span class="article-tag">Verification Gate</span>
|
|
538
|
+
</a>
|
|
539
|
+
|
|
540
|
+
<a href="/guides/agent-context-governance" class="article-card">
|
|
541
|
+
<h3>Agent Context Governance for Long-Running Agents</h3>
|
|
542
|
+
<p>AdaCoM, tokenmaxxing backlash, Managed Agents, lockdown modes, and model-provenance scares all point to one need: clean context and tool gates before agents act.</p>
|
|
543
|
+
<span class="article-tag">Context Governance</span>
|
|
544
|
+
<span class="article-tag">Tool Lockdown</span>
|
|
545
|
+
<span class="article-tag">Model Provenance</span>
|
|
546
|
+
</a>
|
|
547
|
+
|
|
384
548
|
<a href="/guides/roo-code-alternative-cline" class="article-card">
|
|
385
549
|
<h3>Roo Code Alternative: Migrate to Cline Without Losing Agent Memory</h3>
|
|
386
550
|
<p>Use the Roo shutdown window to pitch portable lesson memory and local-first enforcement instead of making operators re-teach the same failures after they switch.</p>
|
|
@@ -421,5 +585,6 @@
|
|
|
421
585
|
</div>
|
|
422
586
|
</div>
|
|
423
587
|
|
|
588
|
+
<script src="/js/buyer-intent.js"></script>
|
|
424
589
|
</body>
|
|
425
590
|
</html>
|
package/public/lessons.html
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
<title>ThumbGate — Lessons Learned</title>
|
|
7
7
|
<link rel="icon" type="image/png" href="/thumbgate-icon.png">
|
|
8
8
|
<link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
|
|
9
|
-
<script defer data-domain="thumbgate
|
|
9
|
+
<script defer data-domain="thumbgate.ai" src="https://plausible.io/js/script.js"></script>
|
|
10
10
|
<script type="application/ld+json">
|
|
11
11
|
{
|
|
12
12
|
"@context": "https://schema.org",
|
|
13
13
|
"@type": "WebPage",
|
|
14
14
|
"name": "ThumbGate Lessons Learned",
|
|
15
|
-
"url": "https://thumbgate
|
|
15
|
+
"url": "https://thumbgate.ai/lessons",
|
|
16
16
|
"dateModified": "2026-04-20",
|
|
17
17
|
"author": {
|
|
18
18
|
"@type": "Person",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"publisher": {
|
|
27
27
|
"@type": "Organization",
|
|
28
28
|
"name": "ThumbGate",
|
|
29
|
-
"url": "https://thumbgate
|
|
29
|
+
"url": "https://thumbgate.ai"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
</script>
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
|
|
212
212
|
<nav>
|
|
213
213
|
<div class="container">
|
|
214
|
-
<a href="/dashboard" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
|
|
214
|
+
<a href="/dashboard" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline-v3.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
|
|
215
215
|
<div class="nav-links">
|
|
216
216
|
<a href="/dashboard">Dashboard</a>
|
|
217
217
|
<a href="/lessons" class="active">Lessons</a>
|
|
@@ -385,8 +385,32 @@ const LOCAL_PRO_BOOTSTRAP = __LESSONS_BOOTSTRAP_ENABLED__;
|
|
|
385
385
|
function escHtml(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
|
|
386
386
|
function escAttr(s) { return escHtml(String(s || '')).replace(/"/g, '"'); }
|
|
387
387
|
|
|
388
|
+
let ACTIVE_PROJECT_DIR = '';
|
|
389
|
+
try {
|
|
390
|
+
var urlParams = new URLSearchParams(window.location.search);
|
|
391
|
+
ACTIVE_PROJECT_DIR = urlParams.get('project') || '';
|
|
392
|
+
} catch (e) {}
|
|
393
|
+
|
|
394
|
+
function preserveProjectQueryParams() {
|
|
395
|
+
if (!ACTIVE_PROJECT_DIR) return;
|
|
396
|
+
var links = document.querySelectorAll('a[href^="/dashboard"], a[href^="/lessons"], a[href="/"]');
|
|
397
|
+
links.forEach(function(link) {
|
|
398
|
+
try {
|
|
399
|
+
var url = new URL(link.href, window.location.origin);
|
|
400
|
+
url.searchParams.set('project', ACTIVE_PROJECT_DIR);
|
|
401
|
+
link.href = url.pathname + url.search + url.hash;
|
|
402
|
+
} catch (e) {}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
window.addEventListener('DOMContentLoaded', preserveProjectQueryParams);
|
|
407
|
+
|
|
388
408
|
function getHeaders() {
|
|
389
|
-
|
|
409
|
+
var headers = { 'Authorization': 'Bearer ' + API_KEY, 'Content-Type': 'application/json' };
|
|
410
|
+
if (ACTIVE_PROJECT_DIR) {
|
|
411
|
+
headers['x-thumbgate-project-dir'] = ACTIVE_PROJECT_DIR;
|
|
412
|
+
}
|
|
413
|
+
return headers;
|
|
390
414
|
}
|
|
391
415
|
|
|
392
416
|
function hasBootstrapKey() {
|
|
@@ -449,6 +473,18 @@ function switchTab(name) {
|
|
|
449
473
|
// Highlight the corresponding stat card
|
|
450
474
|
var cardMap = { rules: 0, timeline: 2, insights: 3 };
|
|
451
475
|
highlightCard(cardMap[name] !== undefined ? cardMap[name] : -1);
|
|
476
|
+
// Scroll the active tab content into view so the click has a visible effect.
|
|
477
|
+
// Without this, clicking a stat card or tab header when its content is below
|
|
478
|
+
// the fold appears to do nothing — the tab changes silently and the user
|
|
479
|
+
// never sees the new content. The tab-strip itself stays visible so the
|
|
480
|
+
// selected-state is still observable.
|
|
481
|
+
if (content && typeof content.scrollIntoView === 'function') {
|
|
482
|
+
try {
|
|
483
|
+
content.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
484
|
+
} catch (_err) {
|
|
485
|
+
content.scrollIntoView();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
452
488
|
if (typeof plausible === 'function') plausible('lessons_tab', { props: { tab: name } });
|
|
453
489
|
}
|
|
454
490
|
|
|
@@ -779,14 +815,107 @@ function deriveSeverity(lesson) {
|
|
|
779
815
|
return 'info';
|
|
780
816
|
}
|
|
781
817
|
|
|
818
|
+
function cleanLiveTitle(titleText, contextText) {
|
|
819
|
+
if (!titleText) return 'Lesson';
|
|
820
|
+
var prefix = '';
|
|
821
|
+
var rest = titleText;
|
|
822
|
+
var match = titleText.match(/^(MISTAKE|SUCCESS|LEARNING|PREFERENCE):\s*(.*)/i);
|
|
823
|
+
if (match) {
|
|
824
|
+
prefix = match[1].toUpperCase() + ': ';
|
|
825
|
+
rest = match[2];
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
var trimmed = rest.trim();
|
|
829
|
+
var isJson = trimmed.indexOf('{') === 0;
|
|
830
|
+
|
|
831
|
+
if (isJson) {
|
|
832
|
+
try {
|
|
833
|
+
var parsed = JSON.parse(trimmed);
|
|
834
|
+
var promptVal = parsed.prompt;
|
|
835
|
+
var hookVal = parsed.hook_event_name || parsed.hookEventName;
|
|
836
|
+
if (promptVal) {
|
|
837
|
+
var dirName = parsed.cwd ? parsed.cwd.split('/').pop() : '';
|
|
838
|
+
return prefix + 'Prompt "' + promptVal + '"' + (dirName ? ' inside ' + dirName : '');
|
|
839
|
+
}
|
|
840
|
+
if (hookVal) {
|
|
841
|
+
var dirName = parsed.cwd ? parsed.cwd.split('/').pop() : '';
|
|
842
|
+
return prefix + 'Hook event ' + hookVal + (dirName ? ' inside ' + dirName : '');
|
|
843
|
+
}
|
|
844
|
+
if (parsed.signal) {
|
|
845
|
+
var dirName = parsed.cwd ? parsed.cwd.split('/').pop() : '';
|
|
846
|
+
return prefix + (parsed.signal === 'up' ? 'Thumbs Up' : 'Thumbs Down') + (dirName ? ' inside ' + dirName : '');
|
|
847
|
+
}
|
|
848
|
+
} catch (e) {
|
|
849
|
+
if (contextText) {
|
|
850
|
+
var ctxTrimmed = contextText.trim();
|
|
851
|
+
if (ctxTrimmed.indexOf('{') === 0) {
|
|
852
|
+
try {
|
|
853
|
+
var parsedCtx = JSON.parse(ctxTrimmed);
|
|
854
|
+
var promptValCtx = parsedCtx.prompt;
|
|
855
|
+
var hookValCtx = parsedCtx.hook_event_name || parsedCtx.hookEventName;
|
|
856
|
+
if (promptValCtx) {
|
|
857
|
+
var dirName = parsedCtx.cwd ? parsedCtx.cwd.split('/').pop() : '';
|
|
858
|
+
return prefix + 'Prompt "' + promptValCtx + '"' + (dirName ? ' inside ' + dirName : '');
|
|
859
|
+
}
|
|
860
|
+
if (hookValCtx) {
|
|
861
|
+
var dirName = parsedCtx.cwd ? parsedCtx.cwd.split('/').pop() : '';
|
|
862
|
+
return prefix + 'Hook event ' + hookValCtx + (dirName ? ' inside ' + dirName : '');
|
|
863
|
+
}
|
|
864
|
+
} catch (err) {
|
|
865
|
+
// ignore
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
var promptMatch = rest.match(/"prompt"\s*:\s*"([^"]+)"/) || (contextText && contextText.match(/"prompt"\s*:\s*"([^"]+)"/));
|
|
872
|
+
if (promptMatch) {
|
|
873
|
+
var cwdMatch = rest.match(/"cwd"\s*:\s*"([^"]+)"/) || (contextText && contextText.match(/"cwd"\s*:\s*"([^"]+)"/));
|
|
874
|
+
var dirName = cwdMatch ? cwdMatch[1].split('/').pop() : '';
|
|
875
|
+
return prefix + 'Prompt "' + promptMatch[1] + '"' + (dirName ? ' inside ' + dirName : '');
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
var hookMatch = rest.match(/"hook_?event_?name"\s*:\s*"([^"]+)"/i) || (contextText && contextText.match(/"hook_?event_?name"\s*:\s*"([^"]+)"/i));
|
|
879
|
+
if (hookMatch) {
|
|
880
|
+
var cwdMatch = rest.match(/"cwd"\s*:\s*"([^"]+)"/) || (contextText && contextText.match(/"cwd"\s*:\s*"([^"]+)"/));
|
|
881
|
+
var dirName = cwdMatch ? cwdMatch[1].split('/').pop() : '';
|
|
882
|
+
return prefix + 'Hook event ' + hookMatch[1] + (dirName ? ' inside ' + dirName : '');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return titleText;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
function cleanLiveContext(contextText) {
|
|
889
|
+
if (!contextText) return '';
|
|
890
|
+
var trimmed = contextText.trim();
|
|
891
|
+
if (trimmed.indexOf('{') === 0 && trimmed.indexOf('}') === trimmed.length - 1) {
|
|
892
|
+
try {
|
|
893
|
+
var parsed = JSON.parse(trimmed);
|
|
894
|
+
if (parsed.prompt) {
|
|
895
|
+
var dirName = parsed.cwd ? parsed.cwd.split('/').pop() : '';
|
|
896
|
+
var parts = [];
|
|
897
|
+
parts.push('Prompt: "' + parsed.prompt + '"');
|
|
898
|
+
if (parsed.cwd) parts.push('Working dir: ' + parsed.cwd);
|
|
899
|
+
if (parsed.hook_event_name) parts.push('Hook event: ' + parsed.hook_event_name);
|
|
900
|
+
return parts.join(' · ');
|
|
901
|
+
}
|
|
902
|
+
} catch (e) {
|
|
903
|
+
// ignore
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return contextText;
|
|
907
|
+
}
|
|
908
|
+
|
|
782
909
|
function mapLiveRules(payload) {
|
|
783
910
|
return (payload.results || []).map(function(result) {
|
|
784
911
|
var linkedGate = (((result.systemResponse || {}).linkedAutoGates) || [])[0] || null;
|
|
785
912
|
var sourceFeedback = ((result.systemResponse || {}).sourceFeedback) || null;
|
|
913
|
+
var rawTitle = result.title || ((result.lesson || {}).summary) || 'Lesson';
|
|
914
|
+
var rawContext = ((result.lesson || {}).howToAvoid) || ((result.lesson || {}).summary) || (sourceFeedback && sourceFeedback.context) || '';
|
|
786
915
|
return {
|
|
787
916
|
id: result.id,
|
|
788
|
-
title:
|
|
789
|
-
context: (
|
|
917
|
+
title: cleanLiveTitle(rawTitle, rawContext),
|
|
918
|
+
context: cleanLiveContext(rawContext),
|
|
790
919
|
occurrences: linkedGate && linkedGate.occurrences ? linkedGate.occurrences : 1,
|
|
791
920
|
severity: deriveSeverity(result),
|
|
792
921
|
tags: Array.isArray(result.tags) ? result.tags : [],
|
|
@@ -800,13 +929,14 @@ function mapTimelineItems(payload, lessonMap) {
|
|
|
800
929
|
return (payload.results || []).map(function(entry) {
|
|
801
930
|
var linkedLesson = lessonMap.get(entry.id) || null;
|
|
802
931
|
var timestamp = entry.timestamp || null;
|
|
932
|
+
var rawContext = entry.context || entry.title || '';
|
|
803
933
|
return {
|
|
804
934
|
signal: normalizeSignal(entry.signal || entry.feedback),
|
|
805
|
-
context:
|
|
935
|
+
context: cleanLiveContext(rawContext),
|
|
806
936
|
date: formatDate(entry.timestamp),
|
|
807
937
|
timestamp: timestamp,
|
|
808
938
|
dayKey: toDayKey(timestamp),
|
|
809
|
-
learned: linkedLesson ? linkedLesson.title : '',
|
|
939
|
+
learned: linkedLesson ? cleanLiveTitle(linkedLesson.title, rawContext) : '',
|
|
810
940
|
feedbackId: entry.id || ''
|
|
811
941
|
};
|
|
812
942
|
});
|
|
@@ -914,14 +1044,41 @@ async function loadLive() {
|
|
|
914
1044
|
renderTimeline(allTimeline);
|
|
915
1045
|
renderInsights(dashboardSnapshot);
|
|
916
1046
|
renderImprovementMetrics(stats, dashboardSnapshot);
|
|
1047
|
+
var isEnterprise = API_KEY.startsWith('tg_op_') || API_KEY.startsWith('tg_creator_');
|
|
1048
|
+
if (stats.tier) {
|
|
1049
|
+
isEnterprise = (stats.tier === 'Enterprise');
|
|
1050
|
+
}
|
|
1051
|
+
const tierName = isEnterprise ? 'Enterprise' : 'Pro';
|
|
917
1052
|
document.getElementById('proBadge').style.display = 'none';
|
|
918
|
-
setMode('Local
|
|
1053
|
+
setMode('Local ' + tierName + ' connected — this lessons view is reading your live rules, feedback timeline, and insights.', false);
|
|
919
1054
|
} catch (_err) {
|
|
920
1055
|
loadDemo();
|
|
921
1056
|
}
|
|
922
1057
|
}
|
|
923
1058
|
|
|
924
1059
|
loadLive().then(function() {
|
|
1060
|
+
// Handle ?signal= query param from dashboard stat-card navigation.
|
|
1061
|
+
// Vocabulary: 'up' | 'down' | 'all' (canonical). Also accepts the legacy
|
|
1062
|
+
// 'positive' | 'negative' aliases the dashboard once emitted.
|
|
1063
|
+
var qsSignal = new URLSearchParams(window.location.search).get('signal');
|
|
1064
|
+
if (qsSignal) {
|
|
1065
|
+
var signalMap = { positive: 'up', negative: 'down', up: 'up', down: 'down', all: 'all' };
|
|
1066
|
+
var mapped = signalMap[qsSignal];
|
|
1067
|
+
if (mapped) {
|
|
1068
|
+
switchTab('timeline');
|
|
1069
|
+
filterTimeline(mapped, null);
|
|
1070
|
+
var filterBtns = document.querySelectorAll('#tab-timeline .filter-btn');
|
|
1071
|
+
filterBtns.forEach(function(b) {
|
|
1072
|
+
var label = b.textContent.trim().toLowerCase();
|
|
1073
|
+
var match = (mapped === 'all' && label === 'all') ||
|
|
1074
|
+
(mapped === 'up' && (label.indexOf('👍') !== -1 || label.indexOf('positive') !== -1 || label === 'up')) ||
|
|
1075
|
+
(mapped === 'down' && (label.indexOf('👎') !== -1 || label.indexOf('negative') !== -1 || label === 'down'));
|
|
1076
|
+
b.classList.toggle('active', match);
|
|
1077
|
+
});
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
925
1082
|
// Default: highlight Active Rules card on page load
|
|
926
1083
|
highlightCard(0);
|
|
927
1084
|
|
|
@@ -1027,6 +1184,7 @@ async function submitFeedback() {
|
|
|
1027
1184
|
btn.disabled = false; btn.textContent = 'Submit';
|
|
1028
1185
|
}
|
|
1029
1186
|
</script>
|
|
1187
|
+
<script src="/js/buyer-intent.js"></script>
|
|
1030
1188
|
|
|
1031
1189
|
</body>
|
|
1032
1190
|
</html>
|
package/public/numbers.html
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
<meta property="og:title" content="ThumbGate — The Numbers">
|
|
11
11
|
<meta property="og:description" content="Generated first-party operational snapshot: configured gates, recorded interventions, and explicit zero-evidence caveats.">
|
|
12
12
|
<meta property="og:type" content="website">
|
|
13
|
-
<meta property="og:url" content="https://thumbgate
|
|
13
|
+
<meta property="og:url" content="https://thumbgate.ai/numbers">
|
|
14
14
|
<meta name="twitter:card" content="summary_large_image">
|
|
15
|
-
<link rel="canonical" href="https://thumbgate
|
|
15
|
+
<link rel="canonical" href="https://thumbgate.ai/numbers">
|
|
16
16
|
<link rel="icon" type="image/png" href="/thumbgate-icon.png">
|
|
17
17
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
|
18
|
-
<script defer data-domain="thumbgate
|
|
18
|
+
<script defer data-domain="thumbgate.ai" src="https://plausible.io/js/script.js"></script>
|
|
19
19
|
|
|
20
20
|
<script type="application/ld+json">
|
|
21
21
|
{
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"alternateName": "thumbgate",
|
|
26
26
|
"applicationCategory": "DeveloperApplication",
|
|
27
27
|
"operatingSystem": "Cross-platform, Node.js >=18.18.0",
|
|
28
|
-
"softwareVersion": "1.20
|
|
29
|
-
"url": "https://thumbgate
|
|
28
|
+
"softwareVersion": "1.27.20",
|
|
29
|
+
"url": "https://thumbgate.ai/numbers",
|
|
30
30
|
"dateModified": "2026-05-07",
|
|
31
31
|
"creator": {
|
|
32
32
|
"@type": "Person",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@type": "Dataset",
|
|
47
47
|
"name": "ThumbGate Operational Snapshot",
|
|
48
48
|
"description": "First-party operational snapshot from the ThumbGate pre-action check runtime: configured checks, recorded block/warn events, estimated token savings from recorded blocks, and Bayes error rate when the sample supports it.",
|
|
49
|
-
"url": "https://thumbgate
|
|
49
|
+
"url": "https://thumbgate.ai/numbers",
|
|
50
50
|
"license": "https://opensource.org/licenses/MIT",
|
|
51
51
|
"creator": {
|
|
52
52
|
"@type": "Person",
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
<main class="container">
|
|
203
203
|
<h1>The Numbers</h1>
|
|
204
204
|
<p class="subtitle">Generated first-party operational snapshot from the ThumbGate runtime. This is not customer traction, install volume, revenue, or proof that a configured gate has fired.</p>
|
|
205
|
-
<div class="freshness">Updated: 2026-05-07 · Version 1.20
|
|
205
|
+
<div class="freshness">Updated: 2026-05-07 · Version 1.27.20</div>
|
|
206
206
|
<div class="truth-note"><strong>Read this first:</strong> configured checks are inventory. Recorded blocks and warnings are usage evidence. This snapshot currently reports 0 recorded hard-block event(s) and 0 recorded warning event(s).</div>
|
|
207
207
|
|
|
208
208
|
<h2>Gate enforcement</h2>
|