import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; 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'; import { DeltaShardBinary } from '../../src/core/shards/DeltaShardBinary.js'; function buildSnapshot(bucketSize = 4) { const graph = new CondensedGraph(); const nodes = []; for (let i = 0; i < 6; i++) { nodes.push(graph._ensureNode(`node:${i}`)); } graph.addEdge(nodes[0], 'owner', nodes[1]); graph.addEdge(nodes[0], 'owner', nodes[2]); graph.addEdge(nodes[3], 'owner', nodes[4]); graph.addEdge(nodes[5], 'owner', nodes[0]); graph.finalizePerfectHash(); graph.finalizeWaveletAdjacency({ dropAdjacencyList: true }); const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sharded-delta-layer-')); 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 { snapshot, dir, nodes, manifest }; } function writeDeltaLayer(snapshot, dir, entries, mode = 'override') { fs.mkdirSync(dir, { recursive: true }); const merged = new Map(); for (const entry of entries) { const shardMeta = snapshot._selectShardMeta(entry.relationId, entry.direction, entry.srcId); assert.ok(shardMeta, 'Missing shard meta for delta entry'); const localSource = snapshot._localSource(entry.srcId, shardMeta); const key = shardMeta.cacheKey; let bucket = merged.get(key); if (!bucket) { bucket = { shardMeta, additions: [], removals: [] }; merged.set(key, bucket); } for (const add of entry.additions) { bucket.additions.push({ srcLocal: localSource, otherId: add.dstId, possBits: add.possBits, relBits: add.relBits }); } for (const rem of entry.removals) { bucket.removals.push({ srcLocal: localSource, otherId: rem.dstId }); } } const shards = []; for (const bucket of merged.values()) { const shardMeta = bucket.shardMeta; const buffer = DeltaShardBinary.serialize({ relationId: shardMeta.relationId, direction: shardMeta.direction, rangeStart: shardMeta.rangeStart, rangeEnd: shardMeta.rangeEnd, nodeCount: snapshot.nodeCount, additions: bucket.additions, removals: bucket.removals }); const shardKey = `delta-${shardMeta.key}`; fs.writeFileSync(path.join(dir, shardKey), new Uint8Array(buffer)); shards.push({ key: shardKey, relationId: shardMeta.relationId, direction: shardMeta.direction, rangeStart: shardMeta.rangeStart, rangeEnd: shardMeta.rangeEnd, cacheKey: shardMeta.cacheKey }); } return { shards, storage: new FileShardStorage(dir), mode }; } // ADR-003: sharded snapshots are stubs in src/core/shards/ — tests are the spec for when the subsystem is implemented. describe.skip('Sharded delta layering semantics', () => { test('later override layers win over earlier layers', () => { const { snapshot, dir, nodes } = buildSnapshot(4); const relId = snapshot.relationIdToName.indexOf('owner'); const layer1 = writeDeltaLayer(snapshot, path.join(dir, 'l1'), [ { relationId: relId, direction: 'out', srcId: nodes[0], additions: [{ dstId: nodes[3], possBits: 65535, relBits: 65535 }], removals: [] } ], 'override'); const layer2 = writeDeltaLayer(snapshot, path.join(dir, 'l2'), [ { relationId: relId, direction: 'out', srcId: nodes[0], additions: [], removals: [{ dstId: nodes[3] }] } ], 'override'); snapshot.setDeltaLayers([layer1, layer2]); const edge = snapshot.findEdgeSync(nodes[0], relId, nodes[3]); assert.equal(edge, null); fs.rmSync(dir, { recursive: true, force: true }); }); test('union overlays do not override writer removals', () => { const { snapshot, dir, nodes } = buildSnapshot(4); const relId = snapshot.relationIdToName.indexOf('owner'); const writerLayer = writeDeltaLayer(snapshot, path.join(dir, 'writer'), [ { relationId: relId, direction: 'out', srcId: nodes[0], additions: [], removals: [{ dstId: nodes[1] }] } ], 'override'); const unionLayer = writeDeltaLayer(snapshot, path.join(dir, 'union'), [ { relationId: relId, direction: 'out', srcId: nodes[0], additions: [], removals: [{ dstId: nodes[2] }] } ], 'union'); snapshot.setDeltaLayers([writerLayer, unionLayer]); const removedByWriter = snapshot.findEdgeSync(nodes[0], relId, nodes[1]); assert.equal(removedByWriter, null); const unionRemovalIgnored = snapshot.findEdgeSync(nodes[0], relId, nodes[2]); assert.ok(unionRemovalIgnored, 'Union overlay must not remove base access'); fs.rmSync(dir, { recursive: true, force: true }); }); });