/** * Post-hoc reconciliation: `aidlc cost sync` (FR4). * * Correlates platform usage records with instances via sessions.ndjson. * Platform-id sessions match records by id equality; agent-id sessions * match by interval overlap with a strict single-candidate rule. Appends * `reconciled` entries only where coverage is not already held at equal or * higher fidelity. Idempotent by construction; never guesses โ€” ambiguity * goes to the report, unattributable usage to unattributed.ndjson. * * Design: design.md ยง4.4 */ import { type ProviderEnv } from './providers/provider.js'; export interface SyncReport { attributed: number; skipped: string[]; unattributed: number; /** Records captured for the first time from local provider records (FR4.5). */ backfilled: number; /** Records moved out of unattributed.ndjson into an instance ledger (FR4.6). */ recovered: number; /** Records left unattributed because several instances could claim them. */ stillAmbiguous: number; /** Records left unattributed because no claim window covers them. */ stillOrphaned: number; /** Records no pass could append, and why (cost-sync-silent-rejections/AC-4). */ rejected: SyncRejections; } export interface SyncRejections { /** Records the ledger's schema refused, keyed by `validateEntry`'s reason. */ invalid: Record; /** Records that could not be written, keyed by system error code, or `unknown`. */ unwritable: Record; } /** * What a failed write is reported as: its system error code, or `unknown`. Never the * message, which names the ledger's path (SR1, cost-sync-silent-rejections/AC-3). */ export declare function writeFailureCode(err: unknown): string; /** * The summary lines for what sync could not append: one per distinct reason, the * largest count first and ties by reason so the order is stable. Empty when nothing * was refused, so a clean run prints exactly what it always did * (cost-sync-silent-rejections/AC-2, AC-9). */ export declare function rejectionLines(rejected: SyncRejections): string[]; /** * Reconcile one or all instances. Streams platform records session by * session; reports everything it skipped and why (FR4.3). */ export declare function syncCosts(projectRoot: string, instanceFilter: string | null, claimTimeoutMinutes: number, env?: ProviderEnv): Promise; /** * Local claude-code transcripts **belonging to this repository**. * * The scoping is load-bearing, not defensive. `transcriptRoot` is a single * directory holding every project this machine has ever worked on โ€” 12 of them * here, including unrelated repositories. Walking all of them and attributing by * time would charge this project for work done elsewhere whenever an unrelated * session happened to overlap a claim window. That is a worse failure than the one * being fixed: a wrong number is harder to notice than a missing one. * * Identity is the git common dir, so every worktree of this repo counts as this * repo and nothing else does. A transcript whose cwd no longer exists is skipped โ€” * under-recovering is the safe direction. */ export declare function projectClaudeCodeRecords(projectRoot: string, env: ProviderEnv): Array<{ sessionId: string; path: string; }>; //# sourceMappingURL=sync.d.ts.map