diff --git a/src/__tests__/code-ingest.test.ts b/src/__tests__/code-ingest.test.ts index b316465..463ffbd 100644 --- a/src/__tests__/code-ingest.test.ts +++ b/src/__tests__/code-ingest.test.ts @@ -349,4 +349,30 @@ describe('packAnalysisUnits', () => { expect(text).toContain('risk signals:'); expect(text).toContain('requests.get(url)'); // body included }); + + it('redacts source secrets before producing LLM-facing context', () => { + const blocks = parseFile('secrets.py', `def leak():\n api_key = "sk-ant-api03-ABCDEFGHIJKLMNOP"\n return "Authorization: Bearer abcdefghijklmnop"\n`); + const block = blocks[0]; + if (!block) throw new Error('expected parseFile to return a block'); + const unit: AnalysisUnit = { + block, + exposure: 'neutral', + callers: [], + callees: [], + reachable: false, + reachDepth: Infinity, + reachabilityPaths: [], + riskSignals: [], + priority: 0, + }; + + const formatted = formatUnitForLLM(unit); + const packed = packAnalysisUnits([unit], 100_000).text; + + for (const text of [formatted, packed]) { + expect(text).not.toContain('sk-ant-api03-ABCDEFGHIJKLMNOP'); + expect(text).not.toContain('Bearer abcdefghijklmnop'); + expect(text).toContain('[redacted]'); + } + }); }); diff --git a/src/recon/code-ingest.ts b/src/recon/code-ingest.ts index ec8d394..be9ca8b 100644 --- a/src/recon/code-ingest.ts +++ b/src/recon/code-ingest.ts @@ -43,6 +43,7 @@ import { type SourceFile, type SourceBundle, } from '../orchestration/context-pack.js'; +import { redactString } from '../redact.js'; // ============================================================================= // TYPES @@ -861,7 +862,7 @@ export function formatUnitForLLM(unit: AnalysisUnit): string { `risk signals: ${unit.riskSignals.length ? unit.riskSignals.join(', ') : '(none)'}`, ); lines.push('---'); - lines.push(b.body); + lines.push(redactString(b.body)); return lines.join('\n'); }