/** * Replay oracle (Bottom-Up hard gate: "replay the same fixture twice and prove * no duplicate business state"). Ingests a fixture, counts, ingests it AGAIN, * counts again. The caller asserts: same interaction id, unchanged count. * * The `ingest` function the caller supplies must derive its idempotency key * deterministically from the fixture (e.g. its providerEventId) so the second * run is a true duplicate. */ export interface ReplayResult { firstId: string; secondId: string; countAfterFirst: number; countAfterSecond: number; } export async function replayTwice( fixture: F, ingest: (f: F) => Promise<{ interactionId: string }>, countInteractions: () => Promise, ): Promise { const first = await ingest(fixture); const countAfterFirst = await countInteractions(); const second = await ingest(fixture); const countAfterSecond = await countInteractions(); return { firstId: first.interactionId, secondId: second.interactionId, countAfterFirst, countAfterSecond, }; } /** Convenience predicate: true when a replay produced no new business state. */ export function isIdempotent(r: ReplayResult): boolean { return r.firstId === r.secondId && r.countAfterFirst === r.countAfterSecond; }