faultmesh 1.0.0 → 1.1.0

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 (43) hide show
  1. package/README.md +61 -19
  2. package/dist/dashboard/app.js +1906 -139
  3. package/dist/dashboard/index.html +393 -99
  4. package/dist/dashboard/styles.css +1191 -23
  5. package/dist/engine/ControlApi.d.ts +13 -1
  6. package/dist/engine/ControlApi.js +304 -14
  7. package/dist/engine/FaultMeshProxy.d.ts +2 -0
  8. package/dist/engine/FaultMeshProxy.js +41 -5
  9. package/dist/engine/TelemetryHub.d.ts +1 -0
  10. package/dist/engine/TelemetryHub.js +3 -0
  11. package/dist/engine/ToxicPipeline.d.ts +5 -4
  12. package/dist/engine/ToxicPipeline.js +17 -4
  13. package/dist/healer/AiHealer.d.ts +30 -0
  14. package/dist/healer/AiHealer.js +188 -0
  15. package/dist/healer/AutoHealer.d.ts +24 -0
  16. package/dist/healer/AutoHealer.js +503 -0
  17. package/dist/healer/DiffGenerator.d.ts +10 -0
  18. package/dist/healer/DiffGenerator.js +63 -0
  19. package/dist/healer/DiffUtil.d.ts +6 -0
  20. package/dist/healer/DiffUtil.js +67 -0
  21. package/dist/healer/transformers/ExpressTransformers.d.ts +43 -0
  22. package/dist/healer/transformers/ExpressTransformers.js +228 -0
  23. package/dist/healer/transformers/FastApiTransformers.d.ts +19 -0
  24. package/dist/healer/transformers/FastApiTransformers.js +93 -0
  25. package/dist/healer/transformers/GoTransformers.d.ts +19 -0
  26. package/dist/healer/transformers/GoTransformers.js +106 -0
  27. package/dist/healer/types.d.ts +59 -0
  28. package/dist/healer/types.js +1 -0
  29. package/dist/redteam/EccAgentBridge.d.ts +20 -0
  30. package/dist/redteam/EccAgentBridge.js +303 -0
  31. package/dist/redteam/RedTeamEngine.d.ts +56 -0
  32. package/dist/redteam/RedTeamEngine.js +709 -0
  33. package/dist/redteam/types.d.ts +117 -0
  34. package/dist/redteam/types.js +5 -0
  35. package/dist/scorer/ResilienceScorer.d.ts +5 -0
  36. package/dist/scorer/ResilienceScorer.js +323 -7
  37. package/dist/scorer/SecurityAuditor.d.ts +8 -0
  38. package/dist/scorer/SecurityAuditor.js +471 -69
  39. package/dist/scorer/TrafficStormAuditor.d.ts +5 -0
  40. package/dist/scorer/TrafficStormAuditor.js +328 -69
  41. package/dist/server.js +17 -10
  42. package/dist/types.d.ts +7 -3
  43. package/package.json +2 -1
