@claude-flow/embeddings
Version:
V3 Embedding Service - OpenAI, Transformers.js, Agentic-Flow (ONNX), Mock providers with hyperbolic embeddings, normalization, and chunking
233 lines (211 loc) • 7.87 kB
text/typescript
/**
* ADR-121 Phase 18 — Witness ledger (chain) tests.
*
* Covers:
* - Empty ledger verifies as valid (zero entries, zero failures)
* - Single-entry chain (genesis with prevContentHash=null)
* - Multi-entry chain — sequence + prev-hash linkage
* - Tamper detection at every position (genesis, middle, tail)
* - Sequence mismatch detection
* - Wrong version rejected
* - Verification result reports the FIRST failure position
* - Same signer key carries across appends
*/
import { describe, it, expect } from 'vitest';
import {
appendToLedger,
verifyEntry,
verifyLedger,
generateLedgerKeypair,
type BenchmarkLedger,
} from '../witness-ledger.js';
function input(name: string, ts: string, results: unknown) {
return {
benchmark: name,
timestamp: ts,
commit: `commit-${name}`,
model: 'test-model',
corpus: { id: 'fp-corpus', size: 10 },
queries: { id: 'fp-queries', count: 3 },
results,
};
}
describe('appendToLedger — chain construction', () => {
it('initializes a fresh ledger with a single genesis entry', () => {
const { ledger, entry } = appendToLedger(undefined, input('b1', '2026-01-01T00:00:00Z', { recall: 0.5 }));
expect(ledger.version).toBe(1);
expect(ledger.entries.length).toBe(1);
expect(entry.sequence).toBe(1);
expect(entry.prevContentHash).toBeNull();
});
it('chains a second entry to the genesis', () => {
const kp = generateLedgerKeypair();
const { ledger: l1, entry: e1 } = appendToLedger(undefined, input('b1', '2026-01-01T00:00:00Z', { recall: 0.5 }), kp);
const { ledger: l2, entry: e2 } = appendToLedger(l1, input('b2', '2026-01-02T00:00:00Z', { recall: 0.7 }), kp);
expect(l2.entries.length).toBe(2);
expect(e2.sequence).toBe(2);
expect(e2.prevContentHash).toBe(e1.contentHash);
});
it('three-entry chain has correct sequence + links', () => {
const kp = generateLedgerKeypair();
let ledger: BenchmarkLedger | undefined;
const hashes: string[] = [];
for (let i = 0; i < 3; i++) {
const result = appendToLedger(ledger, input(`b${i}`, `2026-01-0${i + 1}T00:00:00Z`, { i }), kp);
ledger = result.ledger;
hashes.push(result.entry.contentHash);
}
expect(ledger!.entries.length).toBe(3);
expect(ledger!.entries[0]!.prevContentHash).toBeNull();
expect(ledger!.entries[1]!.prevContentHash).toBe(hashes[0]);
expect(ledger!.entries[2]!.prevContentHash).toBe(hashes[1]);
expect(ledger!.entries.map(e => e.sequence)).toEqual([1, 2, 3]);
});
it('same keypair → same publicKey on every entry', () => {
const kp = generateLedgerKeypair();
let ledger: BenchmarkLedger | undefined;
const pubs: string[] = [];
for (let i = 0; i < 3; i++) {
const r = appendToLedger(ledger, input(`b${i}`, `2026-01-0${i + 1}T00:00:00Z`, { i }), kp);
ledger = r.ledger;
pubs.push(r.entry.publicKey);
}
expect(new Set(pubs).size).toBe(1);
});
it('no keypair → fresh ephemeral key per entry (different publicKeys)', () => {
let ledger: BenchmarkLedger | undefined;
const pubs: string[] = [];
for (let i = 0; i < 3; i++) {
const r = appendToLedger(ledger, input(`b${i}`, `2026-01-0${i + 1}T00:00:00Z`, { i }));
ledger = r.ledger;
pubs.push(r.entry.publicKey);
}
expect(new Set(pubs).size).toBe(3);
});
});
describe('verifyLedger — happy path', () => {
it('empty ledger is valid', () => {
const result = verifyLedger({ version: 1, entries: [] });
expect(result.valid).toBe(true);
expect(result.entryCount).toBe(0);
expect(result.firstFailureAt).toBe(-1);
});
it('single-entry chain verifies', () => {
const { ledger } = appendToLedger(undefined, input('b1', '2026-01-01T00:00:00Z', { r: 1 }));
const result = verifyLedger(ledger);
expect(result.valid).toBe(true);
expect(result.entryCount).toBe(1);
});
it('multi-entry chain verifies', () => {
const kp = generateLedgerKeypair();
let ledger: BenchmarkLedger | undefined;
for (let i = 0; i < 5; i++) {
ledger = appendToLedger(ledger, input(`b${i}`, `2026-01-0${i + 1}T00:00:00Z`, { i }), kp).ledger;
}
const result = verifyLedger(ledger!);
expect(result.valid).toBe(true);
expect(result.entryCount).toBe(5);
});
it('unknown version rejected', () => {
const result = verifyLedger({ version: 99 } as unknown as BenchmarkLedger);
expect(result.valid).toBe(false);
expect(result.reason).toMatch(/version/);
});
});
describe('verifyLedger — tamper detection', () => {
function buildChain(n: number): BenchmarkLedger {
const kp = generateLedgerKeypair();
let ledger: BenchmarkLedger | undefined;
for (let i = 0; i < n; i++) {
ledger = appendToLedger(ledger, input(`b${i}`, `2026-01-0${i + 1}T00:00:00Z`, { i }), kp).ledger;
}
return ledger!;
}
it('detects tampering at the genesis entry', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [
{ ...ledger.entries[0]!, results: { i: 999 } }, // tamper genesis
ledger.entries[1]!,
ledger.entries[2]!,
],
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
expect(result.firstFailureAt).toBe(0);
});
it('detects tampering at a middle entry', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [
ledger.entries[0]!,
{ ...ledger.entries[1]!, results: { i: 999 } },
ledger.entries[2]!,
],
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
expect(result.firstFailureAt).toBe(1);
});
it('detects tampering at the tail entry', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [
ledger.entries[0]!,
ledger.entries[1]!,
{ ...ledger.entries[2]!, results: { i: 999 } },
],
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
expect(result.firstFailureAt).toBe(2);
});
it('detects removed entry (sequence mismatch)', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [ledger.entries[0]!, ledger.entries[2]!], // skip middle
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
// The first wrong entry is at index 1 (sequence expected 2, got 3 OR bad prevHash)
expect(result.firstFailureAt).toBe(1);
});
it('detects swapped entries', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [ledger.entries[1]!, ledger.entries[0]!, ledger.entries[2]!],
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
});
it('detects forged prevContentHash with otherwise valid signature', () => {
const ledger = buildChain(3);
const tampered: BenchmarkLedger = {
...ledger,
entries: [
ledger.entries[0]!,
{ ...ledger.entries[1]!, prevContentHash: 'ff'.repeat(32) },
ledger.entries[2]!,
],
};
const result = verifyLedger(tampered);
expect(result.valid).toBe(false);
expect(result.firstFailureAt).toBe(1);
});
});
describe('verifyEntry — single-entry signature check', () => {
it('valid entry verifies', () => {
const { entry } = appendToLedger(undefined, input('b1', '2026-01-01T00:00:00Z', { r: 1 }));
expect(verifyEntry(entry)).toBe(true);
});
it('tampered entry fails', () => {
const { entry } = appendToLedger(undefined, input('b1', '2026-01-01T00:00:00Z', { r: 1 }));
const tampered = { ...entry, results: { r: 999 } };
expect(verifyEntry(tampered)).toBe(false);
});
});