const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const { test } = require('node:test'); const { assertPrivateEvidenceFile, buildEvidenceReport, mountForPath, normalizeManifest, parseArguments, parseMountTable, parseOsRelease, readFaultEvidence, readIdleEvidence, readAdoptionScaleEvidence, readApplicationStartEvidence, readComposeStorageEvidence, validateAdoptionScaleEvidenceReport, validateApplicationStartEvidenceReport, validateComposeStorageEvidenceReport, validateFaultEvidenceReport, validateIdleEvidenceReport, validateObservedPlatform, writeNoReplace, } = require('../../scripts/ql3-physical-edge-evidence.cjs'); const { runBenchmark: runPluginPackageRecoveryEdgeBenchmark, } = require('../../scripts/ql3-plugin-package-recovery-edge-benchmark.cjs'); const { buildReport: buildAdoptionScaleReport, normalizeManifest: normalizeAdoptionScaleManifest, } = require('../../scripts/ql3-physical-edge-adoption-scale.cjs'); const { buildComposeStorageReport, normalizeComposeStorageManifest, } = require('../../scripts/ql3-physical-edge-compose-storage.cjs'); const { buildApplicationStartReport, normalizeApplicationStartManifest, } = require('../../scripts/ql3-physical-edge-application-start.cjs'); test('rejects relative fault evidence paths and foreign-owned reports', () => { assert.throws( () => parseArguments([ '--manifest=/etc/ql3/device.json', '--data-path=/data', '--fault-evidence=relative.json', ]), /faultEvidencePath must be absolute/, ); const effectiveUserId = process.geteuid(); const privateFile = { isFile: () => true, isSymbolicLink: () => false, mode: 0o100600, uid: effectiveUserId, }; assert.doesNotThrow(() => assertPrivateEvidenceFile(privateFile, 'supplemental evidence'), ); assert.throws( () => assertPrivateEvidenceFile( { ...privateFile, uid: effectiveUserId + 1 }, 'supplemental evidence', ), /current-user-owned private regular file/, ); }); function manifest(overrides = {}) { return normalizeManifest({ schemaVersion: 1, evidenceClass: 'physical_edge_candidate', profile: 'edge', deviceId: 'router-a1', deviceModel: 'Example Router A1', soc: 'Example SoC', storageMedium: 'emmc', expectedArchitecture: 'arm64', memoryBytes: { minimum: 240 * 1024 * 1024, maximum: 320 * 1024 * 1024, }, expectedFilesystem: 'ext4', ...overrides, }); } function observed(overrides = {}) { return { platform: 'linux', architecture: 'arm64', node: 'v24.18.0', bootId: '019f0000-0000-7000-8000-000000000001', kernel: '6.6.0', distribution: { id: 'openwrt', versionId: '24.10' }, libc: 'musl-ld-musl-aarch64.so.1', cpuModel: 'Example CPU', cpuCount: 1, totalMemoryBytes: 256 * 1024 * 1024, observedModel: 'Example Router A1', dataPath: '/opt/qinglong/data', dataFilesystem: 'ext4', dataMountOptions: ['rw', 'noatime'], dataBytes: 4 * 1024 * 1024 * 1024, dataAvailableBytes: 2 * 1024 * 1024 * 1024, virtualizationIndicators: [], ...overrides, }; } test('accepts one exact physical Edge device manifest', () => { const value = manifest(); assert.equal(value.deviceId, 'router-a1'); assert.equal(value.profile, 'edge'); assert.equal(value.memoryBytes.minimum, 240 * 1024 * 1024); }); test('rejects widened, virtual and under-specified manifests', () => { assert.throws( () => manifest({ extra: true }), /manifest keys must be exactly/, ); assert.throws( () => manifest({ storageMedium: 'virtual' }), /storageMedium must be one of/, ); assert.throws( () => manifest({ memoryBytes: { minimum: 64 * 1024 * 1024, maximum: 128 * 1024 * 1024 }, }), /128 MiB to 64 GiB/, ); }); test('finds the most specific data mount and parses OS identity', () => { const mounts = parseMountTable( 'root / ext4 rw,noatime 0 0\ndata /opt/qinglong ext4 rw,nodev 0 0\ntmp /tmp tmpfs rw,nosuid 0 0\n', ); assert.equal( mountForPath(mounts, '/opt/qinglong/data').path, '/opt/qinglong', ); assert.deepEqual(parseOsRelease('ID=openwrt\nVERSION_ID="24.10"\n'), { id: 'openwrt', versionId: '24.10', }); }); test('fails closed on architecture, memory, filesystem and virtualization drift', () => { assert.deepEqual( validateObservedPlatform( manifest(), observed({ architecture: 'x64', totalMemoryBytes: 512 * 1024 * 1024, dataFilesystem: 'overlay', virtualizationIndicators: ['DMI'], }), ), [ 'architecture x64 did not equal arm64', 'observed memory is outside the declared device range', 'filesystem overlay did not equal ext4', 'virtualization indicators found: DMI', ], ); }); test('produces digest-bound candidate evidence but never supported status', async () => { const pluginPackageRecovery = await runPluginPackageRecoveryEdgeBenchmark({ maxDatabaseGrowthBytes: 4 * 1024 * 1024, maxDurationMs: 10_000, maxRssDeltaBytes: 96 * 1024 * 1024, }); const workloads = [ { name: 'edge-executor', report: { schemaVersion: 1, profile: 'edge', host: { platform: 'linux', architecture: 'arm64' }, gates: { passed: true, violations: [] }, }, }, { name: 'node-sqlite-on-device-storage', report: { platform: 'linux', arch: 'arm64', journalMode: 'delete', synchronous: 'full', integrityCheck: 'ok', databaseBytes: 16_384, rssDeltaMb: 1, }, }, { name: 'plugin-package-failed-upgrade', report: { ...pluginPackageRecovery, identity: { ...pluginPackageRecovery.identity, platform: 'linux', architecture: 'arm64', }, }, }, ]; const report = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads, generatedAt: '2026-07-22T00:00:00.000Z', }); assert.equal(report.supported, false); assert.equal(report.qualification.physicalCandidate, true); assert.ok( report.qualification.collectedEvidence.includes( 'plugin_package_failed_upgrade_retains_active_generation', ), ); assert.equal(report.sha256.length, 64); const foreignWorkload = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [ workloads[0], workloads[1], { ...workloads[2], report: { ...workloads[2].report, identity: { ...workloads[2].report.identity, platform: 'darwin', }, }, }, ], generatedAt: '2026-07-22T00:00:00.000Z', }); assert.equal(foreignWorkload.qualification.physicalCandidate, false); assert.match( foreignWorkload.qualification.violations.join('; '), /runtime identity did not match/, ); const changed = buildEvidenceReport({ manifest: manifest({ deviceId: 'router-a2' }), observed: observed(), workloads: [], generatedAt: '2026-07-22T00:00:00.000Z', }); assert.equal(changed.qualification.physicalCandidate, false); assert.ok( changed.qualification.remainingRequiredEvidence.includes( 'plugin_package_failed_upgrade_retains_active_generation', ), ); assert.notEqual(changed.sha256, report.sha256); }); test('requires canonical absolute input paths', () => { assert.deepEqual( parseArguments([ '--', '--manifest=/etc/ql3/device.json', '--data-path=/opt/qinglong/data', '--output=/opt/qinglong/evidence.json', '--idle-evidence=/opt/qinglong/idle.json', '--adoption-scale-evidence=/opt/qinglong/adoption.json', '--compose-storage-evidence=/opt/qinglong/compose-storage.json', '--application-start-evidence=/opt/qinglong/application-start.json', '--fault-evidence=/opt/qinglong/enospc.json', '--fault-evidence=/opt/qinglong/readonly.json', '--json', ]), { manifestPath: '/etc/ql3/device.json', dataPath: '/opt/qinglong/data', outputPath: '/opt/qinglong/evidence.json', idleEvidencePath: '/opt/qinglong/idle.json', adoptionScaleEvidencePath: '/opt/qinglong/adoption.json', composeStorageEvidencePath: '/opt/qinglong/compose-storage.json', applicationStartEvidencePath: '/opt/qinglong/application-start.json', faultEvidencePaths: [ '/opt/qinglong/enospc.json', '/opt/qinglong/readonly.json', ], json: true, }, ); assert.throws( () => parseArguments(['--manifest=device.json', '--data-path=/data']), /manifestPath must be absolute/, ); assert.throws( () => parseArguments([ '--', '--', '--manifest=/etc/ql3/device.json', '--data-path=/data', ]), /unsupported argument --/, ); }); test('imports exact same-boot ENOSPC and read-only evidence independently', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-fault-import-test-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const createFault = (fault) => { const errorCode = fault === 'enospc_filesystem' ? 'ENOSPC' : 'EROFS'; const body = { schemaVersion: 1, evidenceClass: 'physical_edge_fault_candidate', supported: false, generatedAt: '2026-07-22T00:00:00.000Z', manifest: { schemaVersion: 1, evidenceClass: 'physical_edge_fault_candidate', profile: 'edge', deviceId: 'router-a1', fault, probePath: `/mnt/${fault}`, expectedFilesystem: 'ext4', maximumFilesystemBytes: 64 * 1024 * 1024, }, observed: { platform: 'linux', architecture: 'arm64', node: 'v24.18.0', bootId: observed().bootId, processUid: 1000, probePath: `/mnt/${fault}`, mountPath: `/mnt/${fault}`, filesystem: 'ext4', mountOptions: [fault === 'enospc_filesystem' ? 'rw' : 'ro', 'nodev'], totalBytes: 32 * 1024 * 1024, availableBytes: fault === 'enospc_filesystem' ? 0 : 4096, expectedErrorCode: errorCode, probeEntryCreated: false, probeEntryRemained: false, }, qualification: { passed: true, violations: [], scope: fault, doesNotProve: [ 'main_data_filesystem_fault', 'application_level_recovery', 'power_loss_survival', ], }, }; return { ...body, sha256: require('node:crypto') .createHash('sha256') .update(JSON.stringify(body)) .digest('hex'), }; }; const enospc = createFault('enospc_filesystem'); const readonly = createFault('read_only_filesystem'); assert.deepEqual( validateFaultEvidenceReport(enospc, manifest(), observed()), [], ); const enospcPath = path.join(directory, 'enospc.json'); writeNoReplace(enospcPath, `${JSON.stringify(enospc)}\n`); assert.equal( readFaultEvidence(enospcPath, manifest(), observed()).manifest.fault, 'enospc_filesystem', ); const report = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [], supplementalEvidence: [enospc, readonly], generatedAt: '2026-07-22T00:01:00.000Z', }); assert.ok( report.qualification.collectedEvidence.includes('real_enospc_filesystem'), ); assert.ok( report.qualification.collectedEvidence.includes('read_only_filesystem'), ); assert.ok( !report.qualification.remainingRequiredEvidence.includes( 'real_enospc_filesystem', ), ); assert.ok( !report.qualification.remainingRequiredEvidence.includes( 'read_only_filesystem', ), ); const widened = { ...enospc, observed: { ...enospc.observed, availableBytes: 4096 }, }; assert.match( validateFaultEvidenceReport(widened, manifest(), observed()).join('; '), /SHA-256 did not match.*ENOSPC evidence did not prove/, ); }); test('imports one same-device 100000-row adoption report into aggregate evidence', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-adoption-import-test-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const adoptionManifest = normalizeAdoptionScaleManifest({ schemaVersion: 1, evidenceClass: 'physical_edge_adoption_scale_candidate', profile: 'edge', deviceId: manifest().deviceId, expectedArchitecture: manifest().expectedArchitecture, expectedFilesystem: manifest().expectedFilesystem, rowCount: 100_000, maxReviewFileBytes: 32 * 1024 * 1024, }); const measurement = { durationMs: 100, peakRssBytes: 30_000_000, sampleCount: 10, readBytes: 4096, writeBytes: 8192, cancelledWriteBytes: 0, exitCode: 0, }; const adoption = buildAdoptionScaleReport({ manifest: adoptionManifest, observed: observed(), preflight: { sourceRowCount: 100_000, reviewFileBytes: 20_000_000, targetLedgerCount: 0, targetStorage: { logicalBytes: 4096, allocatedBytes: 4096, files: [], }, }, issue: measurement, commit: measurement, final: { ledgerCount: 1, adoptedTaskCount: 100_000, adoptedTriggerCount: 100_000, targetStorage: { logicalBytes: 8192, allocatedBytes: 8192, files: [], }, }, generatedAt: '2026-07-22T00:00:00.000Z', }); assert.deepEqual( validateAdoptionScaleEvidenceReport(adoption, manifest(), observed()), [], ); const evidencePath = path.join(directory, 'adoption.json'); writeNoReplace(evidencePath, `${JSON.stringify(adoption)}\n`); assert.equal( readAdoptionScaleEvidence(evidencePath, manifest(), observed()).sha256, adoption.sha256, ); const aggregate = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [], supplementalEvidence: [adoption], generatedAt: '2026-07-22T00:01:00.000Z', }); assert.ok( aggregate.qualification.collectedEvidence.includes( 'legacy_adoption_100000_row_scaling', ), ); assert.ok( !aggregate.qualification.remainingRequiredEvidence.includes( 'legacy_adoption_100000_row_scaling', ), ); assert.match( validateAdoptionScaleEvidenceReport( { ...adoption, sha256: '0'.repeat(64) }, manifest(), observed(), ).join('; '), /SHA-256/, ); }); test('imports only private digest-bound idle evidence from the same device boot', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-idle-import-test-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const idleManifest = { schemaVersion: 1, evidenceClass: 'physical_edge_idle_candidate', profile: 'edge', deviceId: 'router-a1', processId: 123, expectedExecutable: '/usr/bin/node', durationSeconds: 30, sampleIntervalMs: 10_000, }; const body = { schemaVersion: 1, evidenceClass: 'physical_edge_idle_candidate', supported: false, generatedAt: '2026-07-22T00:00:00.000Z', manifest: idleManifest, identity: { platform: 'linux', architecture: 'arm64', node: 'v24.18.0', bootId: observed().bootId, processId: 123, processUid: 1000, executable: '/usr/bin/node', commandSha256: 'a'.repeat(64), startTicks: 100, }, summary: { sampleCount: 4, actualDurationMs: 30_000 }, qualification: { passed: true, violations: [], measures: [ 'process_rss', 'process_cpu_ticks', 'process_context_switches', 'process_io', ], doesNotProve: [ 'whole_device_cpu_wakeups', 'whole_device_flash_write_amplification', 'cold_start_or_first_ready', ], }, }; const idle = { ...body, sha256: require('node:crypto') .createHash('sha256') .update(JSON.stringify(body)) .digest('hex'), }; assert.deepEqual( validateIdleEvidenceReport(idle, manifest(), observed()), [], ); const idlePath = path.join(directory, 'idle.json'); writeNoReplace(idlePath, `${JSON.stringify(idle)}\n`); assert.equal( readIdleEvidence(idlePath, manifest(), observed()).sha256, idle.sha256, ); const report = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [], supplementalEvidence: [idle], generatedAt: '2026-07-22T00:01:00.000Z', }); assert.deepEqual(report.qualification.collectedEvidence, [ 'idle_process_rss_cpu_ticks_context_switches_and_io', ]); assert.ok( !report.qualification.remainingRequiredEvidence.includes( 'idle_process_rss_cpu_ticks_context_switches_and_io', ), ); assert.ok( report.qualification.remainingRequiredEvidence.includes( 'whole_device_cpu_wakeups_and_flash_write_amplification', ), ); const drifted = { ...idle, identity: { ...idle.identity, bootId: 'different' }, }; assert.match( validateIdleEvidenceReport(drifted, manifest(), observed()).join('; '), /SHA-256 did not match.*runtime identity did not match/, ); }); test('publishes private evidence without replacing an existing record', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-evidence-test-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const outputPath = path.join(directory, 'evidence.json'); writeNoReplace(outputPath, '{"schemaVersion":1}\n'); assert.equal(fs.statSync(outputPath).mode & 0o777, 0o600); assert.equal(fs.readFileSync(outputPath, 'utf8'), '{"schemaVersion":1}\n'); assert.throws( () => writeNoReplace(outputPath, 'replacement'), (error) => error?.code === 'EEXIST', ); }); test('imports a different-boot Compose collection storage candidate without widening power-loss claims', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-compose-storage-import-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const supplementalManifest = normalizeComposeStorageManifest({ schemaVersion: 1, evidenceClass: 'physical_edge_compose_storage_candidate', profile: 'edge', deviceId: manifest().deviceId, expectedArchitecture: manifest().expectedArchitecture, expectedFilesystem: manifest().expectedFilesystem, snapshotCount: 3, databasePayloadBytes: 4 * 1024 * 1024, maximumPrepareWriteAmplificationPermille: 50_000, maximumResumeWriteAmplificationPermille: 50_000, }); const targetSnapshot = { contractVersion: 44, sha256: 'a'.repeat(64), bytes: 4_000_000, pageCount: 1000, pageSize: 4096, }; const before = { platform: 'linux', architecture: 'arm64', bootId: '019f0000-0000-4000-8000-000000000001', mountPath: observed().dataPath, filesystem: 'ext4', mountOptions: ['rw', 'noatime'], blockDevice: '/dev/mmcblk0p3', sectorsWritten: 10_000, }; const afterStart = { ...before, bootId: observed().bootId, sectorsWritten: 200, }; const after = { ...afterStart, sectorsWritten: 220 }; const session = { sessionId: '019f0000-0000-4000-8000-000000000010', sha256: 'b'.repeat(64), preparedAt: '2026-07-29T00:00:00.000Z', dataPath: observed().dataPath, collection: { target: { rolloutId: '019f0000-0000-4000-8000-000000000011', snapshot: targetSnapshot, }, }, }; const composeStorage = buildComposeStorageReport({ manifest: supplementalManifest, session, observed: { before, afterStart, after }, measurements: { logicalSnapshotBytes: 12_000_000, collectedSnapshotBytes: 4_000_000, prepareDeviceBytesWritten: 24_000_000, resumeDeviceBytesWritten: 10_240, prepareWriteAmplificationPermille: 2000, resumeWriteAmplificationPermille: 3, barrierAllocatedBytes: 20_500_000, finalAllocatedBytes: 16_400_000, reclaimedAllocatedBytes: 4_100_000, }, outcomes: { commitStatus: 'collected', replayStatus: 'existing', sqliteIntegrity: 'ok', stageRemoved: true, tombstonePresent: true, retainedSnapshots: 2, }, generatedAt: '2026-07-29T00:01:00.000Z', }); assert.deepEqual( validateComposeStorageEvidenceReport( composeStorage, manifest(), observed(), ), [], ); const evidencePath = path.join(directory, 'compose-storage.json'); writeNoReplace(evidencePath, `${JSON.stringify(composeStorage)}\n`); assert.equal( readComposeStorageEvidence(evidencePath, manifest(), observed()).sha256, composeStorage.sha256, ); const aggregate = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [], supplementalEvidence: [composeStorage], generatedAt: '2026-07-29T00:02:00.000Z', }); assert.ok( aggregate.qualification.collectedEvidence.includes( 'compose_sqlite_collection_reboot_and_partition_write_upper_bound', ), ); assert.ok( !aggregate.qualification.remainingRequiredEvidence.includes( 'compose_sqlite_collection_reboot_and_partition_write_upper_bound', ), ); assert.ok( aggregate.qualification.remainingRequiredEvidence.includes( 'power_loss_restart', ), ); assert.ok( composeStorage.qualification.doesNotProve.includes( 'abrupt_power_interruption_provenance', ), ); }); test('imports post-reboot warm-Node native application activation while retaining the full cold-start gate', (t) => { const directory = fs.realpathSync( fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-application-start-import-')), ); t.after(() => fs.rmSync(directory, { recursive: true, force: true })); const artifact = { artifactSha256: 'a'.repeat(64), artifactMetadataSha256: 'e'.repeat(64), artifactFiles: 320, artifactBytes: 2_000_000, entrypointSha256: 'b'.repeat(64), packages: [ '@qinglong/local-admin', '@qinglong/local-application', '@qinglong/local-command-file', '@qinglong/local-execution', '@qinglong/local-process', '@qinglong/local-secret', '@qinglong/local-sqlite', '@qinglong/runtime-core', 'croner', 'semver', ], }; const applicationManifest = normalizeApplicationStartManifest({ schemaVersion: 1, evidenceClass: 'physical_edge_application_start_candidate', profile: 'edge', deviceId: manifest().deviceId, expectedArchitecture: manifest().expectedArchitecture, expectedFilesystem: manifest().expectedFilesystem, expectedArtifactSha256: artifact.artifactSha256, expectedArtifactFiles: artifact.artifactFiles, expectedArtifactBytes: artifact.artifactBytes, expectedNodeSha256: 'c'.repeat(64), maximumBootAgeMs: 180_000, maximumFirstActiveMs: 30_000, maximumSampledRssBytes: 256 * 1024 * 1024, sampleIntervalMs: 10, }); const previousBoot = { platform: 'linux', architecture: 'arm64', bootId: '019f0000-0000-4000-8000-000000000001', dataFilesystem: 'ext4', nodeExecutable: '/usr/bin/node', nodeSha256: 'c'.repeat(64), nodeVersion: 'v24.18.0', bootAgeMs: 50_000, }; const currentBoot = { ...previousBoot, bootId: observed().bootId, bootAgeMs: 5_000, }; const session = { sessionId: '019f0000-0000-4000-8000-000000000010', sha256: 'd'.repeat(64), preparedAt: '2026-07-29T00:00:00.000Z', artifact, paths: { dataPath: observed().dataPath }, }; const applicationStart = buildApplicationStartReport({ manifest: applicationManifest, session, observed: { before: previousBoot, after: currentBoot, artifact, }, measurements: { firstActiveMs: 1200, maximumSampledRssBytes: 80 * 1024 * 1024, processReadBytes: 4096, processWriteBytes: 8192, sampleCount: 20, eventCount: 5, }, outcomes: { activeEventCount: 1, aiStatus: 'deployment_excluded', gracefulStop: true, exitCode: 0, exitSignal: null, stderrBytes: 0, sqliteContractVersion: 41, }, generatedAt: '2026-07-29T00:01:00.000Z', }); assert.deepEqual( validateApplicationStartEvidenceReport( applicationStart, manifest(), observed(), ), [], ); const evidencePath = path.join(directory, 'application-start.json'); writeNoReplace(evidencePath, `${JSON.stringify(applicationStart)}\n`); assert.equal( readApplicationStartEvidence(evidencePath, manifest(), observed()).sha256, applicationStart.sha256, ); const aggregate = buildEvidenceReport({ manifest: manifest(), observed: observed(), workloads: [], supplementalEvidence: [applicationStart], generatedAt: '2026-07-29T00:02:00.000Z', }); assert.ok( aggregate.qualification.collectedEvidence.includes( 'post_reboot_warm_node_native_application_start_to_active', ), ); assert.ok( !aggregate.qualification.remainingRequiredEvidence.includes( 'cold_start_and_first_ready', ), ); assert.ok( aggregate.qualification.remainingRequiredEvidence.includes( 'power_on_cold_node_and_service_manager_start_to_first_ready', ), ); assert.ok( aggregate.qualification.remainingRequiredEvidence.includes( 'power_loss_restart', ), ); });