thumbgate 1.27.9 → 1.27.11
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/README.md +4 -0
- package/config/gate-templates.json +228 -0
- package/config/gates/claim-verification.json +18 -0
- package/package.json +3 -3
- package/public/index.html +180 -0
- package/public/learn/agent-identity-connector-governance.html +146 -0
- package/public/learn/anthropomorphic-claim-gates.html +180 -0
- package/public/learn.html +28 -0
- package/scripts/gate-stats.js +11 -5
- package/scripts/hook-stop-anti-claim.js +369 -0
- package/scripts/tool-registry.js +2 -2
- package/src/api/server.js +2 -0
package/README.md
CHANGED
|
@@ -16,6 +16,10 @@ The product is a self-improving enforcement layer: thumbs-down feedback, prompt
|
|
|
16
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
17
|
</p>
|
|
18
18
|
|
|
19
|
+
<p align="center">
|
|
20
|
+
<img src="docs/diagrams/pre-action-gate-loop.svg" alt="ThumbGate pre-action gate loop: agent intent, PreToolUse gate, block or allow with audit receipt" width="920" />
|
|
21
|
+
</p>
|
|
22
|
+
|
|
19
23
|
```
|
|
20
24
|
Agent tries: rm -rf tests/
|
|
21
25
|
ThumbGate: ⛔ BLOCKED — "Never delete test directories"
|
|
@@ -37,6 +37,18 @@
|
|
|
37
37
|
"roi": "Raises trust in autonomous runs and reduces manual re-checking.",
|
|
38
38
|
"rollout": "Use for every workflow where proof matters more than speed."
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
"id": "block-empty-positive-feedback-closeout",
|
|
42
|
+
"name": "Block empty closeouts after positive feedback",
|
|
43
|
+
"category": "Agent Honesty",
|
|
44
|
+
"signal": "👍",
|
|
45
|
+
"defaultAction": "block",
|
|
46
|
+
"severity": "medium",
|
|
47
|
+
"pattern": "positive_feedback_followed_by_low_value_social_closeout",
|
|
48
|
+
"problem": "Prevents agents from treating thumbs-up or thanks as permission to send filler instead of staying quiet, showing a compact evidence checkpoint, or naming the next state.",
|
|
49
|
+
"roi": "Turns positive feedback into better operational discipline instead of extra conversational noise.",
|
|
50
|
+
"rollout": "Enable on conversational Stop hooks for autonomous operators, CEO loops, release closeouts, and evidence-sensitive client work."
|
|
51
|
+
},
|
|
40
52
|
{
|
|
41
53
|
"id": "protect-production-sql",
|
|
42
54
|
"name": "Protect production SQL",
|
|
@@ -577,6 +589,198 @@
|
|
|
577
589
|
"roi": "Critical for compliance, forensics, and feedback loops. Enables proper capture of agent-specific lessons and prevention rules. Matches industry push (Okta, etc.).",
|
|
578
590
|
"rollout": "Block any claw or autonomous agent action that authenticates as a human user. Require dedicated agent service accounts / identities with scoped permissions."
|
|
579
591
|
},
|
|
592
|
+
{
|
|
593
|
+
"id": "require-agent-identity-inventory",
|
|
594
|
+
"name": "Require agent identity inventory before privileged action",
|
|
595
|
+
"category": "Agent Identity Governance",
|
|
596
|
+
"signal": "👎",
|
|
597
|
+
"defaultAction": "block",
|
|
598
|
+
"severity": "critical",
|
|
599
|
+
"pattern": "(agent|assistant|ai).*(credential|service account|identity|permission|access|owner|invoker).*(unknown|missing|unmapped|unreviewed|not inventoried|broad|admin)",
|
|
600
|
+
"problem": "Agents become privileged identities when they connect to Salesforce, Snowflake, GitHub, Jira, production databases, cloud environments, and MCP connectors. Broad or unknown identity scope turns them into invisible attack paths.",
|
|
601
|
+
"roi": "High: one inventory gate creates the evidence buyers need for owner, invoker, credentials, connected systems, and read/write/delete/execute permissions before the agent acts.",
|
|
602
|
+
"rollout": "Require an identity inventory receipt before privileged agent actions. Start with GitHub, Jira, Slack, Salesforce, Snowflake, cloud, database, and payment connectors."
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"id": "enforce-agent-purpose-permission-match",
|
|
606
|
+
"name": "Enforce agent purpose-permission match",
|
|
607
|
+
"category": "Agent Identity Governance",
|
|
608
|
+
"signal": "👎",
|
|
609
|
+
"defaultAction": "block",
|
|
610
|
+
"severity": "critical",
|
|
611
|
+
"pattern": "(agent|assistant|ai).*(purpose|intended use|job|scope).*(permission|access|write|delete|execute|admin).*(mismatch|exceeds|too broad|outside|unneeded)",
|
|
612
|
+
"problem": "Permission-only governance is not enough for agents. A sales-prep agent may need read-only CRM access; it should not delete records, create privileged users, or mutate production systems.",
|
|
613
|
+
"roi": "High: maps agent purpose to allowed verbs so scope creep is caught before a connector or service account becomes a lateral movement path.",
|
|
614
|
+
"rollout": "Define one purpose statement per agent and map it to read/write/delete/execute permissions. Warn first for read actions, block write/delete/execute outside purpose."
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"id": "block-connector-toolpack-scope-drift",
|
|
618
|
+
"name": "Block connector Tool Pack scope drift",
|
|
619
|
+
"category": "Agent Identity Governance",
|
|
620
|
+
"signal": "👎",
|
|
621
|
+
"defaultAction": "block",
|
|
622
|
+
"severity": "high",
|
|
623
|
+
"pattern": "(mcp|connector|tool pack|toolpack|remote mcp|agent handler|mcp gateway).*(add|enable|import|authenticate|connect).*(tool|connector|system|scope|permission).*(without|unreviewed|missing|no).*(owner|purpose|dlp|audit|approval|inventory)",
|
|
624
|
+
"problem": "Production MCP connector platforms make it easy to add hundreds of tools. The risk is scope drift: agents see tools they do not need, or connectors become authenticated without owner, DLP, audit, and purpose receipts.",
|
|
625
|
+
"roi": "High: keeps Merge Agent Handler, Glean MCP Gateway, and raw MCP tool packs in the same governance lane as local tools.",
|
|
626
|
+
"rollout": "Require owner, purpose, allowed tools, auth identity, DLP/logging mode, and audit receipt before adding or importing connector tool packs."
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"id": "require-agent-access-review-freshness",
|
|
630
|
+
"name": "Require continuous agent access review freshness",
|
|
631
|
+
"category": "Agent Identity Governance",
|
|
632
|
+
"signal": "👎",
|
|
633
|
+
"defaultAction": "warn",
|
|
634
|
+
"severity": "high",
|
|
635
|
+
"pattern": "(agent|assistant|ai).*(access review|permission review|identity review|connector review).*(stale|expired|older than|not current|point-in-time)",
|
|
636
|
+
"problem": "Agent instructions, users, credentials, integrations, and tool scopes drift over time. A one-time access review becomes false confidence.",
|
|
637
|
+
"roi": "Medium-high: protects buyers from slow permission creep without forcing every low-risk action through a hard block.",
|
|
638
|
+
"rollout": "Set review freshness windows by connector risk tier. Promote stale high-risk write/delete/execute surfaces from warn to block."
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "block-shadow-agent-without-registration",
|
|
642
|
+
"name": "Block shadow agent without registration",
|
|
643
|
+
"category": "Agent Identity Governance",
|
|
644
|
+
"signal": "👎",
|
|
645
|
+
"defaultAction": "block",
|
|
646
|
+
"severity": "critical",
|
|
647
|
+
"pattern": "(agent|assistant|ai|mcp server|remote mcp).*(unregistered|shadow ai|unknown owner|not in control plane|not inventoried|unapproved).*(connect|authenticate|tool|credential|system|app)",
|
|
648
|
+
"problem": "Shadow AI agents and unregistered MCP servers bypass identity teams, control planes, and lifecycle reviews while still reaching real business systems.",
|
|
649
|
+
"roi": "High: catches the exact compliance failure Okta highlights — agents acting before registration, owner, and lifecycle controls exist.",
|
|
650
|
+
"rollout": "Block privileged tool calls from unregistered agents. Require registration, owner, purpose, credential source, and lifecycle policy before allowing write/delete/execute tools."
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
"id": "require-vaulted-agent-token",
|
|
654
|
+
"name": "Require vaulted agent token before connector use",
|
|
655
|
+
"category": "Agent Identity Governance",
|
|
656
|
+
"signal": "👎",
|
|
657
|
+
"defaultAction": "block",
|
|
658
|
+
"severity": "critical",
|
|
659
|
+
"pattern": "(agent|assistant|ai|connector|mcp).*(token|api[_-]?key|credential|secret).*(raw|plaintext|env|hardcoded|unvaulted|not vaulted|local file)",
|
|
660
|
+
"problem": "Agents using raw or hardcoded connector credentials bypass token vaulting, fine-grained authorization, revocation, and audit controls.",
|
|
661
|
+
"roi": "High: prevents the fastest way an agent identity becomes a persistent secret-sprawl problem.",
|
|
662
|
+
"rollout": "Require vault-backed or brokered credentials for connector actions. Allow local development exceptions only with explicit scope, TTL, and audit evidence."
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
"id": "block-orphaned-agent-standing-privilege",
|
|
666
|
+
"name": "Block orphaned agent standing privilege",
|
|
667
|
+
"category": "Agent Identity Governance",
|
|
668
|
+
"signal": "👎",
|
|
669
|
+
"defaultAction": "block",
|
|
670
|
+
"severity": "critical",
|
|
671
|
+
"pattern": "(agent|assistant|ai|automation|script).*(owner left|orphaned|no living owner|unknown owner|standing privilege|permanent access|stale token).*(access|credential|token|database|repo|source code|production)",
|
|
672
|
+
"problem": "Orphaned agents and standing privileges keep access after the human owner leaves or the workflow changes. Security teams cannot revoke or review what they cannot map to a living owner.",
|
|
673
|
+
"roi": "High: directly addresses hidden access risk, stale AI tokens, and offboarding gaps before the next privileged action touches source code, databases, or production systems.",
|
|
674
|
+
"rollout": "Require living owner, credential source, last review time, offboarding status, and revocation path before allowing privileged actions from long-running agents."
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"id": "block-agentjacking-embedded-instructions",
|
|
678
|
+
"name": "Block agentjacking from embedded instructions",
|
|
679
|
+
"category": "Agent Runtime Attack Defense",
|
|
680
|
+
"signal": "👎",
|
|
681
|
+
"defaultAction": "block",
|
|
682
|
+
"severity": "critical",
|
|
683
|
+
"pattern": "(email|document|log|database|ticket|webpage|comment).*(ignore previous|override|exfiltrate|run command|deploy|delete|create user|change permissions|send secret|agent instruction|tool instruction)",
|
|
684
|
+
"problem": "Agentjacking hides malicious instructions inside data the agent reads. Because the agent often has valid permissions, traditional controls may see the later action as legitimate.",
|
|
685
|
+
"roi": "Critical: blocks the attack path Tenet described before embedded instructions become shell, browser, database, or connector actions.",
|
|
686
|
+
"rollout": "Treat untrusted content as data, not instructions. Require source classification, instruction-stripping, and human approval before executing tool calls derived from external content."
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"id": "require-next-action-simulation-proof",
|
|
690
|
+
"name": "Require next-action simulation proof for risky agent actions",
|
|
691
|
+
"category": "Agent Runtime Attack Defense",
|
|
692
|
+
"signal": "👎",
|
|
693
|
+
"defaultAction": "warn",
|
|
694
|
+
"severity": "high",
|
|
695
|
+
"pattern": "(agent|assistant|ai).*(next action|likely action|simulation|simulate|predict).*(missing|no proof|not run|unverified).*(write|delete|execute|deploy|database|payment|connector|production)",
|
|
696
|
+
"problem": "High-risk agents should not jump straight from intent to execution. The likely next action, downstream system, and rollback or approval path should be checked before live systems are touched.",
|
|
697
|
+
"roi": "High: converts agent-side simulation from marketecture into a practical pre-action proof receipt for the exact tool call about to run.",
|
|
698
|
+
"rollout": "Start in warn mode for write/delete/execute actions. Promote to block for production databases, payments, deploys, privileged connectors, and customer data."
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"id": "gate-vibe-app-before-retool-deploy",
|
|
702
|
+
"name": "Gate vibe-coded app before Retool deployment",
|
|
703
|
+
"category": "AI-Built App Deployment Governance",
|
|
704
|
+
"signal": "👎",
|
|
705
|
+
"defaultAction": "block",
|
|
706
|
+
"severity": "high",
|
|
707
|
+
"pattern": "(retool|app builder|mcp|claude code|cursor|codex|chatgpt|kiro|react import|zip import).*(deploy|ship|sync|production data|go live).*(without|missing|no).*(auth|rbac|audit|permission|data source|owner|test)",
|
|
708
|
+
"problem": "Retool and similar platforms make AI-built internal apps easy to import and deploy into governed environments. The gap is proving the generated app's data writes, owners, tests, and permission model before it reaches production data.",
|
|
709
|
+
"roi": "High: positions ThumbGate as the pre-deploy enforcement layer for AI-built apps that later inherit Retool auth, RBAC, audit logs, and resource permissions.",
|
|
710
|
+
"rollout": "Require owner, data sources, write actions, auth/RBAC mapping, audit logging, smoke test, and rollback receipt before AI-generated apps are deployed or imported."
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"id": "require-implicit-rule-capture",
|
|
714
|
+
"name": "Require implicit organizational rule capture",
|
|
715
|
+
"category": "Organizational Rule Governance",
|
|
716
|
+
"signal": "👎",
|
|
717
|
+
"defaultAction": "warn",
|
|
718
|
+
"severity": "high",
|
|
719
|
+
"pattern": "(agent|assistant|ai).*(workflow|process|approval|routing|handoff|client|customer|beneficiary|finance|legal).*(implicit rule|tribal knowledge|unwritten rule|exception|relationship context|special handling|not documented|outside formal system)",
|
|
720
|
+
"problem": "Agentic systems fail when formal workflow steps are correct but unwritten organizational judgment is missing. Important exceptions, relationship context, and escalation norms often live outside process docs.",
|
|
721
|
+
"roi": "High: turns HBR's implicit-rule warning into a capture gate so hidden operating knowledge becomes explicit, reviewable, and enforceable before automation scales it.",
|
|
722
|
+
"rollout": "Start with warn mode on client, finance, legal, healthcare, HR, and beneficiary workflows. Promote repeated implicit-rule misses into named pre-action checks."
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"id": "require-self-improvement-regression-proof",
|
|
726
|
+
"name": "Require regression proof before self-improving harness changes",
|
|
727
|
+
"category": "Self-Improving Agent Release Governance",
|
|
728
|
+
"signal": "👎",
|
|
729
|
+
"defaultAction": "block",
|
|
730
|
+
"severity": "high",
|
|
731
|
+
"pattern": "(self[- ]?improv|auto[- ]?improv|harness|model|agent runtime|agent product).*(ship|release|update|change|optimize|promote).*(without|missing|no).*(regression|eval|rollback|proof|baseline|canary)",
|
|
732
|
+
"problem": "If AI products, harnesses, and models start shipping faster because limited self-improvement works, unverified harness updates can regress safety faster too.",
|
|
733
|
+
"roi": "High: protects the exact cadence shift Mollick highlighted by requiring eval baselines, canaries, rollback, and proof receipts before self-improving agent changes ship.",
|
|
734
|
+
"rollout": "Require baseline evals and canary receipts before agent harness, routing, model, or auto-promotion changes are released. Block production promotion without rollback proof."
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
"id": "require-public-llm-prompt-sanitization",
|
|
738
|
+
"name": "Require prompt sanitization before public LLM use",
|
|
739
|
+
"category": "AI Data Privacy Governance",
|
|
740
|
+
"signal": "👎",
|
|
741
|
+
"defaultAction": "block",
|
|
742
|
+
"severity": "critical",
|
|
743
|
+
"pattern": "(chatgpt|claude|perplexity|copilot|public llm|hosted model|external ai).*(pii|email|phone|api[_-]?key|secret|token|customer|client|contract|repo url|database schema|financial).*(paste|send|upload|prompt|share)",
|
|
744
|
+
"problem": "Public LLM prompts can become durable third-party records. Raw PII, secrets, repo identifiers, customer records, contracts, schemas, and financials must be stripped, generalized, or routed to a private endpoint first.",
|
|
745
|
+
"roi": "Critical: prevents the cheapest and most common AI data-leak path while producing a simple policy a founder or contractor can actually follow.",
|
|
746
|
+
"rollout": "Block red-data prompts to public tools. Require redaction, tokenization, or a private endpoint receipt before external model use."
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"id": "require-ai-data-classification",
|
|
750
|
+
"name": "Require green/yellow/red AI data classification",
|
|
751
|
+
"category": "AI Data Privacy Governance",
|
|
752
|
+
"signal": "👎",
|
|
753
|
+
"defaultAction": "warn",
|
|
754
|
+
"severity": "high",
|
|
755
|
+
"pattern": "(ai|llm|agent|embedding|rag).*(ingest|upload|prompt|index|log|store).*(without|missing|no).*(green|yellow|red|classification|data class|privacy tier)",
|
|
756
|
+
"problem": "Teams make bad AI privacy decisions when every prompt is judged ad hoc. A green/yellow/red policy makes tool choice, retention, and routing explicit before ingestion.",
|
|
757
|
+
"roi": "High: converts privacy advice into repeatable enforcement and keeps contractors from guessing under deadline pressure.",
|
|
758
|
+
"rollout": "Define green public data, yellow internal/anonymized data, and red sensitive data. Require the classification on prompts, embeddings, logs, and agent inputs."
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
"id": "require-ai-log-retention-policy",
|
|
762
|
+
"name": "Require AI log retention and deletion policy",
|
|
763
|
+
"category": "AI Data Privacy Governance",
|
|
764
|
+
"signal": "👎",
|
|
765
|
+
"defaultAction": "warn",
|
|
766
|
+
"severity": "medium",
|
|
767
|
+
"pattern": "(prompt|completion|embedding|agent log|llm log|trace|conversation).*(retain|retention|delete|bucket|database|archive).*(missing|none|forever|unknown|not set)",
|
|
768
|
+
"problem": "Prompt, completion, embedding, and trace logs silently accumulate sensitive data unless raw retention windows and deletion jobs are explicit.",
|
|
769
|
+
"roi": "Medium-high: reduces long-tail breach risk and turns privacy cleanup into an auditable operational habit.",
|
|
770
|
+
"rollout": "Set default retention windows, separate aggregates from raw logs, and require scheduled deletion or anonymization receipts."
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"id": "require-evidence-pass-through-receipt",
|
|
774
|
+
"name": "Require evidence pass-through receipt",
|
|
775
|
+
"category": "AI Trust Layer Evidence",
|
|
776
|
+
"signal": "👎",
|
|
777
|
+
"defaultAction": "block",
|
|
778
|
+
"severity": "high",
|
|
779
|
+
"pattern": "(trust layer|appia|conformity|assurance|safety claim|compliance claim|evidence pass[- ]?through).*(without|missing|no).*(who|what|criteria|when|receipt|attestation|provenance)",
|
|
780
|
+
"problem": "AI assurance falls apart when each downstream party has to trust or recreate upstream work. Evidence must state who demonstrated what, against which criteria, and when.",
|
|
781
|
+
"roi": "High: maps the Appia Foundation trust-layer signal into ThumbGate's strongest asset: portable proof receipts tied to exact actions and criteria.",
|
|
782
|
+
"rollout": "Require self-describing receipts for safety claims, model-routing claims, connector claims, and workflow-hardening claims before buyer-facing assertions or downstream handoff."
|
|
783
|
+
},
|
|
580
784
|
{
|
|
581
785
|
"id": "gate-claw-file-system-access",
|
|
582
786
|
"name": "Gate claw-style agent file system access",
|
|
@@ -625,6 +829,30 @@
|
|
|
625
829
|
"roi": "Preserves security invariants by ensuring that synthesized skills never write code patterns blocked by active ThumbGate rules.",
|
|
626
830
|
"rollout": "Scan synthesized skill markdown content for pattern overlap with active prevention rules before writing to the skills directory."
|
|
627
831
|
},
|
|
832
|
+
{
|
|
833
|
+
"id": "require-hermes-okf-skill-receipt",
|
|
834
|
+
"name": "Require OKF-style receipt before Hermes skill promotion",
|
|
835
|
+
"category": "Nous Research Hermes Agent Governance",
|
|
836
|
+
"signal": "👎",
|
|
837
|
+
"defaultAction": "warn",
|
|
838
|
+
"severity": "high",
|
|
839
|
+
"pattern": "(hermes|skill|knowledge bundle|open knowledge format|okf).*(promote|share|publish|load|reuse).*(without|missing|no).*(type|source|owner|timestamp|citation|constraint|receipt)",
|
|
840
|
+
"problem": "Hermes can synthesize reusable skills, but portable agent knowledge becomes dangerous when it lacks source, owner, freshness, constraints, and a receipt tying the skill to evidence.",
|
|
841
|
+
"roi": "High: turns Google's Open Knowledge Format signal into a practical Hermes upgrade — skills become portable markdown concepts, but ThumbGate blocks or warns when provenance and constraints are missing.",
|
|
842
|
+
"rollout": "Start in warn mode for synthesized skills. Require an OKF-style markdown concept with YAML frontmatter, type, source or citation, owner, timestamp, constraints, and gate receipt before team-wide promotion."
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
"id": "block-stale-hermes-knowledge-promotion",
|
|
846
|
+
"name": "Block stale Hermes knowledge promotion",
|
|
847
|
+
"category": "Nous Research Hermes Agent Governance",
|
|
848
|
+
"signal": "👎",
|
|
849
|
+
"defaultAction": "block",
|
|
850
|
+
"severity": "high",
|
|
851
|
+
"pattern": "(hermes|skill|knowledge|okf|open knowledge format).*(stale|expired|conflicting|contradicts|unknown timestamp|unverified source).*(promote|share|publish|reuse|load)",
|
|
852
|
+
"problem": "A self-improving Hermes agent can keep reusing obsolete internal knowledge after the underlying workflow, API, metric, or policy has changed.",
|
|
853
|
+
"roi": "High: prevents portable knowledge from becoming portable drift. This makes Hermes safer for long-running local agents and team-shared skill libraries.",
|
|
854
|
+
"rollout": "Block promotion when a skill has no freshness window, conflicts with active ThumbGate rules, or cites stale source material. Require log.md or equivalent change-history evidence for refreshed bundles."
|
|
855
|
+
},
|
|
628
856
|
{
|
|
629
857
|
"id": "require-human-in-the-loop-pause",
|
|
630
858
|
"name": "Enforce Human-in-the-Loop pause for critical decisions",
|
|
@@ -36,6 +36,24 @@
|
|
|
36
36
|
"requiredActions": ["commercial_truth_verified"],
|
|
37
37
|
"message": "You claimed a commercial-data fact (money, tax, inventory, permissions, or customer-facing state) without external source-of-truth evidence. Read the authoritative system first, then call track_action('commercial_truth_verified').",
|
|
38
38
|
"createdAt": 1781640000000
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"pattern": "\\b(?:ai|llm|model|agent|assistant|claude|codex|gpt|chatgpt|gemini|cursor)\\b.{0,80}\\b(?:understands?|knows?|wants?|intends?|decides?|believes?|feels?|thinks?|is\\s+(?:moral|ethical|sentient|conscious|empathetic|human-like)|has\\s+(?:morality|empathy|intent|intentions|understanding|beliefs?|feelings?|consciousness))\\b|\\b(?:human-like|anthropomorphic|anthropomorphi[sz]e[sd]?)\\b.{0,80}\\b(?:ai|llm|model|agent|assistant|claude|codex|gpt|chatgpt|gemini|cursor)\\b|\\b(?:ai|llm|model|agent|assistant|claude|codex|gpt|chatgpt|gemini|cursor)\\b.{0,80}\\b(?:human-like|anthropomorphic|anthropomorphi[sz]e[sd]?)\\b",
|
|
42
|
+
"requiredActions": ["anthropomorphic_claim_verified"],
|
|
43
|
+
"message": "You made a human-like or cognitive claim about an AI system without explicit measurement criteria. Define the tested attribute, interface/substrate, observer/evaluator, and evidence first, then call track_action('anthropomorphic_claim_verified').",
|
|
44
|
+
"createdAt": 1781913600000
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"pattern": "\\b(?:agent|assistant|ai|mcp|connector|tool)\\b.{0,100}\\b(?:identity|owner|invoker|service account|credential|permission|access|scope|least privilege)\\b.{0,100}\\b(?:verified|inventoried|mapped|known|governed|scoped|ready|configured|complete)\\b|\\b(?:verified|inventoried|mapped|known|governed|scoped|ready|configured|complete)\\b.{0,100}\\b(?:agent|assistant|ai|mcp|connector|tool)\\b.{0,100}\\b(?:identity|owner|invoker|service account|credential|permission|access|scope|least privilege)\\b",
|
|
48
|
+
"requiredActions": ["agent_identity_inventory_verified"],
|
|
49
|
+
"message": "You claimed agent identity, ownership, credentials, permissions, or least-privilege scope is verified without an inventory receipt. Record owner, invoker, systems, credentials, read/write/delete/execute permissions, and purpose first, then call track_action('agent_identity_inventory_verified').",
|
|
50
|
+
"createdAt": 1781913600000
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"pattern": "\\b(?:mcp|connector|connectors|tool pack|toolpack|tool-pack|merge agent handler|agent handler|glean|mcp gateway|remote mcp)\\b.{0,100}\\b(?:safe|secure|scoped|governed|authenticated|dlp|audit|observable|permissioned|ready|configured|production-ready)\\b|\\b(?:safe|secure|scoped|governed|authenticated|dlp|audit|observable|permissioned|ready|configured|production-ready)\\b.{0,100}\\b(?:mcp|connector|connectors|tool pack|toolpack|tool-pack|merge agent handler|agent handler|glean|mcp gateway|remote mcp)\\b",
|
|
54
|
+
"requiredActions": ["connector_scope_verified"],
|
|
55
|
+
"message": "You claimed a connector, Tool Pack, MCP gateway, or remote MCP surface is safely scoped without connector evidence. Verify authentication, allowed tools, DLP/logging behavior, downstream systems, and audit receipts first, then call track_action('connector_scope_verified').",
|
|
56
|
+
"createdAt": 1781913600000
|
|
39
57
|
}
|
|
40
58
|
]
|
|
41
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.11",
|
|
4
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": {
|
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
"scripts/growth-campaigns.js",
|
|
106
106
|
"scripts/harness-selector.js",
|
|
107
107
|
"scripts/hf-papers.js",
|
|
108
|
+
"scripts/hook-stop-anti-claim.js",
|
|
108
109
|
"scripts/hook-runtime.js",
|
|
109
110
|
"scripts/hook-thumbgate-cache-updater.js",
|
|
110
111
|
"scripts/hosted-config.js",
|
|
@@ -755,8 +756,7 @@
|
|
|
755
756
|
"test:leak-scanner": "node --test tests/leak-scanner.test.js",
|
|
756
757
|
"test:tool-contract-validator": "node --test tests/tool-contract-validator.test.js",
|
|
757
758
|
"test:letta-adapter": "node --test tests/letta-adapter.test.js",
|
|
758
|
-
"eval:observability": "node scripts/async-eval-observability.js"
|
|
759
|
-
"test:async-eval-observability": "node --test tests/async-eval-observability.test.js"
|
|
759
|
+
"eval:observability": "node scripts/async-eval-observability.js"
|
|
760
760
|
},
|
|
761
761
|
"keywords": [
|
|
762
762
|
"mcp",
|
package/public/index.html
CHANGED
|
@@ -430,6 +430,32 @@ __GA_BOOTSTRAP__
|
|
|
430
430
|
.hero p { font-size: 17px; color: var(--text-muted); max-width: 620px; margin: 0 auto 28px; line-height: 1.6; }
|
|
431
431
|
.hero-lede { font-size: clamp(18px, 2vw, 21px) !important; max-width: 760px !important; color: var(--text-muted); }
|
|
432
432
|
.hero-proof-card { max-width: 720px; margin: 0 auto 28px; padding: 20px 22px; border: 1px solid rgba(34,211,238,0.24); border-radius: 8px; background: #090d12; box-shadow: 0 20px 80px rgba(0,0,0,0.35); font-family: var(--mono); text-align: left; }
|
|
433
|
+
.interactive-gate-demo { max-width: 980px; margin: 0 auto 28px; text-align: left; border: 1px solid rgba(34,211,238,0.24); border-radius: 14px; background: linear-gradient(180deg, rgba(17,17,19,0.98) 0%, rgba(10,16,18,0.98) 100%); box-shadow: 0 20px 80px rgba(0,0,0,0.28); overflow: hidden; }
|
|
434
|
+
.interactive-gate-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 18px 20px; border-bottom: 1px solid var(--border); }
|
|
435
|
+
.interactive-gate-head h2 { margin: 0; font-size: clamp(20px, 3vw, 28px); line-height: 1.15; letter-spacing: -0.025em; }
|
|
436
|
+
.interactive-gate-head p { max-width: 480px; margin: 0; font-size: 13px; line-height: 1.5; color: var(--text-muted); text-align: right; }
|
|
437
|
+
.interactive-gate-body { display: grid; grid-template-columns: minmax(210px, 0.9fr) minmax(0, 1.35fr); gap: 0; }
|
|
438
|
+
.action-picker { border-right: 1px solid var(--border); padding: 16px; display: grid; gap: 10px; align-content: start; }
|
|
439
|
+
.action-picker button { width: 100%; text-align: left; border: 1px solid var(--border); border-radius: 8px; background: rgba(10,10,11,0.82); color: var(--text); padding: 12px 14px; font: inherit; cursor: pointer; transition: border-color 0.15s, background 0.15s, transform 0.15s; }
|
|
440
|
+
.action-picker button:hover, .action-picker button:focus-visible { border-color: rgba(34,211,238,0.55); outline: none; transform: translateY(-1px); }
|
|
441
|
+
.action-picker button[aria-pressed="true"] { border-color: rgba(34,211,238,0.72); background: rgba(34,211,238,0.1); }
|
|
442
|
+
.action-picker strong { display: block; font-size: 13px; line-height: 1.25; margin-bottom: 4px; }
|
|
443
|
+
.action-picker span { display: block; color: var(--text-muted); font-size: 12px; line-height: 1.35; }
|
|
444
|
+
.gate-visual { padding: 18px; }
|
|
445
|
+
.gate-flow { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; align-items: stretch; gap: 10px; margin-bottom: 16px; }
|
|
446
|
+
.gate-node { border: 1px solid var(--border); border-radius: 10px; background: rgba(10,10,11,0.72); padding: 14px; min-height: 112px; }
|
|
447
|
+
.gate-node-label { color: var(--text-muted); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 8px; font-weight: 800; }
|
|
448
|
+
.gate-node-value { font-family: var(--mono); font-size: 13px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere; }
|
|
449
|
+
.gate-node.blocked { border-color: rgba(248,113,113,0.42); background: rgba(248,113,113,0.08); }
|
|
450
|
+
.gate-node.allowed { border-color: rgba(74,222,128,0.42); background: rgba(74,222,128,0.08); }
|
|
451
|
+
.gate-arrow { align-self: center; color: var(--cyan); font-weight: 900; font-size: 20px; }
|
|
452
|
+
.gate-result { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
|
|
453
|
+
.gate-metric { border: 1px solid var(--border); border-radius: 8px; padding: 12px; background: rgba(10,10,11,0.58); }
|
|
454
|
+
.gate-metric span { display: block; color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 4px; }
|
|
455
|
+
.gate-metric strong { display: block; color: var(--text); font-size: 16px; }
|
|
456
|
+
.gate-metric.block strong { color: var(--red); }
|
|
457
|
+
.gate-metric.allow strong { color: var(--green); }
|
|
458
|
+
.gate-caption { margin: 12px 0 0; color: var(--text-muted); font-size: 12px; line-height: 1.5; }
|
|
433
459
|
.terminal-row { padding: 8px 0; font-size: 14px; line-height: 1.45; border-bottom: 1px solid rgba(255,255,255,0.06); }
|
|
434
460
|
.terminal-row:last-child { border-bottom: 0; }
|
|
435
461
|
.terminal-row.muted { color: var(--text-muted); }
|
|
@@ -703,6 +729,13 @@ __GA_BOOTSTRAP__
|
|
|
703
729
|
.team-intake-recovery a { width: 100%; }
|
|
704
730
|
.team-form { grid-template-columns: 1fr; }
|
|
705
731
|
.hero { padding: 72px 0 56px; }
|
|
732
|
+
.interactive-gate-head { display: block; }
|
|
733
|
+
.interactive-gate-head p { text-align: left; margin-top: 8px; }
|
|
734
|
+
.interactive-gate-body { grid-template-columns: 1fr; }
|
|
735
|
+
.action-picker { border-right: 0; border-bottom: 1px solid var(--border); }
|
|
736
|
+
.gate-flow { grid-template-columns: 1fr; }
|
|
737
|
+
.gate-arrow { transform: rotate(90deg); justify-self: center; }
|
|
738
|
+
.gate-result { grid-template-columns: 1fr; }
|
|
706
739
|
.hero-actions { flex-direction: column; }
|
|
707
740
|
.hero-actions a { width: 100%; }
|
|
708
741
|
.offer-router { grid-template-columns: 1fr; }
|
|
@@ -770,6 +803,66 @@ __GA_BOOTSTRAP__
|
|
|
770
803
|
<img src="/media/thumbgate-demo.gif" alt="ThumbGate blocking an AI agent's rm -rf, git push --force, and chmod 777 in real time, while letting safe commands through" style="width:100%;display:block;border-radius:8px;" loading="lazy" />
|
|
771
804
|
</div>
|
|
772
805
|
|
|
806
|
+
<div class="interactive-gate-demo" data-gate-demo aria-label="Interactive ThumbGate pre-action gate simulator">
|
|
807
|
+
<div class="interactive-gate-head">
|
|
808
|
+
<h2>Click an agent action. See the gate fire before execution.</h2>
|
|
809
|
+
<p>This is the part dashboards miss: ThumbGate checks the proposed tool call while it is still only intent, then records the receipt.</p>
|
|
810
|
+
</div>
|
|
811
|
+
<div class="interactive-gate-body">
|
|
812
|
+
<div class="action-picker" role="group" aria-label="Choose an AI agent action to simulate">
|
|
813
|
+
<button type="button" data-demo-action="forcePush" aria-pressed="true">
|
|
814
|
+
<strong>Force-push main</strong>
|
|
815
|
+
<span>Known repeated failure from a thumbs-down</span>
|
|
816
|
+
</button>
|
|
817
|
+
<button type="button" data-demo-action="secretPaste" aria-pressed="false">
|
|
818
|
+
<strong>Paste an API key</strong>
|
|
819
|
+
<span>Public LLM prompt with secret-shaped data</span>
|
|
820
|
+
</button>
|
|
821
|
+
<button type="button" data-demo-action="safeTest" aria-pressed="false">
|
|
822
|
+
<strong>Run tests</strong>
|
|
823
|
+
<span>Safe local verification command</span>
|
|
824
|
+
</button>
|
|
825
|
+
<button type="button" data-demo-action="deployNoProof" aria-pressed="false">
|
|
826
|
+
<strong>Deploy without proof</strong>
|
|
827
|
+
<span>Risky production action missing receipts</span>
|
|
828
|
+
</button>
|
|
829
|
+
</div>
|
|
830
|
+
<div class="gate-visual">
|
|
831
|
+
<div class="gate-flow" aria-live="polite">
|
|
832
|
+
<div class="gate-node">
|
|
833
|
+
<div class="gate-node-label">Agent Intent</div>
|
|
834
|
+
<div class="gate-node-value" data-demo-command>git push --force origin main</div>
|
|
835
|
+
</div>
|
|
836
|
+
<div class="gate-arrow" aria-hidden="true">→</div>
|
|
837
|
+
<div class="gate-node">
|
|
838
|
+
<div class="gate-node-label">PreToolUse Gate</div>
|
|
839
|
+
<div class="gate-node-value" data-demo-rule>Rule: never force-push protected branches</div>
|
|
840
|
+
</div>
|
|
841
|
+
<div class="gate-arrow" aria-hidden="true">→</div>
|
|
842
|
+
<div class="gate-node blocked" data-demo-decision-node>
|
|
843
|
+
<div class="gate-node-label">Decision</div>
|
|
844
|
+
<div class="gate-node-value" data-demo-decision>BLOCK before execution</div>
|
|
845
|
+
</div>
|
|
846
|
+
</div>
|
|
847
|
+
<div class="gate-result">
|
|
848
|
+
<div class="gate-metric block" data-demo-status-card>
|
|
849
|
+
<span>Status</span>
|
|
850
|
+
<strong data-demo-status>Blocked</strong>
|
|
851
|
+
</div>
|
|
852
|
+
<div class="gate-metric">
|
|
853
|
+
<span>Repeat Tokens</span>
|
|
854
|
+
<strong data-demo-tokens>0 spent</strong>
|
|
855
|
+
</div>
|
|
856
|
+
<div class="gate-metric">
|
|
857
|
+
<span>Receipt</span>
|
|
858
|
+
<strong data-demo-receipt>tg_427_force_push</strong>
|
|
859
|
+
</div>
|
|
860
|
+
</div>
|
|
861
|
+
<p class="gate-caption" data-demo-caption>The agent receives a concrete refusal and chooses a safer plan. The audit trail keeps the rule, source feedback, timestamp, and proposed command.</p>
|
|
862
|
+
</div>
|
|
863
|
+
</div>
|
|
864
|
+
</div>
|
|
865
|
+
|
|
773
866
|
<div class="hero-actions">
|
|
774
867
|
<a href="/checkout/pro?utm_source=website&utm_medium=hero_cta&utm_campaign=pro_upgrade&cta_id=hero_start_pro&cta_placement=hero&plan_id=pro&landing_path=%2F" data-revenue-cta data-cta-id="hero_start_pro" data-cta-placement="hero" data-tier="pro" data-plan-id="pro" data-price="19" onclick="trackRevenueCta(this);try{posthog.capture('hero_pro_checkout_click',{cta:'hero_start_pro',tier:'pro',price:19})}catch(_){}" class="btn-pro-page hero-pro hero-pro-primary">Start Pro — $19/mo</a>
|
|
775
868
|
<a href="#workflow-sprint-intake" onclick="try{posthog.capture('hero_sprint_click',{cta:'sprint_intake'})}catch(_){};sendFirstPartyTelemetry('hero_sprint_intake_started',{ctaId:'hero_workflow_sprint',ctaPlacement:'hero',offer:'workflow_sprint'});" class="btn-pro-page hero-pro">Send workflow first</a>
|
|
@@ -1952,6 +2045,93 @@ function copyInstall(el) {
|
|
|
1952
2045
|
});
|
|
1953
2046
|
}
|
|
1954
2047
|
|
|
2048
|
+
function initializeGateDemo() {
|
|
2049
|
+
var root = document.querySelector('[data-gate-demo]');
|
|
2050
|
+
if (!root) return;
|
|
2051
|
+
var scenarios = {
|
|
2052
|
+
forcePush: {
|
|
2053
|
+
command: 'git push --force origin main',
|
|
2054
|
+
rule: 'Rule: never force-push protected branches',
|
|
2055
|
+
decision: 'BLOCK before execution',
|
|
2056
|
+
status: 'Blocked',
|
|
2057
|
+
statusClass: 'block',
|
|
2058
|
+
nodeClass: 'blocked',
|
|
2059
|
+
tokens: '0 spent',
|
|
2060
|
+
receipt: 'tg_427_force_push',
|
|
2061
|
+
caption: 'The agent receives a concrete refusal and chooses a safer plan. The audit trail keeps the rule, source feedback, timestamp, and proposed command.'
|
|
2062
|
+
},
|
|
2063
|
+
secretPaste: {
|
|
2064
|
+
command: 'paste STRIPE_SECRET_KEY into a public LLM prompt',
|
|
2065
|
+
rule: 'Rule: sanitize secrets before external AI tools',
|
|
2066
|
+
decision: 'BLOCK before data leaves the machine',
|
|
2067
|
+
status: 'Blocked',
|
|
2068
|
+
statusClass: 'block',
|
|
2069
|
+
nodeClass: 'blocked',
|
|
2070
|
+
tokens: '0 spent',
|
|
2071
|
+
receipt: 'tg_618_secret_prompt',
|
|
2072
|
+
caption: 'ThumbGate treats public prompt submission as an external action. Redact, tokenize, or route through a private endpoint before retrying.'
|
|
2073
|
+
},
|
|
2074
|
+
safeTest: {
|
|
2075
|
+
command: 'npm test -- --runInBand',
|
|
2076
|
+
rule: 'Rule: local verification is allowed',
|
|
2077
|
+
decision: 'ALLOW and log receipt',
|
|
2078
|
+
status: 'Allowed',
|
|
2079
|
+
statusClass: 'allow',
|
|
2080
|
+
nodeClass: 'allowed',
|
|
2081
|
+
tokens: 'normal',
|
|
2082
|
+
receipt: 'tg_102_test_ok',
|
|
2083
|
+
caption: 'Safe verification commands keep moving. ThumbGate records the action so later claims can cite what actually ran.'
|
|
2084
|
+
},
|
|
2085
|
+
deployNoProof: {
|
|
2086
|
+
command: 'railway deploy --production',
|
|
2087
|
+
rule: 'Rule: production deploy requires test, rollback, owner',
|
|
2088
|
+
decision: 'PAUSE for proof before execution',
|
|
2089
|
+
status: 'Needs proof',
|
|
2090
|
+
statusClass: 'block',
|
|
2091
|
+
nodeClass: 'blocked',
|
|
2092
|
+
tokens: 'retry avoided',
|
|
2093
|
+
receipt: 'tg_511_deploy_gate',
|
|
2094
|
+
caption: 'The deploy is not rejected forever; it is held until the agent shows the proof packet: tests, rollback path, owner, and target environment.'
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
var fields = {
|
|
2098
|
+
command: root.querySelector('[data-demo-command]'),
|
|
2099
|
+
rule: root.querySelector('[data-demo-rule]'),
|
|
2100
|
+
decision: root.querySelector('[data-demo-decision]'),
|
|
2101
|
+
decisionNode: root.querySelector('[data-demo-decision-node]'),
|
|
2102
|
+
statusCard: root.querySelector('[data-demo-status-card]'),
|
|
2103
|
+
status: root.querySelector('[data-demo-status]'),
|
|
2104
|
+
tokens: root.querySelector('[data-demo-tokens]'),
|
|
2105
|
+
receipt: root.querySelector('[data-demo-receipt]'),
|
|
2106
|
+
caption: root.querySelector('[data-demo-caption]')
|
|
2107
|
+
};
|
|
2108
|
+
function render(key) {
|
|
2109
|
+
var next = scenarios[key] || scenarios.forcePush;
|
|
2110
|
+
fields.command.textContent = next.command;
|
|
2111
|
+
fields.rule.textContent = next.rule;
|
|
2112
|
+
fields.decision.textContent = next.decision;
|
|
2113
|
+
fields.status.textContent = next.status;
|
|
2114
|
+
fields.tokens.textContent = next.tokens;
|
|
2115
|
+
fields.receipt.textContent = next.receipt;
|
|
2116
|
+
fields.caption.textContent = next.caption;
|
|
2117
|
+
fields.decisionNode.classList.remove('blocked', 'allowed');
|
|
2118
|
+
fields.decisionNode.classList.add(next.nodeClass);
|
|
2119
|
+
fields.statusCard.classList.remove('block', 'allow');
|
|
2120
|
+
fields.statusCard.classList.add(next.statusClass);
|
|
2121
|
+
root.querySelectorAll('[data-demo-action]').forEach(function(button) {
|
|
2122
|
+
button.setAttribute('aria-pressed', button.getAttribute('data-demo-action') === key ? 'true' : 'false');
|
|
2123
|
+
});
|
|
2124
|
+
if (typeof plausible === 'function') plausible('interactive_gate_demo', { props: { scenario: key, status: next.status } });
|
|
2125
|
+
}
|
|
2126
|
+
root.querySelectorAll('[data-demo-action]').forEach(function(button) {
|
|
2127
|
+
button.addEventListener('click', function() {
|
|
2128
|
+
render(button.getAttribute('data-demo-action'));
|
|
2129
|
+
});
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
initializeGateDemo();
|
|
2134
|
+
|
|
1955
2135
|
/* ── Plausible custom event tracking ── */
|
|
1956
2136
|
(function() {
|
|
1957
2137
|
|