@@ -0,0 +1,303 @@
1
+ /**
2
+ * FaultMesh — Autonomous Red Chaos Team Engine
3
+ * Agent Squadron Bridge: Loads and translates autonomous agent personas into active attack strategies.
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ export class EccAgentBridge {
9
+ agentsDir;
10
+ personas = new Map();
11
+ initialized = false;
12
+ constructor(customAgentsDir) {
13
+ if (customAgentsDir) {
14
+ this.agentsDir = customAgentsDir;
15
+ }
16
+ else {
17
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
18
+ // Try root workspace .agents/agents
19
+ const candidateRoot = path.resolve(currentDir, '../../.agents/agents');
20
+ const candidateLocal = path.resolve(currentDir, '../.agents/agents');
21
+ if (fs.existsSync(candidateRoot)) {
22
+ this.agentsDir = candidateRoot;
23
+ }
24
+ else if (fs.existsSync(candidateLocal)) {
25
+ this.agentsDir = candidateLocal;
26
+ }
27
+ else {
28
+ this.agentsDir = path.resolve(process.cwd(), '.agents/agents');
29
+ }
30
+ }
31
+ }
32
+ async initialize() {
33
+ if (this.initialized)
34
+ return;
35
+ const corePersonaFiles = [
36
+ {
37
+ filename: 'security-reviewer.md',
38
+ id: 'security-reviewer',
39
+ callSign: 'VULN-HUNTER',
40
+ specialty: 'security',
41
+ defaultHuntTargets: [
42
+ 'Host Header Poisoning & Reflection',
43
+ 'Path Traversal & Relative Directory Escape',
44
+ 'CORS Wildcard & Credential Leakage',
45
+ 'Unsigned / Broken Auth Header Crashes',
46
+ 'URL Credential & Secret Query Exposure',
47
+ 'Response PII & Sensitive Body Leakage',
48
+ 'SQL / NoSQL Canary Injection Probing',
49
+ ],
50
+ },
51
+ {
52
+ filename: 'silent-failure-hunter.md',
53
+ id: 'silent-failure-hunter',
54
+ callSign: 'SILENT-TRAPPER',
55
+ specialty: 'silent-failure',
56
+ defaultHuntTargets: [
57
+ 'Swallowed Exceptions (HTTP 500 returned as 200 OK)',
58
+ 'Truncated / Incomplete JSON Parsing Boundaries',
59
+ 'Premature Client Abort & Zombie Connection Leaks',
60
+ 'Dropped Socket Recovery During Mid-Stream Cut',
61
+ 'Missing Downstream Timeout Enforcement',
62
+ ],
63
+ },
64
+ {
65
+ filename: 'performance-optimizer.md',
66
+ id: 'performance-optimizer',
67
+ callSign: 'SURGE-STORMER',
68
+ specialty: 'performance',
69
+ defaultHuntTargets: [
70
+ 'Slowloris Request Header Drip Defense',
71
+ 'Chunked POST Stream Starvation',
72
+ 'Oversized 1MB+ Buffer OOM Protection (HTTP 413)',
73
+ 'Resource Avalanche & Queue Saturation Flood',
74
+ 'Rate Limit Exponential Back-Off (HTTP 429)',
75
+ ],
76
+ },
77
+ {
78
+ filename: 'gan-generator.md',
79
+ id: 'gan-adversary',
80
+ callSign: 'MUTANT-PROBER',
81
+ specialty: 'adversarial-gan',
82
+ defaultHuntTargets: [
83
+ 'Catastrophic ReDoS Backtracking Payloads',
84
+ 'Concurrent Race Conditions (Double-Spend Transaction Probing)',
85
+ 'HTTP Parameter Pollution (HPP) Array Type Confusion',
86
+ 'Client IP Spoofing & Header Smuggling',
87
+ ],
88
+ },
89
+ {
90
+ filename: 'network-troubleshooter.md',
91
+ id: 'network-troubleshooter',
92
+ callSign: 'NET-FRACTURER',
93
+ specialty: 'transport',
94
+ defaultHuntTargets: [
95
+ 'High Packet Latency Spike (+400ms)',
96
+ 'High Jitter Variance (±250ms)',
97
+ 'Throttled Bandwidth Starvation (16 kbps Cap)',
98
+ 'Upstream Gateway Timeout Hang (504 Simulation)',
99
+ 'Temporary Upstream Outage (503 Service Unavailable)',
100
+ ],
101
+ },
102
+ ];
103
+ for (const spec of corePersonaFiles) {
104
+ const filePath = path.join(this.agentsDir, spec.filename);
105
+ let persona;
106
+ if (fs.existsSync(filePath)) {
107
+ try {
108
+ const content = fs.readFileSync(filePath, 'utf-8');
109
+ persona = this.parseAgentMarkdown(content, spec.id, spec.callSign, spec.specialty, spec.filename, spec.defaultHuntTargets);
110
+ }
111
+ catch (err) {
112
+ persona = this.createFallbackPersona(spec.id, spec.callSign, spec.specialty, spec.filename, spec.defaultHuntTargets);
113
+ }
114
+ }
115
+ else {
116
+ persona = this.createFallbackPersona(spec.id, spec.callSign, spec.specialty, spec.filename, spec.defaultHuntTargets);
117
+ }
118
+ this.personas.set(persona.id, persona);
119
+ }
120
+ this.initialized = true;
121
+ }
122
+ async getPersonas() {
123
+ await this.initialize();
124
+ return Array.from(this.personas.values());
125
+ }
126
+ getPersona(id) {
127
+ return this.personas.get(id);
128
+ }
129
+ parseAgentMarkdown(raw, id, callSign, specialty, filename, defaultHuntTargets) {
130
+ const frontmatterMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
131
+ const parsedFm = {};
132
+ if (frontmatterMatch) {
133
+ const yamlLines = frontmatterMatch[1].split(/\r?\n/);
134
+ let inTools = false;
135
+ const tools = [];
136
+ for (const line of yamlLines) {
137
+ const trimmed = line.trim();
138
+ if (trimmed.startsWith('name:')) {
139
+ parsedFm.name = trimmed.replace('name:', '').trim();
140
+ }
141
+ else if (trimmed.startsWith('description:')) {
142
+ parsedFm.description = trimmed.replace('description:', '').trim();
143
+ }
144
+ else if (trimmed.startsWith('model:')) {
145
+ parsedFm.model = trimmed.replace('model:', '').trim();
146
+ }
147
+ else if (trimmed.startsWith('tools:')) {
148
+ inTools = true;
149
+ }
150
+ else if (inTools && trimmed.startsWith('-')) {
151
+ tools.push(trimmed.replace('-', '').trim());
152
+ }
153
+ else if (trimmed.length > 0 && !trimmed.startsWith('-')) {
154
+ inTools = false;
155
+ }
156
+ }
157
+ if (tools.length > 0) {
158
+ parsedFm.tools = tools;
159
+ }
160
+ }
161
+ // Extract Hunt Targets from markdown headings or bullet points
162
+ const huntTargets = [...defaultHuntTargets];
163
+ const targetsRegex = /(?:###|##|\*|-)\s+(?:\d+\.\s+)?([A-Z][A-Za-z0-9\s&/()_,-]{4,60})/g;
164
+ let match;
165
+ let count = 0;
166
+ while ((match = targetsRegex.exec(raw)) !== null && count < 6) {
167
+ const title = match[1].trim();
168
+ if (!huntTargets.includes(title) && !title.toLowerCase().includes('responsibilities') && !title.toLowerCase().includes('output format') && !title.toLowerCase().includes('prompt defense')) {
169
+ huntTargets.push(title);
170
+ count++;
171
+ }
172
+ }
173
+ // Extract clean excerpt of system prompt
174
+ const bodyWithoutFm = raw.replace(/^---\r?\n[\s\S]*?\r?\n---/, '').trim();
175
+ const firstParagraph = bodyWithoutFm.split(/\r?\n\r?\n/)[0] || '';
176
+ const cleanExcerpt = firstParagraph.replace(/[#*`_]/g, '').trim().slice(0, 200);
177
+ return {
178
+ id,
179
+ name: parsedFm.name || id,
180
+ callSign,
181
+ description: parsedFm.description || `Autonomous Red Team agent specialized in ${specialty}.`,
182
+ model: parsedFm.model || 'autonomous-agent-v1',
183
+ tools: parsedFm.tools || ['view_file', 'grep_search', 'run_command'],
184
+ specialty,
185
+ huntTargets: huntTargets.slice(0, 8),
186
+ systemPromptExcerpt: cleanExcerpt,
187
+ sourceFile: `.agents/agents/${filename}`,
188
+ };
189
+ }
190
+ createFallbackPersona(id, callSign, specialty, filename, huntTargets) {
191
+ const titles = {
192
+ 'security-reviewer': 'Security Vulnerability & Exploitation Reviewer',
193
+ 'silent-failure-hunter': 'Silent Failure & Error Swallowing Hunter',
194
+ 'performance-optimizer': 'Resource Exhaustion & Traffic Stormer',
195
+ 'gan-adversary': 'Adversarial GAN Mutant Probe Generator',
196
+ 'network-troubleshooter': 'Network Transport & Fault Injector',
197
+ };
198
+ return {
199
+ id,
200
+ name: titles[id] || id,
201
+ callSign,
202
+ description: `Autonomous Red Team Agent Persona targeting ${specialty} vulnerabilities.`,
203
+ model: 'autonomous-agent-v1',
204
+ tools: ['view_file', 'grep_search', 'run_command'],
205
+ specialty,
206
+ huntTargets,
207
+ systemPromptExcerpt: `Autonomous Red Team specialist executing adversarial ${specialty} evaluation.`,
208
+ sourceFile: `.agents/agents/${filename}`,
209
+ };
210
+ }
211
+ /**
212
+ * Translates active personas and chosen intensity into calibrated assault waves
213
+ */
214
+ generateCampaignWaves(intensity = 'sustained') {
215
+ const waves = [];
216
+ // Multipliers based on intensity
217
+ const probeMultiplier = intensity === 'avalanche' ? 3 : intensity === 'stealth' ? 1 : 2;
218
+ const baseConcurrency = intensity === 'avalanche' ? 10 : intensity === 'stealth' ? 1 : 4;
219
+ // Wave 1: Recon & Security Perimeter Breach (Security Reviewer)
220
+ waves.push({
221
+ id: 'wave-1-security-recon',
222
+ waveNumber: 1,
223
+ name: 'Host Poisoning, IP Spoofing & Auth Perimeter Assault',
224
+ personaId: 'security-reviewer',
225
+ personaName: 'Security Reviewer',
226
+ callSign: 'VULN-HUNTER',
227
+ category: 'security',
228
+ targetEndpoint: '/api/data',
229
+ toxicsToInject: [],
230
+ probesCount: 4 * probeMultiplier,
231
+ concurrency: intensity === 'avalanche' ? 6 : intensity === 'stealth' ? 1 : 3,
232
+ description: 'Dispatches Host header poisoning, X-Forwarded-For IP spoofing, path traversal, and malformed auth tokens.',
233
+ });
234
+ // Wave 2: Silent Failures Under Transport Stress (Silent Failure Hunter + Net Troubleshooter)
235
+ waves.push({
236
+ id: 'wave-2-transport-stress',
237
+ waveNumber: 2,
238
+ name: 'Abrupt Socket Cut & Corrupted JSON Stream Injection',
239
+ personaId: 'silent-failure-hunter',
240
+ personaName: 'Silent Failure Hunter',
241
+ callSign: 'SILENT-TRAPPER',
242
+ category: 'resilience',
243
+ targetEndpoint: '/api/data',
244
+ toxicsToInject: [
245
+ { type: 'bandwidth', config: { rateKbps: 32 }, direction: 'downstream' },
246
+ { type: 'cut', config: { cutAfterBytes: 40 }, direction: 'downstream' },
247
+ ],
248
+ probesCount: 3 * probeMultiplier,
249
+ concurrency: Math.min(2, baseConcurrency),
250
+ description: 'Restricts downstream bandwidth and abruptly severs TCP sockets mid-transfer to evaluate error propagation.',
251
+ });
252
+ // Wave 3: Jitter & Gateway Timeout Degradation (Net Troubleshooter)
253
+ waves.push({
254
+ id: 'wave-3-jitter-degrade',
255
+ waveNumber: 3,
256
+ name: 'Latency Flutter & Gateway 504 Timeout Hang',
257
+ personaId: 'network-troubleshooter',
258
+ personaName: 'Network Troubleshooter',
259
+ callSign: 'NET-FRACTURER',
260
+ category: 'resilience',
261
+ targetEndpoint: '/api/users',
262
+ toxicsToInject: [
263
+ { type: 'latency', config: { latencyMs: 450, jitterMs: 250 }, direction: 'downstream' },
264
+ ],
265
+ probesCount: 3 * probeMultiplier,
266
+ concurrency: Math.min(3, baseConcurrency),
267
+ description: 'Injects severe latency flutter (450ms ± 250ms) and checks client request timeout boundaries.',
268
+ });
269
+ // Wave 4: Adversarial Mutants: ReDoS & Race Condition Injections (GAN Adversary)
270
+ waves.push({
271
+ id: 'wave-4-adversarial-mutant',
272
+ waveNumber: 4,
273
+ name: 'Catastrophic ReDoS & Transactional Race Interleaving',
274
+ personaId: 'gan-adversary',
275
+ personaName: 'Adversarial GAN Mutant',
276
+ callSign: 'MUTANT-PROBER',
277
+ category: 'storm',
278
+ targetEndpoint: '/api/checkout',
279
+ toxicsToInject: [],
280
+ probesCount: 4 * probeMultiplier,
281
+ concurrency: Math.max(4, baseConcurrency),
282
+ description: 'Dispatches catastrophic backtracking regex inputs and rapid parallel duplicate idempotency requests.',
283
+ });
284
+ // Wave 5: Resource Exhaustion & Connection Drip (Performance Optimizer)
285
+ waves.push({
286
+ id: 'wave-5-resource-exhaustion',
287
+ waveNumber: 5,
288
+ name: 'Slowloris Drip, 1MB Buffer Overflow & Avalanche Surge',
289
+ personaId: 'performance-optimizer',
290
+ personaName: 'Performance Optimizer',
291
+ callSign: 'SURGE-STORMER',
292
+ category: 'storm',
293
+ targetEndpoint: '/api/data',
294
+ toxicsToInject: [
295
+ { type: 'latency', config: { latencyMs: 200 }, direction: 'downstream' },
296
+ ],
297
+ probesCount: 5 * probeMultiplier,
298
+ concurrency: baseConcurrency,
299
+ description: 'Fires slow header drips, buffer threshold overloads (>1MB), and sudden concurrency bursts to test pool exhaustion.',
300
+ });
301
+ return waves;
302
+ }
303
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * FaultMesh — Autonomous Red Chaos Team Engine
3
+ * RedTeamEngine: Coordinates adversarial multi-wave assault campaigns using autonomous agent personas.
4
+ */
5
+ import { ToxicPipeline } from '../engine/ToxicPipeline.js';
6
+ import { TelemetryHub } from '../engine/TelemetryHub.js';
7
+ import { EccAgentBridge } from './EccAgentBridge.js';
8
+ import { CampaignOptions, CampaignReport, CampaignStatus } from './types.js';
9
+ export declare class RedTeamEngine {
10
+ private pipeline;
11
+ private telemetryHub;
12
+ private bridge;
13
+ private currentPhase;
14
+ private activeCampaignId;
15
+ private aborted;
16
+ private active;
17
+ private currentWaveIndex;
18
+ private totalWaves;
19
+ private currentWaveName;
20
+ private activePersonaName;
21
+ private probesSent;
22
+ private breaches;
23
+ private logs;
24
+ private startTime;
25
+ private endTime;
26
+ private targetUrl;
27
+ private intensity;
28
+ private lastReport;
29
+ constructor(pipeline: ToxicPipeline, telemetryHub: TelemetryHub, bridge?: EccAgentBridge);
30
+ getStatus(): CampaignStatus;
31
+ getReport(): CampaignReport | null;
32
+ startCampaign(options?: CampaignOptions): Promise<CampaignReport>;
33
+ abortCampaign(): {
34
+ success: boolean;
35
+ message: string;
36
+ };
37
+ private executeReconPhase;
38
+ private executeAssaultWave;
39
+ private runSecurityWave;
40
+ private runTransportStressWave;
41
+ private runJitterDegradeWave;
42
+ private runAdversarialMutantWave;
43
+ private runResourceExhaustionWave;
44
+ private runGenericWave;
45
+ private installWaveToxics;
46
+ private cleanupToxics;
47
+ private finalizeSuccessfulCampaign;
48
+ private finalizeAbortedCampaign;
49
+ private dispatchProbe;
50
+ private addLog;
51
+ private emitProgress;
52
+ private emitWaveStart;
53
+ private emitBreach;
54
+ private emitComplete;
55
+ private sleep;
56
+ }