thumbgate 1.27.6 → 1.27.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/.claude/commands/thumbgate-blocked.md +27 -0
  2. package/.claude/commands/thumbgate-doctor.md +30 -0
  3. package/.claude/commands/thumbgate-guard.md +36 -0
  4. package/.claude/commands/thumbgate-protect.md +30 -0
  5. package/.claude/commands/thumbgate-rules.md +30 -0
  6. package/.claude-plugin/plugin.json +1 -1
  7. package/.well-known/llms.txt +6 -2
  8. package/.well-known/mcp/server-card.json +1 -1
  9. package/README.md +49 -5
  10. package/adapters/claude/.mcp.json +2 -2
  11. package/adapters/letta/README.md +41 -0
  12. package/adapters/letta/thumbgate-letta-adapter.js +133 -0
  13. package/adapters/mcp/server-stdio.js +16 -1
  14. package/adapters/opencode/opencode.json +1 -1
  15. package/adapters/policy-engine/ethicore-guardian-client.js +68 -0
  16. package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +260 -0
  17. package/bench/observability-eval-suite.json +26 -0
  18. package/bin/cli.js +180 -2
  19. package/bin/postinstall.js +1 -1
  20. package/config/gate-templates.json +84 -0
  21. package/config/gates/claim-verification.json +6 -0
  22. package/config/gates/default.json +20 -0
  23. package/config/github-about.json +1 -1
  24. package/config/model-candidates.json +50 -0
  25. package/package.json +65 -25
  26. package/public/agent-manager.html +41 -1
  27. package/public/agents-cost-savings.html +1 -1
  28. package/public/ai-malpractice-prevention.html +2 -1
  29. package/public/assets/brand/github-social-preview.png +0 -0
  30. package/public/assets/brand/thumbgate-icon-512.png +0 -0
  31. package/public/assets/brand/thumbgate-icon-pro-512.png +0 -0
  32. package/public/assets/brand/thumbgate-icon-team-512.png +0 -0
  33. package/public/assets/brand/thumbgate-logo-1200x360.png +0 -0
  34. package/public/assets/brand/thumbgate-mark-inline.svg +15 -0
  35. package/public/assets/brand/thumbgate-mark-pro.svg +23 -0
  36. package/public/assets/brand/thumbgate-mark-team.svg +26 -0
  37. package/public/assets/brand/thumbgate-mark.svg +15 -0
  38. package/public/assets/brand/thumbgate-wordmark.svg +20 -0
  39. package/public/assets/claude-thumbgate-statusbar.svg +8 -0
  40. package/public/assets/codex-thumbgate-statusbar-test.svg +9 -0
  41. package/public/assets/legal-intake-control-flow.svg +66 -0
  42. package/public/blog.html +1 -1
  43. package/public/brand/thumbgate-mark.svg +15 -0
  44. package/public/brand/thumbgate-og.svg +16 -0
  45. package/public/codex-enterprise.html +1 -1
  46. package/public/codex-plugin.html +1 -1
  47. package/public/compare.html +23 -3
  48. package/public/dashboard.html +312 -30
  49. package/public/federal.html +1 -1
  50. package/public/guide.html +5 -4
  51. package/public/index.html +167 -49
  52. package/public/js/buyer-intent.js +672 -0
  53. package/public/learn.html +74 -7
  54. package/public/lessons.html +2 -1
  55. package/public/numbers.html +3 -3
  56. package/public/pricing.html +63 -15
  57. package/public/pro.html +7 -7
  58. package/scripts/activation-quickstart.js +187 -0
  59. package/scripts/agent-memory-lifecycle.js +211 -0
  60. package/scripts/async-eval-observability.js +236 -0
  61. package/scripts/auto-promote-gates.js +75 -4
  62. package/scripts/build-metadata.js +24 -3
  63. package/scripts/cli-schema.js +22 -0
  64. package/scripts/dashboard-chat.js +2 -1
  65. package/scripts/dashboard.js +8 -0
  66. package/scripts/export-databricks-bundle.js +5 -1
  67. package/scripts/export-dpo-pairs.js +7 -2
  68. package/scripts/feedback-aggregate.js +281 -0
  69. package/scripts/feedback-loop.js +34 -0
  70. package/scripts/filesystem-search.js +35 -10
  71. package/scripts/gates-engine.js +198 -6
  72. package/scripts/gemini-embedding-policy.js +2 -1
  73. package/scripts/hook-stop-anti-claim.js +227 -0
  74. package/scripts/hook-thumbgate-cache-updater.js +18 -2
  75. package/scripts/lesson-inference.js +8 -3
  76. package/scripts/lesson-search.js +17 -1
  77. package/scripts/operational-integrity.js +39 -5
  78. package/scripts/plausible-domain-config.js +4 -2
  79. package/scripts/rate-limiter.js +12 -6
  80. package/scripts/secret-redaction.js +166 -0
  81. package/scripts/security-scanner.js +100 -0
  82. package/scripts/self-distill-agent.js +3 -1
  83. package/scripts/self-harness-optimizer.js +141 -0
  84. package/scripts/seo-gsd.js +635 -0
  85. package/scripts/statusline-cache-path.js +17 -2
  86. package/scripts/statusline-cache-read.js +57 -0
  87. package/scripts/statusline-local-stats.js +9 -1
  88. package/scripts/statusline-meta.js +5 -2
  89. package/scripts/statusline.sh +13 -1
  90. package/scripts/sync-telemetry-from-prod.js +374 -0
  91. package/scripts/telemetry-analytics.js +9 -0
  92. package/scripts/thumbgate-search.js +85 -19
  93. package/scripts/tool-contract-validator.js +76 -0
  94. package/scripts/vector-store.js +44 -0
  95. package/scripts/workspace-evolver.js +62 -2
  96. package/src/api/server.js +715 -86
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: thumbgate-blocked
3
+ description: Show what ThumbGate has actually blocked — gate enforcement stats and the full enforcement matrix. Use for "what has ThumbGate blocked", "show gate stats", "is enforcement working", "how many tokens did we save", "enforcement matrix".
4
+ allowed-tools: mcp__thumbgate__gate_stats, mcp__thumbgate__enforcement_matrix, Bash(npx thumbgate gate-stats:*)
5
+ ---
6
+
7
+ # ThumbGate Blocked
8
+
9
+ Show the enforcement record: how many risky actions were blocked vs warned, which gates fire most, and the full feedback → check → rejection pipeline.
10
+
11
+ This command wraps existing ThumbGate capability — **no new logic**. It reads the live enforcement counters.
12
+
13
+ ## Steps
14
+
15
+ 1. Call the `gate_stats` MCP tool for the headline numbers: blocked count, warned count, and the top gates by hits. (CLI fallback: `npx thumbgate gate-stats`.)
16
+ 2. Call the `enforcement_matrix` MCP tool for the full picture: feedback pipeline stats, active pre-action checks, and the rejection ledger with revival conditions.
17
+ 3. Summarize for the user:
18
+ - Total blocks (each block = a repeat mistake stopped before it spent tokens or did damage).
19
+ - Most-triggered gates.
20
+ - Anything in the rejection ledger that is close to revival.
21
+ 4. If counts are all zero, note that enforcement is wired but hasn't fired yet, and point to `/thumbgate-guard` to promote a rule.
22
+
23
+ ## Example
24
+
25
+ ```
26
+ /thumbgate-blocked
27
+ ```
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: thumbgate-doctor
3
+ description: Health-check the ThumbGate wiring for this project — hooks, MCP server, and agent-readiness — and report what's broken. Use for "is ThumbGate wired up", "thumbgate doctor", "check my guardrails are installed", "why aren't my gates firing", "agent readiness".
4
+ allowed-tools: Bash(npx thumbgate doctor:*), mcp__thumbgate__check_operational_integrity
5
+ ---
6
+
7
+ # ThumbGate Doctor
8
+
9
+ Audit whether ThumbGate is actually wired into this agent: PreToolUse / SessionStart hooks installed, MCP server reachable, lesson store present, and overall agent-readiness — then tell the user exactly what to fix.
10
+
11
+ This command wraps existing ThumbGate capability — **no new logic**. It runs the existing doctor + integrity checks.
12
+
13
+ ## Steps
14
+
15
+ 1. Run the existing wiring/health audit:
16
+ ```bash
17
+ npx thumbgate doctor
18
+ ```
19
+ (Add `--json` for a machine-readable report.) It exits non-zero when the project is not `ready`.
20
+ 2. For deeper runtime state, call the `check_operational_integrity` MCP tool to verify the server-side enforcement path is live, not just the local config.
21
+ 3. Summarize:
22
+ - ✅ what's wired (hooks, MCP, store, statusline).
23
+ - ❌ what's missing, with the exact fix command (usually `npx thumbgate init`).
24
+ 4. If everything is green, say so plainly with the readiness status; if not, lead with the single highest-impact fix.
25
+
26
+ ## Example
27
+
28
+ ```
29
+ /thumbgate-doctor
30
+ ```
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: thumbgate-guard
3
+ description: Turn the last agent mistake into a hard prevention rule the agent cannot bypass. Use after a bad tool call, a wrong action, or a thumbs-down — "guard against this", "block this from happening again", "never do that again", "promote this to a rule".
4
+ allowed-tools: mcp__thumbgate__capture_feedback, Bash(npx thumbgate force-gate:*), Bash(npx thumbgate quickstart:*)
5
+ ---
6
+
7
+ # ThumbGate Guard
8
+
9
+ Capture the mistake the agent just made and promote it into a Pre-Action Check (a `block` gate) so the same tool-call shape is intercepted before it runs again — in this and every future session, across Claude Code, Cursor, Codex, Gemini, Amp, and Cline.
10
+
11
+ This command wraps existing ThumbGate capability. It adds **no new logic** — it routes to the real capture + force-promote path.
12
+
13
+ ## Steps
14
+
15
+ 1. Identify the specific bad action from the recent conversation (e.g. `git push --force origin main`, `DROP TABLE users`, deploy without tests). State it in one sentence.
16
+ 2. Record the signal with the `capture_feedback` MCP tool:
17
+ - `signal: "down"`
18
+ - `context`: one sentence describing what went wrong
19
+ - `whatWentWrong`: the concrete failure
20
+ - `whatToChange`: the prevention action
21
+ - `tags`: the domain (e.g. `git`, `database`, `deploy`)
22
+ - If the user only gave a vague signal, pass the recent turns through `conversationWindow` / `chatHistory` for history-aware distillation instead of refusing.
23
+ 3. Promote it to an enforced block gate using the existing force-promote path:
24
+ ```bash
25
+ npx thumbgate force-gate "<one-sentence context of the mistake>"
26
+ ```
27
+ This prints the new `gateId` and the total active gate count.
28
+ 4. Show the user the promoted rule and confirm it is now enforced as a PreToolUse block.
29
+
30
+ > First rule of the project and want the guided walkthrough (capture → promote → watch it block once)? Run `npx thumbgate quickstart` instead.
31
+
32
+ ## Example
33
+
34
+ ```
35
+ /thumbgate-guard the agent force-pushed to main and overwrote a teammate's commit
36
+ ```
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: thumbgate-protect
3
+ description: Show this repo's branch/release governance and grant a scoped, time-limited approval for an action that touches protected files. Use for "protect this branch", "is main protected", "approve this protected change", "branch governance", "let me edit a protected file".
4
+ allowed-tools: mcp__thumbgate__get_branch_governance, mcp__thumbgate__approve_protected_action
5
+ ---
6
+
7
+ # ThumbGate Protect
8
+
9
+ Inspect the protected-action posture for this project and, when the user explicitly approves, grant a scoped, expiring exception so a protected-file edit or publish can proceed under audit.
10
+
11
+ This command wraps existing ThumbGate capability — **no new logic**. It reads governance state and records a time-boxed approval.
12
+
13
+ ## Steps
14
+
15
+ 1. Read the current posture with the `get_branch_governance` MCP tool: which branches are protected, release rules, and the protected-file globs in effect.
16
+ 2. Report it plainly: what is protected, and what the agent is currently blocked from touching without approval.
17
+ 3. **Only if the user explicitly asks to proceed**, grant a scoped approval with `approve_protected_action`:
18
+ - `pathGlobs`: the smallest set of protected globs the action needs.
19
+ - `reason`: why this is approved (one sentence).
20
+ - `evidence`: supporting note (tests passing, owner sign-off, etc.) when available.
21
+ - `ttlMs`: keep it short — default is 1 hour, never exceed what the task needs.
22
+ 4. Confirm the approval id, covered globs, and expiry. Approvals are deliberately temporary and audited; re-run for the next task.
23
+
24
+ > This is for granting *narrow, temporary* exceptions, not for disabling protection. Never use it to bypass branch governance wholesale.
25
+
26
+ ## Example
27
+
28
+ ```
29
+ /thumbgate-protect
30
+ ```
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: thumbgate-rules
3
+ description: List the active prevention rules and learned lessons guarding this project. Use to answer "what is ThumbGate protecting me from", "show my gates/rules", "what has the agent learned", "what's blocked here".
4
+ allowed-tools: mcp__thumbgate__prevention_rules, mcp__thumbgate__get_reliability_rules, mcp__thumbgate__search_lessons, Bash(npx thumbgate rules:*)
5
+ ---
6
+
7
+ # ThumbGate Rules
8
+
9
+ Show the guardrails currently in force for this project: the auto-promoted prevention rules, the reliability rules, and the promoted lessons behind them.
10
+
11
+ This command wraps existing ThumbGate capability — **no new logic**. It reads the live rule + lesson stores.
12
+
13
+ ## Steps
14
+
15
+ 1. List the active prevention rules with the `prevention_rules` MCP tool (or the CLI fallback `npx thumbgate rules`).
16
+ 2. Pull the reliability rules with `get_reliability_rules` to show which tool-call shapes are gated.
17
+ 3. For each rule, surface the lesson it came from with `search_lessons` so the user sees *why* the rule exists, not just *what* it blocks.
18
+ 4. Present a compact table:
19
+
20
+ | Rule / Gate | Blocks | From lesson | State |
21
+ |-------------|--------|-------------|-------|
22
+ | … | … | … | active / archived |
23
+
24
+ 5. If there are zero active rules, point the user to `/thumbgate-guard` to promote their first one.
25
+
26
+ ## Example
27
+
28
+ ```
29
+ /thumbgate-rules
30
+ ```
@@ -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.27.6",
4
+ "version": "1.27.7",
5
5
  "author": {
6
6
  "name": "Igor Ganapolsky",
7
7
  "email": "ig5973700@gmail.com",
@@ -15,6 +15,7 @@
15
15
  - CLAUDE.md and .cursorrules files are suggestions agents can ignore
16
16
  - No memory between sessions means no learning from corrections
17
17
  - Teams have no shared safety rules across developers
18
+ - AI crawlers and agents create machine traffic without proving buyer intent; teams need AI-discoverable proof plus runtime gates before internal agents act
18
19
 
19
20
  ## How it works
20
21
 
@@ -51,9 +52,9 @@ npx thumbgate init --agent claude-code
51
52
  - ChatGPT App / GPT Action: https://thumbgate.ai/chatgpt-app
52
53
  - Free GPT: advice, checkpointing, and setup help in ChatGPT
53
54
  - Codex Plugin: https://thumbgate.ai/codex-plugin
54
- - Free local CLI: 5 captures/day, 25 total captures, up to 3 active auto-promoted prevention rules, and local Pre-Action Checks after install (recall and lesson search are Pro-only)
55
+ - Free local CLI: 2 captures/day, 10 total captures, up to 3 active auto-promoted prevention rules, and local Pre-Action Checks after install (recall and lesson search are Pro-only)
55
56
  - Pro: $19/mo or $149/yr — personal enforcement proof, local dashboard, check debugger, DPO export, synced lessons/rules across machines, and review-ready exports
56
- - Team: $49/seat/mo, 3-seat minimum after intake — shared lessons, org visibility, approval boundaries, and rollout proof
57
+ - Enterprise: custom pricing, scoped after intake — shared hosted lesson database, org-wide dashboard, GCP/DFCX guardrails, VPC gating, and white-glove workflow hardening sprints
57
58
 
58
59
  ## Links
59
60
 
@@ -63,6 +64,9 @@ npx thumbgate init --agent claude-code
63
64
  - Agent discovery: https://thumbgate.ai/.well-known/mcp.json
64
65
  - Progressive tool index: https://thumbgate.ai/.well-known/mcp/tools.json
65
66
  - Context footprint report: https://thumbgate.ai/.well-known/mcp/footprint.json
67
+ - Headroom context compression guardrails: https://thumbgate.ai/guides/headroom-context-compression-guardrails
68
+ - Sovereign coding model guardrails: https://thumbgate.ai/guides/sovereign-coding-model-guardrails
69
+ - Agentic web governance: https://thumbgate.ai/guides/agentic-web-governance
66
70
  - AI Mode ads and agent governance: https://thumbgate.ai/guides/ai-mode-ads-agent-governance
67
71
  - MCP tool governance: https://thumbgate.ai/guides/mcp-tool-governance
68
72
  - AI agent pre-action approval gates: https://thumbgate.ai/guides/ai-agent-pre-action-approval-gates
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.27.6",
3
+ "version": "1.27.7",
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
@@ -12,6 +12,10 @@ ThumbGate is the local-first firewall for AI coding agents. It runs in the PreTo
12
12
 
13
13
  The product is a self-improving enforcement layer: thumbs-down feedback, prompt evaluation, and proof from prior runs become prevention rules that permanently stop repeated failures before the next tool call.
14
14
 
15
+ <p align="center">
16
+ <img src="docs/media/thumbgate-demo.gif" alt="ThumbGate blocking an AI agent's dangerous commands (rm -rf, force-push, chmod 777) in real time, while letting safe commands through" width="820" />
17
+ </p>
18
+
15
19
  ```
16
20
  Agent tries: rm -rf tests/
17
21
  ThumbGate: ⛔ BLOCKED — "Never delete test directories"
@@ -24,7 +28,7 @@ The product is a self-improving enforcement layer: thumbs-down feedback, prompt
24
28
  npx thumbgate init # auto-detects your agent, wires hooks, 30 seconds
25
29
  ```
26
30
 
27
- Works with **Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode** and any MCP-compatible agent. Free tier: 5 feedback captures/day (25 total) and up to 3 active auto-promoted prevention rules. [Pro: $19/mo or $149/yr](https://thumbgate.ai/checkout/pro?utm_source=github&utm_medium=readme) — unlimited rules, history-aware lessons, feedback sessions, dashboard, DPO export. Enterprise (custom pricing, scoped after intake) adds a shared hosted lesson DB, org dashboard, and shared org-wide enforcement.
31
+ Works with **Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode** and any MCP-compatible agent. Free tier: 2 feedback captures/day (10 total) and up to 3 active auto-promoted prevention rules. [Pro: $19/mo or $149/yr](https://thumbgate.ai/checkout/pro?utm_source=github&utm_medium=readme) — unlimited rules, history-aware lessons, feedback sessions, dashboard, DPO export. Enterprise (custom pricing, scoped after intake) adds a shared hosted lesson DB, org dashboard, and shared org-wide enforcement.
28
32
 
29
33
  [![CI](https://github.com/IgorGanapolsky/ThumbGate/actions/workflows/ci.yml/badge.svg)](https://github.com/IgorGanapolsky/ThumbGate/actions/workflows/ci.yml)
30
34
  [![npm](https://img.shields.io/npm/v/thumbgate)](https://www.npmjs.com/package/thumbgate)
@@ -53,6 +57,24 @@ In that stack, ThumbGate is the pre-action gate between generated intent and exe
53
57
 
54
58
  ---
55
59
 
60
+ ## Discoverable slash-commands — the guardrail layer for spec-driven agents
61
+
62
+ Spec-driven agent frameworks like **GSD** (get-shit-done) and **GitHub Spec Kit** are great at *planning and generating* work — they expose dozens of discoverable `/gsd-*` / `/specify` commands in the agent command palette. ThumbGate is the **guardrail layer for spec-driven agents**: it sits *after* the plan, on the boundary between a generated tool call and its execution. It works **alongside GSD / Spec-Kit, not instead of them** — they decide *what* to build; ThumbGate enforces *what the agent must never do while building it*.
63
+
64
+ `npx thumbgate init` installs these commands into your agent's palette (`.claude/commands/`, `.gemini/commands/`, `.antigravitycli/commands/`) so the enforcement layer is as browsable as the planning layer:
65
+
66
+ | Command | What it does | Wraps (existing capability) |
67
+ |---------|--------------|------------------------------|
68
+ | `/thumbgate-guard` | Turn the last agent mistake into a hard prevention rule | `capture_feedback` + `thumbgate force-gate` |
69
+ | `/thumbgate-rules` | List the active prevention rules + lessons guarding this repo | `prevention_rules`, `get_reliability_rules`, `search_lessons` |
70
+ | `/thumbgate-blocked` | Show what's actually been blocked — gate stats + enforcement matrix | `gate_stats`, `enforcement_matrix` |
71
+ | `/thumbgate-protect` | Show branch/release governance; grant a scoped, expiring approval | `get_branch_governance`, `approve_protected_action` |
72
+ | `/thumbgate-doctor` | Health-check the wiring (hooks, MCP, agent-readiness) | `thumbgate doctor` |
73
+
74
+ Each is a thin wrapper over an existing MCP tool or CLI command — **no new enforcement logic, just discoverability**.
75
+
76
+ ---
77
+
56
78
  ## 🎬 90-second demo
57
79
 
58
80
  Watch the force-push scenario: agent tries to `git push --force`, one thumbs-down, next session it's blocked — zero tokens spent on the repeat.
@@ -185,6 +207,26 @@ Hand-rolled hooks are the right tool for a small, static denylist you maintain b
185
207
 
186
208
  Prompt engineering still matters, but it is only the starting point. ThumbGate adds prompt evaluation on top: proof lanes, benchmarks, and self-heal checks tell you whether your prompt and workflow actually held up under execution instead of leaving you to guess from vibes. Run `npx thumbgate eval --from-feedback --write-report=.thumbgate/prompt-eval-proof.md` to turn real thumbs-up/down feedback into reusable eval cases and a buyer-ready proof report.
187
209
 
210
+ ### Retrieval & latency: local-first, zero network hops
211
+
212
+ ThumbGate's latency advantage is structural, not a tuned cloud cluster: there is no retrieval service and no model on the enforcement path, so the gate decision never leaves your machine.
213
+
214
+ ```mermaid
215
+ flowchart LR
216
+ A["Agent about to run<br/>a tool call"] --> B{"Literal / AST match<br/>on an active rule?"}
217
+ B -- "exact match" --> D["Deterministic gate decision<br/>(no model, on-device)"]
218
+ B -- "no exact match, but<br/>semantically near a<br/>blocked pattern" --> C["Local CPU embeddings<br/>bge-small via LanceDB<br/>(no external API)"]
219
+ C --> D
220
+ D -- "known-bad" --> E["⛔ BLOCK before execution"]
221
+ D -- "safe" --> F["✓ Allow"]
222
+ ```
223
+
224
+ - **Deterministic first.** Most decisions are a literal or AST pattern match against your active rules — sub-millisecond, on-device, no embeddings.
225
+ - **Local semantic fallback.** When an action isn't on the literal block list but is semantically near one you've blocked before, ThumbGate searches the rule corpus with CPU-only `bge-small` embeddings via LanceDB — still local, still no external API call.
226
+ - **No LLM on the enforcement path.** The gate never calls a model to decide block/allow. Thompson Sampling only tunes soft-rule confidence weights; hard rules always fire deterministically (see Layer 2).
227
+
228
+ The fastest network round-trip is the one you never make: enforcement is fully local, so it adds negligible latency to the agent loop — no cloud retrieval, no inference hop, no data leaving the machine.
229
+
188
230
  ### Managed model benchmark lane
189
231
 
190
232
  When a new managed model drops, do not swap ThumbGate over on vendor claims alone. Rank it against the actual ThumbGate workload first:
@@ -342,6 +384,8 @@ npx thumbgate model-candidates --workload=dashboard-analysis --provider=openai -
342
384
  npx thumbgate native-messaging-audit # inspect local browser bridges and extension hosts
343
385
  npx thumbgate dashboard --open # open local project-scoped dashboard in browser
344
386
  thumbgate-dashboard # standalone browser dashboard shortcut (run '/project:thumbgate-dashboard' in Claude/Grok)
387
+ npx thumbgate check-update # check if a new version is available on npm/GitHub
388
+ npx thumbgate self-update # update ThumbGate to the latest version globally
345
389
  npx thumbgate serve # start MCP server on stdio
346
390
  npx thumbgate bench # run reliability benchmark
347
391
  npx thumbgate bench --programbench-smoke # include cleanroom whole-repo proof lane
@@ -382,7 +426,7 @@ If you change MCP or hook settings, restart the affected agent session so Claude
382
426
  | | Free | Pro ($19/mo) | Enterprise |
383
427
  |---|---|---|---|
384
428
  | Local CLI + enforced checks | ✅ | ✅ | ✅ |
385
- | Feedback captures | 5/day (25 total) | Unlimited | Unlimited |
429
+ | Feedback captures | 2/day (10 total) | Unlimited | Unlimited |
386
430
  | Active auto-promoted prevention rules | 3 | Unlimited | Unlimited |
387
431
  | MCP agent integrations | All | All | All |
388
432
  | Personal dashboard | — | ✅ | ✅ |
@@ -396,7 +440,7 @@ If you change MCP or hook settings, restart the affected agent session so Claude
396
440
  | Compliance audit export | — | — | ✅ |
397
441
  | Dedicated onboarding + SLA | — | — | ✅ |
398
442
 
399
- The free tier gives you 5 feedback captures/day (25 total) and up to 3 active auto-promoted prevention rules — enough to make ThumbGate part of your daily flow before you upgrade. MCP integrations for all agents (Claude Code, Cursor, Codex, Gemini, Amp, Cline, OpenCode) ship free.
443
+ The free tier gives you 2 feedback captures/day (10 total) and up to 3 active auto-promoted prevention rules — enough to make ThumbGate part of your daily flow before you upgrade. MCP integrations for all agents (Claude Code, Cursor, Codex, Gemini, Amp, Cline, OpenCode) ship free.
400
444
 
401
445
  Pro ($19/mo or $149/yr) removes the rule cap and adds history-aware lesson recall, lesson search, DPO export, and a personal dashboard. Enterprise (custom pricing, scoped after intake) adds a shared hosted lesson DB, org dashboard, and shared enforcement across the org, plus regulatory gate templates (legal intake, financial compliance, healthcare), custom policy layers scoped to firm/practice-area, compliance audit export, and dedicated onboarding with SLA.
402
446
 
@@ -487,7 +531,7 @@ curl -X POST http://localhost:3456/v1/dpo/export \
487
531
  | Layer | Technology |
488
532
  |-------|-----------|
489
533
  | **Storage** | SQLite + FTS5, LanceDB vectors, JSONL logs |
490
- | **Capture** | 5/day, 25 total on Free; unlimited on Pro, Team, and Enterprise |
534
+ | **Capture** | 2/day, 10 total on Free; unlimited on Pro, Team, and Enterprise |
491
535
  | **Intelligence** | MemAlign dual recall, Thompson Sampling |
492
536
  | **Enforcement** | PreToolUse hook engine, Checks config |
493
537
  | **Interfaces** | MCP stdio, HTTP API, CLI (Node.js >=18) |
@@ -575,7 +619,7 @@ Those are suggestions the agent can ignore. ThumbGate checks are enforced — th
575
619
  If it supports MCP or pre-action hooks, yes. Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode all work out of the box.
576
620
 
577
621
  **Is it free?**
578
- The free tier gives you 5 feedback captures/day, 25 total captures, and up to 3 active auto-promoted prevention rules — enough for solo devs to prove a blocked repeat before upgrading. MCP integrations ship free for every agent.
622
+ The free tier gives you 2 feedback captures/day, 10 total captures, and up to 3 active auto-promoted prevention rules — enough for solo devs to prove a blocked repeat before upgrading. MCP integrations ship free for every agent.
579
623
 
580
624
  Pro ($19/mo or $149/yr) removes the rule cap and adds history-aware lesson recall, lesson search, and a personal dashboard. Enterprise (custom pricing, scoped after intake) adds a shared hosted lesson DB, org dashboard, and shared enforcement.
581
625
 
@@ -2,13 +2,13 @@
2
2
  "mcpServers": {
3
3
  "thumbgate": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "thumbgate@1.27.6", "thumbgate", "serve"]
5
+ "args": ["--yes", "--package", "thumbgate@1.27.7", "thumbgate", "serve"]
6
6
  }
7
7
  },
8
8
  "hooks": {
9
9
  "preToolUse": {
10
10
  "command": "npx",
11
- "args": ["--yes", "--package", "thumbgate@1.27.6", "thumbgate", "gate-check"]
11
+ "args": ["--yes", "--package", "thumbgate@1.27.7", "thumbgate", "gate-check"]
12
12
  }
13
13
  }
14
14
  }
@@ -0,0 +1,41 @@
1
+ # Letta Adapter
2
+
3
+ Letta is a stateful-agent runtime with persistent memory, MCP tools, custom server tools, and client-side tool execution. ThumbGate should not compete with that memory surface. ThumbGate should sit underneath it as the deterministic local enforcement layer.
4
+
5
+ ## Integration Pattern
6
+
7
+ Use `thumbgate-letta-adapter.js` to wrap Letta tool execution:
8
+
9
+ 1. Letta agent proposes a tool call.
10
+ 2. The wrapper normalizes the Letta event into ThumbGate's provider-action schema.
11
+ 3. Your app calls ThumbGate's local gate-check transport.
12
+ 4. If ThumbGate blocks or requires approval, the tool executor is never called.
13
+ 5. If allowed, the original Letta tool executes normally.
14
+
15
+ This works for the two practical Letta surfaces:
16
+
17
+ - **MCP tools**: Letta forwards the tool call through the Letta server to an MCP server. Wrap the forwarding boundary or expose the downstream tool through a ThumbGate-guarded MCP server.
18
+ - **Client tools**: Letta asks your client application to execute a tool locally. Wrap the client tool handler with `createLettaToolGuard`.
19
+
20
+ ## Example
21
+
22
+ ```js
23
+ const { createLettaToolGuard } = require('./thumbgate-letta-adapter');
24
+
25
+ const guardedTool = createLettaToolGuard({
26
+ gateCheck: async (normalizedAction) => thumbgateGateCheck(normalizedAction),
27
+ executeTool: async (lettaEvent) => runOriginalTool(lettaEvent),
28
+ });
29
+
30
+ await guardedTool({
31
+ agentId: 'agent-123',
32
+ clientTool: {
33
+ name: 'shell',
34
+ input: { command: 'git push --force origin main' },
35
+ },
36
+ });
37
+ ```
38
+
39
+ ## Positioning
40
+
41
+ Letta helps agents remember and operate with state. ThumbGate helps teams decide what those agents are allowed to do next. The moat is adapter coverage: ThumbGate works under memory-first runtimes instead of asking buyers to replace them.
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { normalizeProviderAction } = require('../../scripts/provider-action-normalizer');
5
+
6
+ function asObject(value) {
7
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
8
+ }
9
+
10
+ function firstString(...values) {
11
+ for (const value of values) {
12
+ const text = String(value || '').trim();
13
+ if (text) return text;
14
+ }
15
+ return '';
16
+ }
17
+
18
+ function extractLettaToolCall(input = {}) {
19
+ const event = asObject(input);
20
+ const toolCall = asObject(event.toolCall || event.tool_call || event.lettaToolCall);
21
+ const functionCall = asObject(toolCall.function || event.function);
22
+ const mcp = asObject(event.mcp || event.mcpToolCall);
23
+ const clientTool = asObject(event.clientTool || event.client_tool);
24
+ const params = asObject(event.params);
25
+
26
+ const name = firstString(
27
+ event.toolName,
28
+ event.name,
29
+ toolCall.name,
30
+ functionCall.name,
31
+ clientTool.name,
32
+ mcp.name,
33
+ params.name
34
+ );
35
+ const args = asObject(
36
+ event.arguments
37
+ || event.args
38
+ || event.input
39
+ || toolCall.arguments
40
+ || toolCall.input
41
+ || functionCall.arguments
42
+ || clientTool.arguments
43
+ || clientTool.input
44
+ || mcp.arguments
45
+ || params.arguments
46
+ );
47
+
48
+ return {
49
+ id: firstString(event.id, event.toolCallId, event.tool_call_id, toolCall.id, clientTool.id),
50
+ name,
51
+ arguments: args,
52
+ server: firstString(event.mcpServer, mcp.server, params.server),
53
+ surface: firstString(event.surface, event.executionSurface, clientTool.name ? 'client-tool' : mcp.name || params.name ? 'mcp-tool' : 'server-tool'),
54
+ };
55
+ }
56
+
57
+ function normalizeLettaAction(input = {}) {
58
+ const event = asObject(input);
59
+ const toolCall = extractLettaToolCall(event);
60
+
61
+ const normalized = normalizeProviderAction({
62
+ ...event,
63
+ provider: 'letta',
64
+ toolCall: {
65
+ id: toolCall.id,
66
+ name: toolCall.name,
67
+ input: toolCall.arguments,
68
+ },
69
+ toolName: toolCall.name,
70
+ input: toolCall.arguments,
71
+ mcpServer: toolCall.server,
72
+ });
73
+
74
+ return {
75
+ ...normalized,
76
+ provider: 'letta',
77
+ agentRuntime: 'letta',
78
+ letta: {
79
+ agentId: firstString(event.agentId, event.agent_id),
80
+ messageId: firstString(event.messageId, event.message_id),
81
+ surface: toolCall.surface,
82
+ toolCallId: toolCall.id,
83
+ },
84
+ };
85
+ }
86
+
87
+ function normalizeGateDecision(decision = {}) {
88
+ const value = asObject(decision);
89
+ const raw = firstString(value.decision, value.mode, value.action, value.status).toLowerCase();
90
+ const blocked = value.allowed === false
91
+ || value.accepted === false
92
+ || value.blocked === true
93
+ || ['block', 'deny', 'denied', 'reject', 'rejected'].includes(raw);
94
+ const approvalRequired = value.requiresApproval === true || raw === 'approve';
95
+ return {
96
+ allowed: !blocked && !approvalRequired,
97
+ blocked,
98
+ approvalRequired,
99
+ reason: firstString(value.reason, value.message, Array.isArray(value.reasons) ? value.reasons.join('; ') : ''),
100
+ raw: value,
101
+ };
102
+ }
103
+
104
+ function createLettaToolGuard({ gateCheck, executeTool, onDecision } = {}) {
105
+ if (typeof gateCheck !== 'function') {
106
+ throw new TypeError('createLettaToolGuard requires a gateCheck function');
107
+ }
108
+ if (typeof executeTool !== 'function') {
109
+ throw new TypeError('createLettaToolGuard requires an executeTool function');
110
+ }
111
+
112
+ return async function guardedLettaTool(input = {}) {
113
+ const normalizedAction = normalizeLettaAction(input);
114
+ const decision = normalizeGateDecision(await gateCheck(normalizedAction));
115
+ if (typeof onDecision === 'function') {
116
+ await onDecision({ normalizedAction, decision });
117
+ }
118
+ if (!decision.allowed) {
119
+ const error = new Error(decision.reason || 'ThumbGate blocked this Letta tool call before execution.');
120
+ error.code = decision.approvalRequired ? 'THUMBGATE_APPROVAL_REQUIRED' : 'THUMBGATE_BLOCKED';
121
+ error.thumbgate = { normalizedAction, decision };
122
+ throw error;
123
+ }
124
+ return executeTool(input, { normalizedAction, decision });
125
+ };
126
+ }
127
+
128
+ module.exports = {
129
+ createLettaToolGuard,
130
+ extractLettaToolCall,
131
+ normalizeGateDecision,
132
+ normalizeLettaAction,
133
+ };
@@ -231,7 +231,7 @@ const {
231
231
  finalizeSession: finalizeFeedbackSession,
232
232
  } = require('../../scripts/feedback-session');
233
233
 
234
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.27.6' };
234
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.27.7' };
235
235
  const COMMERCE_CATEGORIES = [
236
236
  'product_recommendation',
237
237
  'brand_compliance',
@@ -674,6 +674,21 @@ function buildEstimateUncertaintyResponse(args = {}) {
674
674
 
675
675
  async function callTool(name, args = {}) {
676
676
  assertToolAllowed(name, getActiveMcpProfile());
677
+
678
+ // Validate tool input contract against schema
679
+ const { TOOLS } = require('../../scripts/tool-registry');
680
+ const toolDef = TOOLS.find(t => t.name === name);
681
+ if (toolDef && toolDef.inputSchema) {
682
+ const { validateToolContract } = require('../../scripts/tool-contract-validator');
683
+ const validation = validateToolContract(toolDef.inputSchema, args);
684
+ if (!validation.valid) {
685
+ const err = new Error(`Tool contract violation on '${name}': ${validation.errors.join('; ')}`);
686
+ err.errorCategory = 'contract';
687
+ err.isRetryable = false;
688
+ throw err;
689
+ }
690
+ }
691
+
677
692
  if (name !== 'workflow_sentinel' && process.env.THUMBGATE_DISABLE_MCP_FIREWALL !== '1') {
678
693
  const firewallResult = (await evaluateGatesAsync(name, args)) || evaluateSecretGuard({ tool_name: name, tool_input: args });
679
694
  if (firewallResult && firewallResult.decision === 'deny') {
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.27.6",
10
+ "thumbgate@1.27.7",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const DEFAULT_ENDPOINT = 'https://api.oraclestechnologies.com/v1/guardian/analyze';
5
+
6
+ function requireApiKey(env = process.env) {
7
+ const key = env.ETHICORE_API_KEY || env.GUARDIAN_API_KEY || env.ORACLES_GUARDIAN_API_KEY;
8
+ if (!key) {
9
+ throw new Error('ETHICORE_API_KEY env var is required');
10
+ }
11
+ return key;
12
+ }
13
+
14
+ async function analyzeText(text, options = {}) {
15
+ if (!String(text || '').trim()) {
16
+ throw new Error('analyzeText requires text');
17
+ }
18
+
19
+ const env = options.env || process.env;
20
+ const endpoint = options.endpoint || env.ETHICORE_GUARDIAN_ENDPOINT || DEFAULT_ENDPOINT;
21
+ const apiKey = options.apiKey || requireApiKey(env);
22
+ const fetchImpl = options.fetch || fetch;
23
+
24
+ const response = await fetchImpl(endpoint, {
25
+ method: 'POST',
26
+ headers: {
27
+ Authorization: `Bearer ${apiKey}`,
28
+ 'Content-Type': 'application/json',
29
+ },
30
+ body: JSON.stringify({ text }),
31
+ });
32
+
33
+ const bodyText = await response.text();
34
+ let body = bodyText;
35
+ try {
36
+ body = bodyText ? JSON.parse(bodyText) : {};
37
+ } catch {
38
+ // Keep non-JSON body for diagnostics.
39
+ }
40
+
41
+ if (!response.ok) {
42
+ throw new Error(`Ethicore Guardian API ${response.status}: ${typeof body === 'string' ? body : JSON.stringify(body)}`);
43
+ }
44
+
45
+ return body;
46
+ }
47
+
48
+ function createEthicorePolicyCheck(options = {}) {
49
+ return async function ethicorePolicyCheck(action = {}) {
50
+ const toolText = [
51
+ action.toolName,
52
+ action.actionType,
53
+ action.command,
54
+ action.path,
55
+ action.url,
56
+ action.input ? JSON.stringify(action.input) : '',
57
+ ].filter(Boolean).join('\n');
58
+
59
+ return analyzeText(toolText || JSON.stringify(action), options);
60
+ };
61
+ }
62
+
63
+ module.exports = {
64
+ DEFAULT_ENDPOINT,
65
+ analyzeText,
66
+ createEthicorePolicyCheck,
67
+ requireApiKey,
68
+ };