thumbgate 1.35.0 → 1.37.1
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/.agents/skills/cyberstrike-compare-not-clone/SKILL.md +36 -0
- package/.agents/skills/gitlab-sandbox-allowlist-not-trust/SKILL.md +77 -0
- package/.agents/skills/jit-harness-compare-not-clone/SKILL.md +34 -0
- package/.agents/skills/openui-catalog-compose-honesty/SKILL.md +64 -0
- package/.agents/skills/zvec-grep-compare-not-clone/SKILL.md +34 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/llms.txt +1 -0
- package/.well-known/mcp/server-card.json +1 -1
- package/CONTRIBUTING.md +95 -0
- package/README.md +195 -632
- package/THIRD_PARTY_NOTICES.md +89 -0
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/forge/forge.yaml +3 -3
- package/adapters/future-agi/.mcp.json +8 -0
- package/adapters/future-agi/FUTURE_AGI.md +23 -0
- package/adapters/future-agi/config.toml +3 -0
- package/adapters/future-agi/future-agi-bridge.js +9 -0
- package/adapters/future-agi/opencode.json +8 -0
- package/adapters/herdr/herdr-plugin.toml +18 -0
- package/adapters/mcp/server-stdio.js +238 -25
- package/adapters/opencode/opencode.json +1 -1
- package/adapters/workos/WORKOS.md +52 -0
- package/bin/cli.js +336 -3
- package/bin/futureagi-bridge +9 -0
- package/config/gate-templates.json +581 -4
- package/config/gates/actor-critic-audit.json +34 -0
- package/config/gates/default.json +9 -3
- package/config/gates/five-walls-governance.json +34 -0
- package/config/gates/future-agi-guardrails.json +34 -0
- package/config/gates/radware-threat-defense-2026.json +61 -0
- package/config/gates/simatree-data-governance.json +33 -0
- package/config/mcp-allowlists.json +4 -0
- package/config/merge-quality-checks.json +6 -0
- package/config/model-candidates.json +312 -29
- package/config/model-tiers.json +18 -0
- package/config/post-deploy-marketing-pages.json +10 -0
- package/config/progressive/01-wire-only.json +11 -0
- package/config/progressive/02-dashboard-empty-ok.json +10 -0
- package/config/progressive/03-one-lesson.json +10 -0
- package/config/progressive/04-warn-fires.json +11 -0
- package/config/progressive/05-strict-optional.json +11 -0
- package/config/progressive/README.md +15 -0
- package/config/schemas/broker-execution-receipt.schema.json +139 -0
- package/config/schemas/provider-execution-attestation-v1.schema.json +58 -0
- package/conformance/provider-attestation/vectors.json +320 -0
- package/docs/specs/provider-execution-attestation-v1.md +69 -0
- package/openapi/openapi.yaml +15 -0
- package/package.json +390 -148
- package/public/about.html +2 -2
- package/public/ai-malpractice-prevention.html +7 -7
- package/public/blog/a-10-dollar-vps-is-not-a-computer.html +143 -0
- package/public/blog/a-receipt-is-not-world-state.html +388 -0
- package/public/blog/git-at-agent-scale.html +374 -0
- package/public/blog/no-llm-in-the-gate.html +133 -0
- package/public/blog.html +80 -0
- package/public/case-studies.html +16 -1
- package/public/compare.html +28 -0
- package/public/diagnostic.html +216 -7
- package/public/docs/connectors.html +39 -0
- package/public/federal.html +2 -2
- package/public/founders.html +639 -0
- package/public/index.html +87 -9
- package/public/install.html +8 -8
- package/public/learn.html +39 -0
- package/public/numbers.html +2 -2
- package/public/peter.html +310 -0
- package/public/platform-partners.html +119 -0
- package/public/pricing.html +24 -3
- package/public/privacy.html +117 -0
- package/public/pro.html +17 -0
- package/public/support.html +62 -0
- package/public/terms.html +130 -0
- package/public/third-party-notices.html +95 -0
- package/public/yt.html +351 -0
- package/scripts/action-receipts.js +133 -3
- package/scripts/adaptive-governance-arena.js +349 -0
- package/scripts/admin-override.js +205 -0
- package/scripts/agent-action-inventory.js +869 -0
- package/scripts/agent-audit-trace.js +42 -2
- package/scripts/agent-egress-policy.js +1117 -0
- package/scripts/agent-memory-lifecycle.js +141 -2
- package/scripts/agent-operations-planner.js +441 -1
- package/scripts/agent-readiness.js +68 -0
- package/scripts/agent-security-central.js +647 -0
- package/scripts/allowlist-bridge-honesty.js +417 -0
- package/scripts/async-job-runner.js +102 -11
- package/scripts/audit-trail.js +212 -0
- package/scripts/billing.js +1 -1
- package/scripts/broker-execution-receipts.js +719 -0
- package/scripts/budget-aware-gates-proof.js +423 -0
- package/scripts/claude-feedback-sync.js +29 -3
- package/scripts/claw-harness-production.js +237 -0
- package/scripts/cli-schema.js +163 -1
- package/scripts/codex-runbook-flywheel.js +318 -0
- package/scripts/context-footprint.js +186 -0
- package/scripts/contextfs.js +143 -61
- package/scripts/dashboard.js +251 -32
- package/scripts/deepseek-v4-runtime-guardrails.js +72 -6
- package/scripts/docker-sandbox-planner.js +18 -0
- package/scripts/double-blind-eval-protocol.js +252 -0
- package/scripts/edotenv-rl-gateway.js +259 -0
- package/scripts/ensure-production-search-corpus.js +162 -0
- package/scripts/eval-holdout.js +311 -0
- package/scripts/feedback-aggregate.js +21 -2
- package/scripts/feedback-loop.js +87 -5
- package/scripts/feedback-quality.js +9 -0
- package/scripts/file-ledger-lock.js +4 -1
- package/scripts/financial-control-plane.js +41 -1
- package/scripts/find-dormant-requires.js +118 -0
- package/scripts/fs-utils.js +84 -8
- package/scripts/gates-engine.js +810 -63
- package/scripts/generate-case-study-outreach.js +24 -15
- package/scripts/git-at-scale.js +628 -0
- package/scripts/governance-conflict-audit.js +1650 -0
- package/scripts/governance-difficulty-curriculum.js +328 -0
- package/scripts/graphrag-retrieval.js +275 -0
- package/scripts/gurobi-optimizer.js +324 -0
- package/scripts/gurobi_optimizer.py +485 -0
- package/scripts/harness-selector.js +82 -1
- package/scripts/hidden-entry-points.js +284 -0
- package/scripts/human-escalation.js +199 -1
- package/scripts/hybrid-feedback-context.js +152 -19
- package/scripts/intent-governed-execution.js +602 -0
- package/scripts/intervention-policy.js +123 -20
- package/scripts/jit-harness-compose.js +628 -0
- package/scripts/jsonl-watcher.js +10 -0
- package/scripts/lesson-embedding-index.js +95 -12
- package/scripts/lesson-retrieval.js +105 -19
- package/scripts/local-model-profile.js +19 -2
- package/scripts/mailer/resend-mailer.js +1 -1
- package/scripts/matryoshka-embedding.js +235 -0
- package/scripts/mcp-oauth.js +42 -4
- package/scripts/mcp-session-handles.js +1016 -0
- package/scripts/mcp-wiring-doctor.js +314 -0
- package/scripts/memory-firewall.js +115 -2
- package/scripts/memory-scope-readiness.js +299 -0
- package/scripts/memory-vs-rag-route.js +161 -0
- package/scripts/model-tier-router.js +148 -21
- package/scripts/nvidia-specdecode-al-doctor.js +536 -0
- package/scripts/openui-catalog-compose-honesty.js +593 -0
- package/scripts/operational-integrity.js +19 -1
- package/scripts/override-audit.js +213 -0
- package/scripts/package-manager-honesty-doctor.js +458 -0
- package/scripts/pr-manager.js +63 -1
- package/scripts/prove-herdr-adapter.js +52 -0
- package/scripts/prove-memory-pyramid-and-symbolic-canvas.js +95 -0
- package/scripts/prove-workos.js +73 -0
- package/scripts/provider-attestation-conformance.js +192 -0
- package/scripts/provider-receipt-contract.js +136 -0
- package/scripts/qwen38-max-cost-optimizer.js +401 -0
- package/scripts/radware-threat-defense.js +280 -0
- package/scripts/rag-embedding-identity.js +221 -0
- package/scripts/rag-precision-guardrails.js +112 -2
- package/scripts/remote-feedback-capture.js +159 -0
- package/scripts/research-agent-harness.js +256 -0
- package/scripts/rsi-safety-hillclimb.js +200 -0
- package/scripts/rule-sprawl.js +188 -0
- package/scripts/schedule-manager.js +147 -0
- package/scripts/self-heal.js +8 -0
- package/scripts/session-lease.js +415 -0
- package/scripts/simatree-data-governance.js +347 -0
- package/scripts/slo-alert-engine.js +172 -7
- package/scripts/solver-parity.js +539 -0
- package/scripts/stealth-memory-injection-gate.js +333 -0
- package/scripts/switchyard-router.js +366 -0
- package/scripts/telemetry-analytics.js +84 -27
- package/scripts/temporal-decay-weighting.js +138 -0
- package/scripts/test-all.js +165 -0
- package/scripts/token-savings.js +42 -0
- package/scripts/tool-kpi-tracker.js +108 -5
- package/scripts/tool-registry.js +193 -5
- package/scripts/universal-claim-evaluator.js +14 -2
- package/scripts/vector-store.js +279 -9
- package/scripts/workflow-notebook.js +391 -0
- package/scripts/workflow-sentinel.js +111 -12
- package/scripts/workos-production-guard.js +260 -0
- package/scripts/workspace-search-route.js +515 -0
- package/server.json +2 -2
- package/src/agent-identity-boundary.js +76 -0
- package/src/agent-retrieval-cache.js +155 -0
- package/src/alert-noise-ledger.js +502 -0
- package/src/api/server.js +724 -153
- package/src/git-fast-cache.js +220 -0
- package/src/git-wal-sync.js +156 -0
- package/src/hash-anchored-edit.js +82 -0
- package/src/hermes-platform-protocol.js +475 -0
- package/src/hermes-sync-plane.js +241 -0
- package/src/index.js +30 -1
- package/src/iso42001-compliance-guard.js +97 -0
- package/src/latency-budget.js +244 -0
- package/src/mcp-writeguard.js +316 -0
- package/src/miminions-adapter.js +106 -0
- package/src/pipeline-compass.js +104 -0
- package/src/ppl-alert-pipeline.js +284 -0
- package/src/rendezvous-router.js +90 -0
- package/src/security-questionnaire.js +195 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Intent → governed execution doctor — CyberStrikeAI FORMAT steal.
|
|
6
|
+
*
|
|
7
|
+
* Steals the process shape from Ed1s0nZ/CyberStrikeAI (via @tom_doerr):
|
|
8
|
+
* natural-language intent → risk class → required governance rails
|
|
9
|
+
* → HITL when high/critical → evidence back into memory
|
|
10
|
+
*
|
|
11
|
+
* Maps onto EXISTING ThumbGate rails:
|
|
12
|
+
* intent-router, harness-selector, PreToolUse/gates-engine,
|
|
13
|
+
* admin-override / protectedApprovals, subagent-profiles maxChars,
|
|
14
|
+
* lesson-retrieval / capture-feedback
|
|
15
|
+
*
|
|
16
|
+
* Does NOT clone CyberStrikeAI, CloudWeGo Eino, WebShell, C2, or a pentest SKU.
|
|
17
|
+
* Offensive/cyber tooling stays fail-closed unless THUMBGATE_ALLOW_OFFENSIVE=1.
|
|
18
|
+
*
|
|
19
|
+
* Source inspiration (not affiliated):
|
|
20
|
+
* https://github.com/Ed1s0nZ/CyberStrikeAI
|
|
21
|
+
* https://x.com/tom_doerr/status/2094509419929174170
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const fs = require('node:fs');
|
|
25
|
+
const path = require('node:path');
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
selectHarnessName,
|
|
29
|
+
HARNESSES,
|
|
30
|
+
} = require('./harness-selector');
|
|
31
|
+
const {
|
|
32
|
+
listSubagentProfiles,
|
|
33
|
+
getSubagentProfile,
|
|
34
|
+
} = require('./subagent-profiles');
|
|
35
|
+
const {
|
|
36
|
+
RISK_LEVELS,
|
|
37
|
+
evaluatePlanQuality,
|
|
38
|
+
getRequiredApprovalRisks,
|
|
39
|
+
loadPolicyBundle,
|
|
40
|
+
} = require('./intent-router');
|
|
41
|
+
|
|
42
|
+
const SOURCE_URL = 'https://github.com/Ed1s0nZ/CyberStrikeAI';
|
|
43
|
+
const SOURCE_POST = 'https://x.com/tom_doerr/status/2094509419929174170';
|
|
44
|
+
|
|
45
|
+
const RISK_ORDER = Object.freeze({
|
|
46
|
+
low: 0,
|
|
47
|
+
medium: 1,
|
|
48
|
+
high: 2,
|
|
49
|
+
critical: 3,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const INTENT_CLASSES = Object.freeze({
|
|
53
|
+
code_edit: {
|
|
54
|
+
label: 'code edit',
|
|
55
|
+
risk: 'medium',
|
|
56
|
+
harness: 'code-edit',
|
|
57
|
+
profile: 'pr_workflow',
|
|
58
|
+
hitl: false,
|
|
59
|
+
},
|
|
60
|
+
review: {
|
|
61
|
+
label: 'review / read-only',
|
|
62
|
+
risk: 'low',
|
|
63
|
+
harness: null,
|
|
64
|
+
profile: 'review_workflow',
|
|
65
|
+
hitl: false,
|
|
66
|
+
},
|
|
67
|
+
deploy: {
|
|
68
|
+
label: 'deploy / publish',
|
|
69
|
+
risk: 'high',
|
|
70
|
+
harness: 'deploy',
|
|
71
|
+
profile: 'secure_runtime',
|
|
72
|
+
hitl: true,
|
|
73
|
+
},
|
|
74
|
+
db_write: {
|
|
75
|
+
label: 'database write',
|
|
76
|
+
risk: 'high',
|
|
77
|
+
harness: 'db-write',
|
|
78
|
+
profile: 'secure_runtime',
|
|
79
|
+
hitl: true,
|
|
80
|
+
},
|
|
81
|
+
secret_or_auth: {
|
|
82
|
+
label: 'secrets / auth change',
|
|
83
|
+
risk: 'critical',
|
|
84
|
+
harness: 'five-walls-governance',
|
|
85
|
+
profile: 'secure_runtime',
|
|
86
|
+
hitl: true,
|
|
87
|
+
},
|
|
88
|
+
offensive_cyber: {
|
|
89
|
+
label: 'offensive / pentest tooling',
|
|
90
|
+
risk: 'critical',
|
|
91
|
+
harness: 'radware-threat-defense',
|
|
92
|
+
profile: 'secure_runtime',
|
|
93
|
+
hitl: true,
|
|
94
|
+
requiresOffensiveGrant: true,
|
|
95
|
+
},
|
|
96
|
+
recon_readonly: {
|
|
97
|
+
label: 'authorized recon (read-only)',
|
|
98
|
+
risk: 'medium',
|
|
99
|
+
harness: null,
|
|
100
|
+
profile: 'review_workflow',
|
|
101
|
+
hitl: false,
|
|
102
|
+
},
|
|
103
|
+
default: {
|
|
104
|
+
label: 'general intent',
|
|
105
|
+
risk: 'medium',
|
|
106
|
+
harness: null,
|
|
107
|
+
profile: 'pr_workflow',
|
|
108
|
+
hitl: false,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const GOVERNANCE_STEPS = Object.freeze([
|
|
113
|
+
{
|
|
114
|
+
id: 'classify',
|
|
115
|
+
label: 'Classify intent risk',
|
|
116
|
+
rails: ['intent-router evaluatePlanQuality', 'harness-selector'],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'authorize',
|
|
120
|
+
label: 'Authorization / scope',
|
|
121
|
+
rails: ['session-lease', 'task-scope', 'THUMBGATE_ALLOW_OFFENSIVE for offensive'],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'gate',
|
|
125
|
+
label: 'PreToolUse gates',
|
|
126
|
+
rails: ['gates-engine', 'config/gates harness', 'MCP allowlist'],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'hitl',
|
|
130
|
+
label: 'Human oversight when required',
|
|
131
|
+
rails: ['admin-override grants', 'protectedApprovals', 'approve_protected_action'],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'execute',
|
|
135
|
+
label: 'Bounded tool execution',
|
|
136
|
+
rails: ['subagent-profiles', 'result maxChars / output caps'],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: 'evidence',
|
|
140
|
+
label: 'Evidence → operational memory',
|
|
141
|
+
rails: ['capture-feedback', 'lesson-retrieval', 'prevention-rules'],
|
|
142
|
+
},
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
function normalizeBoolean(value) {
|
|
146
|
+
if (value === true || value === 1) return true;
|
|
147
|
+
if (value === false || value === 0 || value == null) return false;
|
|
148
|
+
const s = String(value).trim().toLowerCase();
|
|
149
|
+
return s === '1' || s === 'true' || s === 'yes' || s === 'on';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function detectOffensiveGrant(env = process.env) {
|
|
153
|
+
return normalizeBoolean(env.THUMBGATE_ALLOW_OFFENSIVE);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function detectCloneAttempt(text) {
|
|
157
|
+
const t = String(text || '');
|
|
158
|
+
const hits = [];
|
|
159
|
+
if (/\b(clone|vendor|fork)\b/i.test(t) && /\b(CyberStrikeAI|cyberstrike)\b/i.test(t)) {
|
|
160
|
+
hits.push('cyberstrike_clone');
|
|
161
|
+
}
|
|
162
|
+
if (/\b(webshell|c2 beacon|metasploit|msfvenom)\b/i.test(t) && /\b(install|enable|ship)\b/i.test(t)) {
|
|
163
|
+
hits.push('offensive_sku_clone');
|
|
164
|
+
}
|
|
165
|
+
if (/\beino\b/i.test(t) && /\b(rebuild|vendor|cloudwego)\b/i.test(t)) {
|
|
166
|
+
hits.push('eino_framework_clone');
|
|
167
|
+
}
|
|
168
|
+
return [...new Set(hits)];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function classifyIntent(intentText, options = {}) {
|
|
172
|
+
const q = String(intentText || '').trim();
|
|
173
|
+
const reasons = [];
|
|
174
|
+
if (options.intentClass && INTENT_CLASSES[options.intentClass]) {
|
|
175
|
+
return {
|
|
176
|
+
intentClass: options.intentClass,
|
|
177
|
+
confidence: 1,
|
|
178
|
+
reasons: [`explicit intentClass=${options.intentClass}`],
|
|
179
|
+
gateHarness: INTENT_CLASSES[options.intentClass].harness,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (!q) {
|
|
183
|
+
return {
|
|
184
|
+
intentClass: 'default',
|
|
185
|
+
confidence: 0.35,
|
|
186
|
+
reasons: ['empty intent → default'],
|
|
187
|
+
gateHarness: null,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const toolName = options.toolName || 'Bash';
|
|
192
|
+
const gateHarness = selectHarnessName(toolName, { command: q, content: q });
|
|
193
|
+
if (gateHarness && HARNESSES[gateHarness]) {
|
|
194
|
+
reasons.push(`harness-selector → ${gateHarness}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (
|
|
198
|
+
/\b(nmap|nuclei|sqlmap|metasploit|msfvenom|hydra|hashcat|webshell|c2|bloodhound|mimikatz|exploit)\b/i.test(q)
|
|
199
|
+
|| /\b(pentest|penetration test|red.?team|offensive security|attack chain)\b/i.test(q)
|
|
200
|
+
) {
|
|
201
|
+
reasons.push('offensive / pentest vocabulary');
|
|
202
|
+
return {
|
|
203
|
+
intentClass: 'offensive_cyber',
|
|
204
|
+
confidence: 0.92,
|
|
205
|
+
reasons,
|
|
206
|
+
gateHarness: gateHarness || 'radware-threat-defense',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (/\b(recon|enumerate subdomain|httpx|read-only scan|authorized inventory)\b/i.test(q)) {
|
|
210
|
+
reasons.push('authorized recon vocabulary');
|
|
211
|
+
return { intentClass: 'recon_readonly', confidence: 0.8, reasons, gateHarness };
|
|
212
|
+
}
|
|
213
|
+
if (gateHarness === 'deploy' || /\b(deploy|railway|npm publish|docker push)\b/i.test(q)) {
|
|
214
|
+
reasons.push('deploy vocabulary');
|
|
215
|
+
return { intentClass: 'deploy', confidence: 0.9, reasons, gateHarness: 'deploy' };
|
|
216
|
+
}
|
|
217
|
+
if (gateHarness === 'db-write' || /\b(DROP TABLE|TRUNCATE|DELETE FROM|ALTER TABLE)\b/i.test(q)) {
|
|
218
|
+
reasons.push('db-write vocabulary');
|
|
219
|
+
return { intentClass: 'db_write', confidence: 0.9, reasons, gateHarness: 'db-write' };
|
|
220
|
+
}
|
|
221
|
+
if (/\b(secret|api[_-]?key|credential|rotate.?pat|chmod 777|\.pem|\.env)\b/i.test(q)) {
|
|
222
|
+
reasons.push('secret / auth vocabulary');
|
|
223
|
+
return {
|
|
224
|
+
intentClass: 'secret_or_auth',
|
|
225
|
+
confidence: 0.9,
|
|
226
|
+
reasons,
|
|
227
|
+
gateHarness: gateHarness || 'five-walls-governance',
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (/\b(review|read-only|audit PR|risk analysis)\b/i.test(q)) {
|
|
231
|
+
reasons.push('review vocabulary');
|
|
232
|
+
return { intentClass: 'review', confidence: 0.85, reasons, gateHarness };
|
|
233
|
+
}
|
|
234
|
+
if (gateHarness === 'code-edit' || /\b(implement|fix|refactor|patch|edit file)\b/i.test(q)) {
|
|
235
|
+
reasons.push('code-edit vocabulary');
|
|
236
|
+
return {
|
|
237
|
+
intentClass: 'code_edit',
|
|
238
|
+
confidence: 0.86,
|
|
239
|
+
reasons,
|
|
240
|
+
gateHarness: gateHarness || 'code-edit',
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
reasons.push('no strong class → default');
|
|
245
|
+
return { intentClass: 'default', confidence: 0.5, reasons, gateHarness };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function composeGovernance(classification, options = {}) {
|
|
249
|
+
const preset = INTENT_CLASSES[classification.intentClass] || INTENT_CLASSES.default;
|
|
250
|
+
const risk = options.risk && RISK_LEVELS.includes(options.risk)
|
|
251
|
+
? options.risk
|
|
252
|
+
: preset.risk;
|
|
253
|
+
const harness = options.harness || classification.gateHarness || preset.harness;
|
|
254
|
+
const profiles = listSubagentProfiles();
|
|
255
|
+
let profileName = options.profile || preset.profile;
|
|
256
|
+
if (!profiles.includes(profileName)) {
|
|
257
|
+
profileName = profiles.includes('pr_workflow') ? 'pr_workflow' : profiles[0] || null;
|
|
258
|
+
}
|
|
259
|
+
let profile = null;
|
|
260
|
+
if (profileName) {
|
|
261
|
+
try {
|
|
262
|
+
profile = getSubagentProfile(profileName);
|
|
263
|
+
} catch {
|
|
264
|
+
profile = null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
let requiredApprovalRisks = ['high', 'critical'];
|
|
269
|
+
try {
|
|
270
|
+
const bundle = loadPolicyBundle(options.bundleId);
|
|
271
|
+
requiredApprovalRisks = getRequiredApprovalRisks(
|
|
272
|
+
bundle,
|
|
273
|
+
profile?.mcpProfile || options.mcpProfile || 'default'
|
|
274
|
+
);
|
|
275
|
+
} catch {
|
|
276
|
+
// bundle optional for doctor map-only paths
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const hitlRequired = Boolean(
|
|
280
|
+
preset.hitl
|
|
281
|
+
|| requiredApprovalRisks.includes(risk)
|
|
282
|
+
|| RISK_ORDER[risk] >= RISK_ORDER.high
|
|
283
|
+
);
|
|
284
|
+
const approved = normalizeBoolean(options.approved);
|
|
285
|
+
const offensiveGrant = detectOffensiveGrant(options.env || process.env);
|
|
286
|
+
const needsOffensiveGrant = Boolean(preset.requiresOffensiveGrant);
|
|
287
|
+
|
|
288
|
+
const planQuality = evaluatePlanQuality({
|
|
289
|
+
intentId: classification.intentClass,
|
|
290
|
+
intent: { id: classification.intentClass, risk, description: preset.label },
|
|
291
|
+
context: String(options.intent || options.task || ''),
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const steps = GOVERNANCE_STEPS.map((step) => {
|
|
295
|
+
const copy = { ...step, status: 'pending' };
|
|
296
|
+
if (step.id === 'classify') copy.status = 'ready';
|
|
297
|
+
if (step.id === 'authorize') {
|
|
298
|
+
if (needsOffensiveGrant && !offensiveGrant) copy.status = 'blocked';
|
|
299
|
+
else copy.status = 'ready';
|
|
300
|
+
}
|
|
301
|
+
if (step.id === 'gate') {
|
|
302
|
+
copy.status = 'ready';
|
|
303
|
+
copy.harness = harness || 'default-gates-only';
|
|
304
|
+
}
|
|
305
|
+
if (step.id === 'hitl') {
|
|
306
|
+
copy.status = hitlRequired ? (approved ? 'satisfied' : 'required') : 'not_required';
|
|
307
|
+
}
|
|
308
|
+
if (step.id === 'execute') {
|
|
309
|
+
copy.status = (needsOffensiveGrant && !offensiveGrant) || (hitlRequired && !approved)
|
|
310
|
+
? 'blocked'
|
|
311
|
+
: 'ready';
|
|
312
|
+
copy.maxChars = profile?.context?.maxChars || null;
|
|
313
|
+
}
|
|
314
|
+
if (step.id === 'evidence') copy.status = 'after_execute';
|
|
315
|
+
return copy;
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
risk,
|
|
320
|
+
harness: harness || null,
|
|
321
|
+
subagentProfile: profileName,
|
|
322
|
+
mcpProfile: profile?.mcpProfile || null,
|
|
323
|
+
maxChars: profile?.context?.maxChars || null,
|
|
324
|
+
hitlRequired,
|
|
325
|
+
approved,
|
|
326
|
+
needsOffensiveGrant,
|
|
327
|
+
offensiveGrant,
|
|
328
|
+
requiredApprovalRisks,
|
|
329
|
+
planQuality,
|
|
330
|
+
steps,
|
|
331
|
+
nextActions: buildNextActions({
|
|
332
|
+
hitlRequired,
|
|
333
|
+
approved,
|
|
334
|
+
needsOffensiveGrant,
|
|
335
|
+
offensiveGrant,
|
|
336
|
+
harness,
|
|
337
|
+
profileName,
|
|
338
|
+
}),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function buildNextActions({
|
|
343
|
+
hitlRequired,
|
|
344
|
+
approved,
|
|
345
|
+
needsOffensiveGrant,
|
|
346
|
+
offensiveGrant,
|
|
347
|
+
harness,
|
|
348
|
+
profileName,
|
|
349
|
+
}) {
|
|
350
|
+
const actions = [];
|
|
351
|
+
if (needsOffensiveGrant && !offensiveGrant) {
|
|
352
|
+
actions.push({
|
|
353
|
+
id: 'set_offensive_grant',
|
|
354
|
+
command: 'export THUMBGATE_ALLOW_OFFENSIVE=1 # only for authorized systems you own',
|
|
355
|
+
why: 'Offensive/cyber intents are fail-closed without an explicit grant.',
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
if (hitlRequired && !approved) {
|
|
359
|
+
actions.push({
|
|
360
|
+
id: 'obtain_hitl',
|
|
361
|
+
command: 'npx thumbgate protect # or admin-override for a single gate id',
|
|
362
|
+
why: 'High/critical risk requires human oversight before tool execution.',
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (harness) {
|
|
366
|
+
actions.push({
|
|
367
|
+
id: 'load_harness',
|
|
368
|
+
command: `THUMBGATE_HARNESS=${harness} # additive on default.json`,
|
|
369
|
+
why: 'Specialized gate harness for this intent class.',
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
actions.push({
|
|
373
|
+
id: 'bound_profile',
|
|
374
|
+
command: `use subagent profile ${profileName || 'pr_workflow'}`,
|
|
375
|
+
why: 'Bound MCP tools + context maxChars (result governance).',
|
|
376
|
+
});
|
|
377
|
+
actions.push({
|
|
378
|
+
id: 'capture_evidence',
|
|
379
|
+
command: 'node .claude/scripts/feedback/capture-feedback.js --feedback=up|down --context="..."',
|
|
380
|
+
why: 'Evidence becomes operational memory (lessons → prevention rules).',
|
|
381
|
+
});
|
|
382
|
+
return actions;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function buildIntentGovernedExecutionReport(options = {}) {
|
|
386
|
+
const root = options.root
|
|
387
|
+
? path.resolve(String(options.root))
|
|
388
|
+
: path.resolve(__dirname, '..');
|
|
389
|
+
const intent = options.intent || options.task || options.query || '';
|
|
390
|
+
const findings = [];
|
|
391
|
+
const cloneHits = detectCloneAttempt(intent);
|
|
392
|
+
for (const arg of options.argv || []) {
|
|
393
|
+
cloneHits.push(...detectCloneAttempt(arg));
|
|
394
|
+
}
|
|
395
|
+
const uniqueCloneHits = [...new Set(cloneHits)];
|
|
396
|
+
if (uniqueCloneHits.length) {
|
|
397
|
+
findings.push({
|
|
398
|
+
severity: 'fail',
|
|
399
|
+
id: 'cyberstrike_clone_refused',
|
|
400
|
+
message: `Refusing CyberStrike/Eino/offensive SKU clone (${uniqueCloneHits.join(', ')}). Compose existing ThumbGate rails only.`,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const classification = classifyIntent(intent, {
|
|
405
|
+
intentClass: options.class || options.intentClass || null,
|
|
406
|
+
toolName: options.toolName || options.tool || null,
|
|
407
|
+
});
|
|
408
|
+
const governance = composeGovernance(classification, {
|
|
409
|
+
...options,
|
|
410
|
+
intent,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
if (governance.needsOffensiveGrant && !governance.offensiveGrant) {
|
|
414
|
+
findings.push({
|
|
415
|
+
severity: 'fail',
|
|
416
|
+
id: 'offensive_ungranted',
|
|
417
|
+
message: 'Offensive/cyber intent blocked: set THUMBGATE_ALLOW_OFFENSIVE=1 only for systems you own or are authorized to test.',
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (governance.hitlRequired && !governance.approved) {
|
|
421
|
+
findings.push({
|
|
422
|
+
severity: 'warn',
|
|
423
|
+
id: 'hitl_required',
|
|
424
|
+
message: 'Human oversight required before execute (high/critical). Pass --approved only after a real human grant.',
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (governance.planQuality?.gate === 'block') {
|
|
428
|
+
findings.push({
|
|
429
|
+
severity: 'warn',
|
|
430
|
+
id: 'plan_quality_block',
|
|
431
|
+
message: `Plan quality blocked: missing context [${(governance.planQuality.missingContext || []).join(', ')}]`,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const probes = [
|
|
436
|
+
{ id: 'intent_router', path: path.join(root, 'scripts', 'intent-router.js') },
|
|
437
|
+
{ id: 'harness_selector', path: path.join(root, 'scripts', 'harness-selector.js') },
|
|
438
|
+
{ id: 'gates_engine', path: path.join(root, 'scripts', 'gates-engine.js') },
|
|
439
|
+
{ id: 'admin_override', path: path.join(root, 'scripts', 'admin-override.js') },
|
|
440
|
+
{ id: 'subagent_profiles', path: path.join(root, 'config', 'subagent-profiles.json') },
|
|
441
|
+
].map((p) => ({ ...p, exists: fs.existsSync(p.path) }));
|
|
442
|
+
|
|
443
|
+
for (const p of probes.filter((x) => !x.exists)) {
|
|
444
|
+
findings.push({
|
|
445
|
+
severity: 'warn',
|
|
446
|
+
id: `missing_rail_${p.id}`,
|
|
447
|
+
message: `Expected rail missing: ${p.path}`,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
let status = 'ready';
|
|
452
|
+
if (findings.some((f) => f.severity === 'fail')) status = 'fail';
|
|
453
|
+
else if (findings.some((f) => f.severity === 'warn')) status = 'checkpoint_required';
|
|
454
|
+
else if (governance.steps.some((s) => s.status === 'blocked' || s.status === 'required')) {
|
|
455
|
+
status = 'checkpoint_required';
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const mapOnly = normalizeBoolean(options.map || options['map-only']);
|
|
459
|
+
const report = {
|
|
460
|
+
name: 'thumbgate-intent-governed-execution',
|
|
461
|
+
status,
|
|
462
|
+
intent: intent || null,
|
|
463
|
+
intentClass: classification.intentClass,
|
|
464
|
+
intentLabel: (INTENT_CLASSES[classification.intentClass] || INTENT_CLASSES.default).label,
|
|
465
|
+
confidence: classification.confidence,
|
|
466
|
+
reasons: classification.reasons,
|
|
467
|
+
governance,
|
|
468
|
+
railProbes: probes,
|
|
469
|
+
compareNotClone: true,
|
|
470
|
+
never: [
|
|
471
|
+
'clone CyberStrikeAI / Ed1s0nZ product',
|
|
472
|
+
'vendor CloudWeGo Eino as a ThumbGate SKU',
|
|
473
|
+
'ship WebShell / C2 / metasploit recipes',
|
|
474
|
+
'invent ROI percentages (70% automation theater)',
|
|
475
|
+
'execute offensive tools without authorization grant',
|
|
476
|
+
],
|
|
477
|
+
source: SOURCE_URL,
|
|
478
|
+
sourcePost: SOURCE_POST,
|
|
479
|
+
disclaimer:
|
|
480
|
+
'FORMAT steal from CyberStrikeAI (intent→governed execution + HITL + evidence memory). Not affiliated. Does not install CyberStrikeAI or Eino.',
|
|
481
|
+
findings,
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
if (mapOnly) {
|
|
485
|
+
report.map = GOVERNANCE_STEPS;
|
|
486
|
+
report.intentClasses = Object.keys(INTENT_CLASSES);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return report;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function formatIntentGovernedExecutionReport(report) {
|
|
493
|
+
const g = report.governance || {};
|
|
494
|
+
const lines = [
|
|
495
|
+
'ThumbGate Intent → Governed Execution (CyberStrike FORMAT steal)',
|
|
496
|
+
`Status : ${report.status}`,
|
|
497
|
+
`Intent : ${report.intent || '(none)'}`,
|
|
498
|
+
`Class : ${report.intentClass} (${report.intentLabel}) confidence=${report.confidence}`,
|
|
499
|
+
`Risk : ${g.risk} HITL=${g.hitlRequired ? (g.approved ? 'approved' : 'REQUIRED') : 'not required'}`,
|
|
500
|
+
`Harness : ${g.harness || 'default-gates-only'}`,
|
|
501
|
+
`Profile : ${g.subagentProfile || 'none'} mcp=${g.mcpProfile || 'n/a'} maxChars=${g.maxChars || 'n/a'}`,
|
|
502
|
+
`Offensive grant: ${g.offensiveGrant ? 'yes' : 'no'}${g.needsOffensiveGrant ? ' (required)' : ''}`,
|
|
503
|
+
'Steps :',
|
|
504
|
+
];
|
|
505
|
+
for (const step of g.steps || []) {
|
|
506
|
+
lines.push(` [${step.status}] ${step.id}: ${step.label}`);
|
|
507
|
+
lines.push(` rails=${(step.rails || []).join(' · ')}`);
|
|
508
|
+
}
|
|
509
|
+
if (g.nextActions?.length) {
|
|
510
|
+
lines.push('Next :');
|
|
511
|
+
for (const a of g.nextActions) {
|
|
512
|
+
lines.push(` - ${a.id}: ${a.command}`);
|
|
513
|
+
lines.push(` why: ${a.why}`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (report.findings?.length) {
|
|
517
|
+
lines.push('Findings:');
|
|
518
|
+
for (const f of report.findings) {
|
|
519
|
+
lines.push(` [${f.severity}] ${f.id}: ${f.message}`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
lines.push(`Never : ${(report.never || []).join('; ')}`);
|
|
523
|
+
lines.push(`Source : ${report.source}`);
|
|
524
|
+
lines.push(report.disclaimer);
|
|
525
|
+
return `${lines.join('\n')}\n`;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function printHelp() {
|
|
529
|
+
process.stdout.write(`Usage: node scripts/intent-governed-execution.js [options]
|
|
530
|
+
|
|
531
|
+
CyberStrikeAI FORMAT steal — NL intent → governed execution on existing rails.
|
|
532
|
+
Does not clone CyberStrikeAI / Eino / WebShell / C2.
|
|
533
|
+
|
|
534
|
+
Options:
|
|
535
|
+
--intent=<text> Natural-language intent
|
|
536
|
+
--class=<intentClass> Force class (${Object.keys(INTENT_CLASSES).join('|')})
|
|
537
|
+
--risk=low|medium|high|critical
|
|
538
|
+
--harness=<name> Force gate harness
|
|
539
|
+
--profile=<name> Force subagent profile
|
|
540
|
+
--approved Mark HITL already satisfied (human grant only)
|
|
541
|
+
--map-only Print governance step map
|
|
542
|
+
--json
|
|
543
|
+
--strict Exit 1 unless status=ready
|
|
544
|
+
--root=<dir>
|
|
545
|
+
`);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function main(argv = process.argv.slice(2)) {
|
|
549
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
550
|
+
printHelp();
|
|
551
|
+
return 0;
|
|
552
|
+
}
|
|
553
|
+
const options = { argv };
|
|
554
|
+
for (const arg of argv) {
|
|
555
|
+
if (arg === '--json') options.json = true;
|
|
556
|
+
else if (arg === '--strict') options.strict = true;
|
|
557
|
+
else if (arg === '--map' || arg === '--map-only') options.map = true;
|
|
558
|
+
else if (arg === '--approved') options.approved = true;
|
|
559
|
+
else if (arg.startsWith('--intent=')) options.intent = arg.slice('--intent='.length);
|
|
560
|
+
else if (arg.startsWith('--task=')) options.intent = arg.slice('--task='.length);
|
|
561
|
+
else if (arg.startsWith('--query=')) options.intent = arg.slice('--query='.length);
|
|
562
|
+
else if (arg.startsWith('--class=')) options.intentClass = arg.slice('--class='.length);
|
|
563
|
+
else if (arg.startsWith('--risk=')) options.risk = arg.slice('--risk='.length);
|
|
564
|
+
else if (arg.startsWith('--harness=')) options.harness = arg.slice('--harness='.length);
|
|
565
|
+
else if (arg.startsWith('--profile=')) options.profile = arg.slice('--profile='.length);
|
|
566
|
+
else if (arg.startsWith('--toolName=')) options.toolName = arg.slice('--toolName='.length);
|
|
567
|
+
else if (arg.startsWith('--root=')) options.root = arg.slice('--root='.length);
|
|
568
|
+
else if (!arg.startsWith('-') && !options.intent) options.intent = arg;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const report = buildIntentGovernedExecutionReport(options);
|
|
572
|
+
if (options.json) {
|
|
573
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
574
|
+
} else {
|
|
575
|
+
process.stdout.write(formatIntentGovernedExecutionReport(report));
|
|
576
|
+
}
|
|
577
|
+
if (options.strict && report.status !== 'ready') return 1;
|
|
578
|
+
if (report.status === 'fail') return 1;
|
|
579
|
+
return 0;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (require.main === module || (
|
|
583
|
+
process.argv[1]
|
|
584
|
+
&& path.resolve(process.argv[1]) === path.resolve(__filename)
|
|
585
|
+
)) {
|
|
586
|
+
process.exitCode = main();
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
module.exports = {
|
|
590
|
+
INTENT_CLASSES,
|
|
591
|
+
GOVERNANCE_STEPS,
|
|
592
|
+
RISK_ORDER,
|
|
593
|
+
classifyIntent,
|
|
594
|
+
composeGovernance,
|
|
595
|
+
detectOffensiveGrant,
|
|
596
|
+
detectCloneAttempt,
|
|
597
|
+
buildIntentGovernedExecutionReport,
|
|
598
|
+
formatIntentGovernedExecutionReport,
|
|
599
|
+
main,
|
|
600
|
+
SOURCE_URL,
|
|
601
|
+
SOURCE_POST,
|
|
602
|
+
};
|