import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; import * as fs from 'node:fs'; import * as net from 'node:net'; import * as os from 'node:os'; import * as path from 'node:path'; import { resolveNatsBinary } from '../../src/utils/runner-transport.js'; import { assertExitCode, parseLastJson, runMxCli } from '../helpers/cli-harness.js'; async function getAvailablePorts(count: number): Promise { const servers = await Promise.all( Array.from({ length: count }, () => new Promise((resolve, reject) => { const server = net.createServer(); server.once('error', reject); server.listen(0, '127.0.0.1', () => resolve(server)); })), ); const ports = servers.map((server) => { const address = server.address(); assert.ok(address && typeof address === 'object'); return address.port; }); await Promise.all(servers.map((server) => new Promise((resolve, reject) => { server.close((error) => (error ? reject(error) : resolve())); }))); return ports; } async function createServiceFixture(rootDir: string, options?: { readonly conflictingTopLevelFields?: boolean; readonly topLevelSecretsFile?: boolean; readonly withEnvironment?: boolean; }): Promise { const packageDir = path.join(rootDir, 'sample-service'); const runtimeDir = path.join(packageDir, 'dist', 'runtime'); fs.mkdirSync(runtimeDir, { recursive: true }); const conflictingTopLevelFields = options?.conflictingTopLevelFields === true; const topLevelSecretsFile = options?.topLevelSecretsFile === true; const withEnvironment = options?.withEnvironment === true; const runtimeFactory = { kind: 'factory', export: 'createSampleService', ...(conflictingTopLevelFields ? { mount: 'old.mount', config: { file: './config/old-config.json', }, dependsOn: ['old.identity'], policyRef: 'policies/old', } : {}), ...(topLevelSecretsFile ? { secrets: { file: './config/manifest-secrets.json', }, } : {}), bootstrap: { root: 'local.root', transport: { mode: 'local-memory', }, http: { enabled: false, }, overrides: { config: { source: 'manifest', nested: { enabled: false }, }, }, }, instance: { packageName: '@acme/sample-service', packageRevision: '1.0.0', class: 'service', rootKind: 'package-root', mount: 'sample-service.local', configRef: './config/service-config.json', secretRefs: [ { name: 'apiKey', provider: 'system.factotum', ref: 'secret://sample/api-key', required: true, }, ], dependsOn: ['system.identity'], policyRef: 'policies/standalone', autoStart: true, }, }; fs.writeFileSync( path.join(packageDir, 'package.json'), JSON.stringify({ name: '@acme/sample-service', version: '1.0.0', type: 'module', main: './dist/runtime/index.js', }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'matrix.json'), JSON.stringify({ name: '@acme/sample-service', version: '1.0.0', namespace: 'sample', root: { type: 'SampleRoot', export: 'SampleRoot', mount: 'sample', }, runtime: { language: 'typescript', entry: './dist/runtime/index.js', factory: runtimeFactory, }, components: [ { type: 'SampleService', export: 'SampleService', mount: 'worker', accepts: ['sample.run', 'sample.run'], autoStart: true, }, ], permissions: { fsPolicy: 'none', }, }, null, 2), 'utf8', ); fs.mkdirSync(path.join(packageDir, 'config'), { recursive: true }); fs.writeFileSync( path.join(packageDir, 'config', 'old-config.json'), JSON.stringify({ config: { old: true, }, }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'config', 'service-config.json'), JSON.stringify({ config: { fromFile: true, nested: { file: true }, }, }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'config', 'cli-config.json'), JSON.stringify({ config: { fromCliFile: true, nested: { file: 'cli' }, }, }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'config', 'cli-secrets.json'), JSON.stringify([ { name: 'overrideKey', provider: 'system.factotum', ref: 'secret://sample/override-key', }, ], null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'config', 'manifest-secrets.json'), JSON.stringify([ { name: 'manifestKey', provider: 'system.factotum', ref: 'secret://sample/manifest-key', }, ], null, 2), 'utf8', ); fs.writeFileSync( path.join(runtimeDir, 'index.js'), `export async function createSampleService(overrides = {}, services = {}, _configResolution, bootstrapContext) { return { ok: true, effectiveConfig: overrides, bootContext: bootstrapContext, runnerRuntimeProvided: Boolean(services.runtime), runnerRuntimeRoot: services.runtime?.transport?.root ?? null, runtime: { async shutdown() { return undefined; } } }; } `, 'utf8', ); if (withEnvironment) { const [natsPort, wsPort] = await getAvailablePorts(2); fs.mkdirSync(path.join(packageDir, '.matrix'), { recursive: true }); fs.writeFileSync( path.join(packageDir, '.matrix', 'dev.environment.json'), JSON.stringify({ name: 'dev', runtime: { root: 'COM.TEST.PACKAGE-ENV', runtimeId: 'sample-service-dev', }, package: { publicRoot: 'sample', }, nats: { mode: 'embedded', port: natsPort, wsPort, binaryPath: resolveNatsBinary(process.cwd()), }, }, null, 2), 'utf8', ); } return packageDir; } function createPackageRootFixture(rootDir: string): string { const packageDir = path.join(rootDir, 'package-root-service'); const runtimeDir = path.join(packageDir, 'dist', 'runtime'); fs.mkdirSync(runtimeDir, { recursive: true }); fs.writeFileSync( path.join(packageDir, 'package.json'), JSON.stringify({ name: '@acme/package-root-service', version: '2.0.0', type: 'module', main: './dist/runtime/index.js', }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'matrix.json'), JSON.stringify({ name: '@acme/package-root-service', version: '2.0.0', runtime: { language: 'typescript', entry: './dist/runtime/index.js', factory: { kind: 'factory', export: 'createPackageRootService', bootstrap: { overrides: { mode: 'package-root', }, }, instance: { rootKind: 'package-root', }, }, }, components: [ { type: 'NestedService', export: 'NestedService', mount: 'nested-component-mount', autoStart: true, }, ], permissions: { fsPolicy: 'none', }, }, null, 2), 'utf8', ); fs.writeFileSync( path.join(runtimeDir, 'index.js'), `export async function createPackageRootService(overrides = {}, _services, _configResolution, bootstrapContext) { return { ok: true, effectiveConfig: overrides, bootContext: bootstrapContext, runtime: { async shutdown() { return undefined; } } }; } `, 'utf8', ); return packageDir; } function createComponentRootFixture( rootDir: string, options: { name: string; components: Array<{ type: string; mount?: string }>; instance?: Record; }, ): string { const packageDir = path.join(rootDir, options.name); const runtimeDir = path.join(packageDir, 'dist', 'runtime'); fs.mkdirSync(runtimeDir, { recursive: true }); fs.writeFileSync( path.join(packageDir, 'package.json'), JSON.stringify({ name: `@acme/${options.name}`, version: '1.0.0', type: 'module', main: './dist/runtime/index.js', }, null, 2), 'utf8', ); fs.writeFileSync( path.join(packageDir, 'matrix.json'), JSON.stringify({ name: `@acme/${options.name}`, version: '1.0.0', runtime: { language: 'typescript', entry: './dist/runtime/index.js', factory: { kind: 'factory', export: 'createComponentRootService', instance: { rootKind: 'component', ...(options.instance ?? {}), }, }, }, components: options.components.map((component) => ({ type: component.type, export: component.type, ...(component.mount ? { mount: component.mount } : {}), autoStart: false, })), permissions: { fsPolicy: 'none', }, }, null, 2), 'utf8', ); fs.writeFileSync( path.join(runtimeDir, 'index.js'), `export async function createComponentRootService(overrides = {}, _services, _configResolution, bootstrapContext) { return { ok: true, effectiveConfig: overrides, bootContext: bootstrapContext, runtime: { async shutdown() { return undefined; } } }; } `, 'utf8', ); return packageDir; } describe('mx service command', () => { it('marks runtime control ready before registry registration', () => { const source = fs.readFileSync(path.join(process.cwd(), 'src', 'commands', 'service.ts'), 'utf8'); const controlIndex = source.indexOf('const mountedControlMount = mounted.controlMount;'); const readyIndex = source.indexOf("lifecycleState = 'ready';"); const registerIndex = source.indexOf('const runtimeRegistration = await registerRunnerRuntime('); const liveIndex = source.indexOf("lifecycleState = 'live';"); assert.notEqual(controlIndex, -1); assert.notEqual(readyIndex, -1); assert.notEqual(registerIndex, -1); assert.notEqual(liveIndex, -1); assert.ok(controlIndex < readyIndex, 'control actor mount result must precede ready state'); assert.ok(readyIndex < registerIndex, 'runtime.ready must not wait on self-registration'); assert.ok(registerIndex < liveIndex, 'live state remains after registry registration'); }); it('loads matrix.json runtime.factory and invokes the declared bootstrap export in check mode', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-')); try { const packageDir = await createServiceFixture(tmpRoot); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', '--root', 'cli.root', '--mount', 'cli.mount', '--config', './config/cli-config.json', '--secrets', './config/cli-secrets.json', '--overrides', JSON.stringify({ config: { nested: { enabled: true }, cli: 'override', }, }), ]); assertExitCode(result, 0); const payload = parseLastJson(result.logs) as { packageName: string; exportName: string; checked: boolean; root?: string; mount?: string; configRef?: string; secretsRef?: string; instance?: { id?: string; class?: string; mount?: string; rootKind?: string; configRef?: string; policyRef?: string; dependsOn?: string[]; secretRefs?: Array<{ name?: string; provider?: string; ref?: string; required?: boolean; }>; registrationSource?: string; }; serviceInstance?: { id?: string; class?: string; mount?: string; rootKind?: string; configRef?: string; policyRef?: string; dependsOn?: string[]; secretRefs?: Array<{ name?: string; provider?: string; ref?: string; required?: boolean; }>; registrationSource?: string; }; runtimeRegistration?: { runtimeId?: string; runtimeRoot?: string; registryMount?: string; created?: boolean; actorCount?: number; runtimeCount?: number; }; bindingRegistration?: { runtimeId?: string; registryMount?: string; registeredCount?: number; bindings?: Array<{ binding?: string; localMount?: string; packageName?: string; ops?: string[]; }>; }; runtimeDeregistration?: { runtimeId?: string; registryMount?: string; removed?: boolean; runtimeCount?: number; }; bindingDeregistration?: { runtimeId?: string; registryMount?: string; removedCount?: number; }; result?: { effectiveConfig?: { config?: { source?: string; cli?: string; nested?: { enabled?: boolean }; fromCliFile?: boolean; }; }; runnerRuntimeProvided?: boolean; runnerRuntimeRoot?: string | null; bootContext?: { root?: string; mount?: string; configRef?: string; secretsRef?: string; transport?: { mode?: string }; http?: { enabled?: boolean }; instance?: { mount?: string; configRef?: string; dependsOn?: string[]; policyRef?: string; secretRefs?: Array<{ name?: string; provider?: string; ref?: string; }>; registrationSource?: string; }; serviceInstance?: { mount?: string; configRef?: string; dependsOn?: string[]; policyRef?: string; secretRefs?: Array<{ name?: string; provider?: string; ref?: string; }>; registrationSource?: string; }; }; }; }; assert.equal(payload.packageName, '@acme/sample-service'); assert.equal(payload.exportName, 'createSampleService'); assert.equal(payload.checked, true); assert.equal(payload.root, 'cli.root'); assert.equal(payload.mount, 'cli.mount'); assert.equal(payload.configRef, './config/cli-config.json'); assert.equal(payload.secretsRef, './config/cli-secrets.json'); assert.equal(payload.result?.effectiveConfig?.config?.source, 'manifest'); assert.equal(payload.result?.effectiveConfig?.config?.fromCliFile, true); assert.equal(payload.result?.effectiveConfig?.config?.cli, 'override'); assert.equal(payload.result?.effectiveConfig?.config?.nested?.enabled, true); assert.equal(payload.result?.runnerRuntimeProvided, true); assert.equal(payload.result?.runnerRuntimeRoot, 'cli.root'); assert.equal(payload.runtimeRegistration?.runtimeId, '@acme/sample-service:sample-service.local'); assert.equal(payload.runtimeRegistration?.runtimeRoot, 'cli.root'); assert.equal(payload.runtimeRegistration?.registryMount, 'system.runtimes'); assert.equal(payload.runtimeRegistration?.created, true); // Runtime control now has one RuntimeControlActor at // system.runtimes.. LoadedPackageActor adds one mount while // the separate .control mount is absent, so actorCount stays at 5. assert.equal(payload.runtimeRegistration?.actorCount, 5); assert.equal(payload.runtimeRegistration?.runtimeCount, 1); assert.equal(payload.bindingRegistration?.runtimeId, '@acme/sample-service:sample-service.local'); assert.equal(payload.bindingRegistration?.registryMount, 'system.bindings'); assert.equal(payload.bindingRegistration?.registeredCount, 2); assert.deepEqual(payload.bindingRegistration?.bindings, [ { binding: 'sample', localMount: 'cli.mount', packageName: '@acme/sample-service', ops: [], }, { binding: 'sample.worker', localMount: 'cli.mount.worker', packageName: '@acme/sample-service', ops: ['sample.run'], }, ]); assert.equal(payload.runtimeDeregistration?.runtimeId, '@acme/sample-service:sample-service.local'); assert.equal(payload.runtimeDeregistration?.registryMount, 'system.runtimes'); assert.equal(payload.runtimeDeregistration?.removed, true); assert.equal(payload.runtimeDeregistration?.runtimeCount, 0); assert.equal(payload.bindingDeregistration?.runtimeId, '@acme/sample-service:sample-service.local'); assert.equal(payload.bindingDeregistration?.registryMount, 'system.bindings'); assert.equal(payload.bindingDeregistration?.removedCount, 2); assert.equal(payload.instance?.autoStart, true); assert.equal(payload.instance?.mount, 'cli.mount'); assert.equal(payload.instance?.configRef, './config/cli-config.json'); assert.equal(payload.instance?.rootKind, 'package-root'); assert.equal(payload.instance?.policyRef, 'policies/standalone'); assert.deepEqual(payload.instance?.dependsOn, ['system.identity']); assert.equal(payload.instance?.registrationSource, 'matrix-service'); assert.equal(payload.instance?.secretRefs?.[0]?.name, 'overrideKey'); assert.equal(payload.instance?.secretRefs?.[0]?.provider, 'system.factotum'); assert.equal(payload.instance?.secretRefs?.[0]?.ref, 'secret://sample/override-key'); assert.equal(payload.serviceInstance?.mount, 'cli.mount'); assert.equal(payload.serviceInstance?.configRef, './config/cli-config.json'); assert.equal(payload.serviceInstance?.rootKind, 'package-root'); assert.equal(payload.serviceInstance?.autoStart, true); assert.equal(payload.serviceInstance?.policyRef, 'policies/standalone'); assert.deepEqual(payload.serviceInstance?.dependsOn, ['system.identity']); assert.equal(payload.serviceInstance?.registrationSource, 'matrix-service'); assert.equal(payload.serviceInstance?.secretRefs?.[0]?.name, 'overrideKey'); assert.equal(payload.serviceInstance?.secretRefs?.[0]?.provider, 'system.factotum'); assert.equal(payload.serviceInstance?.secretRefs?.[0]?.ref, 'secret://sample/override-key'); assert.equal(payload.result?.bootContext?.root, 'cli.root'); assert.equal(payload.result?.bootContext?.mount, 'cli.mount'); assert.equal(payload.result?.bootContext?.configRef, './config/cli-config.json'); assert.equal(payload.result?.bootContext?.secretsRef, './config/cli-secrets.json'); assert.equal(payload.result?.bootContext?.transport?.mode, 'local-memory'); assert.equal(payload.result?.bootContext?.http?.enabled, false); assert.equal(payload.result?.bootContext?.instance?.mount, 'cli.mount'); assert.equal(payload.result?.bootContext?.instance?.configRef, './config/cli-config.json'); assert.equal(payload.result?.bootContext?.instance?.autoStart, true); assert.deepEqual(payload.result?.bootContext?.instance?.dependsOn, ['system.identity']); assert.equal(payload.result?.bootContext?.instance?.policyRef, 'policies/standalone'); assert.equal(payload.result?.bootContext?.instance?.registrationSource, 'matrix-service'); assert.equal(payload.result?.bootContext?.instance?.secretRefs?.[0]?.name, 'overrideKey'); assert.equal(payload.result?.bootContext?.serviceInstance?.mount, 'cli.mount'); assert.equal(payload.result?.bootContext?.serviceInstance?.configRef, './config/cli-config.json'); assert.equal(payload.result?.bootContext?.serviceInstance?.autoStart, true); assert.deepEqual(payload.result?.bootContext?.serviceInstance?.dependsOn, ['system.identity']); assert.equal(payload.result?.bootContext?.serviceInstance?.policyRef, 'policies/standalone'); assert.equal(payload.result?.bootContext?.serviceInstance?.registrationSource, 'matrix-service'); assert.equal(payload.result?.bootContext?.serviceInstance?.secretRefs?.[0]?.name, 'overrideKey'); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('loads package-local environment manifests and threads them into standalone bootstrap', async () => { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-env-')); const packageDir = await createServiceFixture(tempRoot, { withEnvironment: true }); const result = await runMxCli(['node', 'mx', 'service', packageDir, '--check', '--json', '--env', 'dev']); assertExitCode(result, 0); const payload = parseLastJson(result.logs) as { environmentName?: string; root?: string; environmentPath?: string; runnerTransport?: { mode?: string; root?: string; url?: string; wsUrl?: string; dataDir?: string; pidFile?: string; }; runtimeRegistration?: { runtimeId?: string; runtimeRoot?: string; runtimeCount?: number; }; bindingRegistration?: { runtimeId?: string; registryMount?: string; registeredCount?: number; bindings?: Array<{ binding?: string; localMount?: string; packageName?: string; ops?: string[]; }>; }; runtimeDeregistration?: { runtimeId?: string; removed?: boolean; runtimeCount?: number; }; bindingDeregistration?: { runtimeId?: string; removedCount?: number; }; result?: { bootContext?: { environment?: { name?: string; runtime?: { root?: string }; }; runnerTransport?: { mode?: string; url?: string; wsUrl?: string; }; }; }; }; assert.equal(payload.environmentName, 'dev'); assert.equal(payload.root, 'COM.TEST.PACKAGE-ENV'); assert.equal( payload.environmentPath, path.join(packageDir, '.matrix', 'dev.environment.json'), ); assert.equal(payload.runnerTransport?.mode, 'embedded'); assert.equal(payload.runnerTransport?.root, 'COM.TEST.PACKAGE-ENV'); assert.match(String(payload.runnerTransport?.url), /^nats:\/\/127\.0\.0\.1:\d+$/); assert.match(String(payload.runnerTransport?.wsUrl), /^ws:\/\/127\.0\.0\.1:\d+$/); assert.equal(payload.runnerTransport?.dataDir, path.join(packageDir, '.matrix', 'state', 'dev', 'nats')); assert.equal(payload.runnerTransport?.pidFile, path.join(packageDir, '.matrix', 'state', 'dev', 'nats-server.pid')); assert.equal(payload.result?.bootContext?.environment?.name, 'dev'); assert.equal(payload.result?.bootContext?.environment?.runtime?.root, 'COM.TEST.PACKAGE-ENV'); assert.equal(payload.result?.bootContext?.runnerTransport?.mode, 'embedded'); assert.match(String(payload.result?.bootContext?.runnerTransport?.url), /^nats:\/\/127\.0\.0\.1:\d+$/); assert.match(String(payload.result?.bootContext?.runnerTransport?.wsUrl), /^ws:\/\/127\.0\.0\.1:\d+$/); assert.equal(payload.runtimeRegistration?.runtimeId, 'sample-service-dev'); assert.equal(payload.runtimeRegistration?.runtimeRoot, 'COM.TEST.PACKAGE-ENV'); assert.equal(payload.runtimeRegistration?.runtimeCount, 1); assert.equal(payload.bindingRegistration?.runtimeId, 'sample-service-dev'); assert.equal(payload.bindingRegistration?.registryMount, 'system.bindings'); assert.equal(payload.bindingRegistration?.registeredCount, 2); assert.deepEqual(payload.bindingRegistration?.bindings, [ { binding: 'sample', localMount: 'sample-service.local', packageName: '@acme/sample-service', ops: [], }, { binding: 'sample.worker', localMount: 'sample-service.local.worker', packageName: '@acme/sample-service', ops: ['sample.run'], }, ]); assert.equal(payload.runtimeDeregistration?.runtimeId, 'sample-service-dev'); assert.equal(payload.runtimeDeregistration?.removed, true); assert.equal(payload.runtimeDeregistration?.runtimeCount, 0); assert.equal(payload.bindingDeregistration?.runtimeId, 'sample-service-dev'); assert.equal(payload.bindingDeregistration?.removedCount, 2); }); it('fails clearly when standalone top-level fields are present', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-instance-conflict-')); try { const packageDir = await createServiceFixture(tmpRoot, { conflictingTopLevelFields: true }); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 1); assert.match(result.errors.join('\n'), /top-level "mount" is no longer supported; use "instance\.mount"/i); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('fails clearly when matrix.json runtime.factory uses top-level secrets.file', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-secrets-field-')); try { const packageDir = await createServiceFixture(tmpRoot, { topLevelSecretsFile: true }); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 1); assert.match(result.errors.join('\n'), /top-level "secrets\.file" is no longer supported; use "instance\.secretRefs or CLI --secrets"/i); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('fails clearly when matrix.json runtime.factory uses top-level standalone bootstrap fields', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-bootstrap-field-')); try { const packageDir = await createServiceFixture(tmpRoot); const manifestPath = path.join(packageDir, 'matrix.json'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { runtime?: { factory?: Record }; }; fs.writeFileSync( manifestPath, JSON.stringify({ ...manifest, runtime: { ...(manifest.runtime ?? {}), factory: { ...(manifest.runtime?.factory ?? {}), root: 'old.root', }, }, }, null, 2), 'utf8', ); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 1); assert.match(result.errors.join('\n'), /top-level "root" is no longer supported; use "bootstrap\.root"/i); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('fails clearly when matrix.json runtime.factory is missing', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-missing-')); try { const packageDir = path.join(tmpRoot, 'broken-service'); fs.mkdirSync(packageDir, { recursive: true }); fs.writeFileSync( path.join(packageDir, 'matrix.json'), JSON.stringify({ name: '@acme/broken-service', version: '1.0.0', runtime: { language: 'typescript', entry: './dist/runtime/index.js' }, components: [], permissions: { fsPolicy: 'none' }, }, null, 2), 'utf8', ); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', ]); assertExitCode(result, 1); assert.match(result.errors.join('\n'), /matrix\.json runtime\.factory must be a JSON object/i); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('fails clearly when matrix.json runtime.factory instance identity disagrees with matrix.json', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-package-identity-mismatch-')); try { const packageDir = await createServiceFixture(tmpRoot); const manifestPath = path.join(packageDir, 'matrix.json'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { runtime?: { factory?: { instance?: Record } }; }; fs.writeFileSync( manifestPath, JSON.stringify({ ...manifest, runtime: { ...(manifest.runtime ?? {}), factory: { ...(manifest.runtime?.factory ?? {}), instance: { ...(manifest.runtime?.factory?.instance ?? {}), packageName: '@acme/not-the-same-service', }, }, }, }, null, 2), 'utf8', ); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 1); assert.match( result.errors.join('\n'), /instance\.packageName "@acme\/not-the-same-service" does not match matrix\.json name "@acme\/sample-service"/, ); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('does not invent a component mount for package-root standalone services', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-package-root-')); try { const packageDir = createPackageRootFixture(tmpRoot); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 0); const payload = parseLastJson(result.logs) as { mount?: string; instance?: { id?: string; mount?: string; rootKind?: string; }; serviceInstance?: { id?: string; mount?: string; rootKind?: string; }; result?: { bootContext?: { mount?: string; instance?: { mount?: string; rootKind?: string; }; serviceInstance?: { mount?: string; rootKind?: string; }; }; }; }; assert.equal(payload.mount, undefined); assert.equal(payload.instance?.id, '@acme/package-root-service'); assert.equal(payload.instance?.mount, undefined); assert.equal(payload.instance?.rootKind, 'package-root'); assert.equal(payload.serviceInstance?.id, '@acme/package-root-service'); assert.equal(payload.serviceInstance?.mount, undefined); assert.equal(payload.serviceInstance?.rootKind, 'package-root'); assert.equal(payload.result?.bootContext?.mount, undefined); assert.equal(payload.result?.bootContext?.instance?.mount, undefined); assert.equal(payload.result?.bootContext?.instance?.rootKind, 'package-root'); assert.equal(payload.result?.bootContext?.serviceInstance?.mount, undefined); assert.equal(payload.result?.bootContext?.serviceInstance?.rootKind, 'package-root'); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('resolves component-root standalone services by declared componentType', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-component-root-')); try { const packageDir = createComponentRootFixture(tmpRoot, { name: 'component-root-service', components: [ { type: 'PrimaryService', mount: 'primary.mount' }, { type: 'SecondaryService', mount: 'secondary.mount' }, ], instance: { componentType: 'SecondaryService', }, }); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', '--json', ]); assertExitCode(result, 0); const payload = parseLastJson(result.logs) as { mount?: string; instance?: { componentType?: string; mount?: string; rootKind?: string; }; result?: { bootContext?: { mount?: string; instance?: { componentType?: string; mount?: string; rootKind?: string; }; }; }; }; assert.equal(payload.mount, 'secondary.mount'); assert.equal(payload.instance?.componentType, 'SecondaryService'); assert.equal(payload.instance?.mount, 'secondary.mount'); assert.equal(payload.instance?.rootKind, 'component'); assert.equal(payload.result?.bootContext?.mount, 'secondary.mount'); assert.equal(payload.result?.bootContext?.instance?.componentType, 'SecondaryService'); assert.equal(payload.result?.bootContext?.instance?.mount, 'secondary.mount'); assert.equal(payload.result?.bootContext?.instance?.rootKind, 'component'); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); it('fails clearly when component-root standalone bootstrap is ambiguous', async () => { const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mx-service-component-ambiguous-')); try { const packageDir = createComponentRootFixture(tmpRoot, { name: 'ambiguous-component-root-service', components: [ { type: 'PrimaryService', mount: 'primary.mount' }, { type: 'SecondaryService', mount: 'secondary.mount' }, ], }); const result = await runMxCli([ 'node', 'mx', 'service', packageDir, '--check', ]); assertExitCode(result, 1); assert.match(result.errors.join('\n'), /component-root bootstrap is ambiguous/i); } finally { fs.rmSync(tmpRoot, { recursive: true, force: true }); } }); });