import EmbeddedPostgres from 'embedded-postgres' import { runOwnedVrfProductionProfile } from './vrf-production-profile.mjs' import { mkdtemp, rm, readFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, resolve, relative, isAbsolute, delimiter, dirname } from 'node:path' import { randomBytes } from 'node:crypto' import { fileURLToPath } from 'node:url' import { createServer } from 'node:net' import { spawn, execFile } from 'node:child_process' // Explicit targeted reruns use a fresh owned regression database. They never // claim the primary integration or terminal restore was rerun. // Fixed groups only; ordinary full/selected regression semantics stay unchanged. function profilesOnlyGroup(args) { const groups = args.filter(arg => arg.startsWith('--profiles-group=')) if (!groups.length) return null const group = groups[0].slice('--profiles-group='.length) if (groups.length !== 1 || args.length !== 3 || !args.includes('--all') || !args.includes('--profiles-only') || !['base37', 'vrf1'].includes(group)) { throw new Error('Fixed profile group requires exactly --all --profiles-only --profiles-group=base37|vrf1') } return group } function regressionProfiles(profiles, selected, group) { if (group === null) return [...new Set([...profiles, 'test:logs:pg', ...(!selected ? ['test:vrf:production'] : [])])] if (!['base37', 'vrf1'].includes(group) || selected || profiles.length !== 36 || new Set(profiles).size !== 36 || profiles.includes('test:logs:pg') || profiles.includes('test:vrf:production')) { throw new Error('Fixed 37+1 profile coverage changed; review groups before running') } return group === 'base37' ? [...profiles, 'test:logs:pg'] : ['test:vrf:production'] } // End fixed-group pure selectors. const profilesGroup = profilesOnlyGroup(process.argv.slice(2)) const profilesOnly = process.argv.includes('--profiles-only') if (profilesOnly && (process.argv.length !== 4 + (profilesGroup ? 1 : 0) || !process.argv.includes('--all') || process.argv.slice(2).some(arg => !['--all', '--profiles-only', ...(profilesGroup ? ['--profiles-group=' + profilesGroup] : [])].includes(arg)))) { throw new Error('Profiles-only requires exactly --all --profiles-only, without restore, selected profiles or other flags') } const regressionOnly = process.argv.includes('--regression-only') if (regressionOnly && (!process.argv.includes('--all') || process.argv.filter(arg => arg.startsWith('--profile=')).length !== 1 || process.argv.slice(2).some(arg => !['--all', '--regression-only'].includes(arg) && !arg.startsWith('--profile=')))) { throw new Error('Regression-only requires exactly --all --regression-only --profile=, without restore or other profiles') } const operatorDockerSql = process.argv.includes('--operator-docker-sql') if (operatorDockerSql && process.argv.slice(2).some(arg => arg !== '--operator-docker-sql')) throw new Error('Operator Docker SQL requires a separate disposable cluster without restore') const pollMemoryCost = process.argv.includes('--poll-memory-cost') const pollMemoryBootstrap = process.argv.includes('--poll-memory-bootstrap') const pollMemory = process.argv.includes('--poll-memory') || pollMemoryCost || pollMemoryBootstrap if (pollMemory && (process.argv.length !== 3 || process.argv[2] !== (pollMemoryBootstrap ? '--poll-memory-bootstrap' : pollMemoryCost ? '--poll-memory-cost' : '--poll-memory'))) throw new Error('Compiled poll memory requires its own disposable cluster without other profiles') const pollMemoryEnvironment = Object.fromEntries(['SystemRoot', 'WINDIR', 'TEMP', 'TMP', 'LANG', 'LC_ALL'] .filter(key => typeof process.env[key] === 'string').map(key => [key, process.env[key]])) const pollJournalSnapshot = process.argv.includes('--poll-journal-snapshot') if (pollJournalSnapshot && process.argv.slice(2).some(arg => arg !== '--poll-journal-snapshot')) throw new Error('Journal snapshot lock evidence requires its own disposable cluster') const principalSecuritySource = process.argv.includes('--principal-security-source') if (principalSecuritySource && process.argv.slice(2).some(arg => arg !== '--principal-security-source')) throw new Error('Principal security source requires its own disposable cluster') const pollArchiveFlags = ['--poll-terminal-archive', '--poll-terminal-archive-lost-ack', '--poll-terminal-archive-history', '--poll-terminal-archive-history-cold', '--poll-terminal-archive-claim-loss'] const chosenArchiveFlags = process.argv.slice(2).filter(arg => pollArchiveFlags.includes(arg)) const pollArchiveLostAck = chosenArchiveFlags[0] === '--poll-terminal-archive-lost-ack' const pollArchiveCold = chosenArchiveFlags[0] === '--poll-terminal-archive-history-cold' const pollArchiveHistory = chosenArchiveFlags[0] === '--poll-terminal-archive-history' || pollArchiveCold const pollArchiveClaimLoss = chosenArchiveFlags[0] === '--poll-terminal-archive-claim-loss' const pollTerminalArchive = chosenArchiveFlags.length > 0 if (pollTerminalArchive && (chosenArchiveFlags.length !== 1 || process.argv.slice(2).some(arg => ![chosenArchiveFlags[0], '--restore'].includes(arg)))) throw new Error('Poll terminal archive requires its own disposable cluster') const pollArchiveSchema = process.argv.includes('--poll-archive-schema') if (pollArchiveSchema && process.argv.slice(2).some(arg => arg !== '--poll-archive-schema')) throw new Error('Poll archive schema requires its own disposable cluster') const telemetrySettingsConfiguration = process.argv.includes('--telemetry-settings-configuration') if (telemetrySettingsConfiguration && process.argv.slice(2).some(arg => arg !== '--telemetry-settings-configuration')) throw new Error('Telemetry settings configuration requires its own disposable cluster') const routingReservationSchema = process.argv.includes('--routing-reservation-schema') if (routingReservationSchema && process.argv.slice(2).some(arg => arg !== '--routing-reservation-schema')) throw new Error('Routing reservation schema requires its own disposable cluster') const routingForwardRounds = process.argv.includes('--routing-network-forward-rounds') if (routingForwardRounds && process.argv.slice(2).some(arg => arg !== '--routing-network-forward-rounds')) throw new Error('Routing forward rounds requires its own disposable cluster') const flowActiveServices = process.argv.includes('--flow-active-services') if (flowActiveServices && process.argv.slice(2).some(arg => arg !== '--flow-active-services')) throw new Error('Flow active services requires its own disposable cluster') const flowActiveRebuild = process.argv.includes('--flow-active-rebuild') if (flowActiveRebuild && process.argv.slice(2).some(arg => arg !== '--flow-active-rebuild')) throw new Error('Flow active rebuild requires its own disposable cluster') const flowQuality = process.argv.includes('--flow-quality') if (flowQuality && process.argv.slice(2).some(arg => arg !== '--flow-quality')) throw new Error('Flow quality requires its own disposable cluster') const flowWorkerIpc = process.argv.includes('--flow-worker-ipc') if (flowWorkerIpc && process.argv.slice(2).some(arg => arg !== '--flow-worker-ipc')) throw new Error('Flow worker IPC requires its own disposable cluster') const manualUptime = process.argv.includes('--manual-uptime') if (manualUptime && process.argv.slice(2).some(arg => arg !== '--manual-uptime')) throw new Error('Manual uptime requires its own disposable cluster') const manualPingGroup = process.argv.includes('--manual-ping-group') if (manualPingGroup && process.argv.slice(2).some(arg => arg !== '--manual-ping-group')) throw new Error('Manual Ping group requires its own disposable cluster') const manualTraffic = process.argv.includes('--manual-traffic') if (manualTraffic && process.argv.slice(2).some(arg => arg !== '--manual-traffic')) throw new Error('Manual traffic requires its own disposable cluster') const manualApiPing = process.argv.includes('--manual-api-ping') if (manualApiPing && process.argv.slice(2).some(arg => arg !== '--manual-api-ping')) throw new Error('Manual API Ping requires its own disposable cluster') const simpleSpeed = process.argv.includes('--simple-speed') if (simpleSpeed && process.argv.slice(2).some(arg => arg !== '--simple-speed')) throw new Error('Simple speed acceptance requires its own disposable cluster') const simpleSpeedChr = process.argv.includes('--simple-speed-chr') if (simpleSpeedChr && process.argv.slice(2).some(arg => arg !== '--simple-speed-chr')) throw new Error('Simple speed CHR acceptance requires its own disposable cluster') const publicRegistryMetadata = process.argv.includes('--public-registry-metadata') if (publicRegistryMetadata && process.argv.slice(2).some(arg => arg !== '--public-registry-metadata')) throw new Error('Public registry metadata requires a separate disposable cluster without restore') const operatorPeerMetadata = process.argv.includes('--operator-peer-metadata') if (operatorPeerMetadata && process.argv.slice(2).some(arg => arg !== '--operator-peer-metadata')) throw new Error('Operator peer metadata requires a separate disposable cluster without restore') const externalPeerMetadata = process.argv.includes('--external-peer-metadata') if (externalPeerMetadata && process.argv.slice(2).some(arg => arg !== '--external-peer-metadata')) throw new Error('Guarded external peer metadata requires a separate disposable cluster without restore') const mcpOperationOrigin = process.argv.includes('--mcp-operation-origin') if (mcpOperationOrigin && process.argv.slice(2).some(arg => arg !== '--mcp-operation-origin')) throw new Error('MCP operation root requires a separate disposable cluster without restore') const mcpSpeedOriginal = process.argv.includes('--mcp-speed-original') if (mcpSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--mcp-speed-original')) throw new Error('MCP speed component requires a separate disposable cluster without restore') const routerConfigurationGuard = process.argv.includes('--router-configuration-guard') if (routerConfigurationGuard && process.argv.slice(2).some(arg => arg !== '--router-configuration-guard')) throw new Error('Router configuration guard requires a separate disposable cluster without restore') const scheduledSpeedOriginal = process.argv.includes('--scheduled-speed-original') if (scheduledSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--scheduled-speed-original')) throw new Error('Scheduled speed origin requires a separate disposable cluster without restore') const bandwidthSpeedWorkflow = process.argv.includes('--bandwidth-speed-workflow') if (bandwidthSpeedWorkflow && process.argv.slice(2).some(arg => arg !== '--bandwidth-speed-workflow')) throw new Error('Whole speed workflow requires its own disposable cluster; restore is not implemented') const restSpeedOriginal = process.argv.includes('--rest-speed-original') if (restSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--rest-speed-original')) throw new Error('REST speed origin acceptance requires its own disposable cluster; restore is not implemented for this profile') const operationLocks = process.argv.includes('--operation-locks') const serviceExecutionOrigin = process.argv.includes('--service-execution-origin') const bandwidthNodeSource = process.argv.includes('--bandwidth-node-source') const bandwidthExternalRegistry = process.argv.includes('--bandwidth-external-registry') if (bandwidthExternalRegistry && process.argv.slice(2).some(arg => arg !== '--bandwidth-external-registry')) throw new Error('External registry acceptance requires its own disposable cluster; restore is not implemented for this profile') const bandwidthNodeRegistry = process.argv.includes('--bandwidth-node-registry') const bandwidthControlSource = process.argv.includes('--bandwidth-control-source') const bandwidthAdmission = process.argv.includes('--bandwidth-admission') const diagnosticCancelHost = process.argv.includes('--diagnostic-cancel-host') const ipsecExportHttp = process.argv.includes('--ipsec-export-http') const ipsecExportJournal = process.argv.includes('--ipsec-export-journal') const routingRecoveryAuthority = process.argv.includes('--routing-recovery-authority') const legacyFlowRebuild = process.argv.includes('--legacy-flow-rebuild') const serverPollStorageFresh = process.argv.includes('--server-poll-storage-fresh') const serverPollStorage = process.argv.includes('--server-poll-storage') const serverPollDurable = process.argv.includes('--server-poll-durable') const collectorPartitionWriters = process.argv.includes('--collector-partition-writers') const routingReservations = process.argv.includes('--routing-reservations') const routingReservationRuntime = process.argv.includes('--routing-reservation-runtime') const routingNetworkNative = process.argv.includes('--routing-network-native') const migrationDataInventory = process.argv.includes('--migration-data-inventory') const migrationSchemaInventory = process.argv.includes('--migration-schema-inventory') const databaseSchemaControl = process.argv.includes('--database-schema-control') const controlledMigrations = process.argv.includes('--controlled-migrations') const controlledSchemaReference = process.argv.includes('--controlled-schema-reference') const probeStorageHistory = process.argv.includes('--probe-storage-history') const probeStorageJournal = process.argv.includes('--probe-storage-journal') const probeLegacyOrphans = process.argv.includes('--probe-legacy-orphans') const probeStorageFresh = process.argv.includes('--probe-storage-fresh') for (const [selected, flag] of [[operationLocks, '--operation-locks'], [serviceExecutionOrigin, '--service-execution-origin'], [bandwidthNodeSource, '--bandwidth-node-source'], [bandwidthNodeRegistry, '--bandwidth-node-registry'], [bandwidthExternalRegistry, '--bandwidth-external-registry'], [bandwidthControlSource, '--bandwidth-control-source'], [bandwidthAdmission, '--bandwidth-admission'], [serverPollStorageFresh, '--server-poll-storage-fresh'], [serverPollStorage, '--server-poll-storage'], [diagnosticCancelHost, '--diagnostic-cancel-host'], [ipsecExportHttp, '--ipsec-export-http'], [ipsecExportJournal, '--ipsec-export-journal'], [routingRecoveryAuthority, '--routing-recovery-authority'], [legacyFlowRebuild, '--legacy-flow-rebuild'], [serverPollDurable, '--server-poll-durable'], [collectorPartitionWriters, '--collector-partition-writers'], [routingReservations, '--routing-reservations'], [routingReservationRuntime, '--routing-reservation-runtime'], [routingNetworkNative, '--routing-network-native'], [migrationDataInventory, '--migration-data-inventory'], [migrationSchemaInventory, '--migration-schema-inventory'], [databaseSchemaControl, '--database-schema-control'], [controlledMigrations, '--controlled-migrations'], [controlledSchemaReference, '--controlled-schema-reference'], [probeStorageHistory, '--probe-storage-history'], [probeStorageJournal, '--probe-storage-journal'], [probeLegacyOrphans, '--probe-legacy-orphans'], [probeStorageFresh, '--probe-storage-fresh']]) { if (selected && process.argv.slice(2).some(arg => ![flag, '--restore'].includes(arg))) throw new Error('Focused writer/recovery acceptance requires a separate disposable run') } const probeJournal = process.argv.includes('--server-probe-journal') if (probeJournal && process.argv.slice(2).some(arg => !['--server-probe-journal', '--restore'].includes(arg))) throw new Error('Server probe journal acceptance requires a separate disposable run') const flowHostKeys = process.argv.includes('--flow-host-keys') if (flowHostKeys && process.argv.slice(2).some(arg => !['--flow-host-keys','--restore'].includes(arg))) throw new Error('Host keys acceptance requires a separate disposable run') const flowRebuildMcp = process.argv.includes('--flow-rebuild-mcp') if (flowRebuildMcp && process.argv.slice(2).some(arg => arg !== '--flow-rebuild-mcp')) throw new Error('MCP flow rebuild acceptance requires a separate disposable run') const flowRebuild = process.argv.includes('--flow-rebuild') if (flowRebuild && process.argv.slice(2).some(arg => arg !== '--flow-rebuild')) throw new Error('Flow rebuild SQL acceptance requires a separate disposable run') const flowWrites = process.argv.includes('--flow-writes') if (flowWrites && process.argv.slice(2).some(arg => arg !== '--flow-writes')) throw new Error('Flow writer SQL acceptance requires a separate disposable run') const chrGreMutation = process.argv.includes('--chr-gre-mutation') const chrGreRevision = process.argv.includes('--chr-gre-revision') const chrGreRevisionRecovery = process.argv.includes('--chr-gre-revision-recovery') const chrRead = process.argv.includes('--chr-read') const chrIdentity = process.argv.includes('--chr-ospf-identity-read') const chrRecursive = process.argv.includes('--chr-recursive-restore') const chrFirewallRestore = process.argv.includes('--chr-firewall-restore') const chrAddress = process.argv.includes('--chr-address-list') const chrFirewallWrite = process.argv.includes('--chr-firewall-write') const chrFirewallMove = process.argv.includes('--chr-firewall-move') const chrVpn = process.argv.includes('--chr-vpn-catalog') const chrFilters = process.argv.includes('--chr-filter-write') const chrLegacyOspf = process.argv.includes('--chr-ospf-legacy') const greRevision = process.argv.includes('--gre-revision') const applicationAdapters = process.argv.includes('--application-adapters') const scopedRoutingDiagnostics = process.argv.includes('--scoped-routing-diagnostics') const interfaceEventsCompatibility = process.argv.includes('--interface-events-compatibility') const wireguardExport = process.argv.includes('--wireguard-export') if (wireguardExport && process.argv.includes('--wireguard-transfer')) throw new Error('Choose WireGuard transfer or export acceptance mode') const wireguardTransfer = process.argv.includes('--wireguard-transfer') || wireguardExport const scopedCheckpointAdapters = process.argv.includes('--scoped-checkpoint-adapters') const nativeConservation = process.argv.includes('--native-conservation') const nativeCreateId = process.argv.includes('--native-create-id') const moduleCompletion = process.argv.includes('--module-completion') const completionTarget = process.argv.find(arg => arg.startsWith('--only='))?.slice(7) ?? 'all' if (!['all','wireguard','ipsec-init','ipsec-restore','ipsec-delete','ipsec-create','vrf'].includes(completionTarget) || (completionTarget !== 'all' && !moduleCompletion)) throw new Error('Unknown isolated module target') if (moduleCompletion && process.argv.slice(2).some(arg => !['--module-completion', '--restore', `--only=${completionTarget}`].includes(arg))) throw new Error('Module completion acceptance requires a separate disposable run') const ipsecAdapters = process.argv.includes('--ipsec-adapters') || moduleCompletion if (nativeCreateId && (ipsecAdapters || process.argv.includes('--recovery-maintenance'))) throw new Error('Choose native CREATE ID or another focused acceptance mode') if (ipsecAdapters && process.argv.includes('--recovery-maintenance')) throw new Error('Choose IPsec adapters or recovery maintenance acceptance mode') if (nativeConservation && (nativeCreateId || ipsecAdapters || process.argv.includes('--recovery-maintenance'))) throw new Error('Choose native conservation or another focused acceptance mode') const recoveryMaintenance = process.argv.includes('--recovery-maintenance') || ipsecAdapters || nativeCreateId || nativeConservation if (Number(chrGreMutation) + Number(chrGreRevision) + Number(chrGreRevisionRecovery) + Number(chrFirewallRestore) + Number(chrAddress) + Number(chrFirewallWrite) + Number(chrRead) + Number(chrIdentity) + Number(chrRecursive) + Number(chrFirewallMove) + Number(chrVpn) + Number(chrFilters) + Number(chrLegacyOspf) + Number(process.argv.includes('--chr')) > 1) throw new Error('Choose exactly one CHR acceptance mode') const chr = process.argv.includes('--chr') || chrGreMutation || chrGreRevision || chrGreRevisionRecovery || chrFirewallRestore || chrAddress || chrFirewallWrite || chrRead || chrIdentity || chrRecursive || chrFirewallMove || chrVpn || chrFilters || chrLegacyOspf if (recoveryMaintenance && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility || wireguardTransfer || scopedCheckpointAdapters)) throw new Error('Recovery maintenance SQL/HTTP mode cannot run with another focused mode') if (scopedCheckpointAdapters && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility || wireguardTransfer)) throw new Error('Scoped checkpoint SQL/HTTP mode cannot run with another focused mode') if (wireguardTransfer && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility)) throw new Error('WireGuard transfer SQL/HTTP mode cannot run with another focused mode') if (interfaceEventsCompatibility && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics)) throw new Error('Interface events SQL/HTTP mode cannot run with other focused modes') if (scopedRoutingDiagnostics && (chr || greRevision || applicationAdapters)) throw new Error('Scoped routing SQL/HTTP mode cannot run with other focused modes') if (applicationAdapters && (chr || greRevision)) throw new Error('Application SQL/HTTP mode cannot run with other focused modes') if (greRevision && chr) throw new Error('GRE revision SQL/HTTP mode cannot run with CHR acceptance') if (chr) { if (!process.env.MMAPP_TEST_CHR_HOSTS || !process.env.MMAPP_TEST_CHR_USER) throw new Error('CHR hosts and user must be explicitly configured') if (!process.env.MMAPP_TEST_CHR_PASSWORD) { if (!process.stdin.isTTY) throw new Error('Use a terminal for the private CHR password prompt') process.stdout.write('CHR password (hidden): ') process.env.MMAPP_TEST_CHR_PASSWORD = await new Promise((resolve, reject) => { let value = '' const timer = setTimeout(() => finish(new Error('Password input timed out')), 60000) const finish = error => { clearTimeout(timer); process.stdin.off('data', read); process.stdin.setRawMode(false); process.stdin.pause(); process.stdout.write('\n') if (error) reject(error); else resolve(value) } const read = chunk => { for (const character of chunk.toString()) { if (character === '\r' || character === '\n') { finish(); return } if (character === '\u0003') { finish(new Error('Cancelled')); return } if (character === '\u007f' || character === '\b') value = value.slice(0, -1) else value += character } } process.stdin.setRawMode(true); process.stdin.resume(); process.stdin.on('data', read) }) } } // A private disposable cluster: never reads backend/.env or the application DB. const directory = await mkdtemp(join(tmpdir(), 'mm-mcp-test-')) const listener = createServer() await new Promise(resolve => listener.listen(0, '127.0.0.1', resolve)) const port = listener.address().port await new Promise(resolve => listener.close(resolve)) const password = randomBytes(24).toString('hex') const postgres = new EmbeddedPostgres({ databaseDir: join(directory, 'pg'), port, user: 'mcp_test', password, persistent: true, createPostgresUser: false, initdbFlags: ['--encoding=UTF8'], postgresFlags: ['-h', '127.0.0.1'], onLog: () => {}, onError: () => {} }) let exitCode = 1 let vrfChildrenExitConfirmed = true try { await postgres.initialise() await postgres.start() const binaries = await import(`@embedded-postgres/${process.platform === 'win32' ? 'windows' : process.platform}-${process.arch}`) const testPath = [process.env.MMAPP_PG_CLIENT_BIN, dirname(binaries.postgres), process.env.PATH ?? process.env.Path ?? ''].filter(Boolean).join(delimiter) if (!profilesOnly && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) { for (const command of ['pg_dump', 'pg_restore']) await new Promise((resolve, reject) => { execFile(command, ['--version'], { env: { ...process.env, PATH: testPath }, windowsHide: true, timeout: 5000, maxBuffer: 4096 }, error => { if (error) reject(new Error(`Restore acceptance requires working ${command}; set MMAPP_PG_CLIENT_BIN to the PostgreSQL client bin directory`)) else resolve() }) }) console.log('PostgreSQL restore client tools preflight PASS') } if (regressionOnly) console.log('Selected regression only: primary integration and terminal restore are not run') if (profilesOnly) console.log('Profiles-only regression matrix: primary integration NOT RUN; terminal restore NOT RUN; full acceptance is not claimed') const result = regressionOnly || profilesOnly ? 0 : await new Promise((resolve, reject) => { const child = spawn(process.execPath, pollMemory ? ['--max-old-space-size=192', '--max-semi-space-size=16', fileURLToPath(new URL('../dist-mcp-memory/services/server-poll-memory.owned.test.js', import.meta.url))] : ['--import', 'tsx', principalSecuritySource ? 'src/modules/mcp/principal-security-source.owned.test.ts' : pollJournalSnapshot ? 'src/services/server-poll-journal-snapshot.owned.test.ts' : pollTerminalArchive ? 'src/services/server-poll-terminal-archive.owned.test.ts' : pollArchiveSchema ? 'src/db/server-poll-terminal-archives.sql.test.ts' : telemetrySettingsConfiguration ? 'src/modules/mcp/telemetry-settings-configuration.owned.test.ts' : routingReservationSchema ? 'src/db/routing-reservation-schema.owned.test.ts' : routingForwardRounds ? 'src/modules/mcp/routing-network-forward-rounds.owned.test.ts' : flowActiveServices ? 'src/services/traffic-flow-active-services.owned.test.ts' : flowActiveRebuild ? 'src/services/traffic-flow-active-rebuild.owned.test.ts' : flowQuality ? 'src/services/traffic-flow-quality.owned.test.ts' : flowWorkerIpc ? 'src/services/traffic-flow-worker-ipc.owned.test.ts' : manualUptime ? 'src/modules/mcp/manual-uptime-http.test.ts' : manualPingGroup ? 'src/modules/mcp/manual-ping-group-http.test.ts' : manualTraffic ? 'src/modules/mcp/manual-traffic-http.test.ts' : manualApiPing ? 'src/modules/mcp/manual-api-ping-http.test.ts' : simpleSpeedChr ? 'src/modules/mcp/simple-speed-chr.test.ts' : simpleSpeed ? 'src/modules/mcp/simple-speed-http.test.ts' : externalPeerMetadata ? 'src/services/bandwidth-external-peer-metadata.sql.test.ts' : operatorPeerMetadata ? 'src/services/bandwidth-operator-metadata.sql.test.ts' : publicRegistryMetadata ? 'src/services/bandwidth-public-registry.sql.test.ts' : operatorDockerSql ? 'src/services/bandwidth-operator-docker-stop.sql.test.ts' : mcpOperationOrigin ? 'src/modules/mcp/operation-execution-origin.sql.test.ts' : mcpSpeedOriginal ? 'src/modules/mcp/speed-bandwidth-original.sql.test.ts' : routerConfigurationGuard ? 'src/services/router-configuration-guard.sql.test.ts' : scheduledSpeedOriginal ? 'src/services/bandwidth-scheduled-speed-original.sql.test.ts' : bandwidthSpeedWorkflow ? 'src/services/bandwidth-speed-workflow.sql.test.ts' : restSpeedOriginal ? 'src/services/bandwidth-rest-speed-original.sql.test.ts' : operationLocks ? 'src/services/operation-config-lock-lease.sql.test.ts' : serviceExecutionOrigin ? 'src/modules/mcp/service-execution-origin.sql.test.ts' : bandwidthNodeSource ? 'src/services/bandwidth-node-source.sql.test.ts' : bandwidthExternalRegistry ? 'src/services/bandwidth-external-node-registry.sql.test.ts' : bandwidthNodeRegistry ? 'src/services/bandwidth-node-registry.sql.test.ts' : bandwidthControlSource ? 'src/services/bandwidth-control-source.sql.test.ts' : bandwidthAdmission ? 'src/services/bandwidth-admission.sql.test.ts' : serverPollStorageFresh ? 'src/services/server-poll-storage-fresh.sql.test.ts' : serverPollStorage ? 'src/services/server-poll-storage.sql.test.ts' : probeStorageFresh ? 'src/services/server-probe-storage-fresh.sql.test.ts' : probeLegacyOrphans ? 'src/services/server-probe-legacy-orphans.sql.test.ts' : diagnosticCancelHost ? 'src/modules/mcp/diagnostic-cancellation-storage.sql.test.ts' : ipsecExportHttp ? 'src/modules/mcp/ipsec-existing-certificate-export-http.sql.test.ts' : ipsecExportJournal ? 'src/services/ipsec-existing-certificate-export-rest-journal.sql.test.ts' : migrationDataInventory ? 'src/db/migration-data-inventory.sql.test.ts' : probeStorageHistory ? 'src/services/server-probe-storage-history.sql.test.ts' : probeStorageJournal ? 'src/services/server-probe-storage-journal.sql.test.ts' : controlledSchemaReference ? 'src/db/controlled-schema-reference.sql.test.ts' : controlledMigrations ? 'src/db/controlled-migrations.sql.test.ts' : databaseSchemaControl ? 'src/db/database-schema-control.sql.test.ts' : migrationSchemaInventory ? 'src/db/migration-schema-inventory.sql.test.ts' : routingNetworkNative ? 'src/modules/mcp/routing-network-native.sql.test.ts' : routingReservationRuntime ? 'src/modules/mcp/routing-reservation-runtime.sql.test.ts' : routingReservations ? 'src/modules/mcp/routing-reservation.sql.test.ts' : collectorPartitionWriters ? 'src/services/collector-partition-writes.sql.test.ts' : serverPollDurable ? 'src/services/server-poll-durable-session.sql.test.ts' : routingRecoveryAuthority ? 'src/modules/mcp/routing-recovery-authority.sql.test.ts' : legacyFlowRebuild ? 'src/test/legacy-flow-rebuild-sql.ts' : probeJournal ? 'src/services/server-probe-journal.sql.test.ts' : flowHostKeys ? 'src/modules/mcp/flow-host-keys-http.test.ts' : flowRebuildMcp ? 'src/modules/mcp/flow-facts-rebuild-http.test.ts' : flowRebuild ? 'src/test/flow-facts-rebuild-sql.ts' : flowWrites ? 'src/services/traffic-flow-write-transaction.pg.test.ts' : nativeConservation ? 'src/modules/mcp/native-conservation-sql.test.ts' : nativeCreateId ? 'src/modules/mcp/native-create-id-http.test.ts' : ipsecAdapters ? "src/modules/mcp/ipsec-adapters-http.test.ts" : recoveryMaintenance ? "src/modules/mcp/recovery-maintenance-http.test.ts" : scopedCheckpointAdapters ? "src/modules/mcp/scoped-checkpoint-adapters-http.test.ts" : wireguardTransfer ? 'src/modules/mcp/wireguard-transfer-http.test.ts' : interfaceEventsCompatibility ? 'src/modules/mcp/interface-events-compatibility-http.test.ts' : scopedRoutingDiagnostics ? 'src/modules/mcp/scoped-routing-diagnostics-http.test.ts' : applicationAdapters ? 'src/modules/mcp/application-adapters-http.test.ts' : greRevision ? 'src/modules/mcp/gre-revision-http.test.ts' : chrGreRevisionRecovery ? 'src/modules/mcp/chr-gre-revision-recovery.test.ts' : chrGreRevision ? 'src/modules/mcp/chr-gre-revision.test.ts' : chrLegacyOspf ? 'src/modules/mcp/chr-ospf-legacy.test.ts' : chrFilters ? 'src/modules/mcp/chr-filter-write.test.ts' : chrGreMutation ? 'src/modules/mcp/chr-gre-mutation.test.ts' : chrFirewallRestore ? 'src/modules/mcp/chr-firewall-restore.test.ts' : chrAddress ? 'src/modules/mcp/chr-address-list.test.ts' : chrFirewallWrite ? 'src/modules/mcp/chr-firewall-write.test.ts' : chrVpn ? 'src/modules/mcp/chr-vpn-catalog.test.ts' : chrFirewallMove ? 'src/modules/mcp/chr-firewall-move.test.ts' : chrRecursive ? 'src/modules/mcp/chr-recursive-restore.test.ts' : chrIdentity ? 'src/modules/mcp/chr-ospf-identity-readonly.test.ts' : chrRead ? 'src/modules/mcp/chr-readonly-acceptance.test.ts' : chr ? 'src/modules/mcp/chr-acceptance.test.ts' : 'src/modules/mcp/integration.test.ts'], { cwd: pollMemory ? directory : new URL('../', import.meta.url), stdio: 'inherit', env: { ...(pollMemory ? pollMemoryEnvironment : process.env), DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`, DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false', MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only', MMAPP_TEST_WG_EXPORT_ONLY: String(wireguardExport), MCP_PUBLIC_URL: 'http://localhost:8000/mcp', NODE_ENV: 'test', PATH: testPath, NODE_OPTIONS: pollMemory ? '' : process.env.NODE_OPTIONS, MMAPP_OWN_PRINCIPAL_SECURITY_SOURCE: String(principalSecuritySource), MMAPP_OWN_POLL_JOURNAL_SNAPSHOT: String(pollJournalSnapshot), MMAPP_OWN_POLL_MEMORY: String(pollMemory), MMAPP_OWN_POLL_BOOTSTRAP: String(pollMemoryBootstrap), MMAPP_OWN_POLL_COST_DIAGNOSTICS: String(pollMemoryCost), MMAPP_OWN_POLL_ARCHIVE_CLAIM_LOSS: String(pollArchiveClaimLoss), MMAPP_OWN_POLL_ARCHIVE_HISTORY: String(pollArchiveHistory), MMAPP_OWN_POLL_ARCHIVE_COLD: String(pollArchiveCold), MMAPP_OWN_POLL_ARCHIVE_LOST_ACK: String(pollArchiveLostAck), MMAPP_OWN_POLL_TERMINAL_ARCHIVE: String(pollTerminalArchive), MMAPP_OWN_POLL_ARCHIVE_SCHEMA: String(pollArchiveSchema), MMAPP_OWN_TELEMETRY_SETTINGS_CONFIGURATION: String(telemetrySettingsConfiguration), MMAPP_OWN_ROUTING_RESERVATION_SCHEMA: String(routingReservationSchema), MMAPP_OWN_ROUTING_FORWARD_ROUNDS: String(routingForwardRounds), MMAPP_OWN_FLOW_ACTIVE_SERVICES: String(flowActiveServices), MMAPP_OWN_FLOW_ACTIVE_REBUILD: String(flowActiveRebuild), MMAPP_OWN_FLOW_QUALITY: String(flowQuality), MMAPP_OWN_FLOW_WORKER_IPC: String(flowWorkerIpc), MMAPP_OWN_MANUAL_UPTIME: String(manualUptime), MMAPP_OWN_MANUAL_PING_GROUP: String(manualPingGroup), MMAPP_OWN_MANUAL_TRAFFIC: String(manualTraffic), MMAPP_OWN_MANUAL_API_PING: String(manualApiPing), MMAPP_OWN_SIMPLE_SPEED: String(simpleSpeed), MMAPP_OWN_SIMPLE_SPEED_CHR: String(simpleSpeedChr), MMAPP_OWN_DIAGNOSTIC_CANCEL_HOST: String(diagnosticCancelHost), MMAPP_OWN_OPERATOR_DOCKER_SQL: String(operatorDockerSql), MMAPP_OWN_PUBLIC_REGISTRY_METADATA: String(publicRegistryMetadata), MMAPP_OWN_OPERATOR_PEER_METADATA: String(operatorPeerMetadata), MMAPP_OWN_EXTERNAL_PEER_METADATA: String(externalPeerMetadata), MMAPP_OWN_BANDWIDTH_EXTERNAL_REGISTRY: String(externalPeerMetadata || operatorPeerMetadata || publicRegistryMetadata || operatorDockerSql || mcpSpeedOriginal || bandwidthSpeedWorkflow || bandwidthExternalRegistry), MMAPP_OWN_BANDWIDTH_SPEED_WORKFLOW: String(bandwidthSpeedWorkflow), MMAPP_OWN_REST_SPEED_ORIGINAL: String(restSpeedOriginal), MMAPP_OWN_MCP_OPERATION_ORIGIN: String(mcpOperationOrigin), MMAPP_OWN_MCP_SPEED_ORIGINAL: String(mcpSpeedOriginal), MMAPP_OWN_SCHEDULED_SPEED_ORIGINAL: String(scheduledSpeedOriginal), MMAPP_TEST_ROUTER_GUARD_OWNED: String(routerConfigurationGuard), MMAPP_TEST_ROUTER_GUARD_CLUSTER_DISPOSABLE: String(routerConfigurationGuard), MMAPP_TEST_ROUTER_GUARD_ADMIN_URL: routerConfigurationGuard ? `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres` : '', MMAPP_OWN_BANDWIDTH_ADMISSION: String(externalPeerMetadata || operatorPeerMetadata || publicRegistryMetadata || operatorDockerSql || mcpOperationOrigin || mcpSpeedOriginal || scheduledSpeedOriginal || bandwidthSpeedWorkflow || restSpeedOriginal || bandwidthExternalRegistry || operationLocks || serviceExecutionOrigin || bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthNodeSource), MMAPP_OWN_BANDWIDTH_RESTORE: String((bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthNodeSource) && process.argv.includes('--restore')), MMAPP_OWN_IPSEC_EXPORT_HTTP: String(ipsecExportHttp), MMAPP_OWN_IPSEC_EXPORT_JOURNAL: String(ipsecExportJournal), MMAPP_OWN_SQL_DB: 'postgres', MMAPP_OWN_PROBE_LEGACY_ORPHANS: String(probeLegacyOrphans), MMAPP_OWN_PROBE_STORAGE_HISTORY: String(probeStorageHistory), MMAPP_OWN_PROBE_STORAGE_FRESH: String(probeStorageFresh), MMAPP_OWN_PROBE_STORAGE_JOURNAL: String(probeStorageJournal || probeStorageFresh), MMAPP_OWN_CONTROLLED_SCHEMA_REFERENCE: String(controlledSchemaReference), MMAPP_OWN_CONTROLLED_MIGRATIONS: String(controlledMigrations), MMAPP_OWN_DATABASE_SCHEMA_CONTROL: String(databaseSchemaControl), MMAPP_OWN_MIGRATION_DATA_INVENTORY: String(migrationDataInventory), MMAPP_OWN_MIGRATION_SCHEMA_INVENTORY: String(migrationSchemaInventory), MMAPP_OWN_ROUTING_NETWORK_NATIVE: String(routingNetworkNative), MMAPP_OWN_ROUTING_RESERVATIONS: String(routingReservations || routingReservationRuntime), MMAPP_OWN_COLLECTOR_PARTITION_WRITERS: String(collectorPartitionWriters), MMAPP_OWN_SERVER_POLL_STORAGE_FRESH: String(serverPollStorageFresh), MMAPP_OWN_SERVER_POLL_STORAGE: String(serverPollStorage), MMAPP_OWN_SERVER_POLL_DURABLE: String(serverPollDurable), MMAPP_OWN_ROUTING_RECOVERY_AUTHORITY: String(routingRecoveryAuthority), MMAPP_OWN_LEGACY_FLOW_REBUILD: String(legacyFlowRebuild), MMAPP_OWN_PROBE_JOURNAL: String(probeJournal), MMAPP_MODULE_COMPLETION_ONLY: String(moduleCompletion), MMAPP_MODULE_COMPLETION_TARGET: completionTarget, MMAPP_OWN_FLOW_HOST_KEYS: String(flowHostKeys), MMAPP_OWN_MCP_FLOW_REBUILD: String(flowRebuildMcp), MMAPP_OWN_FLOW_WRITES: String(flowWrites), MMAPP_OWN_FLOW_REBUILD: String(flowRebuild) }, }) child.once('error', reject); child.once('exit', code => resolve(code ?? 1)) }) exitCode = result if (result === 0 && !regressionOnly && !profilesOnly && !pollMemory && !principalSecuritySource && !pollJournalSnapshot && !pollArchiveSchema && !telemetrySettingsConfiguration && !routingReservationSchema && !routingForwardRounds && !flowActiveServices && !flowActiveRebuild && !flowQuality && !flowWorkerIpc && !manualUptime && !manualPingGroup && !manualTraffic && !manualApiPing && !simpleSpeed && !simpleSpeedChr && !externalPeerMetadata && !operatorPeerMetadata && !publicRegistryMetadata && !operatorDockerSql && !mcpOperationOrigin && !mcpSpeedOriginal && !routerConfigurationGuard && !scheduledSpeedOriginal && !bandwidthSpeedWorkflow && !restSpeedOriginal && !operationLocks && !serviceExecutionOrigin && !bandwidthNodeSource && !bandwidthNodeRegistry && !bandwidthExternalRegistry && !bandwidthControlSource && !bandwidthAdmission && !probeLegacyOrphans && !probeStorageJournal && !probeStorageHistory && !probeJournal && !chr && !flowWrites && !flowRebuild && !flowRebuildMcp && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) { exitCode = await new Promise((resolve, reject) => { const child = spawn(process.execPath, ['--import', 'tsx', 'src/modules/mcp/database-restore.test.ts'], { cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env, DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`, DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false', MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only', MCP_PUBLIC_URL: 'http://localhost:8000/mcp', NODE_ENV: 'test', PATH: testPath, MMAPP_OWN_SQL_DB: 'postgres', MMAPP_OWN_TERMINAL_RESTORE: 'true', MMAPP_OWN_TERMINAL_DATA_EQUIVALENCE: String(migrationDataInventory) }, }) child.once('error', reject); child.once('exit', code => resolve(code ?? 1)) }) } else if (result === 0 && pollArchiveSchema) console.log('Poll archive schema: owned nonempty40 preservation, numbered41 and structural refusal guards; no positive MCP archive claim') else if (result === 0 && telemetrySettingsConfiguration) console.log('Telemetry settings: genuine MCP/SQL configuration binding, collector metadata tolerated; no native or external sources') else if (result === 0 && routingReservationSchema) console.log('Routing reservation numbered0040: ownSQL fresh/legacy/manual preservation; no READY, backfill, capabilities or public native activation') else if (result === 0 && routingForwardRounds) console.log('Routing forward rounds: genuine approved running CONFIG_APPLIED, shared cumulative native budget; logs/security/autoRecovery remain unaccepted') else if (result === 0 && flowActiveServices) console.log('Flow active settings/purge: production services and main Worker; disposable SQL/localhost only') else if (result === 0 && flowActiveRebuild) console.log('Flow active rebuild: production shared service and genuine Worker drain; disposable SQL/localhost only') else if (result === 0 && flowQuality) console.log('Flow quality: production engine and genuine receipt SQL, explicit COMMIT ACK fault on owned cluster only; no CHR/whole-installation RAM claim') else if (result === 0 && flowWorkerIpc) console.log('Flow worker IPC: production main/Worker lifecycle, localhost UDP, owned PostgreSQL only; real CHR and concurrent-spawn acceptance remain separate') else if (result === 0 && manualUptime) console.log('Manual uptime: full resources then ping, actual shared service and deferred alerts; owned PostgreSQL/localhost only') else if (result === 0 && manualPingGroup) console.log('Manual Ping group: existing normalization/mutex/samples/conditional global alerts; owned PostgreSQL/localhost only') else if (result === 0 && manualTraffic) console.log('Manual traffic: full scheduler/events/settings/retention/alerts shared by REST and MCP; owned PostgreSQL/localhost only') else if (result === 0 && manualApiPing) console.log('Manual API Ping: ordinary global collector with alerts hook, own PostgreSQL and localhost only') else if (result === 0 && simpleSpeed) console.log('Simple RouterOS speed: public MCP/REST, ordinary shared service, own PostgreSQL and localhost RouterOS only') else if (result === 0 && simpleSpeedChr) console.log('Simple RouterOS speed: own PostgreSQL, real two-CHR bounded test and ordinary MCP approval; no router configuration changes') else if (result === 0 && externalPeerMetadata) console.log('Guarded peer sources: actual managed/external SQL-owner and localhost license composition; Q/catalog attestation synthetic, full operator window remains open') else if (result === 0 && operatorPeerMetadata) console.log('Operator peer metadata: actual managed endpoint SQL and genuine localhost license origin; synthetic Q, external metadata and full operator window remain open') else if (result === 0 && publicRegistryMetadata) console.log('Public registry metadata: actual owned PostgreSQL and same physical lease; no secret/Q/native/write authority or backend-window acceptance') else if (result === 0 && operatorDockerSql) console.log('Operator Docker SQL: actual owned PostgreSQL with mocked Docker HTTP only; not a real Docker/backend-window acceptance') else if (result === 0 && mcpOperationOrigin) console.log('MCP operation root: owned PostgreSQL ordinary runner provenance; no restore/recovery, global writer activation, CHR or deployment') else if (result === 0 && mcpSpeedOriginal) console.log('MCP speed: genuine trusted service context with real connection/grant/SQL, host receipt and localhost native; synthetic Q/mapping; not a public MCP runner/action acceptance') else if (result === 0 && routerConfigurationGuard) console.log('Router configuration guard: dedicated owned databases/roles and localhost native fixture; no application migration, production activation or real CHR') else if (result === 0 && scheduledSpeedOriginal) console.log('Scheduled speed original: genuine fixed-job scheduler authority, actual owned SQL and localhost read-only TCP; no legacy collector, native bandwidth, history or runtime activation') else if (result === 0 && bandwidthSpeedWorkflow) console.log('Whole speed workflow: actual REST/JWT, signed v2 control SQL, native fixture HTTP and history; synthetic Q/mapping; no runtime activation or real CHR') else if (result === 0 && restSpeedOriginal) console.log('REST speed original profile: owned application SQL and localhost read-only TCP; no bandwidth POST, history, runtime activation or real CHR') else if (result === 0 && operationLocks) console.log('Operation lock profile: owned PostgreSQL/localhost fixtures; no terminal restore or real CHR') else if (result === 0 && serviceExecutionOrigin) console.log('Service origin profile: owned SQL only; no terminal restore or native networking') else if (result === 0 && (bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthExternalRegistry || bandwidthNodeSource)) console.log('Bandwidth proposal profile: dedicated owned data round-trip only; no normal enrollment or production restore claim') else if (result === 0 && (probeLegacyOrphans || probeStorageJournal || probeStorageHistory || probeJournal)) console.log('Legacy-only profile: positive current-version terminal restore belongs to --probe-storage-fresh; no migration marker fabricated') else if (result === 0 && profilesOnly) console.log(profilesGroup ? 'Profiles-only fixed group: ' + profilesGroup + '; partial matrix on its own fresh database' : 'Profiles-only: running the unchanged complete regression list plus mandatory test:logs:pg on one fresh owned database') else if (result === 0 && serverPollStorageFresh && process.env.MMAPP_OWN_SERVER_POLL_SETTINGS_EPOCH === 'true') console.log('Targeted settings epoch upgrade and actual pg_dump/restore accepted; full primary/poll-storage terminal restore not run') else if (result === 0 && !chr && !flowWrites && !flowRebuild && !flowRebuildMcp) console.log('Terminal restore not run: use --restore with PostgreSQL client tools on PATH, or set MMAPP_PG_CLIENT_BIN') if (exitCode === 0 && (serverPollStorage || serverPollStorageFresh) && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) { exitCode = await new Promise((resolve, reject) => { const child = spawn(process.execPath, ['--import', 'tsx', 'src/services/server-poll-storage-restore.sql.test.ts'], { cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env, DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`, DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false', MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only', NODE_ENV: 'test', PATH: testPath, MMAPP_OWN_SERVER_POLL_STORAGE_RESTORE: 'true' }, }) child.once('error', reject); child.once('exit', code => resolve(code ?? 1)) }) } if (exitCode === 0 && process.argv.includes('--all')) { if (!process.env.npm_execpath) throw new Error('Run --all through npm run test:mcp:pg:all') const database = 'mm_accept_166_' + Date.now() await postgres.createDatabase(database) const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')) let profiles = packageJson.scripts['test:all'].split(/\s*&&\s*/).map(command => command.replace('npm run ', '')) if (process.argv.includes('--remaining')) profiles = profiles.slice(profiles.indexOf('test:traffic-flow')) const selected = process.argv.find(value => value.startsWith('--profile='))?.slice('--profile='.length) if (selected) { if (![...profiles, 'test:logs:pg', 'test:vrf:production'].includes(selected)) throw new Error('Unknown regression profile') profiles = [selected] } const failures = [] const requiredProfiles = regressionProfiles(profiles, selected, profilesGroup) for (const script of requiredProfiles) { if (script === 'test:vrf:production') { vrfChildrenExitConfirmed = false const receipt = await runOwnedVrfProductionProfile({ directory, database, databaseUrl: `postgresql://mcp_test:${password}@127.0.0.1:${port}/${database}` }) vrfChildrenExitConfirmed = receipt.childExitConfirmed if (!receipt.accepted) failures.push(script) if (!vrfChildrenExitConfirmed) break continue } const status = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [process.env.npm_execpath, 'run', script], { cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env, DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/${database}`, DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false', MMAPP_OWN_SQL_DB: database, MCP_STATE_DIR: join(directory, 'regression-state'), REQUIRE_TEST_POSTGRES: '1', LOGS_PERFORMANCE: process.argv.includes('--performance') ? '1' : '0', AUTH_REQUIRED: 'false', NODE_ENV: 'test' }, }) child.once('error', reject); child.once('exit', code => resolve(code ?? 1)) }) if (status !== 0) failures.push(script) } exitCode = failures.length ? 1 : 0 console.log('Regression failed profiles:', failures.length ? failures.join(', ') : 'none') if (profilesOnly) console.log('Profiles-only matrix result:', exitCode === 0 ? 'PASS' : 'FAIL', 'profiles=' + requiredProfiles.length, ...(profilesGroup ? ['group=' + profilesGroup, 'completeMatrix=false'] : []), 'primaryIntegration=NOT_RUN terminalRestore=NOT_RUN fullAcceptance=false') } } catch (error) { exitCode = 1 console.error(error) } finally { await postgres.stop() const rel = relative(resolve(tmpdir()), resolve(directory)) if (!rel || rel.startsWith('..') || isAbsolute(rel) || !rel.startsWith('mm-mcp-test-')) throw new Error('Unsafe test cleanup path') if (vrfChildrenExitConfirmed) await rm(directory, { recursive: true, force: true, maxRetries: 10, retryDelay: 250 }) else console.error('VRF child exit unconfirmed; own test directory retained') process.exitCode = exitCode } // embedded-postgres installs a beforeExit hook that otherwise forces exit(0). process.exit(exitCode)