hackmyagent 0.13.1 → 0.14.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 (37) hide show
  1. package/dist/.integrity-manifest.json +1 -1
  2. package/dist/attack/payloads/index.d.ts +2 -1
  3. package/dist/attack/payloads/index.d.ts.map +1 -1
  4. package/dist/attack/payloads/index.js +5 -1
  5. package/dist/attack/payloads/index.js.map +1 -1
  6. package/dist/attack/payloads/lifecycle.d.ts +11 -0
  7. package/dist/attack/payloads/lifecycle.d.ts.map +1 -0
  8. package/dist/attack/payloads/lifecycle.js +218 -0
  9. package/dist/attack/payloads/lifecycle.js.map +1 -0
  10. package/dist/attack/scanner.d.ts.map +1 -1
  11. package/dist/attack/scanner.js +1 -0
  12. package/dist/attack/scanner.js.map +1 -1
  13. package/dist/attack/types.d.ts +1 -1
  14. package/dist/attack/types.d.ts.map +1 -1
  15. package/dist/attack/types.js +5 -0
  16. package/dist/attack/types.js.map +1 -1
  17. package/dist/cli.js +1 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/hardening/scanner.d.ts +6 -0
  20. package/dist/hardening/scanner.d.ts.map +1 -1
  21. package/dist/hardening/scanner.js +24 -0
  22. package/dist/hardening/scanner.js.map +1 -1
  23. package/dist/hardening/security-check.d.ts +58 -0
  24. package/dist/hardening/security-check.d.ts.map +1 -1
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +7 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/lifecycle/assembly-scanner.d.ts +42 -0
  30. package/dist/lifecycle/assembly-scanner.d.ts.map +1 -0
  31. package/dist/lifecycle/assembly-scanner.js +515 -0
  32. package/dist/lifecycle/assembly-scanner.js.map +1 -0
  33. package/dist/lifecycle/index.d.ts +11 -0
  34. package/dist/lifecycle/index.d.ts.map +1 -0
  35. package/dist/lifecycle/index.js +15 -0
  36. package/dist/lifecycle/index.js.map +1 -0
  37. package/package.json +1 -1
