/**
 * keyedFold — the value of ONE state key at one commit, folded from the run's
 * own fold base.
 *
 * Role:  Fold. It reads a finished run's commit log plus the base that log
 *        was recorded against, and answers "what was `key` at commit `idx`?"
 *        It executes nothing, records nothing and stores nothing beside the
 *        log. Its answers are DETACHED — deep-frozen before they are cached,
 *        because a memo that hands out live references is a fold that lets a
 *        reader rewrite the run (`keyedFold.ts` · `freezeDeep`).
 * Reads: a `FoldSource` — a snapshot (`commitLog` + `initialState`) or a
 *        subflow subtree (`history` + `initialState`), through footprintjs's
 *        own `stateAt` (for the base) and `applySmartMerge` (for the replay).
 * Emits: N/A.
 *
 * ── WHY THIS FILE EXISTS ───────────────────────────────────────────────────
 * A commit log stores DIFFS. `commitValueAt` folds them for one key and says
 * so in its own docstring: a value that came from the run's INITIAL state and
 * was never `set` again folds to ABSENT, because the log alone cannot see the
 * pre-run base.
 *
 * That is not an edge case here. A RESUMED agent run is a fresh executor
 * seeded from `checkpoint.sharedState`, so the entire pre-pause world —
 * `systemPromptInjections`, `history`, `dynamicToolSchemas`, every build-time
 * constant `seed` wrote before the pause — is base, not log. Folding the
 * resumed run with `commitValueAt` returns an empty system prompt and a
 * truncated conversation and declares no gap: a confident falsehood about the
 * one question this family exists to answer. footprintjs 9.17 shipped
 * `RuntimeSnapshot.initialState` and `stateAt` for exactly this, and every
 * read in `epochs.ts` goes through here so it lands on that base.
 *
 * ── WHY NOT JUST CALL `stateAt` PER READ ───────────────────────────────────
 * `stateAt` folds the WHOLE state, and it clones that state once per bundle
 * (`applySmartMerge` opens with a `structuredClone` of its base). One fold is
 * therefore O(commits × state size) — measured on a real 100-turn agent
 * (1,719 commits, 101 epochs): 323 ms for a single fold, and 11.7 s to fold
 * once per epoch, against 78 ms for the whole per-epoch scrub before this
 * release. A per-epoch reader cannot pay that.
 *
 * So `stateAt` is used for the ONE thing only it can give — the fold base and
 * the honest `basis` verdict, at `commitIdx: -1`, where it folds nothing and
 * clones the base once — and the forward replay is done per key, through
 * footprintjs's own `applySmartMerge`. There is deliberately no second
 * implementation of the trace verbs here: every `set` / `append` / `merge` /
 * `delete` is applied by the same function the live commit uses.
 * `keyed-fold-equivalence.test.ts` pins the result against `stateAt` itself on
 * real runs, including a resumed one and a merge with no `set` anchor — the
 * one shape that cannot be folded at all without the base.
 */
import type { CommitBundle } from 'foottrace';
/**
 * How a fold was derived — footprintjs's own two answers, restated here so a
 * caller of this module does not have to import the engine's trace barrel to
 * name them.
 *
 * - `'initial+log'` — the recording carried its fold base, so a value seeded
 *   before the run (or before a resume) folds correctly.
 * - `'log-only'` — it did not. Anything the log never `set` reads as absent,
 *   and a reader must say so rather than present the hole as a proof.
 */
export type FoldBasis = 'initial+log' | 'log-only';
/**
 * Anything that carries a commit log and, ideally, the base it was recorded
 * against — the two field spellings footprintjs already has: `commitLog` on a
 * run snapshot, `history` on a subflow subtree.
 */
export interface FoldSourceLike {
    readonly commitLog?: readonly CommitBundle[];
    readonly history?: readonly unknown[];
    readonly initialState?: Record<string, unknown>;
}
/**
 * One key's value at one commit — the question, and the answers already
 * computed for it.
 */
export interface KeyedFold {
    /** How this fold was derived — see {@link FoldBasis}. */
    readonly basis: FoldBasis;
    /** How many bundles the log holds. */
    readonly length: number;
    /**
     * The value of `key` folded through commit ARRAY INDEX `idx`, inclusive.
     * `-1` (or lower) folds nothing and returns the base's value — the state
     * before the log's first commit.
     *
     * DEEP-FROZEN, and the same object on every call for the same question. It
     * is detached from the engine's own bundles AND unmutable, so a caller
     * cannot rewrite what a later index folds to — `keyedFold.ts` · `freezeDeep`
     * says why that is a law here rather than a courtesy. Copy it
     * (`structuredClone`, a spread) if you need something to edit.
     */
    valueAt(key: string, idx: number): unknown;
}
/**
 * The keyed fold for one source, memoized on the source object.
 *
 * Memoized because a per-epoch reader asks the same source for the same keys
 * at many different commits, and the index is the expensive half: building it
 * is one pass over the log, and answering a read afterwards is a binary search
 * plus a replay from the nearest full-value write (normally exactly one).
 *
 * @example
 * ```ts
 * import { keyedFold } from 'agentfootprint';
 *
 * const fold = keyedFold(agent.getSnapshot());
 * fold.basis;                      // 'initial+log' — the base travelled
 * fold.valueAt('history', 12);     // the conversation after the 13th commit
 * fold.valueAt('history', -1);     // …and what the run STARTED from
 * ```
 */
export declare function keyedFold(source: FoldSourceLike | undefined): KeyedFold;
//# sourceMappingURL=keyedFold.d.ts.map