thumbgate 1.23.2 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate-marketplace",
3
- "version": "1.23.2",
3
+ "version": "1.25.0",
4
4
  "owner": {
5
5
  "name": "Igor Ganapolsky",
6
6
  "email": "ig5973700@gmail.com"
@@ -14,7 +14,7 @@
14
14
  "source": "npm",
15
15
  "package": "thumbgate"
16
16
  },
17
- "version": "1.23.2",
17
+ "version": "1.25.0",
18
18
  "author": {
19
19
  "name": "Igor Ganapolsky",
20
20
  "email": "ig5973700@gmail.com",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
3
3
  "description": "One 👎 becomes a hard rule the agent cannot bypass. Captures thumbs-down feedback, distills it into PreToolUse Pre-Action Checks, enforced across every future Claude Code session.",
4
- "version": "1.23.2",
4
+ "version": "1.25.0",
5
5
  "author": {
6
6
  "name": "Igor Ganapolsky",
7
7
  "email": "ig5973700@gmail.com",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.23.2",
3
+ "version": "1.25.0",
4
4
  "description": "ThumbGate — 👍👎 feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
5
5
  "homepage": "https://thumbgate.ai",
6
6
  "transport": "stdio",
package/README.md CHANGED
@@ -26,6 +26,19 @@ npx thumbgate init # auto-detects your agent, wires hooks, 30 seconds
26
26
 
27
27
  Works with **Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode** and any MCP-compatible agent.
28
28
 
29
+ ### Add ThumbGate to Claude (remote connector, 30 seconds, no install)
30
+
31
+ ThumbGate is a hosted remote MCP server. To use it in **Claude.ai / Claude Desktop**:
32
+ **Settings → Connectors → Add custom connector**, then paste:
33
+
34
+ ```
35
+ https://thumbgate.ai/mcp
36
+ ```
37
+
38
+ That's it — Claude can now call ThumbGate's gate-check and feedback tools directly.
39
+ For local/CLI agents (Claude Code, Cursor, Codex, …) use `npx thumbgate init`, which
40
+ auto-wires the hooks. (The same server is published to the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.IgorGanapolsky/thumbgate`.)
41
+
29
42
  **Free:** 5 feedback captures/day (25 total captures), 3 active auto-promoted prevention rules, all MCP integrations, local-first.
30
43
  **[Pro — $19/mo or $149/yr](https://thumbgate.ai/checkout/pro?utm_source=github&utm_medium=readme):** no limits on captures or rules, history-aware lessons, feedback sessions, hosted dashboard, DPO export.
31
44
  **Team — $49/seat/mo:** shared hosted lesson DB, org dashboard, approval boundaries.
@@ -36,11 +49,9 @@ Works with **Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode** and
36
49
 
37
50
  ---
38
51
 
39
- > *"A better dashboard doesn't make the agents more reliable. The hard part isn't visibility. It's trust."*
40
- >
41
- > — **Rob May**, CEO & co-founder, Neurometric AI, quoted in [The New Stack](https://thenewstack.io/claude-code-agent-view/) on Anthropic's Claude Code Agent View (May 2026).
52
+ > **Visibility isn't trust.** A dashboard shows you what an agent did; it doesn't stop the agent from doing it again. ThumbGate is the enforcement layer: PreToolUse gates, thumbs-down → rule, and an audit trail on every interception — so a mistake gets blocked, not just logged.
42
53
  >
43
- > ThumbGate is the open-source layer that makes the trust part real: PreToolUse gates, thumbs-down to rule, audit trail on every interception.
54
+ > Published in the [MCP Registry](https://registry.modelcontextprotocol.io) (`io.github.IgorGanapolsky/thumbgate`) and usable as a one-line Claude connector.
44
55
 
45
56
  ---
46
57
 
@@ -2,13 +2,13 @@
2
2
  "mcpServers": {
3
3
  "thumbgate": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "thumbgate@1.23.2", "thumbgate", "serve"]
5
+ "args": ["--yes", "--package", "thumbgate@1.25.0", "thumbgate", "serve"]
6
6
  }
7
7
  },
8
8
  "hooks": {
9
9
  "preToolUse": {
10
10
  "command": "npx",
11
- "args": ["--yes", "--package", "thumbgate@1.23.2", "thumbgate", "gate-check"]
11
+ "args": ["--yes", "--package", "thumbgate@1.25.0", "thumbgate", "gate-check"]
12
12
  }
13
13
  }
14
14
  }
@@ -216,7 +216,7 @@ const {
216
216
  finalizeSession: finalizeFeedbackSession,
217
217
  } = require('../../scripts/feedback-session');
218
218
 
219
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.23.2' };
219
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.25.0' };
220
220
  const COMMERCE_CATEGORIES = [
221
221
  'product_recommendation',
222
222
  'brand_compliance',
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.23.2",
10
+ "thumbgate@1.25.0",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.23.2",
4
- "description": "ThumbGate self-improving agent governance: thumbs-up/down turns every mistake into a prevention rule and blocks repeat patterns. 33 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
3
+ "version": "1.25.0",
4
+ "description": "ThumbGate self-improving agent governance: thumbs-up/down turns every mistake into a prevention rule and blocks repeat patterns. 36 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
5
5
  "homepage": "https://thumbgate.ai",
6
6
  "repository": {
7
7
  "type": "git",
@@ -120,6 +120,7 @@
120
120
  "scripts/mailer/index.js",
121
121
  "scripts/mailer/resend-mailer.js",
122
122
  "scripts/mcp-config.js",
123
+ "scripts/mcp-oauth.js",
123
124
  "scripts/mcp-policy.js",
124
125
  "scripts/mcp-transport-strategy.js",
125
126
  "scripts/memory-firewall.js",
@@ -258,6 +259,7 @@
258
259
  "verify:full": "node scripts/verify-run.js full",
259
260
  "budget:status": "node scripts/budget-guard.js --status",
260
261
  "revenue:status": "node scripts/revenue-status.js",
262
+ "revenue:truth": "bash bin/revenue-truth.sh",
261
263
  "revenue:doctor": "node scripts/revenue-observability-doctor.js",
262
264
  "revenue:plan": "node scripts/may-2026-revenue-machine.js",
263
265
  "revenue:status:local": "node bin/cli.js cfo",
@@ -338,7 +340,7 @@
338
340
  "social:prospect:bluesky:dry": "node scripts/social-bluesky-prospecting.js --dry-run",
339
341
  "social:reply-publish:bluesky:dry": "node scripts/social-reply-monitor-bluesky.js --publish-approved --dry-run",
340
342
  "test:python": "python3 -m pytest tests/*.py",
341
- "test": "npm run test:python && npm run test:schema && npm run test:loop && npm run test:dpo && npm run test:kto && npm run test:api && npm run test:proof && npm run test:e2e && npm run test:rlaif && npm run test:attribution && npm run test:quality && npm run test:intelligence && npm run test:training-export && npm run test:deployment && npm run test:operational-integrity && npm run test:workflow && npm run test:billing && npm run test:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:session-analyzer && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && npm run test:post-everywhere-zernio-default && npm run test:zernio-canonical-pollers && npm run test:zernio-status && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:memory-scope-readiness && npm run test:belief-update && npm run test:hosted-config && npm run test:operational-summary && npm run test:operational-dashboard && npm run test:operator-artifacts && npm run test:operator-key-auth && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:bot-detector && npm run test:audit-pr-bot-contamination && npm run test:stripe-bootstrap-saas-catalog && npm run test:postinstall && npm run test:funnel-invariants && npm run test:cli-telemetry && npm run test:pro-parity && npm run test:model-tier-router && npm run test:computer-use-firewall && npm run test:skill-exporter && npm run test:statusline && npm run test:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:cross-encoder && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test:lesson-canonical && npm run test:background-governance && npm run test:memory-migration && npm run test:prompt-dlp && npm run test:ephemeral-store && npm run test:agent-security && npm run test:skill-progressive && npm run test:per-step-scoring && npm run test:weekly-auto-post && npm run test:social-post-hourly && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:budget && npm run test:quick-start && npm run test:utm && npm run test:product-feedback && npm run test:feedback-root-consolidator && npm run test:engagement-audit && npm run test:install-growth-automation && npm run test:publish-thumbgate-launch && npm run test:community-course-platform-launch-kit && npm run test:reconcile-thumbgate-campaign && npm run test:reddit-publisher && npm run test:schedule-thumbgate-campaign && npm run test:social-reply-monitor && npm run test:social-dedupe-cleanup && npm run test:sync-launch-assets && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience && npm run test:bot-detection && npm run test:checkout-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && npm run test:session-health && npm run test:session-episodes && npm run test:spec-gate && npm run test:decision-trace && npm run test:dashboard-insights && npm run test:telemetry-tracked-link-slug && npm run test:prompt-eval && npm run test:demo-voiceover && npm run test:gate-coherence && npm run test:gate-eval && npm run test:high-roi && npm run test:public-static-assets && npm run test:token-savings && npm run test:numbers-page && npm run test:workflow-gate-checkpoint && npm run test:lesson-export-import && npm run test:landing-page-claims && npm run test:competitive-positioning-marketing && npm run test:medium-weekly && npm run test:dashboard-deeplink-e2e && npm run test:public-package-parity && npm run test:token-savings-dashboard && npm run test:cursor-wiring && npm run test:pretooluse-injection && npm run test:recent-corrective-context && npm run test:durability-step && npm run test:mailer && npm run test:brand-assets && npm run test:enforcement-teeth && npm run test:bayes-optimal-gate && npm run test:swarm-coordinator && npm run test:session-report && npm run test:agent-reasoning-traces && npm run test:judge-reward && npm run test:llm-behavior-monitor && npm run test:prompting-os && npm run test:single-use-credential-gate && npm run test:structured-prompt-driven && npm run test:require-evidence-gate && npm run test:rule-validator && npm run test:bluesky-atproto && npm run test:social-reply-monitor-bluesky && npm run test:bluesky-delete-replies && npm run test:architect-kit-memory-bridge && npm run test:sonar-review-hotspots && npm run test:actionable-remediations && npm run test:gemini-embedding-policy && npm run test:agent-design-governance && npm run test:public-core-boundary && npm run test:hook-stop-verify-deploy && npm run test:hook-stop-anti-claim && npm run test:plausible-server-events && npm run test:activation-tracker && npm run test:unified-revenue-rollup && npm run test:conversion-rate-stats && npm run test:external-customer-audit && npm run test:telemetry-export && npm run test:stripe-checkout-diagnostic && npm run test:stripe-business-identity-probe && npm run test:revenue-observability-doctor && npm run test:public-bundle-ratchet && npm run test:stripe-payment-link-update && npm run test:ci-cd-hygiene-audit && npm run test:verify-marketing-pages-deployed && npm run test:install-email-capture && npm run test:install-shim && npm run test:hook-runtime-subcommands && npm run test:implementation-notes && npm run test:daily-block-cap && npm run test:free-to-paid-conversion-units && npm run test:metrics-real-endpoint && npm run test:cli-trial-and-help && npm run test:cost-cli && npm run test:silent-failure-cluster",
343
+ "test": "npm run test:python && npm run test:schema && npm run test:loop && npm run test:dpo && npm run test:kto && npm run test:api && npm run test:proof && npm run test:e2e && npm run test:rlaif && npm run test:attribution && npm run test:quality && npm run test:intelligence && npm run test:training-export && npm run test:deployment && npm run test:operational-integrity && npm run test:workflow && npm run test:billing && npm run test:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:session-analyzer && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && npm run test:post-everywhere-zernio-default && npm run test:zernio-canonical-pollers && npm run test:zernio-status && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:memory-scope-readiness && npm run test:belief-update && npm run test:hosted-config && npm run test:operational-summary && npm run test:operational-dashboard && npm run test:operator-artifacts && npm run test:operator-key-auth && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:mcp-tool-annotations && npm run test:mcp-oauth && npm run test:mcp-oauth-flow && npm run test:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:bot-detector && npm run test:audit-pr-bot-contamination && npm run test:stripe-bootstrap-saas-catalog && npm run test:postinstall && npm run test:funnel-invariants && npm run test:cli-telemetry && npm run test:pro-parity && npm run test:model-tier-router && npm run test:computer-use-firewall && npm run test:skill-exporter && npm run test:statusline && npm run test:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:lesson-semantic-retrieval && npm run test:cross-encoder && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:predictive-credible-range && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test:lesson-canonical && npm run test:background-governance && npm run test:memory-migration && npm run test:prompt-dlp && npm run test:ephemeral-store && npm run test:agent-security && npm run test:skill-progressive && npm run test:per-step-scoring && npm run test:weekly-auto-post && npm run test:social-post-hourly && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:budget && npm run test:quick-start && npm run test:utm && npm run test:product-feedback && npm run test:feedback-root-consolidator && npm run test:engagement-audit && npm run test:install-growth-automation && npm run test:publish-thumbgate-launch && npm run test:community-course-platform-launch-kit && npm run test:reconcile-thumbgate-campaign && npm run test:reddit-publisher && npm run test:schedule-thumbgate-campaign && npm run test:social-reply-monitor && npm run test:social-dedupe-cleanup && npm run test:sync-launch-assets && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience && npm run test:bot-detection && npm run test:checkout-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && npm run test:session-health && npm run test:session-episodes && npm run test:spec-gate && npm run test:decision-trace && npm run test:dashboard-insights && npm run test:telemetry-tracked-link-slug && npm run test:prompt-eval && npm run test:demo-voiceover && npm run test:gate-coherence && npm run test:gate-eval && npm run test:high-roi && npm run test:public-static-assets && npm run test:token-savings && npm run test:numbers-page && npm run test:workflow-gate-checkpoint && npm run test:lesson-export-import && npm run test:landing-page-claims && npm run test:competitive-positioning-marketing && npm run test:medium-weekly && npm run test:dashboard-deeplink-e2e && npm run test:public-package-parity && npm run test:token-savings-dashboard && npm run test:cursor-wiring && npm run test:pretooluse-injection && npm run test:recent-corrective-context && npm run test:durability-step && npm run test:mailer && npm run test:brand-assets && npm run test:enforcement-teeth && npm run test:bayes-optimal-gate && npm run test:swarm-coordinator && npm run test:session-report && npm run test:agent-reasoning-traces && npm run test:judge-reward && npm run test:llm-behavior-monitor && npm run test:prompting-os && npm run test:single-use-credential-gate && npm run test:structured-prompt-driven && npm run test:require-evidence-gate && npm run test:rule-validator && npm run test:bluesky-atproto && npm run test:social-reply-monitor-bluesky && npm run test:bluesky-delete-replies && npm run test:architect-kit-memory-bridge && npm run test:sonar-review-hotspots && npm run test:actionable-remediations && npm run test:gemini-embedding-policy && npm run test:agent-design-governance && npm run test:public-core-boundary && npm run test:hook-stop-verify-deploy && npm run test:hook-stop-anti-claim && npm run test:plausible-server-events && npm run test:activation-tracker && npm run test:unified-revenue-rollup && npm run test:conversion-rate-stats && npm run test:external-customer-audit && npm run test:telemetry-export && npm run test:stripe-checkout-diagnostic && npm run test:stripe-business-identity-probe && npm run test:revenue-observability-doctor && npm run test:public-bundle-ratchet && npm run test:stripe-payment-link-update && npm run test:ci-cd-hygiene-audit && npm run test:verify-marketing-pages-deployed && npm run test:install-email-capture && npm run test:install-shim && npm run test:hook-runtime-subcommands && npm run test:implementation-notes && npm run test:daily-block-cap && npm run test:free-to-paid-conversion-units && npm run test:metrics-real-endpoint && npm run test:cli-trial-and-help && npm run test:cost-cli && npm run test:silent-failure-cluster && npm run test:proof:truth",
342
344
  "test:hook-stop-verify-deploy": "node --test tests/hook-stop-verify-deploy.test.js",
343
345
  "test:hook-stop-anti-claim": "node --test tests/hook-stop-anti-claim.test.js",
344
346
  "test:plausible-server-events": "node --test tests/plausible-server-events.test.js tests/plausible-poller.test.js",
@@ -403,6 +405,9 @@
403
405
  "test:operator-key-auth": "node --test tests/api-operator-key-auth.test.js",
404
406
  "test:cloudflare-sandbox": "node --test tests/cloudflare-dynamic-sandbox.test.js tests/cloudflare-sandbox-api.test.js",
405
407
  "test:mcp-config": "node --test tests/mcp-config.test.js",
408
+ "test:mcp-tool-annotations": "node --test tests/mcp-tool-annotations.test.js",
409
+ "test:mcp-oauth": "node --test tests/mcp-oauth.test.js",
410
+ "test:mcp-oauth-flow": "node --test tests/mcp-oauth-flow.test.js",
406
411
  "test:plan-gate": "node --test tests/plan-gate.test.js",
407
412
  "test:pulse": "node --test tests/pulse.test.js",
408
413
  "test:semantic-layer": "node --test tests/semantic-layer.test.js",
@@ -536,6 +541,7 @@
536
541
  "test:data-governance": "node --test tests/data-governance.test.js",
537
542
  "test:lesson-inference": "node --test tests/conversation-context.test.js tests/lesson-inference.test.js tests/lesson-prompt-shape.test.js",
538
543
  "test:lesson-retrieval": "node --test tests/lesson-retrieval.test.js",
544
+ "test:lesson-semantic-retrieval": "node --test tests/lesson-semantic-retrieval.test.js",
539
545
  "test:cross-encoder": "node --test tests/cross-encoder-reranker.test.js",
540
546
  "test:reflector-agent": "node --test tests/reflector-agent.test.js",
541
547
  "test:public-core-boundary": "node --test tests/public-core-boundary.test.js",
@@ -544,6 +550,7 @@
544
550
  "test:hallucination-detector": "node --test tests/hallucination-detector.test.js",
545
551
  "test:history-distiller": "node --test tests/history-distiller.test.js",
546
552
  "test:predictive-insights": "node --test tests/predictive-insights.test.js",
553
+ "test:predictive-credible-range": "node --test tests/predictive-credible-range.test.js",
547
554
  "test:prove-predictive-insights": "node --test tests/prove-predictive-insights.test.js",
548
555
  "prove:predictive-insights": "node scripts/prove-predictive-insights.js",
549
556
  "test:statusbar-cli": "node --test tests/statusbar-cli.test.js",
@@ -679,7 +686,12 @@
679
686
  "test:index-page-clickability": "playwright test tests/e2e/index-page-clickability.spec.js",
680
687
  "test:dashboard-page-clickability": "playwright test tests/e2e/dashboard-page-clickability.spec.js",
681
688
  "test:agent-manager-page-clickability": "playwright test tests/e2e/agent-manager-page-clickability.spec.js",
682
- "test:pricing-page-clickability": "playwright test tests/e2e/pricing-page-clickability.spec.js"
689
+ "test:pricing-page-clickability": "playwright test tests/e2e/pricing-page-clickability.spec.js",
690
+ "test:proof:truth": "node --test tests/knowledge-entropy.test.js tests/mcp-wiring-doctor.test.js tests/sequence-guard.test.js tests/slopsquat-guard.test.js tests/slopsquat-stress.test.js tests/truth-and-proof.test.js tests/wire-proof-gate.test.js",
691
+ "build:grok-plugin": "node scripts/build-grok-plugin.js",
692
+ "promote:launch": "node scripts/x-autonomous-marketing.js",
693
+ "feedback:ingest": "node scripts/ingest-manual-feedback.js",
694
+ "verify-proof": "node scripts/require-proof.js"
683
695
  },
684
696
  "keywords": [
685
697
  "mcp",
@@ -314,11 +314,22 @@
314
314
  Every 👍 / 👎 an attorney logs on an AI answer becomes a lesson in your firm's local DB. Recurring patterns promote to deterministic rules. The next time a similar action is proposed, the rule fires before any human is asked to approve.
315
315
  <a href="/learn/feedback-loop-vs-decision-layer" style="color: var(--cyan); white-space: nowrap;">How the feedback loop works &rarr;</a>
316
316
  </p>
317
+ <p style="color: var(--soft); font-size: 0.95rem; max-width: 760px; margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-left: 3px solid #a78bfa; background: rgba(167, 139, 250, 0.06); border-radius: 0 6px 6px 0;">
318
+ <strong style="color: #a78bfa">No public-facing chatbot? You still have the risk surface.</strong>
319
+ Most BigLaw firms don't take client intake through a chatbot &mdash; but their associates already paste matter context into Claude, Cursor, Codex, and internal LLM gateways every day. The risk isn't a bot giving public advice; it's <em>internal</em> agent use the firm can't see. ThumbGate sits between each agent and its next action, captures attorney 👍/👎 on every output, and produces a <strong style="color: var(--soft)">searchable audit log + RAG of every gated detection</strong> &mdash; queryable by ethics, risk, and innovation owners. Your conflicts DB and document systems stay where they are; we instrument what the agents inside the firm are about to do.
320
+ </p>
321
+ <p style="color: var(--soft); font-size: 0.95rem; max-width: 760px; margin: 0 0 1.1rem; padding: 0.7rem 1rem; border-left: 3px solid #f59e0b; background: rgba(245, 158, 11, 0.06); border-radius: 0 6px 6px 0;">
322
+ <strong style="color: #f59e0b">Already piloting an AI case tool? It makes agents capable &mdash; ThumbGate makes them auditable.</strong>
323
+ Litigation &amp; arbitration teams and in-house counsel are adopting AI case-intelligence and drafting copilots that touch privileged correspondence, pleadings, and matter files. Those tools make the agent <em>capable</em>; they don't give risk, ethics, and innovation owners a control point or a defensible record of what the agent was about to do. ThumbGate is the governance layer <em>around</em> them &mdash; a deterministic gate on the next action, attorney 👍/👎 promoted to firm rules, and an exportable audit trail &mdash; the evidence procurement (and your professional-liability review) actually ask for before agents run on multi-million-dollar matters.
324
+ </p>
317
325
  <div class="hero-actions">
318
326
  <a class="cta" href="mailto:iganapolsky@gmail.com?subject=ThumbGate%2025-minute%20legal%20AI%20pilot%20walkthrough&amp;body=Hi%20Igor%2C%0A%0AWe%27d%20like%20to%20review%20the%2025-minute%20ThumbGate%20legal%20AI%20intake%20pilot.%20Please%20send%20the%20meeting%20invite%20and%20demo%20materials.%0A%0ABest%2C">Book a 25-minute pilot walkthrough</a>
319
327
  <a class="ghost" href="#live-gate-demos">Try the live gates &rarr;</a>
320
328
  <a class="ghost" href="#demo">View the 25-minute demo plan</a>
321
329
  </div>
330
+ <p style="font-size: 0.85rem; color: var(--muted); margin: -0.5rem 0 1.2rem; max-width: 760px;">
331
+ Button not opening your mail client? <button type="button" onclick="__thumbgateCopyPilotEmail(this)" style="padding:0.35rem 0.7rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:5px; cursor:pointer; vertical-align: baseline;">Copy the email instead</button> or write to <span style="color: var(--text); user-select: all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;">iganapolsky@gmail.com</span> directly.
332
+ </p>
322
333
  <div class="proof-row" aria-label="Key proof points">
323
334
  <div class="proof"><strong>Preloaded controls</strong><span>Firm policy, approved disclaimers, adverse-party lists, routing rules, and model endpoint allowlists.</span></div>
324
335
  <div class="proof"><strong>Pre-action checks</strong><span>Controls run before the agent replies, fetches records, schedules intake, or calls an external model.</span></div>
@@ -520,10 +531,27 @@
520
531
  <p>Start narrow: one intake channel, one practice-area workflow, one adverse-party fixture, one approved-model routing policy, and one audit export format.</p>
521
532
  <p>Deliverables: preloaded rule pack, demo agent, screenshot set, 60-second walkthrough clip, security data-flow note, pilot metrics, and a go/no-go rollout recommendation.</p>
522
533
  <p style="margin:1.2rem 0 0.6rem;color:var(--amber);font-size:1.1rem;font-weight:700;">Pilot setup fee: $2,500 &ndash; $7,500 flat (scope-dependent). No per-seat or per-query billing during the pilot.</p>
534
+ <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:0.75rem;margin:1.4rem 0 1rem;">
535
+ <div style="background:rgba(114,227,165,0.06);border-left:3px solid var(--green);padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
536
+ <strong style="color:var(--green);font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What you walk away with</strong>
537
+ <span style="font-size:0.9rem;color:var(--soft)">A searchable audit log + RAG of every gated detection over 30 days, broken down by rule, agent, and disposition. Defensible in front of your risk committee.</span>
538
+ </div>
539
+ <div style="background:rgba(251,191,36,0.06);border-left:3px solid #fbbf24;padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
540
+ <strong style="color:#fbbf24;font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What we don't claim</strong>
541
+ <span style="font-size:0.9rem;color:var(--soft)">Not SOC 2 today. Not BAA-ready as a blanket claim. No hallucination indemnity for third-party model output. Local-first deployment makes the pilot a no-client-data engagement.</span>
542
+ </div>
543
+ <div style="background:rgba(45,212,191,0.06);border-left:3px solid var(--cyan);padding:0.7rem 0.9rem;border-radius:0 6px 6px 0">
544
+ <strong style="color:var(--cyan);font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;display:block;margin-bottom:0.3rem">What you bring</strong>
545
+ <span style="font-size:0.9rem;color:var(--soft)">One named owner, one workflow you're already evaluating AI on, your approved disclaimer language, and read-only access to whichever conflicts DB you already run.</span>
546
+ </div>
547
+ </div>
523
548
  <div style="display:flex;gap:1rem;flex-wrap:wrap;margin-top:1rem;">
524
549
  <a class="cta" href="mailto:iganapolsky@gmail.com?subject=ThumbGate%2025-minute%20legal%20AI%20pilot%20walkthrough&amp;body=Hi%20Igor%2C%0A%0AWe%27d%20like%20to%20review%20the%2025-minute%20ThumbGate%20legal%20AI%20intake%20pilot.%20Please%20send%20the%20meeting%20invite%20and%20demo%20materials.%0A%0ABest%2C">Book a 25-minute pilot walkthrough</a>
525
550
  <a class="ghost" href="/dashboard">View the live dashboard demo</a>
526
551
  </div>
552
+ <p style="font-size:0.85rem; color:var(--muted); margin:0.75rem 0 0;">
553
+ Button not opening your mail client (common on Gmail Web / iPhone)? <button type="button" onclick="__thumbgateCopyPilotEmail(this)" style="padding:0.35rem 0.7rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:5px; cursor:pointer; vertical-align: baseline;">Copy the email instead</button> or write to <span style="color: var(--text); user-select: all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;">iganapolsky@gmail.com</span> directly.
554
+ </p>
527
555
  </div>
528
556
  </section>
529
557
 
@@ -537,16 +565,20 @@
537
565
  <!-- UPL Gate Simulator -->
538
566
  <div class="card" style="margin-bottom:2rem">
539
567
  <h3 style="color:var(--cyan); margin-bottom:0.75rem">1. UPL Gate &mdash; advice-shaped output detector</h3>
540
- <p style="font-size:0.95rem; color:var(--muted)">Type what a client might ask an intake bot. The gate detects predictions, recommendations, or jurisdictional legal analysis from a non-attorney source and blocks delivery.</p>
568
+ <p style="font-size:0.95rem; color:var(--muted)">Paste an <strong>advice-shaped response a bot would deliver to a client</strong> (not a client's question). The gate detects predictions, recommendations, or jurisdictional legal analysis from a non-attorney source and blocks delivery. The patterns it matches were promoted from attorney 👎 feedback.</p>
541
569
  <textarea id="upl-input" placeholder="E.g. 'Based on the facts you described, you likely have a strong claim for breach of contract and could recover significant damages.'" style="width:100%; height:90px; background:#0f0f11; color:var(--text); border:1px solid var(--line); border-radius:8px; padding:0.75rem; font-size:0.95rem; resize:vertical; margin:0.75rem 0"></textarea>
542
- <button onclick="runUPLDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Run through UPL Gate</button>
570
+ <div style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center; margin-bottom:0.5rem">
571
+ <button onclick="runUPLDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Run through UPL Gate</button>
572
+ <button type="button" onclick="document.getElementById('upl-input').value='You have a strong case for wrongful termination. In my opinion, you should file in the Southern District of Florida.';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill sample &mdash; will BLOCK</button>
573
+ <button type="button" onclick="document.getElementById('upl-input').value='I can schedule a 30-minute consultation with one of our employment attorneys. Would 2pm Thursday work?';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill sample &mdash; will CLEAR</button>
574
+ </div>
543
575
  <div id="upl-result" class="demo-result" style="display:none"></div>
544
576
  </div>
545
577
 
546
578
  <!-- Conflict Check Simulator -->
547
579
  <div class="card" style="margin-bottom:2rem">
548
580
  <h3 style="color:var(--cyan); margin-bottom:0.75rem">2. Conflict Gate &mdash; adverse party clearance</h3>
549
- <p style="font-size:0.95rem; color:var(--muted)">Enter a prospective client or party name. The gate checks against a sample adverse-parties list (real firms maintain much larger lists).</p>
581
+ <p style="font-size:0.95rem; color:var(--muted)">Enter a prospective client or party name. <strong>In production this gate queries YOUR firm's existing conflicts DB</strong> (Intapp Open, IntelliPlan, Aderant, or a custom system) &mdash; not a vendor-hosted list. ThumbGate is the agent-side enforcement; your DB stays the source of truth. The sample list below is illustrative only.</p>
550
582
  <div style="display:flex; gap:0.75rem; align-items:flex-end; margin:0.75rem 0; flex-wrap:wrap">
551
583
  <div style="flex:1; min-width:240px">
552
584
  <label style="font-size:0.8rem; color:var(--muted); display:block; margin-bottom:0.25rem">Party / Company Name</label>
@@ -554,6 +586,10 @@
554
586
  </div>
555
587
  <button onclick="runConflictDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem; white-space:nowrap">Check Against Adverse List</button>
556
588
  </div>
589
+ <div style="display:flex; gap:0.5rem; flex-wrap:wrap; margin-bottom:0.5rem">
590
+ <button type="button" onclick="document.getElementById('conflict-input').value='Latam Real Capital S.A.';" style="padding:0.4rem 0.8rem; font-size:0.8rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill &mdash; will BLOCK</button>
591
+ <button type="button" onclick="document.getElementById('conflict-input').value='Acme Manufacturing LLC';" style="padding:0.4rem 0.8rem; font-size:0.8rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill &mdash; will CLEAR</button>
592
+ </div>
557
593
  <div style="font-size:0.8rem; color:var(--muted); margin-bottom:0.5rem">Sample adverse list (synthetic, illustrative): Latam Real Capital S.A. (real estate #M-2847), Hospitalia Holdings (hospitality M&amp;A #M-2911), NovaIA Latam (AI venture #M-2755)</div>
558
594
  <div id="conflict-result" class="demo-result" style="display:none"></div>
559
595
  </div>
@@ -561,9 +597,13 @@
561
597
  <!-- Privilege Egress Simulator -->
562
598
  <div class="card">
563
599
  <h3 style="color:var(--cyan); margin-bottom:0.75rem">3. Egress Gate &mdash; privilege marker detector</h3>
564
- <p style="font-size:0.95rem; color:var(--muted)">Paste content an agent might try to send to an external LLM (e.g. deposition summary request). The gate blocks if it detects privilege markers.</p>
600
+ <p style="font-size:0.95rem; color:var(--muted)">Paste content an agent might try to send to an external LLM (e.g. deposition summary request). The gate blocks if it detects privilege markers. Markers are firm-defined and the list grows from attorney 👍/👎 on what the gate let through.</p>
565
601
  <textarea id="privilege-input" placeholder="Please summarize this deposition transcript. [Attorney Work Product - Matter M-2847 - Confidential]" style="width:100%; height:90px; background:#0f0f11; color:var(--text); border:1px solid var(--line); border-radius:8px; padding:0.75rem; font-size:0.95rem; resize:vertical; margin:0.75rem 0"></textarea>
566
- <button onclick="runPrivilegeDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Attempt External LLM Call</button>
602
+ <div style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center; margin-bottom:0.5rem">
603
+ <button onclick="runPrivilegeDemo()" class="cta" style="padding:0.6rem 1.1rem; font-size:0.9rem">Attempt External LLM Call</button>
604
+ <button type="button" onclick="document.getElementById('privilege-input').value='Please summarize this deposition transcript. [Attorney Work Product - Matter M-2847 - Confidential]';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--cyan); border:1px solid var(--cyan); border-radius:6px; cursor:pointer">Fill sample &mdash; will BLOCK</button>
605
+ <button type="button" onclick="document.getElementById('privilege-input').value='Please summarize the public press release announcing the merger between Acme Corp and Foobar Inc.';" style="padding:0.5rem 0.9rem; font-size:0.85rem; background:transparent; color:var(--green); border:1px solid var(--green); border-radius:6px; cursor:pointer">Fill sample &mdash; will CLEAR</button>
606
+ </div>
567
607
  <div id="privilege-result" class="demo-result" style="display:none"></div>
568
608
  </div>
569
609
 
@@ -573,6 +613,23 @@
573
613
  return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
574
614
  });
575
615
  }
616
+ window.__thumbgateCopyPilotEmail = function(btn) {
617
+ var body = "Hi Igor,\n\nWe'd like to review the 25-minute ThumbGate legal AI intake pilot. Please send the meeting invite and demo materials.\n\nBest,";
618
+ var full = "To: iganapolsky@gmail.com\nSubject: ThumbGate 25-minute legal AI pilot walkthrough\n\n" + body;
619
+ var done = function(label) {
620
+ var orig = btn.dataset.origLabel || btn.textContent;
621
+ btn.dataset.origLabel = orig;
622
+ btn.textContent = label;
623
+ setTimeout(function() { btn.textContent = orig; }, 2400);
624
+ };
625
+ if (navigator.clipboard && navigator.clipboard.writeText) {
626
+ navigator.clipboard.writeText(full)
627
+ .then(function() { done('Copied — paste into Gmail or any mail client'); })
628
+ .catch(function() { done('Copy failed — email iganapolsky@gmail.com directly'); });
629
+ } else {
630
+ done('Email iganapolsky@gmail.com directly');
631
+ }
632
+ };
576
633
  // Produces the same JSON shape a production ThumbGate gate would stream to the firm's SIEM.
577
634
  // Includes ISO 27001 control mapping so procurement can map evidence to controls without translation.
578
635
  window.__thumbgateBuildAudit = function(args) {
package/public/index.html CHANGED
@@ -20,7 +20,7 @@ __GOOGLE_SITE_VERIFICATION_META__
20
20
  <meta property="og:image" content="https://thumbgate.ai/og.png">
21
21
  <meta name="twitter:card" content="summary_large_image">
22
22
  <meta name="twitter:image" content="https://thumbgate.ai/og.png">
23
- <meta name="thumbgate-version" content="1.23.2">
23
+ <meta name="thumbgate-version" content="1.25.0">
24
24
  <meta name="keywords" content="ThumbGate, thumbgate, AI agent orchestration, AI experience orchestration, agentic development cycle, AC/DC framework, Guide Generate Verify Solve, agent enforcement layer, save LLM tokens, reduce Claude API cost, reduce OpenAI cost, AI agent token savings, prevent LLM retries, prevent hallucination retries, stop AI token waste, pre-action checks, agent governance, Claude Code, Cursor, Codex, Gemini, Amp, Cline, OpenCode, workflow hardening, context engineering, AI authenticity, brand authenticity AI">
25
25
  <link rel="canonical" href="__APP_ORIGIN__/">
26
26
  <link rel="alternate" type="text/markdown" title="ThumbGate LLM context" href="__APP_ORIGIN__/llm-context.md">
@@ -1586,7 +1586,7 @@ __GA_BOOTSTRAP__
1586
1586
  <a href="https://www.linkedin.com/in/igorganapolsky" target="_blank" rel="noopener">LinkedIn</a>
1587
1587
  <a href="/blog">Blog</a>
1588
1588
  </div>
1589
- <span class="footer-copy">© 2026 ThumbGate · MIT License · npm v1.23.2</span>
1589
+ <span class="footer-copy">© 2026 ThumbGate · MIT License · npm v1.25.0</span>
1590
1590
  </div>
1591
1591
  </footer>
1592
1592
 
@@ -25,7 +25,7 @@
25
25
  "alternateName": "thumbgate",
26
26
  "applicationCategory": "DeveloperApplication",
27
27
  "operatingSystem": "Cross-platform, Node.js >=18.18.0",
28
- "softwareVersion": "1.23.2",
28
+ "softwareVersion": "1.25.0",
29
29
  "url": "https://thumbgate.ai/numbers",
30
30
  "dateModified": "2026-05-07",
31
31
  "creator": {
@@ -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.23.2</div>
205
+ <div class="freshness">Updated: 2026-05-07 · Version 1.25.0</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>
@@ -55,6 +55,9 @@ const {
55
55
  const {
56
56
  evaluateSecurityScan,
57
57
  } = require('./security-scanner');
58
+ const { evaluateSequenceState } = loadOptionalModule('./sequence-guard', () => ({
59
+ evaluateSequenceState: () => null,
60
+ }));
58
61
  const { getAutoGatesPath } = require('./auto-promote-gates');
59
62
  const { recordAuditEvent, auditToFeedback } = require('./audit-trail');
60
63
 
@@ -2132,8 +2135,9 @@ function buildRecentCorrectiveActionsContext(options = {}) {
2132
2135
  function buildRelevantLessonContext(toolName, toolInput) {
2133
2136
  if (!toolName) return null;
2134
2137
 
2135
- const { retrieveRelevantLessons } = loadOptionalModule('./lesson-retrieval', () => ({
2138
+ const { retrieveRelevantLessons, calculateRetrievalEntropy } = loadOptionalModule('./lesson-retrieval', () => ({
2136
2139
  retrieveRelevantLessons: () => [],
2140
+ calculateRetrievalEntropy: () => 0,
2137
2141
  }));
2138
2142
 
2139
2143
  // Extract a searchable action context from the tool input
@@ -2142,23 +2146,77 @@ function buildRelevantLessonContext(toolName, toolInput) {
2142
2146
 
2143
2147
  try {
2144
2148
  const lessons = retrieveRelevantLessons(toolName, actionContext, { maxResults: 3 });
2145
- // retrieveRelevantLessons already filters at relevanceScore > 0.1 internally;
2146
- // any negative lesson that survives retrieval is relevant enough to surface.
2147
- const negative = lessons.filter((l) => l.signal === 'negative');
2148
- if (negative.length === 0) return null;
2149
-
2150
- const formatted = negative.map((l) => {
2151
- const title = (l.title || '').replace(/^MISTAKE:\s*/, '').slice(0, 140);
2152
- const advice = extractAvoidanceAdvice(l.content);
2153
- return advice ? ` • ${title}\n → ${advice}` : ` • ${title}`;
2154
- });
2155
2149
 
2156
- return `[ThumbGate] Past mistakes relevant to this action — read before proceeding:\n${formatted.join('\n')}`;
2150
+ const entropy = calculateRetrievalEntropy(lessons);
2151
+ if (entropy > 0.7) {
2152
+ recordStat("retrieval_entropy_high", "block");
2153
+ return { decision: "deny", gate: "knowledge-conflict-gate", message: "✗ THUMBGATE: Action blocked due to high Knowledge Entropy (conflicting past lessons).", severity: "high" };
2154
+ }
2155
+ return formatNegativeLessonContext(lessons);
2157
2156
  } catch {
2158
2157
  return null;
2159
2158
  }
2160
2159
  }
2161
2160
 
2161
+ /**
2162
+ * Async counterpart of buildRelevantLessonContext: uses HYBRID (dense embeddings +
2163
+ * lexical) retrieval so the agent is warned about semantically-related past mistakes
2164
+ * even when they share no keywords with the current action. Wired into runAsync.
2165
+ * Degrades to the lexical result automatically when no embedder is available.
2166
+ */
2167
+ async function buildRelevantLessonContextAsync(toolName, toolInput) {
2168
+ if (!toolName) return null;
2169
+
2170
+ const { retrieveRelevantLessonsAsync, retrieveRelevantLessons, calculateRetrievalEntropy } = loadOptionalModule(
2171
+ './lesson-retrieval',
2172
+ () => ({ retrieveRelevantLessonsAsync: null, retrieveRelevantLessons: () => [], calculateRetrievalEntropy: () => 0 }),
2173
+ );
2174
+
2175
+ const actionContext = extractActionContext(toolName, toolInput);
2176
+ if (!actionContext) return null;
2177
+
2178
+ try {
2179
+ const lessons = retrieveRelevantLessonsAsync
2180
+ ? await retrieveRelevantLessonsAsync(toolName, actionContext, { maxResults: 3 })
2181
+ : retrieveRelevantLessons(toolName, actionContext, { maxResults: 3 });
2182
+
2183
+ // Knowledge Conflict Detection: if retrieved lessons have high sentiment entropy,
2184
+ // it indicates conflicting past evidence. Block and require human disambiguation.
2185
+ const entropy = calculateRetrievalEntropy(lessons);
2186
+ if (entropy > 0.7) {
2187
+ recordStat('retrieval_entropy_high', 'block');
2188
+ return {
2189
+ decision: 'deny',
2190
+ gate: 'knowledge-conflict-gate',
2191
+ message: '✗ THUMBGATE: Action blocked due to high Knowledge Entropy (conflicting past lessons). Please disambiguate your instructions or verify the intended behavior manually.',
2192
+ severity: 'high',
2193
+ };
2194
+ }
2195
+
2196
+ return formatNegativeLessonContext(lessons);
2197
+ } catch {
2198
+ return null;
2199
+ }
2200
+ }
2201
+
2202
+ /**
2203
+ * Shared formatter: render the negative (mistake) lessons that survived retrieval
2204
+ * into the PreToolUse warning block. Retrieval already filters by relevance, so any
2205
+ * negative lesson present is relevant enough to surface.
2206
+ */
2207
+ function formatNegativeLessonContext(lessons) {
2208
+ const negative = (lessons || []).filter((l) => l.signal === 'negative');
2209
+ if (negative.length === 0) return null;
2210
+
2211
+ const formatted = negative.map((l) => {
2212
+ const title = (l.title || '').replace(/^MISTAKE:\s*/, '').slice(0, 140);
2213
+ const advice = extractAvoidanceAdvice(l.content);
2214
+ return advice ? ` • ${title}\n → ${advice}` : ` • ${title}`;
2215
+ });
2216
+
2217
+ return `[ThumbGate] Past mistakes relevant to this action — read before proceeding:\n${formatted.join('\n')}`;
2218
+ }
2219
+
2162
2220
  function extractActionContext(toolName, toolInput) {
2163
2221
  if (!toolInput) return toolName;
2164
2222
  const parts = [toolName];
@@ -2196,6 +2254,12 @@ async function runAsync(input) {
2196
2254
 
2197
2255
  const toolName = input.tool_name || '';
2198
2256
  const toolInput = input.tool_input || {};
2257
+
2258
+ const sequenceGuard = evaluateSequenceState(toolName, toolInput);
2259
+ if (sequenceGuard && sequenceGuard.decision === 'deny') {
2260
+ return formatOutput(sequenceGuard);
2261
+ }
2262
+
2199
2263
  const result = await evaluateGatesAsync(toolName, toolInput);
2200
2264
 
2201
2265
  // Attach security warnings to allow/warn results
@@ -2208,11 +2272,18 @@ async function runAsync(input) {
2208
2272
  }
2209
2273
  }
2210
2274
 
2275
+
2211
2276
  const behavioralContext = buildBehavioralContext();
2212
- const lessonContext = buildRelevantLessonContext(toolName, toolInput);
2277
+ const lessonContext = await buildRelevantLessonContextAsync(toolName, toolInput);
2278
+
2279
+ if (lessonContext && lessonContext.decision === "deny") {
2280
+ return formatOutput(lessonContext);
2281
+ }
2282
+
2213
2283
  const recentContext = buildRecentCorrectiveActionsContext();
2214
2284
  const combinedContext = mergeContextStrings(lessonContext, recentContext, behavioralContext);
2215
2285
  return formatOutput(result, combinedContext);
2286
+
2216
2287
  }
2217
2288
 
2218
2289
  function run(input) {
@@ -2229,6 +2300,12 @@ function run(input) {
2229
2300
 
2230
2301
  const toolName = input.tool_name || '';
2231
2302
  const toolInput = input.tool_input || {};
2303
+
2304
+ const sequenceGuard = evaluateSequenceState(toolName, toolInput);
2305
+ if (sequenceGuard && sequenceGuard.decision === 'deny') {
2306
+ return formatOutput(sequenceGuard);
2307
+ }
2308
+
2232
2309
  const result = evaluateGates(toolName, toolInput);
2233
2310
 
2234
2311
  // Attach security warnings to allow/warn results
@@ -2241,11 +2318,18 @@ function run(input) {
2241
2318
  }
2242
2319
  }
2243
2320
 
2321
+
2244
2322
  const behavioralContext = buildBehavioralContext();
2245
2323
  const lessonContext = buildRelevantLessonContext(toolName, toolInput);
2324
+
2325
+ if (lessonContext && lessonContext.decision === "deny") {
2326
+ return formatOutput(lessonContext);
2327
+ }
2328
+
2246
2329
  const recentContext = buildRecentCorrectiveActionsContext();
2247
2330
  const combinedContext = mergeContextStrings(lessonContext, recentContext, behavioralContext);
2248
2331
  return formatOutput(result, combinedContext);
2332
+
2249
2333
  }
2250
2334
 
2251
2335
  // ---------------------------------------------------------------------------
@@ -2562,6 +2646,7 @@ module.exports = {
2562
2646
  buildBehavioralContext,
2563
2647
  buildRecentCorrectiveActionsContext,
2564
2648
  buildRelevantLessonContext,
2649
+ buildRelevantLessonContextAsync,
2565
2650
  extractActionContext,
2566
2651
  extractAvoidanceAdvice,
2567
2652
  mergeContextStrings,