/** * Append-only record of what each send actually achieved, written after the * \Sent read-back has returned. * * This is deliberately not an intent line. "Filed to Sent" written before the * read-back would be the same unverified claim the model was already making, * relocated into a log where it is harder to challenge (Task 1822). Every row * here states an observed outcome. * * It exists because nothing else records that a send happened at all — SMTP * diags only on failure — so the standing sweep had no left-hand side to * reconcile \Sent against. */ export interface SentLedgerEntry { at: string; accountId: string; mailbox: string; messageId: string; copy: "found" | "not-in-sent" | "no-sent-folder" | "check-failed"; sentFolder?: string; sentUid?: number; } export declare function ledgerPath(): string; /** * Append one row. Pure append, never read-modify-write. * * Two sends completing together would otherwise interleave read/read/write/ * write and silently drop a row, which would show up later as a phantom * shortfall. O_APPEND keeps concurrent single-line writes from tearing. * Trimming is the sweep's job — see pruneSentLedger. */ export declare function appendSentLedger(entry: SentLedgerEntry): void; /** * Drop rows past the retention window. * * Called once per sweep run, from the sweep's own single process, rather than * on every send: rewriting the file is the one operation that can lose a * concurrent append, so it happens as rarely as possible and never on the send * path. A send landing inside the rewrite window loses at most its own * observability row, never the mail. */ export declare function pruneSentLedger(): void; export declare function readSentLedger(sinceMs: number): SentLedgerEntry[]; //# sourceMappingURL=sent-ledger.d.ts.map