import assert from 'node:assert/strict' import crypto from 'node:crypto' import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import test from 'node:test' import { activateRelease, verifyReleaseBundle } from '../server/release-broadcast/operator.mjs' import { loadRuntimeState } from '../server/release-broadcast/server.mjs' const sha256 = (bytes) => crypto.createHash('sha256').update(bytes).digest('hex') const writeJson = (file, value) => fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 }) function buildOperatorFixture() { const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'hololake-release-operator-fixture-')) const source = path.join(fixtureRoot, 'source') const approvals = path.join(fixtureRoot, 'approvals') const stateRoot = path.join(fixtureRoot, 'state') for (const directory of [source, approvals, stateRoot]) fs.mkdirSync(directory, { mode: 0o700 }) const packageName = 'HoloLake.app.tar.gz' const packageBytes = Buffer.from('signed-notarized-updater-package') const sourceCommit = '2'.repeat(40) fs.writeFileSync(path.join(source, packageName), packageBytes, { mode: 0o600 }) writeJson(path.join(source, 'HOLOLAKE-CODESIGN.json'), { schema: 'hololake.platform-code-signature-receipt/v1', state: 'DEVELOPER_ID_SIGNATURE_STRICT_AND_GATEKEEPER_ACCEPTED', sourceCommit, }) writeJson(path.join(source, 'HOLOLAKE-NOTARIZATION.json'), { schema: 'hololake.apple-notarization-receipt/v1', state: 'APPLE_NOTARIZATION_ACCEPTED_AND_STAPLED', sourceCommit, }) const broadcast = { schema: 'hololake.release-broadcast/v1', releaseId: 'GH-HOLOLAKE-RELEASE-0.2.0', version: '0.2.0', pub_date: '2026-08-13T10:00:00.000Z', notes: 'Signed release', platforms: { 'darwin-aarch64': { url: `https://guanghulab.com/hololake/releases/0.2.0/${packageName}`, signature: 'trusted-updater-signature', size: packageBytes.length, sha256: sha256(packageBytes), platformCodeSignatureReceipt: 'HOLOLAKE-CODESIGN', notarizationReceipt: 'HOLOLAKE-NOTARIZATION', }, }, hololake: { features: ['Stage one'], fixes: [], compatibility: { minimumVersion: '0.1.0', dataMigrationRequired: false }, restart: { required: true, automaticAllowed: false }, rollback: { supported: true, healthReceiptRequired: true, previousVersion: '0.1.0' }, }, } const broadcastPath = path.join(source, 'latest.json') writeJson(broadcastPath, broadcast) const broadcastSha256 = sha256(fs.readFileSync(broadcastPath)) writeJson(path.join(source, 'pipeline-receipt.json'), { schema: 'hololake.signed-release-pipeline-receipt/v1', state: 'SIGNED_NOTARIZED_RELEASE_BROADCAST_READY_FOR_JD_CONTROLLER_UPLOAD', sourceCommit, broadcastSha256, automaticUpload: false, automaticActivation: false, }) const approval = path.join(approvals, 'approval.json') writeJson(approval, { schema: 'hololake.release-broadcast-human-approval/v1', state: 'HUMAN_APPROVED_EXACT_SIGNED_NOTARIZED_RELEASE', approvalId: 'GH-HUMAN-RELEASE-APPROVAL-002', releaseId: broadcast.releaseId, version: broadcast.version, broadcastSha256, }) return { fixtureRoot, source, approval, stateRoot, expected: { releaseId: broadcast.releaseId, version: broadcast.version, sourceCommit, broadcastSha256 }, } } test('verify reconstructs and validates an exact private candidate without mutating state', () => { const fixture = buildOperatorFixture() try { const result = verifyReleaseBundle(fixture.source, fixture.approval) assert.equal(result.state, 'EXACT_SIGNED_NOTARIZED_HUMAN_APPROVED_BUNDLE_VERIFIED') assert.equal(result.broadcastSha256, fixture.expected.broadcastSha256) assert.equal(result.artifacts.some((artifact) => artifact.name === 'HoloLake.app.tar.gz'), true) assert.deepEqual(fs.readdirSync(fixture.stateRoot), []) } finally { fs.rmSync(fixture.fixtureRoot, { recursive: true, force: true }) } }) test('activation repeats expected facts, commits atomically, and still requires explicit restart', () => { const fixture = buildOperatorFixture() try { const receipt = activateRelease({ sourceDirectory: fixture.source, humanApprovalPath: fixture.approval, stateRoot: fixture.stateRoot, expected: fixture.expected, enforceRootOwner: false, }) assert.equal(receipt.state, 'ACTIVATED_EXPLICIT_SERVICE_RESTART_REQUIRED') assert.equal(receipt.automaticUpload, false) assert.equal(receipt.automaticActivation, false) assert.equal(receipt.automaticRestart, false) assert.equal(loadRuntimeState(fixture.stateRoot).state, 'READY_SIGNED_NOTARIZED_BROADCAST') assert.equal(fs.existsSync(path.join(fixture.stateRoot, '.operator-lock')), false) } finally { fs.rmSync(fixture.fixtureRoot, { recursive: true, force: true }) } }) test('expected-fact mismatch performs no activation or release staging', () => { const fixture = buildOperatorFixture() try { assert.throws(() => activateRelease({ sourceDirectory: fixture.source, humanApprovalPath: fixture.approval, stateRoot: fixture.stateRoot, expected: { ...fixture.expected, broadcastSha256: '3'.repeat(64) }, enforceRootOwner: false, }), /HOLOLAKE_RELEASE_OPERATOR_EXPECTED_BROADCAST_SHA256_MISMATCH/) assert.deepEqual(fs.readdirSync(fixture.stateRoot), []) } finally { fs.rmSync(fixture.fixtureRoot, { recursive: true, force: true }) } }) test('human approval cannot be reused after broadcast bytes change', () => { const fixture = buildOperatorFixture() try { const latestPath = path.join(fixture.source, 'latest.json') const latest = JSON.parse(fs.readFileSync(latestPath, 'utf8')) latest.notes = 'Changed after approval' writeJson(latestPath, latest) assert.throws( () => verifyReleaseBundle(fixture.source, fixture.approval), /HOLOLAKE_RELEASE_OPERATOR_PIPELINE_RECEIPT_INVALID/, ) } finally { fs.rmSync(fixture.fixtureRoot, { recursive: true, force: true }) } }) test('symlinked package inputs are rejected instead of followed', () => { const fixture = buildOperatorFixture() try { const packagePath = path.join(fixture.source, 'HoloLake.app.tar.gz') const moved = path.join(fixture.fixtureRoot, 'moved-package') fs.renameSync(packagePath, moved) fs.symlinkSync(moved, packagePath) assert.throws( () => verifyReleaseBundle(fixture.source, fixture.approval), /HOLOLAKE_RELEASE_OPERATOR_FILE_INVALID/, ) } finally { fs.rmSync(fixture.fixtureRoot, { recursive: true, force: true }) } })