const assert = require('node:assert/strict') const fs = require('node:fs') const crypto = require('node:crypto') const { execFileSync } = require('node:child_process') const schema = `fusion_migration_test_${crypto.randomBytes(6).toString('hex')}` const migration = fs.readFileSync(`${__dirname}/../migrations/versioned/000208_agent_fusions.up.sql`, 'utf8') const checks = [] const sql = query => execFileSync('docker', ['--context', 'colima-yawan', 'exec', '-i', 'WeKnora-postgres', 'psql', '-X', '-U', 'postgres', '-d', 'yawan_native_acceptance_20260915', '-At', '-v', 'ON_ERROR_STOP=1'], { input: `SET search_path TO ${schema}, public;\n${query}`, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim() const check = (name, condition) => { assert.ok(condition, name); checks.push(name) } const value = text => `'${JSON.stringify(text).replaceAll("'", "''")}'::jsonb` function fixture(id, fusion, role = 'production', native = { role: 'production', sentinel: 'preserved' }) { sql(`INSERT INTO custom_agents VALUES ('agent-${id}',10059,${value(native)},NULL); INSERT INTO yawan_legacy_asset_mappings VALUES ('yawan-workbench',1,'agent',${id},10059,'agent-${id}',${value({ role, fusion_agent_ids: fusion })},'{}');`) } const run = () => sql(`BEGIN; ${migration} COMMIT;`) try { sql(`CREATE SCHEMA ${schema}; CREATE TABLE custom_agents (id TEXT PRIMARY KEY,tenant_id BIGINT,config JSONB,deleted_at TIMESTAMPTZ); CREATE TABLE yawan_legacy_asset_mappings (source_system TEXT,source_organization_id BIGINT,source_kind TEXT,source_id BIGINT,target_tenant_id BIGINT,target_id TEXT,source_snapshot JSONB,native_snapshot JSONB);`) fixture(1, [3, 2]); fixture(2, [1]); fixture(3, []) fixture(4, [2], 'production', { role: 'production', fusion_agent_ids: [], sentinel: 'explicit-empty' }) fixture(5, [2], 'production', { role: 'qc', sentinel: 'native-duty-edited' }) run() const data = JSON.parse(sql('SELECT jsonb_object_agg(id,config) FROM custom_agents').split('\n').at(-1)) check('ordered_direct_ids_preserved_without_recursive_cycle_expansion', JSON.stringify(data['agent-1'].fusion_agent_ids) === JSON.stringify(['agent-3', 'agent-2']) && JSON.stringify(data['agent-2'].fusion_agent_ids) === JSON.stringify(['agent-1'])) check('empty_selection_and_native_duty_edits_preserved', data['agent-4'].fusion_agent_ids.length === 0 && !('fusion_agent_ids' in data['agent-5'])) check('unrelated_configuration_preserved', data['agent-1'].sentinel === 'preserved') sql(`UPDATE custom_agents SET config=config || '{"fusion_agent_ids":[],"sentinel":"owner-edit"}' WHERE id='agent-1';`) const before = sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a') run() check('rerun_does_not_restore_user_removed_bindings', before === sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a')) const cases = [[6, [999], 'missing-target'], [7, [2, 2], 'duplicate'], [8, [8], 'self'], [9, ['2'], 'invalid-id'], [10, [2], 'primary-wrong-role']] for (const [id, fusions, label] of cases) { fixture(id, fusions, label === 'primary-wrong-role' ? 'qc' : 'production') const baseline = sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a') let rejected = false try { run() } catch { rejected = true } check(`${label}_rejected_atomically`, rejected && baseline === sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a')) sql(`DELETE FROM custom_agents WHERE id='agent-${id}'; DELETE FROM yawan_legacy_asset_mappings WHERE source_id=${id};`) } fixture(11, [2]) sql(`UPDATE yawan_legacy_asset_mappings SET source_snapshot=jsonb_set(source_snapshot,'{role}','"qc"') WHERE source_id=2;`) let rejected = false try { run() } catch { rejected = true } check('nonproduction_target_rejected', rejected) console.log(JSON.stringify({ passed: true, checks }, null, 2)) } finally { sql(`DROP SCHEMA IF EXISTS ${schema} CASCADE;`) }