thumbgate 1.27.12 → 1.27.13

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 (132) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.well-known/llms.txt +2 -1
  3. package/.well-known/mcp/server-card.json +1 -1
  4. package/README.md +2 -4
  5. package/adapters/claude/.mcp.json +2 -2
  6. package/adapters/mcp/server-stdio.js +1 -1
  7. package/adapters/opencode/opencode.json +1 -1
  8. package/adapters/policy-engine/ethicore-guardian-client.js +68 -0
  9. package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +260 -0
  10. package/bin/cli.js +78 -259
  11. package/config/gate-templates.json +0 -228
  12. package/config/gates/claim-verification.json +0 -18
  13. package/package.json +35 -25
  14. package/public/assets/brand/thumbgate-logo-transparent.svg +22 -0
  15. package/public/assets/brand/thumbgate-mark-inline-v3.svg +19 -0
  16. package/public/assets/brand/thumbgate-mark.svg +11 -5
  17. package/public/blog.html +0 -30
  18. package/public/brand/thumbgate-mark.svg +9 -5
  19. package/public/chatgpt-app.html +2 -2
  20. package/public/compare.html +2 -1
  21. package/public/dashboard.html +1 -1
  22. package/public/federal.html +1 -1
  23. package/public/index.html +95 -216
  24. package/public/learn.html +59 -35
  25. package/public/lessons.html +1 -1
  26. package/public/numbers.html +2 -2
  27. package/public/pro.html +7 -7
  28. package/scripts/aws-blocks-guardrails.js +228 -0
  29. package/scripts/cli-schema.js +22 -10
  30. package/scripts/dashboard-chat.js +2 -1
  31. package/scripts/document-intake.js +1 -49
  32. package/scripts/durability/step.js +3 -3
  33. package/scripts/gate-stats.js +5 -11
  34. package/scripts/gates-engine.js +0 -49
  35. package/scripts/gemini-embedding-policy.js +2 -1
  36. package/scripts/hook-stop-anti-claim.js +116 -184
  37. package/scripts/hosted-config.js +0 -12
  38. package/scripts/lesson-search.js +1 -15
  39. package/scripts/llm-client.js +187 -5
  40. package/scripts/plausible-domain-config.js +3 -1
  41. package/scripts/seo-gsd.js +240 -1
  42. package/scripts/tool-registry.js +2 -2
  43. package/scripts/vector-store.js +44 -0
  44. package/scripts/workspace-evolver.js +62 -2
  45. package/src/api/server.js +340 -131
  46. package/public/assets/brand/thumbgate-mark-inline.svg +0 -15
  47. package/public/compare/adopt-ai.html +0 -219
  48. package/public/compare/agentix-labs.html +0 -197
  49. package/public/compare/ai-experience-orchestration.html +0 -216
  50. package/public/compare/anthropic-claude-for-legal.html +0 -260
  51. package/public/compare/anthropic-containment.html +0 -280
  52. package/public/compare/arcade.html +0 -175
  53. package/public/compare/arcjet.html +0 -239
  54. package/public/compare/bumblebee.html +0 -307
  55. package/public/compare/claude-code-hooks.html +0 -294
  56. package/public/compare/databricks-unity-ai-gateway.html +0 -215
  57. package/public/compare/fallow.html +0 -351
  58. package/public/compare/heidi.html +0 -233
  59. package/public/compare/mem0.html +0 -342
  60. package/public/compare/oak-and-sparrow-gatekeeper.html +0 -289
  61. package/public/compare/rein.html +0 -236
  62. package/public/compare/sigmashake.html +0 -256
  63. package/public/compare/speclock.html +0 -342
  64. package/public/guides/agent-harness-optimization.html +0 -342
  65. package/public/guides/agentic-web-governance.html +0 -406
  66. package/public/guides/ai-agent-governance-sprint.html +0 -415
  67. package/public/guides/ai-agent-pre-action-approval-gates.html +0 -401
  68. package/public/guides/ai-agent-workflow-migration-checklist.html +0 -392
  69. package/public/guides/ai-deployment-readiness.html +0 -415
  70. package/public/guides/ai-mode-ads-agent-governance.html +0 -401
  71. package/public/guides/ai-search-topical-presence.html +0 -342
  72. package/public/guides/autoresearch-agent-safety.html +0 -342
  73. package/public/guides/background-agent-governance.html +0 -358
  74. package/public/guides/best-tools-stop-ai-agents-breaking-production.html +0 -363
  75. package/public/guides/browser-automation-safety.html +0 -342
  76. package/public/guides/chatgpt-ads-trust.html +0 -353
  77. package/public/guides/claude-code-feedback.html +0 -339
  78. package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
  79. package/public/guides/claude-code-skills-guardrails.html +0 -343
  80. package/public/guides/claude-desktop.html +0 -356
  81. package/public/guides/code-knowledge-graph-guardrails.html +0 -365
  82. package/public/guides/codex-cli-guardrails.html +0 -339
  83. package/public/guides/cursor-agent-guardrails.html +0 -339
  84. package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
  85. package/public/guides/database-agent-safety.html +0 -406
  86. package/public/guides/deepseek-v4-runtime-guardrails.html +0 -346
  87. package/public/guides/developer-machine-supply-chain-guardrails.html +0 -358
  88. package/public/guides/gcp-mcp-guardrails.html +0 -147
  89. package/public/guides/gemini-cli-feedback-memory.html +0 -339
  90. package/public/guides/gpt-5-5-model-evaluation.html +0 -358
  91. package/public/guides/internal-ai-engineering-stack-guardrails.html +0 -348
  92. package/public/guides/long-running-agent-context-management.html +0 -346
  93. package/public/guides/mcp-tool-governance.html +0 -401
  94. package/public/guides/multica-thumbgate-setup.html +0 -134
  95. package/public/guides/native-messaging-host-security.html +0 -342
  96. package/public/guides/policy-engine-pre-action-gates.html +0 -346
  97. package/public/guides/pre-action-checks.html +0 -342
  98. package/public/guides/pretooluse-hooks-vs-advisory-prompt-rules.html +0 -342
  99. package/public/guides/prompt-tricks-to-workflow-rules.html +0 -365
  100. package/public/guides/proxy-pointer-rag-guardrails.html +0 -352
  101. package/public/guides/rag-precision-tuning-guardrails.html +0 -352
  102. package/public/guides/reasoning-compression-guardrails.html +0 -346
  103. package/public/guides/relational-knowledge-ai-recommendations.html +0 -342
  104. package/public/guides/roo-code-alternative-cline.html +0 -339
  105. package/public/guides/semantic-programmatic-seo-guardrails.html +0 -352
  106. package/public/guides/seo-agent-skills-guardrails.html +0 -344
  107. package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -342
  108. package/public/learn/ac-dc-runtime-enforcement.html +0 -277
  109. package/public/learn/agent-harness-pattern.html +0 -181
  110. package/public/learn/agent-identity-connector-governance.html +0 -146
  111. package/public/learn/agent-swarms-shared-gates.html +0 -173
  112. package/public/learn/agentic-enterprise-context-brain.html +0 -117
  113. package/public/learn/agentic-os-team-governance.html +0 -146
  114. package/public/learn/ai-agent-governance.html +0 -158
  115. package/public/learn/ai-agent-persistent-memory.html +0 -211
  116. package/public/learn/anthropomorphic-claim-gates.html +0 -180
  117. package/public/learn/background-agent-control-layer.html +0 -184
  118. package/public/learn/claude-code-goal-with-rubrics.html +0 -205
  119. package/public/learn/codex-role-plugins-need-governance.html +0 -125
  120. package/public/learn/cost-aware-agent-gate-routing.html +0 -173
  121. package/public/learn/databricks-unity-ai-gateway-runtime-governance.html +0 -157
  122. package/public/learn/deterministic-agent-workflows.html +0 -185
  123. package/public/learn/feedback-loop-vs-decision-layer.html +0 -283
  124. package/public/learn/from-prototype-to-production.html +0 -223
  125. package/public/learn/learn.css +0 -51
  126. package/public/learn/mcp-pre-action-checks-explained.html +0 -172
  127. package/public/learn/pretix-stripe-connect-marketplaces.html +0 -161
  128. package/public/learn/regulated-agent-execution-boundary.html +0 -196
  129. package/public/learn/spec-driven-development.html +0 -168
  130. package/public/learn/stop-ai-agent-force-push.html +0 -134
  131. package/public/learn/vibe-coding-safety-net.html +0 -142
  132. package/scripts/reddit-browser-notification-watch.js +0 -230
