/** * 📜 ROLLING PROVENANCE — a constant-size, tamper-evident audit trail for a 24/7 run. * * Melete's signed trace is wonderful for one discovery. But run it as a Background Service that re-tunes a * solar grid or an LLM-serving config around the clock, and a naive "log every decision" trail grows without * bound — the customer's disk fills, memory bloats, and the snapshot you'd hand an auditor becomes gigabytes. * * ROLLING PROVENANCE keeps the WHOLE history verifiable while the SNAPSHOT stays O(1): * • Each event is recorded by its content HASH (sha256) — provenance WITHOUT exposing the raw config/secret. * • The most recent W events are kept in full (a sliding window you can read directly). * • Everything older is folded into ONE hash-chain accumulator: root ← sha256(root ∥ eventHash). The chain is * order-dependent and collision-resistant, so altering, reordering, inserting or dropping ANY past event * changes the root — detectable forever, even though that event is no longer stored. * • The checkpoint (root + window + count) is Ed25519-signed, so a third party verifies it OFFLINE with the * embedded public key — no Melete, no network, no shared secret. * * Honest by construction (DIAKRISIS): this is a Merkle/hash-chain accumulator + sliding window + signature — * the achievable, real version of "O(1) provenance". It is NOT a zk-SNARK and makes NO zero-knowledge claim * beyond "binds by hash" (the auditor re-checks the root against the full event stream they hold; the snapshot * alone proves integrity + size-boundedness, not the hidden contents). The gauntlet proves: snapshot size is * constant as the run grows to 100k events; tampering at ANY position is detected (measured at 100%); * append-one-by-one equals build-from-scratch; the signature verifies offline and breaks under tampering. */ import { type KeyObject } from "node:crypto"; export interface ProvFrame { seq: number; kind: string; contentHash: string; } /** One event to record. `payload` is hashed (never stored raw); pass `contentHash` directly if you pre-hashed. */ export interface ProvEvent { kind: string; payload?: unknown; contentHash?: string; } export interface ProvCheckpoint { standard: "melete-provenance/v1"; count: number; windowSize: number; foldedRoot: string; window: ProvFrame[]; signature?: string; publicKeyPem?: string; algo?: "ed25519+sha256"; } /** Start an empty rolling log. */ export declare function emptyCheckpoint(windowSize?: number): ProvCheckpoint; /** Append ONE event, returning a new checkpoint of BOUNDED size (the oldest in-window frame folds into the root). */ export declare function appendEvent(cp: ProvCheckpoint, e: ProvEvent): ProvCheckpoint; /** Build a checkpoint from a full event list (equivalent to appending them one by one). */ export declare function buildCheckpoint(events: ReadonlyArray, windowSize?: number): ProvCheckpoint; /** Re-derive the expected (root, window, count) from the FULL event stream and compare to a checkpoint. */ export declare function verifyAgainst(cp: ProvCheckpoint, fullEvents: ReadonlyArray): { ok: boolean; reason: string; }; /** Ed25519-sign a checkpoint (offline-verifiable). */ export declare function signCheckpoint(cp: ProvCheckpoint, keys?: { publicKey: KeyObject; privateKey: KeyObject; }): ProvCheckpoint; /** Verify a signed checkpoint's signature OFFLINE (no stream needed) using its embedded public key. */ export declare function verifyCheckpointSignature(cp: ProvCheckpoint): { ok: boolean; reason: string; }; /** Bytes of the serialized checkpoint — for the O(1)-size claim. */ export declare function checkpointSize(cp: ProvCheckpoint): number; export declare function provenanceGauntlet(): { score: 0 | 100; checks: Array<{ name: string; pass: boolean; detail: string; }>; }; //# sourceMappingURL=provenance.d.ts.map