thumbgate 1.16.3 โ 1.16.5
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/config/github-about.json +2 -2
- package/package.json +6 -3
- package/public/codex-plugin.html +44 -0
- package/public/dashboard.html +298 -3
- package/public/guide.html +45 -1
- package/public/index.html +20 -17
- package/scripts/background-agent-governance.js +229 -0
- package/scripts/dashboard.js +209 -1
- package/scripts/workflow-sentinel.js +121 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate-marketplace",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.5",
|
|
4
4
|
"owner": {
|
|
5
5
|
"name": "Igor Ganapolsky",
|
|
6
6
|
"email": "ig5973700@gmail.com"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"source": "npm",
|
|
14
14
|
"package": "thumbgate"
|
|
15
15
|
},
|
|
16
|
-
"version": "1.16.
|
|
16
|
+
"version": "1.16.5",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Igor Ganapolsky"
|
|
19
19
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
3
|
"description": "Type ๐ or ๐ on any agent action. ThumbGate captures it, distills a lesson, and blocks the pattern from repeating. One thumbs-down = the agent physically cannot make that mistake again. 33 pre-action checks, budget enforcement, self-protection, and NIST/SOC2 compliance tags.",
|
|
4
|
-
"version": "1.16.
|
|
4
|
+
"version": "1.16.5",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky"
|
|
7
7
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.5",
|
|
4
4
|
"description": "ThumbGate โ ๐๐ feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
|
|
5
5
|
"homepage": "https://thumbgate-production.up.railway.app",
|
|
6
6
|
"transport": "stdio",
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@1.16.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@1.16.5", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@1.16.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@1.16.5", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -201,7 +201,7 @@ const {
|
|
|
201
201
|
finalizeSession: finalizeFeedbackSession,
|
|
202
202
|
} = require('../../scripts/feedback-session');
|
|
203
203
|
|
|
204
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.16.
|
|
204
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.16.5' };
|
|
205
205
|
const COMMERCE_CATEGORIES = [
|
|
206
206
|
'product_recommendation',
|
|
207
207
|
'brand_compliance',
|
package/config/github-about.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"repo": "IgorGanapolsky/ThumbGate",
|
|
3
3
|
"repositoryUrl": "https://github.com/IgorGanapolsky/ThumbGate",
|
|
4
4
|
"homepageUrl": "https://thumbgate-production.up.railway.app",
|
|
5
|
-
"githubDescription": "
|
|
6
|
-
"metaDescription": "Stop paying for the same AI mistake twice. ThumbGate is
|
|
5
|
+
"githubDescription": "Agent governance for ThumbGate: ๐/๐ become Pre-Action Checks that block repeat mistakes before code, money, or customer systems change.",
|
|
6
|
+
"metaDescription": "Stop paying for the same AI mistake twice. ThumbGate is machine-speed pre-action defense for AI coding agents: ๐ thumbs up and ๐ thumbs down become history-aware lessons, shared lessons and org visibility, actionable remediations, agent surface inventory, and Pre-Action Checks that block repeat mistakes before the next tool call across Claude Code, Cursor, Codex, Gemini, Amp, Cline, and OpenCode.",
|
|
7
7
|
"topics": [
|
|
8
8
|
"thumbgate",
|
|
9
9
|
"pre-action-checks",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.5",
|
|
4
4
|
"description": "Self-improving agent governance: type thumbs-up or thumbs-down on any AI agent action. ThumbGate turns every mistake into a prevention rule and blocks the pattern from repeating. One thumbs-down, never again. 33 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
|
|
5
5
|
"homepage": "https://thumbgate-production.up.railway.app",
|
|
6
6
|
"repository": {
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"scripts/audit-trail.js",
|
|
60
60
|
"scripts/auto-promote-gates.js",
|
|
61
61
|
"scripts/auto-wire-hooks.js",
|
|
62
|
+
"scripts/background-agent-governance.js",
|
|
62
63
|
"scripts/bayes-optimal-gate.js",
|
|
63
64
|
"scripts/belief-update.js",
|
|
64
65
|
"scripts/billing.js",
|
|
@@ -234,6 +235,8 @@
|
|
|
234
235
|
"stripe:live": "node scripts/stripe-live-status.js",
|
|
235
236
|
"gtm:revenue-loop": "node scripts/autonomous-sales-agent.js",
|
|
236
237
|
"gtm:aiventyx": "node scripts/aiventyx-marketplace-plan.js",
|
|
238
|
+
"gtm:chatgpt": "node scripts/chatgpt-gpt-revenue-pack.js",
|
|
239
|
+
"gtm:codex": "node scripts/codex-marketplace-revenue-pack.js",
|
|
237
240
|
"sales:pipeline": "node scripts/sales-pipeline.js",
|
|
238
241
|
"social:prepare": "node scripts/social-pipeline.js prepare",
|
|
239
242
|
"social:post": "node scripts/social-pipeline.js post",
|
|
@@ -302,7 +305,7 @@
|
|
|
302
305
|
"test:hosted-config": "node --test tests/hosted-config.test.js",
|
|
303
306
|
"test:operational-summary": "node --test tests/operational-summary.test.js",
|
|
304
307
|
"test:operational-dashboard": "node --test tests/operational-dashboard.test.js",
|
|
305
|
-
"test:operator-artifacts": "node --test tests/operator-artifacts.test.js",
|
|
308
|
+
"test:operator-artifacts": "node --test tests/operator-artifacts.test.js tests/claude-workflow-hardening-pack.test.js tests/gemini-cli-demand-pack.test.js tests/chatgpt-gpt-revenue-pack.test.js",
|
|
306
309
|
"test:operator-key-auth": "node --test tests/api-operator-key-auth.test.js",
|
|
307
310
|
"test:cloudflare-sandbox": "node --test tests/cloudflare-dynamic-sandbox.test.js tests/cloudflare-sandbox-api.test.js",
|
|
308
311
|
"test:mcp-config": "node --test tests/mcp-config.test.js",
|
|
@@ -344,7 +347,7 @@
|
|
|
344
347
|
"test:training-export": "node --test tests/training-export.test.js tests/databricks-export.test.js",
|
|
345
348
|
"test:deployment": "node --test tests/deployment.test.js tests/deploy-policy.test.js tests/publish-decision.test.js tests/changeset-check.test.js tests/release-notes.test.js tests/sonarcloud-workflow.test.js tests/package-boundary.test.js tests/public-package-boundary.test.js tests/revenue-observability-workflow.test.js",
|
|
346
349
|
"test:operational-integrity": "node --test tests/operational-integrity.test.js tests/sync-branch-protection.test.js",
|
|
347
|
-
"test:workflow": "node --test tests/workflow-contract.test.js tests/social-marketing-assets.test.js tests/social-pipeline.test.js tests/positioning-contract.test.js tests/docs-claim-hygiene.test.js tests/thumbgate-scope.test.js tests/workflow-runs.test.js tests/workflow-sprint-intake.test.js tests/gtm-revenue-loop.test.js tests/aiventyx-marketplace-plan.test.js tests/sales-pipeline.test.js tests/enterprise-story.test.js tests/ralph-loop.test.js tests/ralph-mode-ci.test.js",
|
|
350
|
+
"test:workflow": "node --test tests/workflow-contract.test.js tests/social-marketing-assets.test.js tests/social-pipeline.test.js tests/positioning-contract.test.js tests/docs-claim-hygiene.test.js tests/thumbgate-scope.test.js tests/workflow-runs.test.js tests/workflow-sprint-intake.test.js tests/gtm-revenue-loop.test.js tests/aiventyx-marketplace-plan.test.js tests/cursor-marketplace-revenue-pack.test.js tests/codex-marketplace-revenue-pack.test.js tests/codex-plugin-revenue-pack.test.js tests/gemini-cli-demand-pack.test.js tests/chatgpt-gpt-revenue-pack.test.js tests/autonomous-sales-agent.test.js tests/sales-pipeline.test.js tests/reddit-dm-outreach.test.js tests/enterprise-story.test.js tests/ralph-loop.test.js tests/ralph-mode-ci.test.js tests/guide-conversion-path.test.js",
|
|
348
351
|
"test:sales-pipeline": "node --test tests/sales-pipeline.test.js",
|
|
349
352
|
"test:billing": "node --test tests/billing.test.js tests/stripe-sync-product-images.test.js",
|
|
350
353
|
"test:cli": "node --test tests/analytics-report.test.js tests/codex-self-heal.test.js tests/creator-campaigns.test.js tests/cli.test.js tests/codex-bridge-script.test.js tests/dependabot-changeset.test.js tests/dispatch-brief.test.js tests/feedback-normalize.test.js tests/install-mcp.test.js tests/pr-manager.test.js tests/pro-local-dashboard.test.js tests/published-cli.test.js tests/revenue-status.test.js tests/stripe-live-status.test.js",
|
package/public/codex-plugin.html
CHANGED
|
@@ -159,6 +159,29 @@
|
|
|
159
159
|
.caption { color: var(--muted); font-size: 14px; margin-top: 10px; }
|
|
160
160
|
h2 { font-size: 32px; line-height: 1.15; margin: 0 0 16px; letter-spacing: 0; }
|
|
161
161
|
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 24px 0 44px; }
|
|
162
|
+
.proof-bar {
|
|
163
|
+
display: flex;
|
|
164
|
+
gap: 12px;
|
|
165
|
+
flex-wrap: wrap;
|
|
166
|
+
margin: 28px 0 10px;
|
|
167
|
+
}
|
|
168
|
+
.proof-bar a {
|
|
169
|
+
display: inline-flex;
|
|
170
|
+
align-items: center;
|
|
171
|
+
justify-content: center;
|
|
172
|
+
min-height: 40px;
|
|
173
|
+
padding: 10px 14px;
|
|
174
|
+
border-radius: 999px;
|
|
175
|
+
border: 1px solid var(--line);
|
|
176
|
+
background: var(--panel);
|
|
177
|
+
color: var(--text);
|
|
178
|
+
text-decoration: none;
|
|
179
|
+
font-weight: 700;
|
|
180
|
+
}
|
|
181
|
+
.proof-bar a:hover, .proof-bar a:focus-visible {
|
|
182
|
+
border-color: var(--cyan);
|
|
183
|
+
color: var(--cyan);
|
|
184
|
+
}
|
|
162
185
|
code {
|
|
163
186
|
background: rgba(34, 211, 238, 0.1);
|
|
164
187
|
border: 1px solid rgba(34, 211, 238, 0.2);
|
|
@@ -201,6 +224,12 @@
|
|
|
201
224
|
<a class="button secondary" href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/plugins/codex-profile/INSTALL.md" target="_blank" rel="noopener">Read install docs</a>
|
|
202
225
|
<a class="button secondary" href="/guide">Use CLI setup</a>
|
|
203
226
|
</div>
|
|
227
|
+
<nav class="proof-bar" aria-label="Codex proof and conversion links">
|
|
228
|
+
<a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/VERIFICATION_EVIDENCE.md" target="_blank" rel="noopener">Verification evidence</a>
|
|
229
|
+
<a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/COMMERCIAL_TRUTH.md" target="_blank" rel="noopener">Commercial truth</a>
|
|
230
|
+
<a href="/checkout/pro?utm_source=codex&utm_medium=plugin_page&utm_campaign=codex_plugin_follow_on&utm_content=pro&campaign_variant=pro_follow_on&offer_code=CODEX-PRO_FOLLOW_ON&cta_id=codex_pro_follow_on&cta_placement=plugin_page&plan_id=pro&surface=codex_plugin">Upgrade after one blocked repeat</a>
|
|
231
|
+
<a href="/?utm_source=codex&utm_medium=plugin_page&utm_campaign=codex_team_follow_on&utm_content=workflow_sprint&campaign_variant=teams_follow_on&offer_code=CODEX-TEAMS_FOLLOW_ON&cta_id=codex_team_follow_on&cta_placement=plugin_page&surface=codex_plugin#workflow-sprint-intake">Team workflow sprint</a>
|
|
232
|
+
</nav>
|
|
204
233
|
<pre class="terminal">$ npx thumbgate init --agent codex
|
|
205
234
|
# Writes ~/.codex/config.toml and ~/.codex/config.json
|
|
206
235
|
# MCP + hooks install thumbgate@latest before serving or checking gates</pre>
|
|
@@ -254,6 +283,21 @@
|
|
|
254
283
|
</div>
|
|
255
284
|
</section>
|
|
256
285
|
|
|
286
|
+
<section class="wrap grid" aria-label="Proof-backed next steps">
|
|
287
|
+
<div class="tile">
|
|
288
|
+
<h3>Pro only after proof</h3>
|
|
289
|
+
<p>Use the free Codex path to prove one real blocked repeat first. Upgrade to Pro only when you want the personal dashboard, proof-ready exports, and a review surface after that proof exists.</p>
|
|
290
|
+
</div>
|
|
291
|
+
<div class="tile">
|
|
292
|
+
<h3>Commercial truth stays inspectable</h3>
|
|
293
|
+
<p>Pricing, traction guardrails, and what must not be claimed live in the Commercial Truth document, not in launch copy or vibes.</p>
|
|
294
|
+
</div>
|
|
295
|
+
<div class="tile">
|
|
296
|
+
<h3>Team motion starts with one workflow</h3>
|
|
297
|
+
<p>If your buyer already named one repeated workflow failure, one owner, and one approval boundary, route them to the Workflow Hardening Sprint instead of a generic plugin pitch.</p>
|
|
298
|
+
</div>
|
|
299
|
+
</section>
|
|
300
|
+
|
|
257
301
|
<section class="wrap">
|
|
258
302
|
<div class="eyebrow">Operator questions</div>
|
|
259
303
|
<h2>What happens when I click thumbs up or thumbs down?</h2>
|
package/public/dashboard.html
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>ThumbGate Dashboard โ Gate Stats,
|
|
7
|
-
<meta name="description" content="Live dashboard showing gate enforcement stats,
|
|
6
|
+
<title>ThumbGate Dashboard โ Gate Stats, Agent Inventory, Remediations</title>
|
|
7
|
+
<meta name="description" content="Live ThumbGate dashboard showing gate enforcement stats, agent surface inventory, actionable remediations, prevention impact, and system health for pre-action checks.">
|
|
8
8
|
<link rel="canonical" href="https://thumbgate-production.up.railway.app/dashboard">
|
|
9
9
|
<link rel="icon" type="image/png" href="/thumbgate-icon.png">
|
|
10
10
|
<link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
|
|
@@ -123,6 +123,16 @@
|
|
|
123
123
|
.team-note { font-size: 13px; color: var(--text-muted); margin-top: 6px; }
|
|
124
124
|
.team-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
|
|
125
125
|
.risk-row, .blocked-row, .template-meta { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
|
|
126
|
+
.inventory-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-top: 16px; }
|
|
127
|
+
.inventory-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 18px; }
|
|
128
|
+
.inventory-value { font-size: 22px; font-weight: 700; color: var(--cyan); letter-spacing: -0.03em; }
|
|
129
|
+
.inventory-note { font-size: 12px; color: var(--text-muted); margin-top: 6px; line-height: 1.5; }
|
|
130
|
+
.inventory-tools, .inventory-sources, .remediation-list { display: flex; flex-direction: column; gap: 10px; }
|
|
131
|
+
.inventory-row, .remediation-row { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; padding: 10px 0; border-bottom: 1px solid var(--border); }
|
|
132
|
+
.inventory-row:last-child, .remediation-row:last-child { border-bottom: none; }
|
|
133
|
+
.inventory-name, .remediation-name { font-size: 14px; font-weight: 600; }
|
|
134
|
+
.inventory-subtitle, .remediation-subtitle { font-size: 12px; color: var(--text-muted); line-height: 1.55; margin-top: 4px; }
|
|
135
|
+
.remediation-action { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; border-radius: 999px; padding: 4px 10px; background: var(--bg-raised); color: var(--text-muted); border: 1px solid var(--border); white-space: nowrap; }
|
|
126
136
|
.risk-row, .blocked-row { padding: 10px 0; border-bottom: 1px solid var(--border); }
|
|
127
137
|
.risk-row:last-child, .blocked-row:last-child { border-bottom: none; }
|
|
128
138
|
.risk-name, .blocked-name { font-size: 14px; font-weight: 600; }
|
|
@@ -183,7 +193,7 @@
|
|
|
183
193
|
@media (max-width: 700px) {
|
|
184
194
|
.stats-grid { grid-template-columns: repeat(2, 1fr); }
|
|
185
195
|
.search-filters { flex-wrap: wrap; }
|
|
186
|
-
.team-grid, .template-grid, .team-columns, .settings-grid, .generated-grid { grid-template-columns: 1fr; }
|
|
196
|
+
.team-grid, .template-grid, .team-columns, .settings-grid, .generated-grid, .inventory-grid { grid-template-columns: 1fr; }
|
|
187
197
|
}
|
|
188
198
|
</style>
|
|
189
199
|
</head>
|
|
@@ -329,6 +339,51 @@
|
|
|
329
339
|
<h3>Predictive Watchlist</h3>
|
|
330
340
|
<div id="predictiveAnomalies"><div class="loading">Loading predictive watchlist...</div></div>
|
|
331
341
|
</div>
|
|
342
|
+
<div class="panel" style="margin-top:16px;">
|
|
343
|
+
<h3>Agent Surface Inventory</h3>
|
|
344
|
+
<p class="template-summary">See which tools, policy sources, and MCP surfaces are actually active before you widen rollout.</p>
|
|
345
|
+
<div class="inventory-grid" id="inventorySummaryCards"><div class="loading">Loading inventory...</div></div>
|
|
346
|
+
<div class="team-columns" style="margin-top:16px;">
|
|
347
|
+
<div class="panel">
|
|
348
|
+
<h3>Observed Tools</h3>
|
|
349
|
+
<div class="inventory-tools" id="inventoryObservedTools"><div class="loading">Loading observed tools...</div></div>
|
|
350
|
+
</div>
|
|
351
|
+
<div class="panel">
|
|
352
|
+
<h3>Policy Sources</h3>
|
|
353
|
+
<div class="inventory-sources" id="inventoryPolicySources"><div class="loading">Loading policy sources...</div></div>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
<div class="panel" style="margin-top:16px;">
|
|
358
|
+
<h3>Background Agent Mode</h3>
|
|
359
|
+
<p class="template-summary">Queued and scheduled agents need explicit checkpoints before they touch code, money, or customer systems.</p>
|
|
360
|
+
<div class="inventory-grid" id="backgroundAgentSummaryCards"><div class="loading">Loading background-agent mode...</div></div>
|
|
361
|
+
<div class="team-columns" style="margin-top:16px;">
|
|
362
|
+
<div class="panel">
|
|
363
|
+
<h3>Governance Pressure</h3>
|
|
364
|
+
<div class="inventory-tools" id="backgroundAgentHighlights"><div class="loading">Loading background-agent governance...</div></div>
|
|
365
|
+
</div>
|
|
366
|
+
<div class="panel">
|
|
367
|
+
<h3>Run Types</h3>
|
|
368
|
+
<div class="inventory-sources" id="backgroundAgentRunTypes"><div class="loading">Loading background-agent run types...</div></div>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
<div class="panel" style="margin-top:16px;">
|
|
373
|
+
<h3>Regulated Buyer Proof</h3>
|
|
374
|
+
<p class="template-summary">Show where policy came from, how many runs were reviewed, and which proof artifacts are ready when buyers ask for auditability.</p>
|
|
375
|
+
<div class="inventory-grid" id="regulatedProofSummaryCards"><div class="loading">Loading proof posture...</div></div>
|
|
376
|
+
<div class="team-columns" style="margin-top:16px;">
|
|
377
|
+
<div class="panel">
|
|
378
|
+
<h3>Policy Origin Proof</h3>
|
|
379
|
+
<div class="inventory-tools" id="regulatedProofDetails"><div class="loading">Loading policy origin proof...</div></div>
|
|
380
|
+
</div>
|
|
381
|
+
<div class="panel">
|
|
382
|
+
<h3>Latest Replay Artifacts</h3>
|
|
383
|
+
<div class="inventory-sources" id="regulatedProofArtifacts"><div class="loading">Loading replay artifacts...</div></div>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
332
387
|
</div>
|
|
333
388
|
</div>
|
|
334
389
|
|
|
@@ -428,6 +483,12 @@
|
|
|
428
483
|
</div>
|
|
429
484
|
</div>
|
|
430
485
|
|
|
486
|
+
<div class="panel" style="margin-bottom:24px;">
|
|
487
|
+
<h3>Highest-ROI Next Actions</h3>
|
|
488
|
+
<p class="template-summary">These recommendations come from real feedback, risk patterns, and delegation pressure in your current runtime.</p>
|
|
489
|
+
<div class="remediation-list" id="actionableRemediations"><div class="loading">Loading next actions...</div></div>
|
|
490
|
+
</div>
|
|
491
|
+
|
|
431
492
|
<!-- How It Works -->
|
|
432
493
|
<div class="panel">
|
|
433
494
|
<h3 style="margin-bottom:12px;">How ThumbGate Learns</h3>
|
|
@@ -907,9 +968,12 @@ function renderDashboardData(data) {
|
|
|
907
968
|
}
|
|
908
969
|
|
|
909
970
|
renderTeam(data.team || {}, data.analytics || {});
|
|
971
|
+
renderAgentInventory(data.agentSurfaceInventory || {});
|
|
972
|
+
renderBackgroundAgents(data.backgroundAgents || {});
|
|
910
973
|
renderReviewDelta(data.reviewDelta || {});
|
|
911
974
|
renderPredictive(data.predictive || {});
|
|
912
975
|
renderSettingsStatus(data.settingsStatus || {});
|
|
976
|
+
renderRegulatedProof(data.regulatedProof || {});
|
|
913
977
|
renderTemplates(data.templateLibrary || {});
|
|
914
978
|
renderInsights(data);
|
|
915
979
|
}
|
|
@@ -1202,6 +1266,135 @@ function renderPredictive(predictive) {
|
|
|
1202
1266
|
: '<div class="empty" style="padding:20px 0;">No predictive anomalies right now.</div>';
|
|
1203
1267
|
}
|
|
1204
1268
|
|
|
1269
|
+
function renderAgentInventory(inventory) {
|
|
1270
|
+
var cards = [
|
|
1271
|
+
{
|
|
1272
|
+
label: 'MCP profile',
|
|
1273
|
+
value: inventory.profile || 'unknown',
|
|
1274
|
+
note: (inventory.tier || 'custom') + ' tier',
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
label: 'Observed tools',
|
|
1278
|
+
value: String(inventory.observedToolCount || 0),
|
|
1279
|
+
note: 'from decision + audit logs',
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
label: 'Policy sources',
|
|
1283
|
+
value: String((inventory.policySources || []).length),
|
|
1284
|
+
note: 'gates, scanners, or routers firing now',
|
|
1285
|
+
},
|
|
1286
|
+
{
|
|
1287
|
+
label: 'Configured MCP servers',
|
|
1288
|
+
value: String(inventory.configuredServerCount || 0),
|
|
1289
|
+
note: 'from local .mcp.json',
|
|
1290
|
+
}
|
|
1291
|
+
];
|
|
1292
|
+
|
|
1293
|
+
document.getElementById('inventorySummaryCards').innerHTML = cards.map(function(card) {
|
|
1294
|
+
return '<div class="inventory-card"><div class="team-kicker">' + escHtml(card.label) + '</div><div class="inventory-value">' + escHtml(card.value) + '</div><div class="inventory-note">' + escHtml(card.note) + '</div></div>';
|
|
1295
|
+
}).join('');
|
|
1296
|
+
|
|
1297
|
+
var tools = Array.isArray(inventory.observedTools) ? inventory.observedTools : [];
|
|
1298
|
+
document.getElementById('inventoryObservedTools').innerHTML = tools.length
|
|
1299
|
+
? tools.map(function(tool) {
|
|
1300
|
+
return '<div class="inventory-row"><div><div class="inventory-name">' + escHtml(tool.toolName || 'unknown') + '</div><div class="inventory-subtitle">' + escHtml((tool.evaluations || 0) + ' evals ยท ' + (tool.intercepted || 0) + ' intercepted ยท ' + (tool.allow || 0) + ' allowed') + '</div></div><span class="generated-badge">' + escHtml(String((tool.deny || 0) + ' deny / ' + (tool.warn || 0) + ' warn')) + '</span></div>';
|
|
1301
|
+
}).join('')
|
|
1302
|
+
: '<div class="empty" style="padding:20px 0;">No observed tools yet.</div>';
|
|
1303
|
+
|
|
1304
|
+
var sources = Array.isArray(inventory.policySources) ? inventory.policySources : [];
|
|
1305
|
+
document.getElementById('inventoryPolicySources').innerHTML = sources.length
|
|
1306
|
+
? sources.map(function(source) {
|
|
1307
|
+
return '<div class="inventory-row"><div><div class="inventory-name">' + escHtml(source.source || 'unknown') + '</div><div class="inventory-subtitle">Runtime policy source</div></div><span class="generated-badge">' + escHtml(String(source.count || 0) + ' events') + '</span></div>';
|
|
1308
|
+
}).join('')
|
|
1309
|
+
: '<div class="empty" style="padding:20px 0;">No policy sources recorded yet.</div>';
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
function renderBackgroundAgents(backgroundAgents) {
|
|
1313
|
+
var cards = [
|
|
1314
|
+
{
|
|
1315
|
+
label: 'Background runs',
|
|
1316
|
+
value: String(backgroundAgents.total || 0),
|
|
1317
|
+
note: 'last ' + String(backgroundAgents.periodHours || 24) + ' hours',
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
label: 'Pass rate',
|
|
1321
|
+
value: String(backgroundAgents.passRate || 0) + '%',
|
|
1322
|
+
note: String(backgroundAgents.completed || 0) + ' completed / ' + String(backgroundAgents.failed || 0) + ' failed',
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
label: 'Gate pressure',
|
|
1326
|
+
value: String(backgroundAgents.gatesBlocked || 0),
|
|
1327
|
+
note: String(backgroundAgents.gatesChecked || 0) + ' checkpoints evaluated',
|
|
1328
|
+
},
|
|
1329
|
+
{
|
|
1330
|
+
label: 'Checkpoint coverage',
|
|
1331
|
+
value: String(Math.round((backgroundAgents.checkpointCoverage || 0) * 100)) + '%',
|
|
1332
|
+
note: String(backgroundAgents.reviewedRuns || 0) + ' reviewed proof-backed runs',
|
|
1333
|
+
}
|
|
1334
|
+
];
|
|
1335
|
+
|
|
1336
|
+
document.getElementById('backgroundAgentSummaryCards').innerHTML = cards.map(function(card) {
|
|
1337
|
+
return '<div class="inventory-card"><div class="team-kicker">' + escHtml(card.label) + '</div><div class="inventory-value">' + escHtml(card.value) + '</div><div class="inventory-note">' + escHtml(card.note) + '</div></div>';
|
|
1338
|
+
}).join('');
|
|
1339
|
+
|
|
1340
|
+
var highlights = [];
|
|
1341
|
+
if (backgroundAgents.topFailingAgent) {
|
|
1342
|
+
highlights.push('<div class="inventory-row"><div><div class="inventory-name">Top failing agent</div><div class="inventory-subtitle">' + escHtml(backgroundAgents.topFailingAgent.agentId || 'unknown') + '</div></div><span class="generated-badge">' + escHtml(String(backgroundAgents.topFailingAgent.passRate || 0) + '% pass') + '</span></div>');
|
|
1343
|
+
}
|
|
1344
|
+
highlights.push('<div class="inventory-row"><div><div class="inventory-name">Recommended operating mode</div><div class="inventory-subtitle">Use ' + escHtml(backgroundAgents.recommendedMode || 'bootstrapping') + ' when background agents queue code, money, or customer actions.</div></div><span class="generated-badge">' + escHtml(String(backgroundAgents.blocked || 0) + ' blocked') + '</span></div>');
|
|
1345
|
+
document.getElementById('backgroundAgentHighlights').innerHTML = highlights.join('');
|
|
1346
|
+
|
|
1347
|
+
var runTypes = Object.keys(backgroundAgents.byType || {});
|
|
1348
|
+
document.getElementById('backgroundAgentRunTypes').innerHTML = runTypes.length
|
|
1349
|
+
? runTypes.map(function(runType) {
|
|
1350
|
+
return '<div class="inventory-row"><div><div class="inventory-name">' + escHtml(runType) + '</div><div class="inventory-subtitle">Observed background workflow type</div></div><span class="generated-badge">' + escHtml(String(backgroundAgents.byType[runType] || 0) + ' runs') + '</span></div>';
|
|
1351
|
+
}).join('')
|
|
1352
|
+
: '<div class="empty" style="padding:20px 0;">No background-agent runs recorded yet.</div>';
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
function renderRegulatedProof(regulatedProof) {
|
|
1356
|
+
var cards = [
|
|
1357
|
+
{
|
|
1358
|
+
label: 'Policy origins',
|
|
1359
|
+
value: String(regulatedProof.policyOriginCount || 0),
|
|
1360
|
+
note: String(regulatedProof.activeLayerCount || 0) + ' active settings layers',
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
label: 'Reviewed runs',
|
|
1364
|
+
value: String(regulatedProof.reviewedRuns || 0),
|
|
1365
|
+
note: String(regulatedProof.proofBackedRuns || 0) + ' proof-backed runs tracked',
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
label: 'Decision records',
|
|
1369
|
+
value: String(regulatedProof.decisionEvaluations || 0),
|
|
1370
|
+
note: regulatedProof.appendOnlyAuditReady ? 'append-only audit trail live' : 'no decision audit yet',
|
|
1371
|
+
},
|
|
1372
|
+
{
|
|
1373
|
+
label: 'Runtime isolation',
|
|
1374
|
+
value: regulatedProof.runtimeIsolation ? 'on' : 'off',
|
|
1375
|
+
note: 'containerized execution posture',
|
|
1376
|
+
}
|
|
1377
|
+
];
|
|
1378
|
+
|
|
1379
|
+
document.getElementById('regulatedProofSummaryCards').innerHTML = cards.map(function(card) {
|
|
1380
|
+
return '<div class="inventory-card"><div class="team-kicker">' + escHtml(card.label) + '</div><div class="inventory-value">' + escHtml(card.value) + '</div><div class="inventory-note">' + escHtml(card.note) + '</div></div>';
|
|
1381
|
+
}).join('');
|
|
1382
|
+
|
|
1383
|
+
var details = [];
|
|
1384
|
+
if (regulatedProof.latestPolicyOrigin) {
|
|
1385
|
+
details.push('<div class="inventory-row"><div><div class="inventory-name">' + escHtml(regulatedProof.latestPolicyOrigin.path || 'latest setting') + '</div><div class="inventory-subtitle">' + escHtml(regulatedProof.latestPolicyOrigin.sourcePath || 'built-in defaults') + '</div></div><span class="generated-badge">' + escHtml(String(regulatedProof.latestPolicyOrigin.scope || 'default')) + '</span></div>');
|
|
1386
|
+
}
|
|
1387
|
+
details.push('<div class="inventory-row"><div><div class="inventory-name">Checkpoint coverage</div><div class="inventory-subtitle">Reviewed proof-backed runs divided by total proof-backed workflow runs.</div></div><span class="generated-badge">' + escHtml(String(Math.round((regulatedProof.checkpointCoverage || 0) * 100)) + '%') + '</span></div>');
|
|
1388
|
+
document.getElementById('regulatedProofDetails').innerHTML = details.join('');
|
|
1389
|
+
|
|
1390
|
+
var artifacts = Array.isArray(regulatedProof.latestProofArtifacts) ? regulatedProof.latestProofArtifacts : [];
|
|
1391
|
+
document.getElementById('regulatedProofArtifacts').innerHTML = artifacts.length
|
|
1392
|
+
? artifacts.map(function(artifact) {
|
|
1393
|
+
return '<div class="inventory-row"><div><div class="inventory-name">' + escHtml(artifact) + '</div><div class="inventory-subtitle">Proof artifact from ' + escHtml(regulatedProof.latestWorkflowName || 'latest workflow run') + '</div></div><span class="generated-badge">replay-ready</span></div>';
|
|
1394
|
+
}).join('')
|
|
1395
|
+
: '<div class="empty" style="padding:20px 0;">No workflow replay artifacts recorded yet.</div>';
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1205
1398
|
function renderTemplates(templateLibrary) {
|
|
1206
1399
|
const templates = Array.isArray(templateLibrary.templates) ? templateLibrary.templates : [];
|
|
1207
1400
|
const categories = templateLibrary.categories || {};
|
|
@@ -1370,6 +1563,39 @@ function loadDemo() {
|
|
|
1370
1563
|
{ type: 'creator_underperformance', message: 'Creator reach_vb is generating intent without revenue conversion.', severity: 'warning' }
|
|
1371
1564
|
]
|
|
1372
1565
|
});
|
|
1566
|
+
renderAgentInventory({
|
|
1567
|
+
profile: 'default',
|
|
1568
|
+
tier: 'builder',
|
|
1569
|
+
configuredServerCount: 3,
|
|
1570
|
+
observedToolCount: 4,
|
|
1571
|
+
observedTools: [
|
|
1572
|
+
{ toolName: 'Bash', evaluations: 120, intercepted: 19, allow: 101, deny: 12, warn: 7 },
|
|
1573
|
+
{ toolName: 'Edit', evaluations: 64, intercepted: 6, allow: 58, deny: 2, warn: 4 },
|
|
1574
|
+
{ toolName: 'Read', evaluations: 42, intercepted: 0, allow: 42, deny: 0, warn: 0 }
|
|
1575
|
+
],
|
|
1576
|
+
policySources: [
|
|
1577
|
+
{ source: 'gates-engine', count: 23 },
|
|
1578
|
+
{ source: 'secret-guard', count: 6 },
|
|
1579
|
+
{ source: 'workflow-sentinel', count: 4 }
|
|
1580
|
+
]
|
|
1581
|
+
});
|
|
1582
|
+
renderActionableRemediations([
|
|
1583
|
+
{
|
|
1584
|
+
title: 'tighten verification before response ยท recent-signals',
|
|
1585
|
+
rationale: 'Recent approval rate has dropped below the lifetime baseline, so fast completion claims need tighter proof.',
|
|
1586
|
+
action: 'tighten-verification-before-response',
|
|
1587
|
+
},
|
|
1588
|
+
{
|
|
1589
|
+
title: 'audit domain failures ยท git-workflow',
|
|
1590
|
+
rationale: 'Git workflow events are overrepresented in high-risk outcomes and deserve a stronger pre-action gate.',
|
|
1591
|
+
action: 'audit-domain-failures',
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
title: 'review and update skill ยท github',
|
|
1595
|
+
rationale: 'GitHub-related failures have crossed the negative-rate threshold, so the skill needs a correction pass.',
|
|
1596
|
+
action: 'review-and-update-skill',
|
|
1597
|
+
}
|
|
1598
|
+
]);
|
|
1373
1599
|
renderSettingsStatus({
|
|
1374
1600
|
activeLayers: [
|
|
1375
1601
|
{ scope: 'defaults', exists: true, leafCount: 7, sourcePath: null },
|
|
@@ -1412,6 +1638,58 @@ function loadDemo() {
|
|
|
1412
1638
|
]
|
|
1413
1639
|
});
|
|
1414
1640
|
renderGeneratedView(buildDemoGeneratedViewSpec(currentGeneratedView));
|
|
1641
|
+
renderInsights({
|
|
1642
|
+
gateStats: { blocked: 180 },
|
|
1643
|
+
tokenSavings: {
|
|
1644
|
+
dollarsSaved: 0,
|
|
1645
|
+
dollarsSavedDisplay: '$0.00',
|
|
1646
|
+
tokensSavedDisplay: '0',
|
|
1647
|
+
blockedCalls: 0,
|
|
1648
|
+
modelMix: { 'sonnet-4.5': 0.8, 'opus-4.6': 0.15, 'haiku-4.5': 0.05 },
|
|
1649
|
+
blendedPricePer1M: { input: 6.2, output: 24.1 }
|
|
1650
|
+
},
|
|
1651
|
+
lessonPipeline: {
|
|
1652
|
+
stages: [
|
|
1653
|
+
{ id: 'feedback', label: 'Feedback Signals', count: 297, detail: '37 up / 260 down' },
|
|
1654
|
+
{ id: 'lessons', label: 'Lessons Distilled', count: 94, detail: '72 mistakes / 22 good patterns' },
|
|
1655
|
+
{ id: 'gates', label: 'Gates Promoted', count: 21, detail: '22% of lessons become gates' },
|
|
1656
|
+
{ id: 'blocked', label: 'Actions Blocked', count: 180, detail: 'Repeat mistakes prevented' }
|
|
1657
|
+
],
|
|
1658
|
+
rates: { feedbackToLesson: 32, lessonToGate: 22 }
|
|
1659
|
+
},
|
|
1660
|
+
feedbackTimeSeries: {
|
|
1661
|
+
days: Array.from({ length: 30 }, function(_, index) {
|
|
1662
|
+
return {
|
|
1663
|
+
dayKey: '2026-04-' + String(index + 1).padStart(2, '0'),
|
|
1664
|
+
up: index % 6 === 0 ? 2 : (index % 4 === 0 ? 1 : 0),
|
|
1665
|
+
down: 3 + (index % 5),
|
|
1666
|
+
lessons: index % 3 === 0 ? 2 : 1
|
|
1667
|
+
};
|
|
1668
|
+
})
|
|
1669
|
+
},
|
|
1670
|
+
gateAudit: {
|
|
1671
|
+
days: Array.from({ length: 14 }, function(_, index) {
|
|
1672
|
+
return {
|
|
1673
|
+
dayKey: '2026-04-' + String(index + 10).padStart(2, '0'),
|
|
1674
|
+
allow: 8 + (index % 3),
|
|
1675
|
+
deny: 2 + (index % 2),
|
|
1676
|
+
warn: index % 3
|
|
1677
|
+
};
|
|
1678
|
+
})
|
|
1679
|
+
},
|
|
1680
|
+
actionableRemediations: [
|
|
1681
|
+
{
|
|
1682
|
+
title: 'tighten verification before response ยท recent-signals',
|
|
1683
|
+
rationale: 'Recent approval rate has dropped below the lifetime baseline, so fast completion claims need tighter proof.',
|
|
1684
|
+
action: 'tighten-verification-before-response'
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
title: 'audit domain failures ยท git-workflow',
|
|
1688
|
+
rationale: 'Git workflow events are overrepresented in high-risk outcomes and deserve a stronger pre-action gate.',
|
|
1689
|
+
action: 'audit-domain-failures'
|
|
1690
|
+
}
|
|
1691
|
+
]
|
|
1692
|
+
});
|
|
1415
1693
|
}
|
|
1416
1694
|
|
|
1417
1695
|
// Auto-load demo on first visit so visitors see the product immediately
|
|
@@ -1461,6 +1739,23 @@ function renderInsights(data) {
|
|
|
1461
1739
|
renderFeedbackTrendChart(data.feedbackTimeSeries || {});
|
|
1462
1740
|
renderLessonTrendChart(data.feedbackTimeSeries || {});
|
|
1463
1741
|
renderGateAuditChartFromData(data.gateAudit || {});
|
|
1742
|
+
renderActionableRemediations(data.actionableRemediations || []);
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
function renderActionableRemediations(remediations) {
|
|
1746
|
+
var list = document.getElementById('actionableRemediations');
|
|
1747
|
+
if (!list) return;
|
|
1748
|
+
if (!Array.isArray(remediations) || !remediations.length) {
|
|
1749
|
+
list.innerHTML = '<div class="empty" style="padding:20px 0;">No remediation pressure yet. As feedback accumulates, ThumbGate will rank the next highest-ROI fixes here.</div>';
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
list.innerHTML = remediations.map(function(item) {
|
|
1754
|
+
var title = item.title || ((item.action || 'review') + ' ยท ' + (item.target || 'system'));
|
|
1755
|
+
var subtitle = item.rationale || '';
|
|
1756
|
+
var action = item.action || 'review';
|
|
1757
|
+
return '<div class="remediation-row"><div><div class="remediation-name">' + escHtml(title) + '</div><div class="remediation-subtitle">' + escHtml(subtitle) + '</div></div><span class="remediation-action">' + escHtml(String(action).replace(/-/g, ' ')) + '</span></div>';
|
|
1758
|
+
}).join('');
|
|
1464
1759
|
}
|
|
1465
1760
|
|
|
1466
1761
|
/**
|