import { describe, expect, it } from 'vitest' import { readdirSync, readFileSync, statSync } from 'node:fs' import { join } from 'node:path' const SRC = join(import.meta.dirname, '..', '..', 'src') function walk(dir: string): string[] { const out: string[] = [] for (const name of readdirSync(dir)) { const path = join(dir, name) if (statSync(path).isDirectory()) out.push(...walk(path)) else if (name.endsWith('.ts')) out.push(path) } return out } const files = walk(SRC) function code(path: string): string { return readFileSync(path, 'utf8').replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*$/gm, '') } describe('agent security tripwires (T18, INDEX ยง3)', () => { it('INV9: no console.log anywhere in src', () => { for (const f of files) { expect(code(f), `console.log in ${f}`).not.toMatch(/console\.log/) } }) it('INV11: no ANSI/xterm/vt100 import anywhere in src (byte-shuttle)', () => { for (const f of files) { expect(code(f), `terminal-parser import in ${f}`).not.toMatch(/from ['"][^'"]*(xterm|ansi|vt100)[^'"]*['"]/) } }) it('INV2 anti-MITM: hostEndpoint imports NO verifier from relay-e2e (FIX 6b)', () => { const he = code(join(SRC, 'e2e', 'hostEndpoint.ts')) expect(he).not.toMatch(/from ['"]relay-e2e['"]/) expect(he).not.toMatch(/verifyDeviceAuthProof/) }) it('INV12: revocation.ts uses the frozen decoder, no bare integer reason literal', () => { const rev = code(join(SRC, 'lifecycle', 'revocation.ts')) expect(rev).toMatch(/decodeGoAwayReason/) expect(rev).not.toMatch(/reason\s*[=:]\s*\d/) expect(rev).not.toMatch(/===\s*[123]\b/) }) it('INV4: identity exposes no raw private-key byte export', () => { const id = code(join(SRC, 'keys', 'identity.ts')) expect(id).not.toMatch(/exportPrivateRaw|privateKeyBytes|rawPrivateKey/) }) it('every src module is well under the 800-line hard cap', () => { for (const f of files) { const lines = readFileSync(f, 'utf8').split('\n').length expect(lines, `${f} is ${lines} lines`).toBeLessThan(800) } }) })