import type { FileCacheMixin } from '../cache/file/mixin.ts';
import type { Evicted } from '../cache/index/config.ts';
import { FileStat } from '../types.ts';
import { BaseVFS } from '../vfs/base.ts';
import type { MountEntry } from './mount/mount.ts';
import type { Namespace } from './mount/namespace/namespace.ts';
/**
 * Keep the local view honest against backend truth.
 *
 * The single reconcile point every read path shares. Under a mount's
 * `read: fresh` a backend re-stat classifies a path as fresh, stale
 * (fingerprint mismatch), gone
 * (deletion), or unknown (no fingerprint to compare). One deletion signal
 * feeds both consumers with separate reactions: the file cache evicts and the
 * namespace GCs any orphaned attribute overlay.
 *
 * Three read paths call in, all at the dispatcher: its cached-read gate
 * (mayServeCached), its main-op catch (onEnoent), and its first lookup of a
 * path the running command's line names (reconcileRead). The re-stat goes
 * through the ops registry (not mount.call, whose op set omits stat).
 * Reconcile state follows each consumer's store (RAM local, Redis shared
 * across runtimes), so this is a thin coordinator holding references, not
 * config.
 *
 * The gate and reconcileRead both run for a warm named operand, once at the
 * command's first lookup of it and again at the gate, and they share one
 * scope: the command. The
 * first probe's backend answer is kept on the mount's CacheManager for the
 * rest of the command, so the gate, and the command's own stat of the
 * operand, reuse it instead of asking again. A write in the command, the
 * clear after an external program, or a re-list that finds the path gone
 * retires it, and a read outside any command (FUSE, the dispatcher) never sees
 * it.
 */
export declare class Reconciler {
    private readonly cache;
    private readonly namespace;
    constructor(cache: FileCacheMixin & BaseVFS, namespace: Namespace);
    private drop;
    private probe;
    private probeOrUnknown;
    mayServeCached(mount: MountEntry, path: string): Promise<boolean>;
    /**
     * Gate a cached listing: may it be served without re-listing?
     *
     * Under `bounded` the listing is trusted within its bound. Under `fresh` a
     * listing the running command fetched itself is served (a read outside any
     * command trusts one fetched within the last `LISTING_TRUST_WINDOW`
     * seconds instead, `CacheManager.listingTrusted`). Past that, a listing
     * stored at the mount's pin is served without asking: github pins a
     * full-sha ref and serves its listing unchecked when the stored version
     * equals that sha. It names a commit: github.com refuses a 40- or 64-hex
     * branch or tag name, and a GitHub Enterprise host is assumed to as well
     * (`pinOf` in vfs/github/github.ts). A mount that declares a
     * `listingVersion` then has its stored `version` checked against a stat of
     * the mount root (MOUNT) or of the folder (FOLDER), sent through a
     * throwaway index so no cached row answers it. One check answers for a
     * whole command, and concurrent callers share it
     * (`CacheManager.checkedVersion`).
     *
     * A match serves the listing. Anything else answers EXPIRED and keeps the
     * listing stored for the re-list to diff: a moved version, a path the
     * backend no longer has, a stat with no fingerprint, a mount with no stat
     * at all, and a backend that cannot answer, which is logged. The index is
     * never cleared here. A programming error propagates.
     */
    mayServeListing(mount: MountEntry, folder: string, version: string | null): Promise<boolean>;
    private listingFingerprint;
    reconcileRead(mount: MountEntry, path: string): Promise<void>;
    onEnoent(mount: MountEntry, name: string, path: string, err: unknown): Promise<void>;
    onFreshStat(mount: MountEntry, path: string, row: FileStat | null): Promise<void>;
    onGone(gone: readonly Evicted[], excluded?: readonly string[]): Promise<void>;
    private onMissing;
}
//# sourceMappingURL=reconcile.d.ts.map