Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
206 lines
7.4 KiB
JavaScript
206 lines
7.4 KiB
JavaScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
import assert from 'node:assert/strict';
|
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import test from 'node:test';
|
|
import {
|
|
collectRuntimeHostFailureDiagnostic,
|
|
retireCollectedRuntimeHostStartupDiagnostic,
|
|
} from './release-cli-runtime-host-diagnostics.mjs';
|
|
|
|
const ROOT_ID = 'a'.repeat(64);
|
|
const STARTUP_ATTEMPT_ID = '00000000-0000-4000-8000-000000000001';
|
|
|
|
test('collects canonical Runtime Host evidence without invoking mutating storage authority', async () => {
|
|
const fixture = createFixture();
|
|
try {
|
|
const startupDiagnostic = {
|
|
schemaVersion: 1,
|
|
rootId: ROOT_ID,
|
|
startupAttemptId: STARTUP_ATTEMPT_ID,
|
|
candidatePid: 123,
|
|
capturedAt: '2026-08-19T00:00:00.000Z',
|
|
reason: 'local_ipc_security_failed',
|
|
errorChain: [{ message: '{"stage":"acl_apply"}' }],
|
|
logs: ['endpoint setup failed'],
|
|
};
|
|
const securityCalls = [];
|
|
const diagnostic = await collectRuntimeHostFailureDiagnostic('/installed', fixture.root, {
|
|
platform: 'win32',
|
|
architecture: 'x64',
|
|
environment: {
|
|
ImageOS: 'win25',
|
|
ImageVersion: '20260817.1',
|
|
RUNNER_NAME: 'hosted-runner',
|
|
RUNNER_ENVIRONMENT: 'github-hosted',
|
|
},
|
|
loadInstalled: async (_packageRoot, relativePath) => {
|
|
if (relativePath.endsWith('/root-authority.js')) {
|
|
return {
|
|
STORAGE_ROOT_MARKER_FILE: '.maka-storage-root.json',
|
|
discoverMarkedStorageRoot: async () => ({ rootId: ROOT_ID }),
|
|
resolveRootControlNamespace: () => fixture.controlRoot,
|
|
};
|
|
}
|
|
if (relativePath.endsWith('/registration.js')) {
|
|
return {
|
|
RUNTIME_HOST_REGISTRATION_FILE: 'registration.json',
|
|
readHostRegistration: async () => ({
|
|
schemaVersion: 1,
|
|
rootId: ROOT_ID,
|
|
hostEpoch: 'host-epoch',
|
|
state: 'recovering',
|
|
lifecycleMode: 'interactive',
|
|
pid: 123,
|
|
endpoint: '\\\\.\\pipe\\maka-runtime-host',
|
|
}),
|
|
};
|
|
}
|
|
if (relativePath.endsWith('/startup-diagnostic.js')) {
|
|
return {
|
|
RUNTIME_HOST_STARTUP_DIAGNOSTIC_FILE: 'startup-diagnostic.json',
|
|
readCandidateStartupDiagnostic: async () => startupDiagnostic,
|
|
};
|
|
}
|
|
throw new Error(`Unexpected installed module: ${relativePath}`);
|
|
},
|
|
readPathSecurityBatch: async (paths) => {
|
|
securityCalls.push(paths);
|
|
return paths.map(() => ({
|
|
state: 'present',
|
|
owner: 'runner\\user',
|
|
sddl: 'O:SYD:P',
|
|
}));
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(
|
|
diagnostic.paths.map(({ role }) => role),
|
|
[
|
|
'root',
|
|
'root_marker',
|
|
'control_root',
|
|
'control_directory',
|
|
'registration',
|
|
'startup_diagnostic',
|
|
],
|
|
);
|
|
assert.deepEqual(securityCalls, [
|
|
[fixture.root, fixture.controlRoot, fixture.controlDirectory],
|
|
]);
|
|
assert.equal(diagnostic.paths[0].security.owner, 'runner\\user');
|
|
assert.equal(diagnostic.storageAuthority.state, 'valid');
|
|
assert.equal(diagnostic.registration.rootIdMatches, true);
|
|
assert.deepEqual(diagnostic.startup, { state: 'present', diagnostic: startupDiagnostic });
|
|
assert.equal(diagnostic.runner.architecture, undefined);
|
|
|
|
let retired;
|
|
assert.equal(
|
|
await retireCollectedRuntimeHostStartupDiagnostic('/installed', diagnostic, {
|
|
loadInstalled: async (_packageRoot, relativePath) => {
|
|
assert.match(relativePath, /startup-diagnostic\.js$/u);
|
|
return {
|
|
clearSelectedCandidateStartupDiagnostic: async (rootId, startupAttemptId) => {
|
|
retired = { rootId, startupAttemptId };
|
|
return true;
|
|
},
|
|
};
|
|
},
|
|
}),
|
|
true,
|
|
);
|
|
assert.deepEqual(retired, { rootId: ROOT_ID, startupAttemptId: STARTUP_ATTEMPT_ID });
|
|
} finally {
|
|
fixture.cleanup();
|
|
}
|
|
});
|
|
|
|
test('keeps read-only path evidence when root authority validation fails', async () => {
|
|
const fixture = createFixture({ createControlDirectory: false });
|
|
try {
|
|
const diagnostic = await collectRuntimeHostFailureDiagnostic('/installed', fixture.root, {
|
|
platform: 'win32',
|
|
loadInstalled: async (_packageRoot, relativePath) => {
|
|
if (!relativePath.endsWith('/root-authority.js')) {
|
|
throw new Error(`Unexpected installed module: ${relativePath}`);
|
|
}
|
|
return {
|
|
STORAGE_ROOT_MARKER_FILE: '.maka-storage-root.json',
|
|
discoverMarkedStorageRoot: async () => {
|
|
throw new Error('marker validation failed', {
|
|
cause: Object.assign(new Error('Access is denied'), { code: 'EACCES' }),
|
|
});
|
|
},
|
|
resolveRootControlNamespace: () => fixture.controlRoot,
|
|
};
|
|
},
|
|
readPathSecurityBatch: async (paths) => {
|
|
return paths.map((path) =>
|
|
path === fixture.root
|
|
? {
|
|
state: 'unavailable',
|
|
error: { name: 'UnauthorizedAccessException', nativeErrorCode: 5 },
|
|
}
|
|
: { state: 'present', owner: 'runner\\user', sddl: 'O:SYD:P' },
|
|
);
|
|
},
|
|
});
|
|
|
|
assert.equal(diagnostic.storageAuthority.state, 'invalid');
|
|
assert.equal(diagnostic.storageAuthority.error.cause.code, 'EACCES');
|
|
assert.equal(diagnostic.paths[0].security.state, 'unavailable');
|
|
assert.equal(diagnostic.paths[0].security.error.nativeErrorCode, 5);
|
|
assert.deepEqual(
|
|
diagnostic.paths.map(({ role }) => role),
|
|
['root', 'root_marker', 'control_root'],
|
|
);
|
|
assert.equal(existsSync(fixture.controlDirectory), false);
|
|
} finally {
|
|
fixture.cleanup();
|
|
}
|
|
});
|
|
|
|
function createFixture({ createControlDirectory = true } = {}) {
|
|
const base = mkdtempSync(join(tmpdir(), 'maka-runtime-host-diagnostic-test-'));
|
|
const root = join(base, 'root');
|
|
const controlRoot = join(base, 'control');
|
|
const controlDirectory = join(controlRoot, ROOT_ID);
|
|
const registrationPath = join(controlDirectory, 'registration.json');
|
|
const startupPath = join(controlDirectory, 'startup-diagnostic.json');
|
|
mkdirSync(root, { recursive: true });
|
|
mkdirSync(controlRoot, { recursive: true });
|
|
writeFileSync(join(root, '.maka-storage-root.json'), '{}\n');
|
|
if (createControlDirectory) {
|
|
mkdirSync(controlDirectory, { recursive: true });
|
|
writeFileSync(registrationPath, '{}\n');
|
|
writeFileSync(startupPath, '{}\n');
|
|
}
|
|
return {
|
|
root,
|
|
controlRoot,
|
|
controlDirectory,
|
|
registrationPath,
|
|
startupPath,
|
|
cleanup: () => rmSync(base, { recursive: true, force: true }),
|
|
};
|
|
}
|