package/bin/cli.js CHANGED
@@ -2188,6 +2188,26 @@ function pulse() {
2188
2188
  });
2189
2189
  }
2190
2190
 
2191
+ function checkUpdateCmd() {
2192
+ const { checkUpdate } = require(path.join(PKG_ROOT, 'scripts', 'check-update'));
2193
+ const args = parseArgs(process.argv.slice(3));
2194
+ checkUpdate({ verbose: !args.json, force: args.force }).then((res) => {
2195
+ if (args.json) {
2196
+ console.log(JSON.stringify(res, null, 2));
2197
+ }
2198
+ process.exit(0);
2199
+ }).catch((err) => {
2200
+ console.error(err && err.message ? err.message : err);
2201
+ process.exit(1);
2202
+ });
2203
+ }
2204
+
2205
+ function selfUpdateCmd() {
2206
+ const { selfUpdate } = require(path.join(PKG_ROOT, 'scripts', 'check-update'));
2207
+ const success = selfUpdate();
2208
+ process.exit(success ? 0 : 1);
2209
+ }
2210
+
2191
2211
  function dispatchBrief() {
2192
2212
  const args = parseArgs(process.argv.slice(3));
2193
2213
  const {
@@ -3151,6 +3171,7 @@ const SUBCOMMAND_HELP = {
3151
3171
  lessons: 'Usage: npx thumbgate lessons [--query="..."] [--limit=N]\n\nSearch the lesson database (Pro feature).',
3152
3172
  search: 'Usage: npx thumbgate search <query>\n\nSearch ThumbGate knowledge base (Pro feature).',
3153
3173
  'gate-check': 'Usage: npx thumbgate gate-check\n\nPreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict.',
3174
+ 'hermes-gate': 'Usage: npx thumbgate hermes-gate\n\nNous Research Hermes Agent pre_tool_call shell hook: reads Hermes tool-call JSON from stdin, runs the ThumbGate gate pipeline (strict by default), and outputs {"decision":"block","reason":...} to veto or {} to allow. Gates terminal/patch/skill_manage etc. See adapters/hermes/config.yaml.',
3154
3175
  'break-glass': 'Usage: npx thumbgate break-glass --reason="why" [--ttl=5m] [--json]\n\nShort-lived recovery path for over-firing gates. Allows hook settings edits and satisfies PR-create/thread-check gates without disabling core destructive-action protections.',
3155
3176
  serve: 'Usage: npx thumbgate serve\n\nStart the MCP stdio server. This is for agent runtimes, not the local HTTP dashboard.',
3156
3177
  mcp: 'Usage: npx thumbgate mcp\n\nAlias for `thumbgate serve`.',
@@ -3168,11 +3189,6 @@ const SUBCOMMAND_HELP = {
3168
3189
  'ai-inventory': 'Usage: npx thumbgate ai-inventory [--root <dir>] [--format=summary|json|cyclonedx] [--output <path>] [--max-files=N]\n\nScan source/manifests/model artifacts for AI, ML, agent-framework, vector DB, Vertex, Gemini, and Dialogflow CX components. Use --format=cyclonedx to produce exportable ML-BOM evidence for enterprise reviews.',
3169
3190
  brain: 'Usage: npx thumbgate brain [--write] [--json] [--limit=N]\n\nBuild the agent-readable "context brain" — a single artifact consolidating this\nrepo\'s lessons, prevention rules, active gates, and project context for a coding\nagent to read BEFORE acting. --write saves it to .thumbgate/BRAIN.md (versioned,\ndeterministic). --json emits the structured model. --limit caps lessons (default 15).',
3170
3191
  'team-sync': 'Usage: npx thumbgate team-sync\n\nSynchronize prevention rules and context brain with your team\'s git repository (git pull --rebase & git push), then auto-rebuild the local brain.',
3171
- dream: 'Usage: npx thumbgate dream [--min=N] [--feedback-dir=DIR] [--json]\n\nConsolidate raw history and lessons ("Silicon Dreaming"), merge duplicates, promote recurring failures to gates, and rebuild prevention rules + BRAIN.md.',
3172
- consolidate: 'Usage: npx thumbgate consolidate\n\nAlias for npx thumbgate dream.',
3173
- triage: 'Usage: npx thumbgate triage [--schedule="daily 9:00"] [--json]\n\nRun git updates, test verification, and memory consolidation, or schedule it on a cron.',
3174
- hygiene: 'Usage: npx thumbgate hygiene\n\nAlias for npx thumbgate triage.',
3175
- community: 'Usage: npx thumbgate community query <error> | share <rule-id>\n\nQuery or share verified prevention rules with the community knowledge registry.',
3176
3192
  };
3177
3193
 
3178
3194
  if (_wantsHelp && COMMAND && SUBCOMMAND_HELP[COMMAND]) {
@@ -3275,31 +3291,6 @@ function renderBrainMarkdown(model) {
3275
3291
  return out.join('\n');
3276
3292
  }
3277
3293
 
3278
- function autoWireInstructionFile(fileName) {
3279
- const filePath = path.join(CWD, fileName);
3280
- if (!fs.existsSync(filePath)) return;
3281
- try {
3282
- let content = fs.readFileSync(filePath, 'utf8');
3283
- const blockStart = '<!-- ThumbGate -->';
3284
- const blockEnd = '<!-- End ThumbGate -->';
3285
- const block = `${blockStart}\nIMPORTANT: Read .thumbgate/BRAIN.md first for lessons, prevention rules, and active gates in this repo.\n${blockEnd}\n`;
3286
-
3287
- if (content.includes(blockStart)) {
3288
- const startIdx = content.indexOf(blockStart);
3289
- const endIdx = content.indexOf(blockEnd);
3290
- if (endIdx !== -1) {
3291
- content = content.slice(0, startIdx) + block + content.slice(endIdx + blockEnd.length).replace(/^\n+/, '');
3292
- }
3293
- } else {
3294
- content = block + '\n' + content;
3295
- }
3296
- fs.writeFileSync(filePath, content);
3297
- console.error(` Auto-wired agent pointer into ${fileName}`);
3298
- } catch (err) {
3299
- console.warn(`⚠️ Failed to auto-wire agent pointer in ${fileName}: ${err.message}`);
3300
- }
3301
- }
3302
-
3303
3294
  function cmdBrain(args = {}) {
3304
3295
  const model = buildBrainModel({ limit: args.limit });
3305
3296
  if (args.json) { console.log(JSON.stringify(model, null, 2)); return 0; }
@@ -3319,120 +3310,14 @@ function cmdBrain(args = {}) {
3319
3310
  const lt = (model.lessons && model.lessons.total) || 0;
3320
3311
  const rt = (model.rules && model.rules.total) || 0;
3321
3312
  const gt = (model.gates && model.gates.total) || 0;
3322
- console.error(`\u{1f9e0} Wrote context brain to .thumbgate/BRAIN.md (${lt} lessons · ${rt} rules · ${gt} gates).`);
3323
-
3324
- // Auto-inject pointer block into CLAUDE.md / AGENTS.md
3325
- autoWireInstructionFile('CLAUDE.md');
3326
- autoWireInstructionFile('AGENTS.md');
3327
-
3313
+ console.log(`\u{1f9e0} Wrote context brain to .thumbgate/BRAIN.md (${lt} lessons · ${rt} rules · ${gt} gates).`);
3314
+ console.log(' Point your agent at it: add "Read .thumbgate/BRAIN.md first" to CLAUDE.md / AGENTS.md.');
3328
3315
  return 0;
3329
3316
  }
3330
3317
  process.stdout.write(md);
3331
3318
  return 0;
3332
3319
  }
3333
3320
 
3334
- function brain() {
3335
- const args = parseArgs(process.argv.slice(3));
3336
- const subcommand = process.argv.slice(3).find((arg) => !arg.startsWith('--')) || 'status';
3337
- const {
3338
- buildContextPack,
3339
- checkNeverDo,
3340
- cleanupReport,
3341
- ensureBrain,
3342
- formatContextPack,
3343
- recordMemory,
3344
- refreshNeverDoGates,
3345
- } = require(path.join(PKG_ROOT, 'scripts', 'brain'));
3346
-
3347
- if (subcommand === 'init' || subcommand === 'status') {
3348
- const result = ensureBrain(CWD);
3349
- const gates = refreshNeverDoGates(CWD);
3350
- const payload = { ...result, gateCount: gates.gateCount };
3351
- if (args.json) {
3352
- console.log(JSON.stringify(payload, null, 2));
3353
- return;
3354
- }
3355
- console.log('ThumbGate brain');
3356
- console.log('='.repeat(15));
3357
- console.log(`Brain dir : ${path.relative(CWD, result.brainDir)}`);
3358
- console.log(`Created : ${result.created.length}`);
3359
- console.log(`Soul files: ${result.soulFiles.length}`);
3360
- console.log(`Memory dirs: ${result.memoryDirs.length}`);
3361
- console.log(`Never-do gates: ${gates.gateCount}`);
3362
- return;
3363
- }
3364
-
3365
- if (subcommand === 'context') {
3366
- const task = args.task || process.argv.slice(4).find((arg) => !arg.startsWith('--')) || '';
3367
- const pack = buildContextPack(CWD, { task });
3368
- if (args.json) {
3369
- console.log(JSON.stringify(pack, null, 2));
3370
- return;
3371
- }
3372
- process.stdout.write(formatContextPack(pack));
3373
- return;
3374
- }
3375
-
3376
- if (subcommand === 'remember') {
3377
- const title = args.title || process.argv.slice(4).find((arg) => !arg.startsWith('--')) || '';
3378
- const result = recordMemory(CWD, {
3379
- type: args.type,
3380
- title,
3381
- content: args.content || title,
3382
- reason: args.reason,
3383
- source: args.source,
3384
- tags: args.tags,
3385
- date: args.date,
3386
- });
3387
- if (args.json) {
3388
- console.log(JSON.stringify(result, null, 2));
3389
- return;
3390
- }
3391
- if (!result.ok) {
3392
- console.error(result.error);
3393
- process.exit(1);
3394
- }
3395
- console.log(`Stored brain memory: ${result.path}`);
3396
- return;
3397
- }
3398
-
3399
- if (subcommand === 'check') {
3400
- const text = args.text || args.action || readStdinText();
3401
- const result = checkNeverDo(CWD, { text });
3402
- if (args.json) {
3403
- console.log(JSON.stringify(result, null, 2));
3404
- if (!result.ok) process.exit(2);
3405
- return;
3406
- }
3407
- console.log(`ThumbGate brain decision: ${result.decision.toUpperCase()}`);
3408
- for (const rule of result.blocked) console.log(`- ${rule.text}`);
3409
- if (!result.ok) process.exit(2);
3410
- return;
3411
- }
3412
-
3413
- if (subcommand === 'cleanup') {
3414
- const report = cleanupReport(CWD, args);
3415
- if (args.json) {
3416
- console.log(JSON.stringify(report, null, 2));
3417
- return;
3418
- }
3419
- console.log('ThumbGate brain cleanup report');
3420
- console.log('='.repeat(31));
3421
- console.log(`Memory files: ${report.total}`);
3422
- console.log(`Unsourced : ${report.unsourced.length}`);
3423
- console.log(`Stale : ${report.stale.length}`);
3424
- console.log(`Duplicates : ${report.duplicates.length}`);
3425
- if (report.unsourced.length) {
3426
- console.log('\nUnsourced files:');
3427
- for (const filePath of report.unsourced) console.log(`- ${filePath}`);
3428
- }
3429
- return;
3430
- }
3431
-
3432
- console.error('Usage: npx thumbgate brain init|context|remember|check|cleanup [--json]');
3433
- process.exit(1);
3434
- }
3435
-
3436
3321
  async function teamSync() {
3437
3322
  const { execSync } = require('child_process');
3438
3323
 
@@ -3611,127 +3496,6 @@ switch (COMMAND) {
3611
3496
  }
3612
3497
  break;
3613
3498
  }
3614
- case 'dream':
3615
- case 'consolidate': {
3616
- const args = parseArgs(process.argv.slice(3));
3617
- const { dream } = require(path.join(PKG_ROOT, 'scripts', 'dream-consolidation'));
3618
- dream({
3619
- pkgRoot: PKG_ROOT,
3620
- feedbackDir: args['feedback-dir'] || args.feedbackDir || CWD,
3621
- rulesPath: args.output || path.join(CWD, '.thumbgate', 'prevention-rules.md'),
3622
- minOccurrences: args.min || 2,
3623
- }).then(async (result) => {
3624
- try {
3625
- await cmdBrain({ write: true });
3626
- } catch (brainErr) {
3627
- console.warn(`⚠️ Failed to rebuild context brain: ${brainErr.message}`);
3628
- }
3629
- if (args.json) {
3630
- console.log(JSON.stringify(result, null, 2));
3631
- } else {
3632
- console.log(`✨ [Dreaming] Consolidation complete! Merged ${result.consolidated} duplicate(s) into ${result.lessonsCount} lessons.`);
3633
- }
3634
- process.exit(0);
3635
- }).catch((err) => {
3636
- console.error('❌ Error during memory consolidation:', err && err.message ? err.message : err);
3637
- process.exit(1);
3638
- });
3639
- break;
3640
- }
3641
- case 'triage':
3642
- case 'hygiene': {
3643
- const args = parseArgs(process.argv.slice(3));
3644
- const { runTriageLoop } = require(path.join(PKG_ROOT, 'scripts', 'triage-loop'));
3645
-
3646
- if (args.schedule) {
3647
- const { createSchedule } = require(path.join(PKG_ROOT, 'scripts', 'schedule-manager'));
3648
- const scheduleResult = createSchedule({
3649
- id: 'thumbgate-triage-hygiene',
3650
- name: 'ThumbGate Triage & Hygiene Loop',
3651
- description: 'Run autonomous git checks, test suite verification, and Silicon Dreaming memory consolidation.',
3652
- schedule: args.schedule,
3653
- command: `const { runTriageLoop } = require('${path.join(PKG_ROOT, 'scripts', 'triage-loop')}'); runTriageLoop({ cwd: '${CWD}', pkgRoot: '${PKG_ROOT}' }).catch(console.error);`,
3654
- workingDirectory: CWD,
3655
- });
3656
- if (args.json) {
3657
- console.log(JSON.stringify(scheduleResult, null, 2));
3658
- } else {
3659
- if (scheduleResult.success) {
3660
- console.log(`✅ [Triage] Scheduled triage hygiene loop: ${scheduleResult.message}`);
3661
- } else {
3662
- console.error(`❌ [Triage] Failed to schedule: ${scheduleResult.error}`);
3663
- process.exit(1);
3664
- }
3665
- }
3666
- break;
3667
- }
3668
-
3669
- runTriageLoop({
3670
- cwd: CWD,
3671
- pkgRoot: PKG_ROOT,
3672
- }).then(async (result) => {
3673
- try {
3674
- await cmdBrain({ write: true });
3675
- } catch (brainErr) {
3676
- console.warn(`⚠️ Failed to rebuild context brain: ${brainErr.message}`);
3677
- }
3678
- if (args.json) {
3679
- console.log(JSON.stringify(result, null, 2));
3680
- } else {
3681
- console.log(result.log);
3682
- }
3683
- process.exit(0);
3684
- }).catch((err) => {
3685
- console.error('❌ Error during triage loop execution:', err && err.message ? err.message : err);
3686
- process.exit(1);
3687
- });
3688
- break;
3689
- }
3690
- case 'community': {
3691
- const args = parseArgs(process.argv.slice(3));
3692
- const sub = process.argv.slice(3).find((arg) => !arg.startsWith('--'));
3693
- const { queryCommunity, shareRule } = require(path.join(PKG_ROOT, 'scripts', 'community-knowledge'));
3694
-
3695
- if (sub === 'query') {
3696
- const queryIdx = process.argv.indexOf('query');
3697
- const queryText = process.argv.slice(queryIdx + 1).filter(arg => !arg.startsWith('--')).join(' ');
3698
- const result = queryCommunity(queryText, { remote: args.remote });
3699
- if (args.json) {
3700
- console.log(JSON.stringify(result, null, 2));
3701
- } else {
3702
- console.log(`🔍 Found ${result.resultsCount} community rule(s) matching "${result.query}":`);
3703
- for (const r of result.results) {
3704
- console.log(`\n- [${r.id}] ${r.rule}`);
3705
- console.log(` Remedy: ${r.remedy}`);
3706
- console.log(` Explanation: ${r.explanation}`);
3707
- }
3708
- }
3709
- process.exit(0);
3710
- } else if (sub === 'share') {
3711
- const shareIdx = process.argv.indexOf('share');
3712
- const ruleId = process.argv.slice(shareIdx + 1).find(arg => !arg.startsWith('--'));
3713
- if (!ruleId) {
3714
- console.error('❌ Error: rule ID is required for share subcommand.');
3715
- process.exit(1);
3716
- }
3717
- const result = shareRule(ruleId, { feedbackDir: CWD });
3718
- if (args.json) {
3719
- console.log(JSON.stringify(result, null, 2));
3720
- } else {
3721
- if (result.ok) {
3722
- console.log(`✨ Successfully shared rule "${ruleId}" to community registry.`);
3723
- } else {
3724
- console.error(`❌ Failed to share rule: ${result.error}`);
3725
- process.exit(1);
3726
- }
3727
- }
3728
- process.exit(0);
3729
- } else {
3730
- console.error('Usage: npx thumbgate community query <error> | share <rule-id> [--json]');
3731
- process.exit(1);
3732
- }
3733
- break;
3734
- }
3735
3499
  case 'billing:setup':
3736
3500
  require(path.join(PKG_ROOT, 'scripts', 'billing-setup'));
3737
3501
  break;
@@ -4099,6 +3863,14 @@ switch (COMMAND) {
4099
3863
  case 'pulse':
4100
3864
  pulse();
4101
3865
  break;
3866
+ case 'check-update':
3867
+ case 'upgrade-check':
3868
+ checkUpdateCmd();
3869
+ break;
3870
+ case 'self-update':
3871
+ case 'upgrade-cli':
3872
+ selfUpdateCmd();
3873
+ break;
4102
3874
  case 'dispatch':
4103
3875
  case 'dispatch-brief':
4104
3876
  dispatchBrief();
@@ -4124,6 +3896,53 @@ switch (COMMAND) {
4124
3896
  });
4125
3897
  break;
4126
3898
  }
3899
+ case 'hermes-gate': {
3900
+ // Nous Research Hermes Agent `pre_tool_call` shell hook.
3901
+ // Hermes pipes each pending tool call as JSON to stdin and reads a decision from stdout;
3902
+ // {"decision":"block","reason":...} vetoes the call. We reuse the SAME gate pipeline as
3903
+ // `gate-check` (runAsync → secret guard, security scan, force-push / skill_manage / learned
3904
+ // prevention rules) and translate the verdict into Hermes's format.
3905
+ //
3906
+ // Hermes `pre_tool_call` is binary (block or allow) with no warn channel, and the whole point
3907
+ // of wiring it is to gate, so we run STRICT enforcement by default — otherwise ThumbGate's
3908
+ // warn-by-default posture would pass every deny through and the hook would block nothing.
3909
+ // Opt out with THUMBGATE_HERMES_WARN_ONLY=1; THUMBGATE_HOTFIX_BYPASS=1 still disables checks.
3910
+ // Wire it in ~/.hermes/config.yaml — see adapters/hermes/config.yaml.
3911
+ if (process.env.THUMBGATE_HERMES_WARN_ONLY !== '1' && process.env.THUMBGATE_HOTFIX_BYPASS !== '1') {
3912
+ process.env.THUMBGATE_STRICT_ENFORCEMENT = '1';
3913
+ }
3914
+ const { runAsync: hermesGateRun } = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
3915
+ let hermesStdin = '';
3916
+ process.stdin.setEncoding('utf8');
3917
+ process.stdin.on('data', (chunk) => { hermesStdin += chunk; });
3918
+ process.stdin.on('end', async () => {
3919
+ try {
3920
+ const payload = JSON.parse(hermesStdin);
3921
+ // Hermes sends snake_case tool_name/tool_input — gates-engine reads these directly.
3922
+ const verdict = await hermesGateRun({ tool_name: payload.tool_name, tool_input: payload.tool_input });
3923
+ let parsed = {};
3924
+ try { parsed = JSON.parse(verdict); } catch (_e) { parsed = {}; }
3925
+ const hso = parsed.hookSpecificOutput || {};
3926
+ if (hso.permissionDecision === 'deny') {
3927
+ process.stdout.write(JSON.stringify({
3928
+ decision: 'block',
3929
+ reason: hso.permissionDecisionReason || 'Blocked by ThumbGate prevention rule.',
3930
+ }) + '\n');
3931
+ } else {
3932
+ // warn / no match → allow. The gate engine already logged the decision.
3933
+ process.stdout.write(JSON.stringify({}) + '\n');
3934
+ }
3935
+ process.exit(0);
3936
+ } catch (err) {
3937
+ // Hermes hooks fail OPEN on error/timeout — emit an explicit allow so a gate fault
3938
+ // never wedges the agent (reliability ≈ enforcement; keep this fast).
3939
+ process.stderr.write(`hermes-gate error: ${err.message}\n`);
3940
+ process.stdout.write(JSON.stringify({}) + '\n');
3941
+ process.exit(0);
3942
+ }
3943
+ });
3944
+ break;
3945
+ }
4127
3946
  case 'gate-stats':
4128
3947
  gateStats();
4129
3948
  break;
@@ -37,18 +37,6 @@
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
- },
52
40
  {
53
41
  "id": "protect-production-sql",
54
42
  "name": "Protect production SQL",
@@ -589,198 +577,6 @@
589
577
  "roi": "Critical for compliance, forensics, and feedback loops. Enables proper capture of agent-specific lessons and prevention rules. Matches industry push (Okta, etc.).",
590
578
  "rollout": "Block any claw or autonomous agent action that authenticates as a human user. Require dedicated agent service accounts / identities with scoped permissions."
591
579
  },
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
- },
784
580
  {
785
581
  "id": "gate-claw-file-system-access",
786
582
  "name": "Gate claw-style agent file system access",
@@ -829,30 +625,6 @@
829
625
  "roi": "Preserves security invariants by ensuring that synthesized skills never write code patterns blocked by active ThumbGate rules.",
830
626
  "rollout": "Scan synthesized skill markdown content for pattern overlap with active prevention rules before writing to the skills directory."
831
627
  },
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
- },
856
628
  {
857
629
  "id": "require-human-in-the-loop-pause",
858
630
  "name": "Enforce Human-in-the-Loop pause for critical decisions",