@@ -0,0 +1,515 @@
1
+ "use strict";
2
+ /**
3
+ * Context Lifecycle Assembly Scanner (Stage 1)
4
+ *
5
+ * Simulates how agents assemble their system prompt from multiple components
6
+ * (SOUL.md, tool descriptions, memory entries, user preferences, conversation
7
+ * history) and detects injections that only activate post-assembly.
8
+ *
9
+ * Key threat model:
10
+ * - A memory entry that looks benign alone but becomes a prompt injection
11
+ * when concatenated with the system prompt.
12
+ * - Tool descriptions that contain hidden instructions exploiting their
13
+ * position adjacent to safety rules.
14
+ * - Components that combine across boundaries to form split injections
15
+ * (half in memory, half in tool description).
16
+ * - Benign-looking padding that displaces safety instructions out of the
17
+ * attention window.
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.scanAssembly = scanAssembly;
54
+ exports.toLifecycleResult = toLifecycleResult;
55
+ const fs = __importStar(require("fs/promises"));
56
+ const path = __importStar(require("path"));
57
+ /** Patterns that indicate prompt injection when found in assembled context */
58
+ const INJECTION_PATTERNS = [
59
+ { pattern: /ignore\s+(all\s+)?(previous|above|prior)\s+(instructions?|rules?|guidelines?)/i, name: 'instruction-override', severity: 'critical' },
60
+ { pattern: /\[SYSTEM\s*(UPDATE|OVERRIDE|INSTRUCTION)\]/i, name: 'fake-system-tag', severity: 'critical' },
61
+ { pattern: /you\s+are\s+now\s+(a\s+)?(?:new|different|unrestricted)/i, name: 'role-reassignment', severity: 'critical' },
62
+ { pattern: /disregard\s+(your\s+)?(safety|security|guidelines?|rules?|instructions?)/i, name: 'safety-disregard', severity: 'critical' },
63
+ { pattern: /new\s+instructions?\s*:\s*/i, name: 'instruction-injection', severity: 'high' },
64
+ { pattern: /\bdo\s+not\s+follow\s+(the\s+)?(system|original|initial)\b/i, name: 'anti-system', severity: 'high' },
65
+ { pattern: /\bassistant\s*:\s*\n/i, name: 'role-delimiter-injection', severity: 'high' },
66
+ { pattern: /\bsystem\s*:\s*\n/i, name: 'system-delimiter-injection', severity: 'high' },
67
+ { pattern: /\b(reveal|show|output|print)\s+(your\s+)?(system\s+prompt|instructions?|rules?)/i, name: 'prompt-extraction', severity: 'medium' },
68
+ { pattern: /<!--[\s\S]*?(ignore|override|disregard)[\s\S]*?-->/i, name: 'html-comment-injection', severity: 'high' },
69
+ { pattern: /\u200b|\u200c|\u200d|\ufeff/g, name: 'zero-width-char', severity: 'medium' },
70
+ ];
71
+ /**
72
+ * Patterns that are benign in isolation but become injections when components
73
+ * are concatenated. Each entry has two halves: one from component A, one from
74
+ * component B. When they appear adjacent in the assembled prompt, it's a
75
+ * cross-component (semantic split) injection.
76
+ */
77
+ const SPLIT_INJECTION_PAIRS = [
78
+ { partA: /ignore\s+all\s*$/im, partB: /^\s*previous\s+instructions/im, name: 'split-override' },
79
+ { partA: /\[SYSTEM$/im, partB: /^\s*OVERRIDE\]/im, name: 'split-system-tag' },
80
+ { partA: /new\s+role\s*:\s*$/im, partB: /^\s*unrestricted\s+assistant/im, name: 'split-role-change' },
81
+ { partA: /you\s+must\s+now\s*$/im, partB: /^\s*output\s+all\s+(secrets?|credentials?|api\s*keys?)/im, name: 'split-exfiltration' },
82
+ { partA: /disregard\s*$/im, partB: /^\s*(safety|security)\s+guidelines/im, name: 'split-safety-bypass' },
83
+ ];
84
+ /** Files that typically contribute to agent system prompt assembly */
85
+ const SOUL_FILES = ['SOUL.md', 'soul.md', 'SOUL.yaml', 'soul.yaml', 'system-prompt.md', 'system-prompt.txt', 'system_prompt.md', 'persona.md'];
86
+ const TOOL_DESC_FILES = ['tools.json', 'mcp.json', 'mcpServers.json', '.mcp.json', 'tool-descriptions.json', 'capabilities.json'];
87
+ const MEMORY_FILES = ['memory.json', 'context.json', '.memory', 'agent-memory.json', 'conversation-history.json', '.claude/memory/*.md'];
88
+ const USER_PREF_FILES = ['user-preferences.json', 'preferences.json', 'config.json', 'agent-config.json', '.agent.json', 'settings.json'];
89
+ const HISTORY_FILES = ['history.json', 'messages.json', 'chat-history.json', 'conversation.json'];
90
+ /**
91
+ * Discovers assembly components from the target directory.
92
+ */
93
+ async function discoverComponents(targetDir) {
94
+ const components = [];
95
+ const tryReadFiles = async (filenames, role) => {
96
+ for (const filename of filenames) {
97
+ // Handle glob-like patterns
98
+ if (filename.includes('*')) {
99
+ const dir = path.join(targetDir, path.dirname(filename));
100
+ try {
101
+ const entries = await fs.readdir(dir);
102
+ for (const entry of entries) {
103
+ const filePath = path.join(dir, entry);
104
+ try {
105
+ const stat = await fs.stat(filePath);
106
+ if (stat.isFile()) {
107
+ const content = await fs.readFile(filePath, 'utf-8');
108
+ components.push({
109
+ source: path.relative(targetDir, filePath),
110
+ role,
111
+ content,
112
+ });
113
+ }
114
+ }
115
+ catch { /* skip */ }
116
+ }
117
+ }
118
+ catch { /* directory doesn't exist */ }
119
+ continue;
120
+ }
121
+ const filePath = path.join(targetDir, filename);
122
+ try {
123
+ const content = await fs.readFile(filePath, 'utf-8');
124
+ components.push({
125
+ source: filename,
126
+ role,
127
+ content,
128
+ });
129
+ }
130
+ catch { /* file doesn't exist - skip */ }
131
+ }
132
+ };
133
+ await tryReadFiles(SOUL_FILES, 'soul');
134
+ await tryReadFiles(TOOL_DESC_FILES, 'toolDescription');
135
+ await tryReadFiles(MEMORY_FILES, 'memory');
136
+ await tryReadFiles(USER_PREF_FILES, 'userPreference');
137
+ await tryReadFiles(HISTORY_FILES, 'conversationHistory');
138
+ // Also scan for inline system instructions in source files
139
+ const srcDir = path.join(targetDir, 'src');
140
+ try {
141
+ const srcExists = await fs.access(srcDir).then(() => true).catch(() => false);
142
+ if (srcExists) {
143
+ const entries = await fs.readdir(srcDir, { recursive: true });
144
+ for (const entry of entries) {
145
+ const entryStr = String(entry);
146
+ if (!/\.(ts|js|py|mjs)$/.test(entryStr))
147
+ continue;
148
+ const filePath = path.join(srcDir, entryStr);
149
+ try {
150
+ const stat = await fs.stat(filePath);
151
+ if (!stat.isFile() || stat.size > 100000)
152
+ continue;
153
+ const content = await fs.readFile(filePath, 'utf-8');
154
+ // Extract string literals assigned to systemPrompt/system_prompt variables
155
+ const systemPromptMatch = content.match(/(?:systemPrompt|system_prompt|system_message|SYSTEM_PROMPT)\s*(?:=|:)\s*[`'"]([\s\S]*?)[`'"]/);
156
+ if (systemPromptMatch) {
157
+ components.push({
158
+ source: path.relative(targetDir, filePath),
159
+ role: 'systemInstruction',
160
+ content: systemPromptMatch[1],
161
+ });
162
+ }
163
+ }
164
+ catch { /* skip */ }
165
+ }
166
+ }
167
+ }
168
+ catch { /* no src dir */ }
169
+ return components;
170
+ }
171
+ /**
172
+ * Simulates the assembly process: concatenates components in typical agent
173
+ * assembly order (system instructions -> SOUL -> tools -> memory -> prefs -> history).
174
+ */
175
+ function assemblePrompt(components) {
176
+ // Sort by assembly priority (system instructions first, history last)
177
+ const roleOrder = {
178
+ systemInstruction: 0,
179
+ soul: 1,
180
+ toolDescription: 2,
181
+ userPreference: 3,
182
+ memory: 4,
183
+ conversationHistory: 5,
184
+ };
185
+ const sorted = [...components].sort((a, b) => roleOrder[a.role] - roleOrder[b.role]);
186
+ let offset = 0;
187
+ const enriched = [];
188
+ const parts = [];
189
+ for (const comp of sorted) {
190
+ const section = `\n--- ${comp.role}: ${comp.source} ---\n${comp.content}\n`;
191
+ enriched.push({
192
+ ...comp,
193
+ assembledOffset: offset,
194
+ assembledLength: section.length,
195
+ });
196
+ parts.push(section);
197
+ offset += section.length;
198
+ }
199
+ return { assembled: parts.join(''), components: enriched };
200
+ }
201
+ /**
202
+ * Scans the assembled prompt for injection patterns that may not be visible
203
+ * in individual components.
204
+ */
205
+ function scanAssembledPrompt(assembled, components) {
206
+ const findings = [];
207
+ const interactions = [];
208
+ // 1. Scan full assembled prompt for injection patterns
209
+ for (const { pattern, name, severity } of INJECTION_PATTERNS) {
210
+ const matches = assembled.matchAll(new RegExp(pattern.source, pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g'));
211
+ for (const match of matches) {
212
+ if (match.index === undefined)
213
+ continue;
214
+ const matchOffset = match.index;
215
+ // Find which component this match falls in
216
+ const sourceComp = components.find(c => c.assembledOffset !== undefined &&
217
+ c.assembledLength !== undefined &&
218
+ matchOffset >= c.assembledOffset &&
219
+ matchOffset < c.assembledOffset + c.assembledLength);
220
+ // Check if this pattern exists in the original component (pre-assembly)
221
+ // If it does, it's a Stage 0 finding (already detectable). We only flag
222
+ // patterns that emerge from assembly (cross-boundary or context-dependent).
223
+ if (sourceComp) {
224
+ const existsInSource = new RegExp(pattern.source, pattern.flags).test(sourceComp.content);
225
+ if (existsInSource)
226
+ continue; // Already detectable at Stage 0
227
+ }
228
+ findings.push({
229
+ checkId: `LIFECYCLE-001`,
230
+ name: 'Assembly-emergent injection',
231
+ description: `Injection pattern "${name}" detected in assembled system prompt but not visible in individual components. This injection emerges only after components are concatenated.`,
232
+ category: 'context-lifecycle',
233
+ severity,
234
+ passed: false,
235
+ message: `Assembly-emergent injection: "${name}" at offset ${matchOffset}${sourceComp ? ` (near ${sourceComp.source})` : ''}`,
236
+ fixable: false,
237
+ file: sourceComp?.source,
238
+ fix: 'Sanitize component content before assembly. Add injection detection between assembly stages.',
239
+ guidance: 'This injection is invisible when scanning individual files but activates after components are concatenated into the system prompt. Implement assembly-stage sanitization.',
240
+ attackClass: 'ASSEMBLY-INJECT',
241
+ });
242
+ }
243
+ }
244
+ // 2. Detect cross-component (semantic split) injections
245
+ for (let i = 0; i < components.length - 1; i++) {
246
+ const compA = components[i];
247
+ const compB = components[i + 1];
248
+ for (const { partA, partB, name } of SPLIT_INJECTION_PAIRS) {
249
+ if (partA.test(compA.content) && partB.test(compB.content)) {
250
+ const interaction = {
251
+ components: [compA.source, compB.source],
252
+ attackType: 'semanticSplit',
253
+ assembledSegment: `...${compA.content.slice(-100)}${compB.content.slice(0, 100)}...`,
254
+ confidence: 0.85,
255
+ };
256
+ interactions.push(interaction);
257
+ findings.push({
258
+ checkId: 'LIFECYCLE-002',
259
+ name: 'Cross-component split injection',
260
+ description: `Split injection "${name}" detected across component boundary: half in ${compA.source}, half in ${compB.source}. Each component appears benign alone.`,
261
+ category: 'context-lifecycle',
262
+ severity: 'critical',
263
+ passed: false,
264
+ message: `Split injection "${name}" spans ${compA.source} -> ${compB.source}`,
265
+ fixable: false,
266
+ file: compA.source,
267
+ fix: 'Scan component boundaries for split patterns. Add boundary delimiters that prevent cross-component injection.',
268
+ guidance: 'Split injections place half of a malicious instruction in one component and the other half in an adjacent component. When assembled, they form a complete injection that bypasses per-file scanning.',
269
+ attackClass: 'ASSEMBLY-SPLIT',
270
+ });
271
+ }
272
+ }
273
+ }
274
+ // 3. Detect context window displacement attacks
275
+ // If any single component is disproportionately large, it may push
276
+ // safety instructions (typically in soul/systemInstruction) out of
277
+ // the effective attention window.
278
+ const totalLength = assembled.length;
279
+ const safetyComponents = components.filter(c => c.role === 'soul' || c.role === 'systemInstruction');
280
+ const safetyLength = safetyComponents.reduce((sum, c) => sum + c.content.length, 0);
281
+ for (const comp of components) {
282
+ if (comp.role === 'soul' || comp.role === 'systemInstruction')
283
+ continue;
284
+ // Flag if a non-safety component is >60% of total assembled prompt
285
+ if (comp.content.length > totalLength * 0.6 && totalLength > 2000) {
286
+ interactions.push({
287
+ components: [comp.source, ...(safetyComponents.map(c => c.source))],
288
+ attackType: 'displacementAttack',
289
+ assembledSegment: `Component ${comp.source} is ${comp.content.length} chars (${Math.round(comp.content.length / totalLength * 100)}% of assembled prompt)`,
290
+ confidence: 0.7,
291
+ });
292
+ findings.push({
293
+ checkId: 'LIFECYCLE-003',
294
+ name: 'Context window displacement',
295
+ description: `Component "${comp.source}" (${comp.role}) occupies ${Math.round(comp.content.length / totalLength * 100)}% of the assembled prompt. Safety instructions from ${safetyComponents.map(c => c.source).join(', ') || 'SOUL.md'} may be displaced from the effective attention window.`,
296
+ category: 'context-lifecycle',
297
+ severity: 'high',
298
+ passed: false,
299
+ message: `${comp.source} displaces safety instructions (${comp.content.length}/${totalLength} chars)`,
300
+ fixable: false,
301
+ file: comp.source,
302
+ fix: 'Limit component sizes. Pin safety instructions at start and end of the assembled prompt. Implement attention anchoring.',
303
+ guidance: 'LLMs have limited effective attention. A disproportionately large component (memory dump, verbose tool descriptions) can push safety instructions out of the "attention window", effectively disabling them.',
304
+ attackClass: 'ASSEMBLY-DISPLACE',
305
+ });
306
+ }
307
+ }
308
+ // 4. Safety instruction ratio check
309
+ // If safety instructions are <10% of total and total is large enough to matter
310
+ if (totalLength > 5000 && safetyLength > 0 && safetyLength / totalLength < 0.1) {
311
+ findings.push({
312
+ checkId: 'LIFECYCLE-004',
313
+ name: 'Low safety instruction ratio',
314
+ description: `Safety instructions (SOUL.md, system prompts) are only ${Math.round(safetyLength / totalLength * 100)}% of the assembled context (${safetyLength}/${totalLength} chars). Safety rules may be diluted by other content.`,
315
+ category: 'context-lifecycle',
316
+ severity: 'medium',
317
+ passed: false,
318
+ message: `Safety instructions are ${Math.round(safetyLength / totalLength * 100)}% of assembled context`,
319
+ fixable: false,
320
+ file: safetyComponents[0]?.source || 'SOUL.md',
321
+ fix: 'Increase safety instruction coverage. Repeat critical rules at multiple points in the assembly. Trim non-essential context.',
322
+ guidance: 'When safety instructions are a small fraction of total context, the LLM may prioritize other content. Research shows safety instructions need sufficient representation relative to total context.',
323
+ attackClass: 'ASSEMBLY-DILUTE',
324
+ });
325
+ }
326
+ // 5. Detect priority zone hijacking
327
+ // Components at the end of assembly (high attention priority) containing instructions
328
+ const lastComponents = components.slice(-2);
329
+ for (const comp of lastComponents) {
330
+ if (comp.role === 'soul' || comp.role === 'systemInstruction')
331
+ continue;
332
+ // Check if late-position components contain instruction-like patterns
333
+ const instructionPatterns = [
334
+ /\b(must|should|always|never)\s+(do|follow|ignore|output)/i,
335
+ /\b(from now on|henceforth|going forward)\b/i,
336
+ /\b(your (new )?instructions?|updated rules?)\s*(are|:)/i,
337
+ ];
338
+ for (const pat of instructionPatterns) {
339
+ if (pat.test(comp.content)) {
340
+ interactions.push({
341
+ components: [comp.source],
342
+ attackType: 'priorityHijack',
343
+ assembledSegment: comp.content.slice(0, 200),
344
+ confidence: 0.65,
345
+ });
346
+ findings.push({
347
+ checkId: 'LIFECYCLE-005',
348
+ name: 'Priority zone instruction injection',
349
+ description: `Component "${comp.source}" (${comp.role}) is in the high-priority end zone of the assembled prompt and contains instruction-like language. Late-position instructions override earlier ones in many LLMs.`,
350
+ category: 'context-lifecycle',
351
+ severity: 'high',
352
+ passed: false,
353
+ message: `${comp.source} contains instructions in high-priority position`,
354
+ fixable: false,
355
+ file: comp.source,
356
+ fix: 'Move safety-critical instructions to the end of the assembly. Validate that non-safety components do not contain directive language.',
357
+ guidance: 'Many LLMs give higher weight to instructions that appear later in the context (recency bias). If memory or conversation history is assembled after safety rules, injected instructions there will override safety constraints.',
358
+ attackClass: 'ASSEMBLY-HIJACK',
359
+ });
360
+ break; // One finding per component
361
+ }
362
+ }
363
+ }
364
+ // 6. Detect role delimiter injection in non-system components
365
+ for (const comp of components) {
366
+ if (comp.role === 'systemInstruction')
367
+ continue;
368
+ if (/\b(system|assistant|user)\s*:\s*\n/i.test(comp.content)) {
369
+ findings.push({
370
+ checkId: 'LIFECYCLE-006',
371
+ name: 'Role delimiter in non-system component',
372
+ description: `Component "${comp.source}" (${comp.role}) contains role delimiters (system:/assistant:/user:) that could trick the LLM into treating injected text as a new conversation turn.`,
373
+ category: 'context-lifecycle',
374
+ severity: 'high',
375
+ passed: false,
376
+ message: `${comp.source} contains role delimiters in ${comp.role} component`,
377
+ fixable: false,
378
+ file: comp.source,
379
+ fix: 'Strip or escape role delimiters from non-system components before assembly.',
380
+ guidance: 'Role delimiters in memory entries, tool descriptions, or user preferences can trick the LLM into treating the following text as a new system instruction or assistant response, breaking the intended conversation structure.',
381
+ attackClass: 'ASSEMBLY-DELIMITER',
382
+ });
383
+ }
384
+ }
385
+ // 7. Detect HTML/markdown comment hiding
386
+ for (const comp of components) {
387
+ const commentMatches = comp.content.matchAll(/<!--([\s\S]*?)-->/g);
388
+ for (const match of commentMatches) {
389
+ const commentContent = match[1];
390
+ // Check if the comment contains instruction-like content
391
+ if (/ignore|override|disregard|new\s+instructions?|system\s*:|you\s+are/i.test(commentContent)) {
392
+ findings.push({
393
+ checkId: 'LIFECYCLE-007',
394
+ name: 'Hidden instructions in HTML comments',
395
+ description: `Component "${comp.source}" contains HTML comments with instruction-like content. Some LLMs process HTML comment content, making this an injection vector.`,
396
+ category: 'context-lifecycle',
397
+ severity: 'high',
398
+ passed: false,
399
+ message: `${comp.source} has hidden instructions in HTML comments`,
400
+ fixable: false,
401
+ file: comp.source,
402
+ fix: 'Strip HTML comments from all components before assembly, or sanitize comment content.',
403
+ guidance: 'HTML comments are invisible to humans reading markdown but may be processed by LLMs during inference. Attackers hide instructions in comments within memory entries or tool descriptions.',
404
+ attackClass: 'ASSEMBLY-HIDDEN',
405
+ });
406
+ }
407
+ }
408
+ }
409
+ return { findings, interactions };
410
+ }
411
+ /**
412
+ * Runs the full Stage 1 assembly scan.
413
+ */
414
+ async function scanAssembly(options) {
415
+ const { targetDir, onProgress } = options;
416
+ if (onProgress)
417
+ onProgress('Discovering assembly components...');
418
+ const rawComponents = await discoverComponents(targetDir);
419
+ if (rawComponents.length === 0) {
420
+ return {
421
+ findings: [],
422
+ components: [],
423
+ interactions: [],
424
+ assembledPrompt: '',
425
+ tokenEstimate: 0,
426
+ };
427
+ }
428
+ if (onProgress)
429
+ onProgress(`Found ${rawComponents.length} assembly components, simulating assembly...`);
430
+ const { assembled, components } = assemblePrompt(rawComponents);
431
+ if (onProgress)
432
+ onProgress('Scanning assembled prompt for lifecycle attacks...');
433
+ const { findings, interactions } = scanAssembledPrompt(assembled, components);
434
+ // Rough token estimate: ~4 chars per token for English
435
+ const tokenEstimate = Math.ceil(assembled.length / 4);
436
+ // 8. Check for assembly without safety instructions
437
+ const hasSafety = components.some(c => c.role === 'soul' || c.role === 'systemInstruction');
438
+ if (!hasSafety && components.length > 1) {
439
+ findings.push({
440
+ checkId: 'LIFECYCLE-008',
441
+ name: 'Assembly without safety instructions',
442
+ description: 'Agent assembles context from multiple components but has no SOUL.md or system prompt to establish safety boundaries.',
443
+ category: 'context-lifecycle',
444
+ severity: 'critical',
445
+ passed: false,
446
+ message: `${components.length} components assembled with no safety instructions`,
447
+ fixable: false,
448
+ file: components[0]?.source,
449
+ fix: 'Add a SOUL.md or system prompt with safety boundaries. Run: hackmyagent scan-soul to generate one.',
450
+ guidance: 'Without explicit safety instructions in the assembled context, the agent behavior is entirely determined by other components (memory, tools, history) which may be attacker-influenced.',
451
+ attackClass: 'ASSEMBLY-NOSAFETY',
452
+ });
453
+ }
454
+ // 9. Check for duplicate/conflicting instructions across components
455
+ const instructionComponents = components.filter(c => c.role === 'soul' || c.role === 'systemInstruction' || c.role === 'userPreference');
456
+ if (instructionComponents.length > 1) {
457
+ // Simple heuristic: if multiple components define contradictory rules
458
+ const rules = instructionComponents.map(c => ({
459
+ source: c.source,
460
+ hasAllow: /\b(allow|permit|enable)\b/i.test(c.content),
461
+ hasDeny: /\b(deny|forbid|disable|never)\b/i.test(c.content),
462
+ }));
463
+ const hasConflict = rules.some(r => r.hasAllow) && rules.some(r => r.hasDeny);
464
+ if (hasConflict) {
465
+ const allowSources = rules.filter(r => r.hasAllow).map(r => r.source);
466
+ const denySources = rules.filter(r => r.hasDeny).map(r => r.source);
467
+ findings.push({
468
+ checkId: 'LIFECYCLE-009',
469
+ name: 'Conflicting assembly instructions',
470
+ description: `Conflicting directives detected: permissive rules in ${allowSources.join(', ')} vs restrictive rules in ${denySources.join(', ')}. LLM behavior under contradiction is unpredictable.`,
471
+ category: 'context-lifecycle',
472
+ severity: 'medium',
473
+ passed: false,
474
+ message: `Conflicting instructions across ${instructionComponents.length} components`,
475
+ fixable: false,
476
+ file: instructionComponents[0].source,
477
+ fix: 'Consolidate instructions into a single authoritative source (SOUL.md). Remove conflicting directives from other components.',
478
+ guidance: 'When multiple components provide contradictory instructions, LLM behavior is unpredictable. An attacker can exploit this by injecting permissive rules in a lower-priority component that conflict with safety rules.',
479
+ attackClass: 'ASSEMBLY-CONFLICT',
480
+ });
481
+ }
482
+ }
483
+ // 10. Token budget exhaustion risk
484
+ const maxSafe = options.maxAssemblySize || 100000; // ~25K tokens
485
+ if (assembled.length > maxSafe) {
486
+ findings.push({
487
+ checkId: 'LIFECYCLE-010',
488
+ name: 'Assembly exceeds safe context budget',
489
+ description: `Assembled prompt is ${assembled.length} chars (~${tokenEstimate} tokens), exceeding safe budget of ${maxSafe} chars. Early components (safety instructions) may be truncated or compressed.`,
490
+ category: 'context-lifecycle',
491
+ severity: 'high',
492
+ passed: false,
493
+ message: `Assembled prompt: ${assembled.length} chars (~${tokenEstimate} tokens) exceeds ${maxSafe} char budget`,
494
+ fixable: false,
495
+ file: components[components.length - 1]?.source,
496
+ fix: 'Reduce component sizes. Implement context pruning. Use summarization for memory/history. Prioritize safety-critical content.',
497
+ guidance: 'When the assembled prompt exceeds the model context window, providers typically truncate from the beginning, which removes safety instructions. Even within the window, extreme length degrades instruction-following quality.',
498
+ attackClass: 'ASSEMBLY-OVERFLOW',
499
+ });
500
+ }
501
+ if (onProgress)
502
+ onProgress(`Assembly scan complete: ${findings.length} findings from ${components.length} components`);
503
+ return { findings, components, interactions, assembledPrompt: assembled, tokenEstimate };
504
+ }
505
+ /**
506
+ * Wraps a Stage 0 ScanResult into a LifecycleScanResult.
507
+ * This is backward-compatible: existing scan results become Stage 0 lifecycle results.
508
+ */
509
+ function toLifecycleResult(scanResult, stage = 0) {
510
+ return {
511
+ stage,
512
+ scanResult,
513
+ };
514
+ }
515
+ //# sourceMappingURL=assembly-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembly-scanner.js","sourceRoot":"","sources":["../../src/lifecycle/assembly-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Context Lifecycle Scanner
3
+ *
4
+ * Models how agent context evolves through stages of execution:
5
+ * - Stage 0: Static artifact scan (current HMA hardening checks)
6
+ * - Stage 1: System prompt assembly simulation
7
+ * - Stage 2: Runtime behavior monitoring (future, via ARP)
8
+ */
9
+ export { scanAssembly, toLifecycleResult } from './assembly-scanner';
10
+ export type { LifecycleStage, LifecycleScanResult, AssemblyComponent, AssemblyInteraction, } from '../hardening/security-check';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrE,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * Context Lifecycle Scanner
4
+ *
5
+ * Models how agent context evolves through stages of execution:
6
+ * - Stage 0: Static artifact scan (current HMA hardening checks)
7
+ * - Stage 1: System prompt assembly simulation
8
+ * - Stage 2: Runtime behavior monitoring (future, via ARP)
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.toLifecycleResult = exports.scanAssembly = void 0;
12
+ var assembly_scanner_1 = require("./assembly-scanner");
13
+ Object.defineProperty(exports, "scanAssembly", { enumerable: true, get: function () { return assembly_scanner_1.scanAssembly; } });
14
+ Object.defineProperty(exports, "toLifecycleResult", { enumerable: true, get: function () { return assembly_scanner_1.toLifecycleResult; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,uDAAqE;AAA5D,gHAAA,YAAY,OAAA;AAAE,qHAAA,iBAAiB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmyagent",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Find it. Break it. Fix it. The hacker's toolkit for AI agents.",
5
5
  "bin": {
6
6
  "hackmyagent": "dist/cli.js"