/** Offline audit of retained REA exports. Never opens the original package. */ import fs from 'node:fs' import path from 'node:path' import assert from 'node:assert/strict' import crypto from 'node:crypto' import { parse } from 'yaml' const root = path.resolve('.tmp/rea-ui-designer-recovered-20261016') const manifest = JSON.parse(fs.readFileSync(path.join(root, 'evidence-manifest.json'), 'utf8')) const pin = 'c9c83df190f0f0f871706d52b7e372f20b7ad63fde739f59cf9181ace1d08afa' const inventory = JSON.parse(fs.readFileSync(manifest.retainedInventory, 'utf8')) const sha = bytes => crypto.createHash('sha256').update(bytes).digest('hex') assert.equal(manifest.rootSha256, pin) assert.equal(inventory.normalized_result.root_sha256, pin) assert.equal(inventory.evidence_id, manifest.inventoryEvidenceId) assert.equal(inventory.normalized_result.coverage.status, 'complete') assert.equal(manifest.remaining.length, 0) assert.equal(manifest.files.length, 143) assert.deepEqual(manifest.excluded.map(item => item.path), ['.downloaded_at']) const expected = inventory.normalized_result.members.filter(item => item.kind === 'file' && item.path !== '.downloaded_at') assert.deepEqual(manifest.files.map(item => item.path).sort(), expected.map(item => item.path).sort()) const evidence = new Map(), checks = [] for (const file of manifest.files) { const destination = path.resolve(root, file.path), relative = path.relative(root, destination) assert(!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith('..' + path.sep)) const bytes = fs.readFileSync(destination), source = expected.find(item => item.path === file.path) assert.equal(bytes.length, source.size_bytes, file.path) assert.equal(sha(bytes), source.sha256, file.path) assert.equal(file.bytes, bytes.length, file.path) assert.equal(file.sha256, source.sha256, file.path) if (!evidence.has(file.retainedExport)) evidence.set(file.retainedExport, JSON.parse(fs.readFileSync(file.retainedExport, 'utf8'))) const exported = evidence.get(file.retainedExport) assert.equal(exported.evidence_id, file.evidenceId) assert.equal(exported.normalized_result.root_sha256, pin) const selected = exported.normalized_result.files.find(item => item.path === file.path) assert(selected, file.path) const selectedBytes = file.encoding === 'base64' ? Buffer.from(selected.data_base64, 'base64') : Buffer.from(selected.text, 'utf8') assert.equal(selected.sha256, source.sha256, file.path) assert.equal(selected.size_bytes, bytes.length, file.path) assert(bytes.equals(selectedBytes), file.path) checks.push({ path: file.path, bytes: bytes.length, sha256: sha(bytes), evidenceId: exported.evidence_id, retainedExport: file.retainedExport, pass: true }) } const read = file => fs.readFileSync(path.join(root, file), 'utf8') const frontmatter = file => parse(read(file).match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1] ?? '') const plugin = JSON.parse(read('.codebuddy-plugin/plugin.json')) assert.equal(plugin.name, 'ui-designer') assert.deepEqual(plugin.skills, ['./skills/impeccable', './skills/frontend-dev', './skills/browser-use']) const skills = plugin.skills.map(file => ({ path: file, metadata: frontmatter(file + '/SKILL.md') })) for (const file of plugin.agents) assert(manifest.files.some(item => './' + item.path === file)) for (const skill of plugin.skills) assert(manifest.files.some(item => './' + item.path === skill + '/SKILL.md')) assert(!manifest.files.some(item => item.path.endsWith('.mcp.json'))) const miniMaxScripts = manifest.files.filter(item => /frontend-dev\/scripts\/.*\.py$/.test(item.path)).map(item => { const source = read(item.path) assert(source.includes('import requests')) for (const key of ['MINIMAX_API_KEY', 'MINIMAX_API_BASE']) assert(source.includes(`os.getenv("${key}")`)) return { path: item.path, requires: ['Python', 'requests', 'MINIMAX_API_KEY', 'MINIMAX_API_BASE'] } }) assert.equal(miniMaxScripts.length, 4) const html = read('skills/frontend-dev/templates/viewer.html') const templateRemoteUrls = [...new Set(html.match(/https:\/\/[^"'<>\s]+/g))] const groups = Object.fromEntries(['.ttf', '.png', '.LICENSE', '.html', '.py'].map(extension => { const files = manifest.files.filter(item => item.path.endsWith(extension)) return [extension, { files: files.length, bytes: files.reduce((sum, item) => sum + item.bytes, 0) }] })) const report = { rootSha256: pin, inventoryEvidenceId: inventory.evidence_id, packageVersion: plugin.version, functionalFiles: checks.length, functionalBytes: checks.reduce((sum, item) => sum + item.bytes, 0), excluded: manifest.excluded, remaining: 0, evidenceExports: evidence.size, groups, plugin, skills, miniMaxScripts, templateRemoteUrls, checks, scope: 'REA byte recovery and offline dependency analysis; no execution, installation, remote request, or original runtime behavior verification' } const reportPath = path.resolve('.tmp/rea-ui-designer-audit-20261016.json') fs.writeFileSync(reportPath, JSON.stringify(report, null, 2) + '\n') console.log(JSON.stringify({ report: reportPath, rootSha256: pin, verified: checks.length, bytes: report.functionalBytes, remaining: 0, exports: evidence.size, groups, templateRemoteUrls }, null, 2))