/**
 * The Runner's session-scoped read-file-state CACHE and the licence to inherit from it: session-scoped cache
 * machinery, not a phase step — the Runner owns the instance for its lifetime, the run internals carry it to the
 * hands phase, and the hands phase adopts, inherits and seals seats through it.
 */
import type { ReadFileState } from "../../tools/fs/safety.js";
/**
 * The Runner's per-session read-file-state seats (CC parity: readFileState is minted
 * once per REPL session and mutated across turns; it has NO turn-boundary and NO abort clear site —
 * its only clears are compaction/fork/subagent-cleanup/dispose). sema's map stays per-task (the §11
 * ruling-A closure wiring), so the SESSION scope lives here instead: prepare adopts each task's live
 * map under its sessionId, and the next same-session, same-Runner task INHERITS it (through the same
 * containment judgment the transcript-replay seed applies — see `inheritSessionReadFileState`).
 *
 * This seat is a CACHE, never an authority:
 *  - a durable resume's checkpoint seed stays the sole authority on that leg (the seed was cut
 *    atomically with the leaf; this seat may be older OR newer than it);
 *  - a cross-process continuation misses here and falls back to the transcript replay (rung-2);
 *  - eviction (the LRU cap, a Runner restart) degrades to that same replay — never to wrong state.
 *
 * Bounded: an LRU over sessionIds (insertion-order refresh on read), because the SessionStore's own
 * eviction is not observable from here — a dropped seat costs one transcript replay, nothing else.
 * The stored value is the task's LIVE map (object identity), so in-turn mutations — tool write-backs,
 * and above all the compaction clear — are the seat's truth by construction; a snapshot copy
 * here would resurrect summarized-away reads on the next turn.
 *
 * BRANCH BINDING: a sessionId alone does not name a transcript — the same id
 * can be rebranched (`resumeAt`), rewound out-of-band, or DELETED and re-created (`release()` + the
 * default create-on-miss acquire), and the seat's map would then vouch for reads the CURRENT branch
 * never saw. Each seat therefore records `anchorLeafId` — a leaf on the lineage its task produced —
 * and inheritance must first prove the CURRENT branch still descends from that anchor
 * (see {@link sessionSeatAnchorHolds}). The anchor is written twice: at ADOPT (the leaf at prepare;
 * `null` when the branch was still empty) and SEALED at the task's settle to the task's own tail
 * (`reanchor`). A `null` anchor is NEVER inheritable ("the branch is non-empty now" proves
 * nothing about WHOSE messages those are — another Runner repopulating a released id, or a session
 * import, makes a non-empty branch that never contained this seat's reads). An unprovable anchor
 * falls back to the transcript replay, which reads the current branch by construction — cost, never
 * wrongness.
 */
export declare class SessionReadFileStates {
    private readonly seats;
    private static readonly CAP;
    /** The session's seat row, or undefined (cross-process / evicted / first turn) ⇒ caller replays.
     *  The caller must verify the anchor against the session's CURRENT branch before using `state`. */
    get(sessionId: string): {
        state: ReadFileState;
        anchorLeafId: string | null;
    } | undefined;
    /** Adopt THIS task's live map as the session's seat (every hands leg: fresh, continuation, resume).
     *  `anchorLeafId` = the session's leaf as read at THIS prepare (null = the branch was empty; a
     *  null-anchored seat is not inheritable until the settle-time {@link reanchor} names a real leaf). */
    adopt(sessionId: string, state: ReadFileState, anchorLeafId: string | null): void;
    /** The settle-time SEAL: re-anchor the seat to the finished task's own tail, so a
     *  first-task (null-anchor) seat becomes inheritable only through a leaf its task provably wrote.
     *  Identity-guarded: touches the row only while it still holds THIS task's map (a later prepare on
     *  the same session has already replaced the seat and owns its own anchor). */
    reanchor(sessionId: string, state: ReadFileState, anchorLeafId: string): void;
}
/**
 * Does the session's CURRENT branch still descend from the seat's anchor?
 * TRUE is the licence to inherit; anything unprovable answers FALSE (the caller then replays the
 * transcript — the fail-closed direction costs a rebuild, never admits a wrong entry).
 *
 *  - anchor `null`: NEVER inheritable (r2). The seat was adopted on an empty branch and its task
 *    never sealed (crashed pre-settle, or the leaf read failed) — "the branch is non-empty now"
 *    would also be true of a released-and-repopulated id or an imported log, whose messages are not
 *    this seat's lineage. The settle-time reanchor is what upgrades such a seat to a real leaf.
 *  - anchor non-null: holds iff walking parentIds from the current leaf reaches the anchor within
 *    a bounded number of steps (the walk length is one task's appends in the ordinary continuation).
 *    A rebranch/rewind moved the leaf OFF the anchor's subtree ⇒ the walk misses ⇒ no inherit; a
 *    recreated/foreign log does not contain the anchor ⇒ same answer; a re-IMPORT of the same log
 *    keeps the anchor's lineage ⇒ inheritance stays correct there by the same test.
 *  - a COMPACTION on the walked segment (A-082 idx2): refuses, even though the branch is perfectly
 *    intact. The walked segment is exactly what landed AFTER this seat was anchored, and a
 *    compaction there summarized older Read results OUT of the context the model will be shown —
 *    the very state the compaction clear removes from the live map at the landing site. That clear reaches the seat
 *    only when the SAME Runner did both (the seat IS that map, by object identity); a second Runner
 *    on the shared durable session clears its own map and commits the compaction as an ORDINARY
 *    LINEAR APPEND, which every other test here passes. Inheriting across it would let requireRead
 *    and checkStale both pass on a read whose card the model no longer has — a blind edit from a
 *    summarized-away recollection, the exact failure the compaction clear exists to prevent. Refusing
 *    costs one transcript replay, and the replay reads the POST-compaction branch by construction,
 *    so the fail-closed direction is also the CORRECT state. A compaction at or ABOVE the anchor is
 *    not on the walked segment and does not refuse: the seat that observed it already carries its
 *    clear (P-483-4), and an ordinary foreign turn with no compaction still inherits (G-483-5) —
 *    dropping every seat a foreign Runner touched would restore the cross-turn read-state amnesia this seat-anchor check already ended.
 */
export declare function sessionSeatAnchorHolds(getEntry: (id: string) => Promise<{
    parentId: string | null;
    type?: string;
} | null | undefined>, anchorLeafId: string | null, currentLeafId: string | null): Promise<boolean>;
