'use strict'; const assert = require('node:assert/strict'); const test = require('node:test'); const { qualifyA8ControlOperation, qualifyA8ControlEvidence, verifyA8ControlQualification, } = require('../../src/services/ps5-fpkg-a8-control-qualification'); function verifiedOperation(overrides = {}) { return { id: 'qualified-control-operation', titleId: 'PPSA01234', status: 'launch_verified', launchVerified: true, productionRestorable: true, launchEvidence: { schema: 'chimera.ps5-fpkg-launch-evidence.v2', runtimeFingerprint: '7'.repeat(64), preflightCompletedAt: 1_000, requestedAt: 2_000, runtime: { ready: true, capabilities: { debugPackageRuntime: true, fpkgEnableActive: true, kernelPatchReady: true, packageInstallerReady: true, launchServiceReady: true, processObservationReady: true, syslogObservationReady: true, foregroundClean: true, }, runtime: { foregroundGameProcesses: [] }, }, request: { accepted: true, titleId: 'PPSA01234', route: '/api/ps5/app/launch', clientAutomaticRetry: false, }, boundaries: { verifyImage: 'passed', pfsMount: 'passed', executable: 'reached', process: 'stable', basis: 'stable-exact-title-process' }, rawEvidence: [ { observedAt: 2_100, summary: { observed: true, processListTruncated: false, process: { titleId: 'PPSA01234', kind: 'app', pid: 321 } } }, { observedAt: 12_100, summary: { observed: true, processListTruncated: false, process: { titleId: 'PPSA01234', kind: 'app', pid: 321 } } }, ], }, ...overrides, }; } function fullFpkgEvidence(overrides = {}) { return { titleId: 'PPSA01234', packageClass: 'fpkg', sourceEvidenceSha256: 'a'.repeat(64), route: '/api/ps5/app/launch', preflight: { observedAtMs: 1_000, coverageComplete: true, truncated: false, exactTitleAbsent: true, }, request: { observedAtMs: 2_000, operationId: 'qualified-control-operation', titleId: 'PPSA01234', clientRequests: 1, retryPerformed: false, }, processSamples: [ { observedAtMs: 2_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, { observedAtMs: 12_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, ], packageEvidence: { fakePackage: true, artifactSha256: 'b'.repeat(64), installedEvidenceSha256: 'c'.repeat(64), }, ...overrides, }; } test('A8 qualifies only a request-bound stable exact-title fPKG process', () => { const result = qualifyA8ControlEvidence(fullFpkgEvidence()); assert.equal(result.schema, 'chimera.p15-a8-control-qualification.v1'); assert.equal(result.titleId, 'PPSA01234'); assert.equal(result.packageClass, 'fpkg'); assert.equal(result.qualificationScope, 'full_fpkg_route'); assert.equal(result.sameApiRoute, '/api/ps5/app/launch'); assert.equal(result.stableDurationMs, 10_000); assert.equal(result.stableExactTitleProcess, true); assert.match(result.qualificationDigest, /^[a-f0-9]{64}$/); assert.equal(verifyA8ControlQualification(result), result); assert.ok(Object.isFrozen(result)); }); test('an unrelated already-running title cannot become an A8 control', () => { assert.throws(() => qualifyA8ControlEvidence(fullFpkgEvidence({ titleId: 'PPSA02774', preflight: { observedAtMs: 1_000, coverageComplete: true, truncated: false, exactTitleAbsent: false, }, request: { observedAtMs: 2_000, operationId: 'launching-a-different-title', titleId: 'PPSA99099', clientRequests: 1, retryPerformed: false, }, processSamples: [ { observedAtMs: 2_100, coverageComplete: true, truncated: false, titleId: 'PPSA02774', kind: 'app', pid: 121 }, { observedAtMs: 12_100, coverageComplete: true, truncated: false, titleId: 'PPSA02774', kind: 'app', pid: 121 }, ], })), error => error.code === 'P15_A8_CONTROL_NOT_REQUEST_BOUND'); }); test('A8 rejects incomplete, unstable and too-short process observations', () => { assert.throws(() => qualifyA8ControlEvidence(fullFpkgEvidence({ processSamples: [ { observedAtMs: 2_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, { observedAtMs: 12_100, coverageComplete: false, truncated: true, titleId: 'PPSA01234', kind: 'app', pid: 321 }, ], })), error => error.code === 'P15_A8_CONTROL_PROCESS_EVIDENCE_INCOMPLETE'); assert.throws(() => qualifyA8ControlEvidence(fullFpkgEvidence({ processSamples: [ { observedAtMs: 2_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, { observedAtMs: 12_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 322 }, ], })), error => error.code === 'P15_A8_CONTROL_PROCESS_NOT_STABLE'); assert.throws(() => qualifyA8ControlEvidence(fullFpkgEvidence({ processSamples: [ { observedAtMs: 2_100, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, { observedAtMs: 12_099, coverageComplete: true, truncated: false, titleId: 'PPSA01234', kind: 'app', pid: 321 }, ], })), error => error.code === 'P15_A8_CONTROL_PROCESS_NOT_STABLE'); }); test('signed retail evidence can qualify ShellUI only, never the full fPKG route', () => { const evidence = fullFpkgEvidence({ packageClass: 'signed_retail', packageEvidence: { fakePackage: false, artifactSha256: 'b'.repeat(64), installedEvidenceSha256: 'c'.repeat(64), }, }); const result = qualifyA8ControlEvidence(evidence); assert.equal(result.qualificationScope, 'shellui_route_only'); }); test('qualification integrity rejects semantic tampering', () => { const result = qualifyA8ControlEvidence(fullFpkgEvidence()); assert.throws( () => verifyA8ControlQualification({ ...result, titleId: 'PPSA99999' }), error => error.code === 'P15_A8_CONTROL_QUALIFICATION_CORRUPT', ); }); test('A8 derives qualification from an existing durable launch-verified operation', () => { const result = qualifyA8ControlOperation({ operation: verifiedOperation(), sourceEvidenceSha256: 'd'.repeat(64), packageClass: 'fpkg', packageEvidence: { fakePackage: true, artifactSha256: 'e'.repeat(64), installedEvidenceSha256: 'f'.repeat(64) }, }); assert.equal(result.titleId, 'PPSA01234'); assert.equal(result.operationId, 'qualified-control-operation'); assert.equal(result.qualificationScope, 'full_fpkg_route'); }); test('success flags cannot hide route drift, truncated coverage or an unrelated process', () => { const input = { sourceEvidenceSha256: 'd'.repeat(64), packageClass: 'fpkg', packageEvidence: { fakePackage: true, artifactSha256: 'e'.repeat(64), installedEvidenceSha256: 'f'.repeat(64) }, }; assert.throws(() => qualifyA8ControlOperation({ ...input, operation: verifiedOperation({ launchEvidence: { ...verifiedOperation().launchEvidence, request: { ...verifiedOperation().launchEvidence.request, route: '/api/ps5/app/open' } }, }) }), error => error.code === 'P15_A8_CONTROL_ROUTE_MISMATCH'); const truncated = verifiedOperation(); truncated.launchEvidence.rawEvidence[1].summary.processListTruncated = true; assert.throws( () => qualifyA8ControlOperation({ ...input, operation: truncated }), error => error.code === 'P15_A8_CONTROL_PROCESS_EVIDENCE_INCOMPLETE', ); const unrelated = verifiedOperation(); unrelated.launchEvidence.rawEvidence[0].summary.process.titleId = 'PPSA02774'; assert.throws( () => qualifyA8ControlOperation({ ...input, operation: unrelated }), error => error.code === 'P15_A8_CONTROL_PROCESS_NOT_STABLE', ); const missingBoundary = verifiedOperation(); delete missingBoundary.launchEvidence.boundaries; assert.throws( () => qualifyA8ControlOperation({ ...input, operation: missingBoundary }), error => error.code === 'P15_A8_CONTROL_OPERATION_UNQUALIFIED', ); });