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.
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/llms.txt +2 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +2 -4
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/adapters/policy-engine/ethicore-guardian-client.js +68 -0
- package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +260 -0
- package/bin/cli.js +78 -259
- package/config/gate-templates.json +0 -228
- package/config/gates/claim-verification.json +0 -18
- package/package.json +35 -25
- package/public/assets/brand/thumbgate-logo-transparent.svg +22 -0
- package/public/assets/brand/thumbgate-mark-inline-v3.svg +19 -0
- package/public/assets/brand/thumbgate-mark.svg +11 -5
- package/public/blog.html +0 -30
- package/public/brand/thumbgate-mark.svg +9 -5
- package/public/chatgpt-app.html +2 -2
- package/public/compare.html +2 -1
- package/public/dashboard.html +1 -1
- package/public/federal.html +1 -1
- package/public/index.html +95 -216
- package/public/learn.html +59 -35
- package/public/lessons.html +1 -1
- package/public/numbers.html +2 -2
- package/public/pro.html +7 -7
- package/scripts/aws-blocks-guardrails.js +228 -0
- package/scripts/cli-schema.js +22 -10
- package/scripts/dashboard-chat.js +2 -1
- package/scripts/document-intake.js +1 -49
- package/scripts/durability/step.js +3 -3
- package/scripts/gate-stats.js +5 -11
- package/scripts/gates-engine.js +0 -49
- package/scripts/gemini-embedding-policy.js +2 -1
- package/scripts/hook-stop-anti-claim.js +116 -184
- package/scripts/hosted-config.js +0 -12
- package/scripts/lesson-search.js +1 -15
- package/scripts/llm-client.js +187 -5
- package/scripts/plausible-domain-config.js +3 -1
- package/scripts/seo-gsd.js +240 -1
- package/scripts/tool-registry.js +2 -2
- package/scripts/vector-store.js +44 -0
- package/scripts/workspace-evolver.js +62 -2
- package/src/api/server.js +340 -131
- package/public/assets/brand/thumbgate-mark-inline.svg +0 -15
- package/public/compare/adopt-ai.html +0 -219
- package/public/compare/agentix-labs.html +0 -197
- package/public/compare/ai-experience-orchestration.html +0 -216
- package/public/compare/anthropic-claude-for-legal.html +0 -260
- package/public/compare/anthropic-containment.html +0 -280
- package/public/compare/arcade.html +0 -175
- package/public/compare/arcjet.html +0 -239
- package/public/compare/bumblebee.html +0 -307
- package/public/compare/claude-code-hooks.html +0 -294
- package/public/compare/databricks-unity-ai-gateway.html +0 -215
- package/public/compare/fallow.html +0 -351
- package/public/compare/heidi.html +0 -233
- package/public/compare/mem0.html +0 -342
- package/public/compare/oak-and-sparrow-gatekeeper.html +0 -289
- package/public/compare/rein.html +0 -236
- package/public/compare/sigmashake.html +0 -256
- package/public/compare/speclock.html +0 -342
- package/public/guides/agent-harness-optimization.html +0 -342
- package/public/guides/agentic-web-governance.html +0 -406
- package/public/guides/ai-agent-governance-sprint.html +0 -415
- package/public/guides/ai-agent-pre-action-approval-gates.html +0 -401
- package/public/guides/ai-agent-workflow-migration-checklist.html +0 -392
- package/public/guides/ai-deployment-readiness.html +0 -415
- package/public/guides/ai-mode-ads-agent-governance.html +0 -401
- package/public/guides/ai-search-topical-presence.html +0 -342
- package/public/guides/autoresearch-agent-safety.html +0 -342
- package/public/guides/background-agent-governance.html +0 -358
- package/public/guides/best-tools-stop-ai-agents-breaking-production.html +0 -363
- package/public/guides/browser-automation-safety.html +0 -342
- package/public/guides/chatgpt-ads-trust.html +0 -353
- package/public/guides/claude-code-feedback.html +0 -339
- package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
- package/public/guides/claude-code-skills-guardrails.html +0 -343
- package/public/guides/claude-desktop.html +0 -356
- package/public/guides/code-knowledge-graph-guardrails.html +0 -365
- package/public/guides/codex-cli-guardrails.html +0 -339
- package/public/guides/cursor-agent-guardrails.html +0 -339
- package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
- package/public/guides/database-agent-safety.html +0 -406
- package/public/guides/deepseek-v4-runtime-guardrails.html +0 -346
- package/public/guides/developer-machine-supply-chain-guardrails.html +0 -358
- package/public/guides/gcp-mcp-guardrails.html +0 -147
- package/public/guides/gemini-cli-feedback-memory.html +0 -339
- package/public/guides/gpt-5-5-model-evaluation.html +0 -358
- package/public/guides/internal-ai-engineering-stack-guardrails.html +0 -348
- package/public/guides/long-running-agent-context-management.html +0 -346
- package/public/guides/mcp-tool-governance.html +0 -401
- package/public/guides/multica-thumbgate-setup.html +0 -134
- package/public/guides/native-messaging-host-security.html +0 -342
- package/public/guides/policy-engine-pre-action-gates.html +0 -346
- package/public/guides/pre-action-checks.html +0 -342
- package/public/guides/pretooluse-hooks-vs-advisory-prompt-rules.html +0 -342
- package/public/guides/prompt-tricks-to-workflow-rules.html +0 -365
- package/public/guides/proxy-pointer-rag-guardrails.html +0 -352
- package/public/guides/rag-precision-tuning-guardrails.html +0 -352
- package/public/guides/reasoning-compression-guardrails.html +0 -346
- package/public/guides/relational-knowledge-ai-recommendations.html +0 -342
- package/public/guides/roo-code-alternative-cline.html +0 -339
- package/public/guides/semantic-programmatic-seo-guardrails.html +0 -352
- package/public/guides/seo-agent-skills-guardrails.html +0 -344
- package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -342
- package/public/learn/ac-dc-runtime-enforcement.html +0 -277
- package/public/learn/agent-harness-pattern.html +0 -181
- package/public/learn/agent-identity-connector-governance.html +0 -146
- package/public/learn/agent-swarms-shared-gates.html +0 -173
- package/public/learn/agentic-enterprise-context-brain.html +0 -117
- package/public/learn/agentic-os-team-governance.html +0 -146
- package/public/learn/ai-agent-governance.html +0 -158
- package/public/learn/ai-agent-persistent-memory.html +0 -211
- package/public/learn/anthropomorphic-claim-gates.html +0 -180
- package/public/learn/background-agent-control-layer.html +0 -184
- package/public/learn/claude-code-goal-with-rubrics.html +0 -205
- package/public/learn/codex-role-plugins-need-governance.html +0 -125
- package/public/learn/cost-aware-agent-gate-routing.html +0 -173
- package/public/learn/databricks-unity-ai-gateway-runtime-governance.html +0 -157
- package/public/learn/deterministic-agent-workflows.html +0 -185
- package/public/learn/feedback-loop-vs-decision-layer.html +0 -283
- package/public/learn/from-prototype-to-production.html +0 -223
- package/public/learn/learn.css +0 -51
- package/public/learn/mcp-pre-action-checks-explained.html +0 -172
- package/public/learn/pretix-stripe-connect-marketplaces.html +0 -161
- package/public/learn/regulated-agent-execution-boundary.html +0 -196
- package/public/learn/spec-driven-development.html +0 -168
- package/public/learn/stop-ai-agent-force-push.html +0 -134
- package/public/learn/vibe-coding-safety-net.html +0 -142
- 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.
|
|
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",
|