'use strict'; const assert = require('node:assert/strict'); const test = require('node:test'); const { createPs5FpkgCompletionTrace, parseKstuffCompletionSnapshot, } = require('../../src/services/ps5-fpkg-completion-trace'); const OPERATION_ID = '123e4567-e89b-42d3-a456-426614174000'; const FINGERPRINT = 'a'.repeat(64); function runtime(overrides = {}) { return { product: 'EchoStretch/kstuff-lite', version: '1.10', revision: '3b2ab4a16ba43c8ab38daf7ec83cc297014e0e47', payloadSha256: '1'.repeat(64), loaderSha256: '2'.repeat(64), readerSha256: '3'.repeat(64), observabilityPatchSha256: '4'.repeat(64), observabilityProfile: 'chimera-p15-a8-call-bound-completion-v1', identityStatus: 'exact', traceEligible: true, firmware: '9.60', fingerprint: FINGERPRINT, ...overrides, }; } function metrics(overrides = {}) { return { nmountDispatch: 0, taggedArmAttempts: 0, taggedReadFailures: 0, taggedPcbPointerFailures: 0, taggedPcbStateFailures: 0, taggedStackPushFailures: 0, taggedPcbSetFailures: 0, taggedWriteFailures: 0, taggedArmSuccesses: 0, taggedRollbackRestoreFailures: 0, taggedFinishEntries: 0, taggedFinishPeekFailures: 0, taggedFinishRestoreFailures: 0, taggedFinishSuccesses: 0, mailboxTotal: 0, mailboxFpkg: 0, mailboxUnhandled: 0, verifySuperBlockMailbox: 0, verifySuperBlockEmulated: 0, ...overrides, }; } function snapshot(sequence, values) { return { sequence, sampledAt: 1000 + sequence, runtimeFingerprint: FINGERPRINT, metrics: metrics(values) }; } function trace(postMetrics, overrides = {}) { const post = snapshot(11, postMetrics); return createPs5FpkgCompletionTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime(), pre: snapshot(10, metrics()), post, postStable: snapshot(12, postMetrics), postStableConfirm: snapshot(13, postMetrics), launchRequests: 1, retryPerformed: false, ...overrides, }); } test('A8 strict parser accepts the exact semantic completion schema', () => { const parsed = parseKstuffCompletionSnapshot([ 'schema=chimera.p15-a8-completion-metrics.v1', 'status=attached', 'sample=8', 'route nmount_dispatch=7', 'completion tag=nmount attempt=7 read_fail=0 pcb_ptr_fail=0 pcb_state_fail=0 stack_fail=0 pcb_set_fail=0 write_fail=0 armed=7 rollback_restore_fail=0 finish_entry=7 finish_peek_fail=1 finish_restore_fail=0 finish=6', 'mailbox total=4 fpkg=3 unhandled=1', 'fpkg verify=3 verify_emu=3', ].join('\n'), { sequence: 8, sampledAt: 1008, runtimeFingerprint: FINGERPRINT }); assert.equal(parsed.metrics.taggedArmSuccesses, 7); assert.equal(parsed.metrics.taggedFinishEntries, 7); assert.equal(parsed.metrics.taggedFinishPeekFailures, 1); }); test('A8 parser rejects raw data, unknown tags, duplicate fields and sample drift', () => { const base = [ 'schema=chimera.p15-a8-completion-metrics.v1', 'status=attached', 'sample=8', 'route nmount_dispatch=1', 'completion tag=nmount attempt=1 read_fail=0 pcb_ptr_fail=0 pcb_state_fail=0 stack_fail=0 pcb_set_fail=0 write_fail=0 armed=1 rollback_restore_fail=0 finish_entry=1 finish_peek_fail=0 finish_restore_fail=0 finish=1', 'mailbox total=0 fpkg=0 unhandled=0', 'fpkg verify=0 verify_emu=0', ]; for (const unsafe of [ [...base, 'request_ptr=0xffff800012345678'], base.map(line => line.startsWith('completion ') ? line.replace('tag=nmount', 'tag=ioctl') : line), base.map(line => line.startsWith('completion ') ? `${line} finish=1` : line), base.map(line => line === 'sample=8' ? 'sample=9' : line), ]) { assert.throws( () => parseKstuffCompletionSnapshot(unsafe.join('\n'), { sequence: 8, sampledAt: 1008, runtimeFingerprint: FINGERPRINT }), error => error.code === 'PS5_FPKG_COMPLETION_TRACE_UNSAFE_LINE', ); } }); test('A8 proves a balanced call-bound arm and successful finalization', () => { const result = trace(metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1, taggedFinishEntries: 1, taggedFinishSuccesses: 1, })); assert.equal(result.status, 'observed'); assert.equal(result.lifecycle.attribution, 'call-bound-nmount'); assert.equal(result.lifecycle.unresolvedArms, 0); assert.equal(result.recovery.debugRegistersRestored, true); assert.equal(result.normalizedFailure, 'PS5_FPKG_MAILBOX_TARGET_NOT_REACHED'); }); test('A8 makes a post-arm stack peek failure terminal and visible', () => { const result = trace(metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1, taggedFinishEntries: 1, taggedFinishPeekFailures: 1, })); assert.equal(result.status, 'observed'); assert.equal(result.firstFailedStage, 'debug_register_finish_stack_peek_failed'); assert.equal(result.normalizedFailure, 'PS5_FPKG_DEBUG_REGISTER_FINISH_PEEK_FAILED'); assert.equal(result.lifecycle.unresolvedArms, 0); assert.equal(result.recovery.debugRegistersRestored, false); }); test('A8 qualifies a completion that settles after the immediate post sample', () => { const complete = metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1, taggedFinishEntries: 1, taggedFinishSuccesses: 1, }); const result = trace(complete, { post: snapshot(11, metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1 })), postStable: snapshot(12, complete), postStableConfirm: snapshot(13, complete), }); assert.equal(result.status, 'observed'); assert.equal(result.postArmSettled, true); assert.equal(result.lifecycle.unresolvedArms, 0); }); test('A8 fails closed on missing or contradictory call-bound terminal events', () => { const missing = trace(metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1 })); assert.equal(missing.status, 'outcome_unknown'); assert.equal(missing.outcomeReason, 'call_bound_finalization_missing'); assert.equal(missing.lifecycle.unresolvedArms, 1); const contradictory = trace(metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1, taggedFinishEntries: 1, taggedFinishPeekFailures: 1, taggedFinishSuccesses: 1, })); assert.equal(contradictory.status, 'outcome_unknown'); assert.equal(contradictory.outcomeReason, 'finish_accounting_invariant_failed'); }); test('A8 never upgrades the immutable A7 five-count mismatch into a kernel failure claim', () => { const result = trace(metrics({ nmountDispatch: 85, taggedArmAttempts: 85, taggedArmSuccesses: 85, taggedFinishEntries: 80, taggedFinishSuccesses: 80, })); assert.equal(result.status, 'outcome_unknown'); assert.equal(result.outcomeReason, 'launch_scope_ambiguous'); assert.equal(result.legacyA7InferenceAllowed, false); }); test('A8 does not attribute unrelated global mailbox activity to the nmount', () => { const result = trace(metrics({ nmountDispatch: 1, taggedArmAttempts: 1, taggedArmSuccesses: 1, taggedFinishEntries: 1, taggedFinishSuccesses: 1, mailboxTotal: 1, mailboxUnhandled: 1, })); assert.equal(result.status, 'outcome_unknown'); assert.equal(result.outcomeReason, 'mailbox_scope_ambiguous'); assert.equal(result.normalizedFailure, null); });