initial commit: @arbiter/core authorization engine with js-rigor hardening

Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/
binary modes, condensed snapshots, value relations) with 39 rigor test
campaigns. Includes fixes for snapshot binary writer/reader format
mismatch (snapshot-of-snapshot corruption), possibility write-boundary
validation, empty-graph snapshot serialization, relation lookup cache
direction collision, config-redefinition cache invalidation, binary
threshold semantics, defeasible compiled routing, and comparator
reason whitelisting.
This commit is contained in:
John Dvorak
2026-07-31 13:44:06 -07:00
commit 717ae1031e
373 changed files with 654131 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
import fs from 'node:fs';
import path from 'node:path';
import { performance } from 'node:perf_hooks';
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 parseArgs(argv) {
const args = new Map();
for (let i = 2; i < argv.length; i++) {
const value = argv[i];
if (!value.startsWith('--')) continue;
const [key, inline] = value.slice(2).split('=');
if (inline !== undefined) {
args.set(key, inline);
continue;
}
const next = argv[i + 1];
if (next && !next.startsWith('--')) {
args.set(key, next);
i++;
} else {
args.set(key, true);
}
}
return args;
}
const args = parseArgs(process.argv);
const edges = Number(args.get('edges') || 50000);
const users = Number(args.get('users') || 5000);
const docs = Number(args.get('docs') || 20000);
const bucketSize = Number(args.get('bucket') || 4096);
const samples = Number(args.get('samples') || 10000);
const output = args.get('output') || 'tmp/shards-bench';
console.log('Sharded snapshot bench');
console.log(` edges: ${edges}`);
console.log(` users: ${users}`);
console.log(` docs: ${docs}`);
console.log(` bucket: ${bucketSize}`);
console.log(` samples: ${samples}`);
const graph = new CondensedGraph();
const relations = ['owner', 'editor', 'viewer'];
const edgePairs = [];
const buildStart = performance.now();
for (let i = 0; i < edges; i++) {
const userIndex = i % users;
const docIndex = i % docs;
const relId = i % 3;
const srcId = graph._ensureNode(`user:${userIndex}`);
const dstId = graph._ensureNode(`doc:${docIndex}`);
graph.addEdge(srcId, relations[relId], dstId);
edgePairs.push({ srcId, dstId, relId });
}
const buildTime = performance.now() - buildStart;
graph.finalizePerfectHash();
graph.finalizeWaveletAdjacency({ dropAdjacencyList: true });
const snapshot = graph.toBinary();
const snapshotPath = path.join(output, 'snapshot.bin');
fs.mkdirSync(output, { recursive: true });
fs.writeFileSync(snapshotPath, new Uint8Array(snapshot));
const shardStart = performance.now();
const builder = new ShardedSnapshotBuilder({ bucketSize, includeDirections: ['out'] });
const manifest = builder.build(graph, output);
const shardTime = performance.now() - shardStart;
const storage = new FileShardStorage(output);
const sharded = new ShardedSnapshot(manifest, storage, { cacheLimit: 8 });
sharded.initializeSync();
const srcIds = Array.from({ length: users }, (_, i) => i);
const dstIds = Array.from({ length: docs }, (_, i) => i + users);
const findStart = performance.now();
let hits = 0;
for (let i = 0; i < samples; i++) {
const pair = edgePairs[i % edgePairs.length];
const srcId = pair.srcId;
const dstId = pair.dstId;
const relId = pair.relId;
const edge = sharded.findEdgeSync(srcId, relId, dstId);
if (edge) hits++;
}
const findTime = performance.now() - findStart;
const outStart = performance.now();
let outEdges = 0;
for (let i = 0; i < samples; i++) {
const srcId = srcIds[i % srcIds.length];
const relId = i % 3;
const edgesOut = sharded.getOutEdgesSync(srcId, relId);
outEdges += edgesOut.length;
}
const outTime = performance.now() - outStart;
console.log('\nResults');
console.log(` build time: ${buildTime.toFixed(2)} ms`);
console.log(` shard time: ${shardTime.toFixed(2)} ms`);
console.log(` shards: ${manifest.shards.length}`);
console.log(` snapshot size: ${(snapshot.byteLength / 1024 / 1024).toFixed(2)} MB`);
console.log(` findEdge avg: ${(findTime / samples * 1000).toFixed(3)} µs`);
console.log(` getOutEdges avg: ${(outTime / samples * 1000).toFixed(3)} µs`);
console.log(` hits: ${hits}`);
console.log(` outEdges: ${outEdges}`);