/** * @module tests/integration/txlog-origin-and-reconcile * @description Two consumer-driven cures, pinned together because they share * the origin stamp: * * 1. TX-LOG ORIGIN — engine-originated commits stamp `origin` on their * tx-log entry (and the commit fact's meta) so activity feeds filter on * fact: a downstream feed showed a "double tick" because the deferred * vector-landing commit was indistinguishable from a user save, and the * consumer rightly refused a time-window collapse as a quiet loss. User * writes stay UNSTAMPED (absent origin) — the pre-existing reading of * every consumer is exact. * * 2. THE RECONCILE DOOR — `log-live-canonical-absent` refuses auto-cure by * design (a legitimate lost-tombstone deletion is indistinguishable from * canonical loss); `reconcileLogDivergence(id, {attest})` is the human's * door: 'deleted' mints the missing tombstone, 'restore' folds the log's * copy back, wrong-class calls refuse typed with nothing written. */ import { describe, it, expect, afterEach } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { Brainy } from '../../src/index.js' import { NounType } from '../../src/types/graphTypes.js' type RawBox = { storage: { readNounRaw(id: string): Promise<{ metadata: unknown; vector: unknown }> writeNounRaw(id: string, r: { metadata: unknown; vector: unknown }): Promise } } const dirs: string[] = [] const brains: Brainy[] = [] afterEach(async () => { for (const b of brains.splice(0)) await b.close().catch(() => {}) for (const d of dirs.splice(0)) rmSync(d, { recursive: true, force: true }) }) async function fsBrain(): Promise { const dir = mkdtempSync(join(tmpdir(), 'brainy-origin-reconcile-')) dirs.push(dir) const brain = new Brainy({ storage: { type: 'filesystem', path: dir }, requireSubtype: false }) await brain.init() brains.push(brain) return brain } describe('tx-log origin stamp', () => { it('the deferred-embed landing commit is stamped system:embed-landing; the user write is not', async () => { const brain = await fsBrain() await brain.add({ data: 'a row whose vector lands later', type: NounType.Document, metadata: { k: 1 }, deferEmbedding: true }) await brain.awaitPendingEmbeds() await brain.flush() const entries = await brain.transactionLog() const system = entries.filter((e) => (e as { origin?: string }).origin === 'system:embed-landing') const user = entries.filter((e) => !(e as { origin?: string }).origin) expect(system.length, 'the landing commit is stamped').toBeGreaterThanOrEqual(1) expect(user.length, 'the user add stays unstamped').toBeGreaterThanOrEqual(1) // The feed cure in one line: filtering !origin removes the double tick. expect(user.length).toBeLessThan(entries.length) }, 120000) }) describe('reconcileLogDivergence — the attested door', () => { /** Manufacture the class: a live log record whose canonical row is gone. */ async function manufactureDivergence(brain: Brainy): Promise { const id = await brain.add({ data: 'pre-era row whose deletion the log never saw', type: NounType.Document, metadata: { era: 'pre-spine' } }) await brain.flush() // Delete canonical BEHIND the log's back (raw write, no generation) — // exactly the shape a deferred-durability-era crash left behind. const storage = (brain as unknown as RawBox).storage await storage.writeNounRaw(id, { metadata: null, vector: null }) return id } it("attest:'deleted' mints the missing tombstone — the oracle goes green and the commit is stamped system:reconcile", async () => { const brain = await fsBrain() const id = await manufactureDivergence(brain) const before = await brain.verifyLogAuthority() expect( before.mismatches.some((m) => m.id === id && m.reason === 'log-live-canonical-absent'), 'the manufactured divergence is oracle-visible as the refused class' ).toBe(true) const result = await brain.reconcileLogDivergence(id, { attest: 'deleted' }) expect(result.reconciled).toBe('tombstoned') const after = await brain.verifyLogAuthority() expect(after.mismatches.some((m) => m.id === id), 'the id no longer diverges').toBe(false) expect(await brain.get(id), 'canonical stays absent').toBeNull() await brain.flush() const entries = await brain.transactionLog() expect( entries.some((e) => (e as { origin?: string }).origin === 'system:reconcile'), 'the reconcile commit is origin-stamped' ).toBe(true) }, 120000) it("attest:'restore' folds the log's copy back into canonical", async () => { const brain = await fsBrain() const id = await manufactureDivergence(brain) const result = await brain.reconcileLogDivergence(id, { attest: 'restore' }) expect(result.reconciled).toBe('restored') const row = await brain.get(id) expect(row, 'the log’s only copy lives again').not.toBeNull() expect((row!.metadata as { era: string }).era).toBe('pre-spine') expect((await brain.verifyLogAuthority()).mismatches.some((m) => m.id === id)).toBe(false) }, 120000) it('wrong-class calls refuse typed with nothing written', async () => { const brain = await fsBrain() const id = await brain.add({ data: 'healthy row', type: NounType.Document, metadata: { n: 1 } }) await brain.flush() // Canonical present + log agrees: not the class — refuse, name the state. await expect(brain.reconcileLogDivergence(id, { attest: 'deleted' })).rejects.toThrow( /canonical is PRESENT/ ) expect(await brain.get(id), 'nothing was written').not.toBeNull() // Unknown id: no log record at all — refuse, name it. await expect( brain.reconcileLogDivergence('00000000-0000-7000-8000-00000000dead', { attest: 'restore' }) ).rejects.toThrow(/no record at all/) }, 120000) })