Phase 7A+7C: Subsystem aggregator + Flow tracer (post-review fixes)

This commit is contained in:
Jarvis Prime
2026-03-09 06:51:32 +00:00
parent 4221ab4d76
commit 4c212740a2
28 changed files with 2476 additions and 0 deletions

93
test/test-flow.js Normal file
View File

@@ -0,0 +1,93 @@
const fs = require('fs');
const path = require('path');
const GraphStore = require('../graph.js');
const { buildSubsystems } = require('../subsystem.js');
const { buildFlowIndex, traceFlow } = require('../flow.js');
const FIXTURE_DIR = path.join(__dirname, 'fixtures/system-docs');
const SNAPSHOT = path.join(FIXTURE_DIR, 'snapshot.json');
let passed = 0;
let failed = 0;
function assert(condition, name) {
if (condition) { passed++; console.log(`${name}`); }
else { failed++; console.log(`${name}`); }
}
const graph = GraphStore.loadSnapshot(SNAPSHOT);
const subsystemMap = buildSubsystems(graph, { minTraffic: 3, crossCuttingThreshold: 0.6 });
const index = buildFlowIndex(graph, subsystemMap);
console.log('=== 7C: Flow Tracer Tests ===\n');
// Test 1: Simple linear flow across subsystems
console.log('Test 1: Linear flow');
const t1 = traceFlow('channels/telegram.ts:onTelegramMessage', index);
assert(t1.subsystemSequence.includes('channels'), 'Started in channels');
assert(t1.subsystemSequence.includes('gateway'), 'Crossed to gateway');
assert(t1.flow.some(f => f.entity === 'gateway/server.ts:handleRequest' && f.crossedVia === 'CALLS'), 'Recorded CALLS crossing');
// Test 2: Cycle detection (gateway <-> agents)
console.log('\nTest 2: Cycle detection');
const t2 = traceFlow('gateway/session.ts:refreshSession', index);
assert(t2.subsystemSequence.includes('gateway'), 'Started in gateway');
assert(t2.subsystemSequence.includes('agents'), 'Crossed to agents');
assert(t2.flow.length < 20, 'Trace terminated without infinite loop');
// Test 3: God object exclusion
console.log('\nTest 3: God object exclusion');
const indexLowThreshold = buildFlowIndex(graph, subsystemMap, { godThreshold: 2 });
const t3 = traceFlow('channels/telegram.ts:onTelegramMessage', indexLowThreshold);
assert(t3.excludedNodes.includes('utils/logger.ts:log'), 'logger.ts:log was excluded as god object');
assert(!t3.flow.some(f => f.entity === 'utils/logger.ts:log'), 'logger does not appear in flow');
// Test 4: Depth limit
console.log('\nTest 4: Depth limit');
const t4 = traceFlow('channels/telegram.ts:onTelegramMessage', index, { maxDepth: 1.2 });
assert(t4.flow.some(f => f.entity === 'gateway/server.ts:handleRequest'), 'Included depth 1 node');
assert(!t4.flow.some(f => f.entity === 'gateway/session.ts:loadSession'), 'Excluded depth 1.5 node');
// Test 5: Empty trace
console.log('\nTest 5: Empty trace');
const t5 = traceFlow('utils/crypto.ts:hashString', index);
assert(t5.flow.length === 1, 'Only entry point in flow');
assert(t5.subsystemSequence.length === 1, 'Only one subsystem');
// Test 6: Invalid entry point
console.log('\nTest 6: Invalid entry point');
const t6 = traceFlow('nonexistent/file.ts:foo', index);
assert(t6.error !== undefined, 'Returns error for invalid entry point');
assert(t6.flow.length === 0, 'Empty flow for invalid entry');
// Test 7: Multiple traces reuse same index (performance)
console.log('\nTest 7: Index reuse + OpenClaw performance');
const fullSnap = path.join(__dirname, '..', 'snapshots', 'openclaw-full.json');
if (fs.existsSync(fullSnap)) {
const fullGraph = GraphStore.loadSnapshot(fullSnap);
const fullSubs = buildSubsystems(fullGraph);
const indexStart = Date.now();
const fullIndex = buildFlowIndex(fullGraph, fullSubs, { godThreshold: 50 });
const indexTime = Date.now() - indexStart;
console.log(` Index built in ${indexTime}ms`);
// Run 3 traces on the same index
const entries = ['cli/route.ts:tryRouteCli', 'gateway/session-utils.ts', 'pairing/pairing-store.ts'];
let totalTraceTime = 0;
for (const ep of entries) {
const start = Date.now();
const t = traceFlow(ep, fullIndex, { maxDepth: 8 });
const elapsed = Date.now() - start;
totalTraceTime += elapsed;
console.log(` Trace "${ep}": ${t.flow.length} steps, ${t.subsystemSequence.length} subsystems, ${elapsed}ms`);
}
assert(indexTime < 3000, `Index built in <3s (${indexTime}ms)`);
assert(totalTraceTime < 5000, `All 3 traces completed in <5s (${totalTraceTime}ms)`);
} else {
console.log(' (skipped — openclaw-full.json not found)');
}
console.log(`\n=== Results: ${passed} passed, ${failed} failed ===`);
process.exit(failed > 0 ? 1 : 0);