import assert from 'node:assert/strict'; import { describe, test } from 'node:test'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { CondensedGraph } from '../../src/core/CondensedGraph.js'; import { ShardedSnapshotBuilder } from '../../src/core/shards/ShardedSnapshotBuilder.js'; import { ShardedSnapshot } from '../../src/core/shards/ShardedSnapshot.js'; import { FileShardStorage } from '../../src/core/shards/FileShardStorage.js'; function buildShardedSnapshot(bucketSize = 2) { const graph = new CondensedGraph(); const user0 = graph._ensureNode('user:0'); const user1 = graph._ensureNode('user:1'); const user2 = graph._ensureNode('user:2'); const user3 = graph._ensureNode('user:3'); const group0 = graph._ensureNode('group:0'); const group1 = graph._ensureNode('group:1'); const doc0 = graph._ensureNode('doc:0'); graph.addEdge(user0, 'member', group0); graph.addEdge(user3, 'member', group0); graph.addEdge(user2, 'member', group1); graph.addEdge(group0, 'viewer', doc0); graph.addEdge(group1, 'viewer', doc0); graph.addEdge(user0, 'risk', doc0, { value: 0.2, possibility: 1, reliability: 1 }); graph.addEdge(user3, 'risk', doc0, { value: 0.9, possibility: 1, reliability: 1 }); graph.addEdge(user2, 'risk', doc0, { value: 0.6, possibility: 1, reliability: 1 }); graph.finalizePerfectHash(); graph.finalizeWaveletAdjacency({ dropAdjacencyList: true }); const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sharded-cross-chain-')); const builder = new ShardedSnapshotBuilder({ bucketSize, includeDirections: ['out', 'in'] }); const manifest = builder.build(graph, dir); const storage = new FileShardStorage(dir); const snapshot = new ShardedSnapshot(manifest, storage, { cacheLimit: 8 }); snapshot.initializeSync(); return { graph, snapshot, dir, ids: { user0, user1, user2, user3, group0, group1, doc0 } }; } function collectRiskPaths(snapshot, relationIds, docId) { const viewerRel = relationIds.viewer; const memberRel = relationIds.member; const riskRel = relationIds.risk; const paths = []; const viewerEdges = snapshot.executeGetInEdgesSync(docId, viewerRel, new Set()) || []; for (const viewer of viewerEdges) { const groupId = viewer.src; const memberEdges = snapshot.executeGetInEdgesSync(groupId, memberRel, new Set()) || []; for (const member of memberEdges) { const userId = member.src; const riskEdge = snapshot.executeFindEdgeSync(userId, riskRel, docId, new Set()); if (riskEdge) { paths.push({ userId, docId }); } } } return paths; } // ADR-003: sharded snapshots are stubs in src/core/shards/ — tests are the spec for when the subsystem is implemented. describe.skip('Sharded snapshot cross-chain aggregation', () => { test('aggregates risk values across userset paths', () => { const { graph, snapshot, dir, ids } = buildShardedSnapshot(2); const relationIds = { member: graph.getRelationId('member'), viewer: graph.getRelationId('viewer'), risk: graph.getRelationId('risk') }; const plan = new Set(); snapshot.planInEdges(relationIds.viewer, ids.doc0, plan); snapshot.planInEdges(relationIds.member, ids.group0, plan); snapshot.planInEdges(relationIds.member, ids.group1, plan); snapshot.planOutEdges(relationIds.risk, ids.user0, plan); snapshot.planOutEdges(relationIds.risk, ids.user2, plan); snapshot.planOutEdges(relationIds.risk, ids.user3, plan); snapshot.prefetchPlanSync(plan); const paths = collectRiskPaths(snapshot, relationIds, ids.doc0); assert.strictEqual(paths.length, 3); fs.rmSync(dir, { recursive: true, force: true }); }); test('cross-bucket paths resolve with inbound and outbound shards', () => { const { graph, snapshot, dir, ids } = buildShardedSnapshot(2); const relationIds = { member: graph.getRelationId('member'), viewer: graph.getRelationId('viewer'), risk: graph.getRelationId('risk') }; const plan = new Set(); snapshot.planInEdges(relationIds.viewer, ids.doc0, plan); snapshot.planInEdges(relationIds.member, ids.group0, plan); snapshot.planInEdges(relationIds.member, ids.group1, plan); snapshot.planOutEdges(relationIds.risk, ids.user0, plan); snapshot.planOutEdges(relationIds.risk, ids.user2, plan); snapshot.planOutEdges(relationIds.risk, ids.user3, plan); snapshot.prefetchPlanSync(plan); const paths = collectRiskPaths(snapshot, relationIds, ids.doc0); assert.strictEqual(paths.length, 3); fs.rmSync(dir, { recursive: true, force: true }); }); });