import type { CartographerTree } from './CartographerTree.js';
import type { PressureReading } from '../monitoring/SessionReaper.js';
import { type LastDetectStatus } from './cartographerDetect.js';
export declare const CARTOGRAPHER_SWEEP_COMPONENT = "CartographerSweep";
/**
 * Slice 3 (fix instar#1069): resolve the sweep's effective routing framework +
 * its source, EXPLICIT-SET-ONLY. Precedence: an explicit
 * overrides.CartographerSweep wins; else an explicitly-configured categories.job
 * wins (migration safety — never silently override an operator's choice); else
 * cartographer.freshnessSweep.framework becomes the effective override (the
 * off-Claude knob the field was always meant to be); else the router default.
 * `injectOverride` tells the caller to write overrides.CartographerSweep so BOTH
 * the routing probe AND the author call resolve consistently. Pure → unit-tested.
 */
export declare function resolveSweepFrameworkRouting(cf: {
    overrides?: Record<string, string>;
    categories?: Record<string, string>;
} | undefined, freshnessSweepFramework: string | undefined): {
    framework: string | undefined;
    source: 'overrides.CartographerSweep' | 'categories.job' | 'freshnessSweep.framework' | 'default';
    injectOverride: boolean;
};
export interface SweepEngineConfig {
    maxNodesPerPass: number;
    maxCentsPerPass: number;
    estCentsPerAuthor: number;
    maxLeafBytes: number;
    minSummaryChars: number;
    maxSummaryChars: number;
    /** Whether an author call resolving to the default (Claude) framework is allowed. Default false. */
    allowClaudeFallback: boolean;
    nodeFailQuarantineThreshold: number;
    maxDeferredPasses: number;
    revalidateSamplePerPass: number;
    /** Curtailed node ceiling while CPU pressure is moderate. */
    minNodesUnderPressure: number;
    /** Run detect + index writes in a worker thread (default true). false = the SAME bounded pure module synchronously (operator escape hatch — never tree.staleNodes()). */
    detectInWorker?: boolean;
    /** Bound on the detect worker await; on timeout the worker is terminated + the pass refuses (default 120000). */
    detectTimeoutMs?: number;
    /** Worker V8 old-space cap, co-sized above maxIndexBytes×~6 parse expansion so the byte-guard ceiling stays parseable (default 1536). */
    detectWorkerHeapMb?: number;
    /** Pre-parse byte guard: refuse detect-index-too-large above this on-disk size (default 200MB; 200×6≈1200MB < heap). */
    maxIndexBytes?: number;
    /** Cap on the published stale sample in the snapshot (default 500). */
    snapshotSampleMax?: number;
    /** Explicit git ls-tree maxBuffer (default 64MB) so a big tree never throws ENOBUFS. */
    gitMaxBuffer?: number;
    /** Ordered-candidate headroom: maxCandidates = maxNodesPerPass × this (default 4). */
    detectCandidateHeadroom?: number;
    /** Grace window for the never-authored-past-grace split (default cadence×2 ≈ 1.2M ms). */
    detectGraceMs?: number;
}
export interface SweepRouterLike {
    readonly defaultFramework: string;
    for(component: string): {
        component: string;
        category: string;
        framework: string;
        available: boolean;
    };
    evaluate(prompt: string, opts: {
        attribution: {
            component: string;
            category: string;
        };
        model?: string;
    }): Promise<string>;
}
export declare class SweepAbortedError extends Error {
    constructor();
}
export interface SweepLlmQueueLike {
    enqueue(lane: 'interactive' | 'background', fn: (signal: AbortSignal) => Promise<string>, costCents?: number): Promise<string>;
}
export interface SweepEngineDeps {
    tree: CartographerTree;
    router: SweepRouterLike;
    llmQueue: SweepLlmQueueLike;
    /** Re-sampled between author calls; the curtail/break signal. */
    pressure: () => PressureReading;
    /** Author ONLY when this returns true (lease holder). Single-machine ⇒ () => true. */
    holdsLease: () => boolean;
    config: SweepEngineConfig;
    stateDir: string;
    now?: () => number;
    log?: (msg: string) => void;
    /** Optional: thrown by the queue when a higher-priority lane preempts a background call. */
    isAbortError?: (err: unknown) => boolean;
}
export interface SweepPassResult {
    /** False when this machine is not the lease holder OR the routing probe refused. */
    ranAuthorPath: boolean;
    refused: boolean;
    refusalReason?: string;
    candidateCount: number;
    authored: number;
    fingerprintRefreshed: number;
    failed: number;
    quarantined: number;
    deferred: number;
    skipped: number;
    contentExcluded: number;
    revalidated: number;
    /** Candidates left unauthored this pass because a per-pass cap bound first. */
    remaining: number;
    centsSpent: number;
    abortedBackpressure: boolean;
    reason: string;
    /** fix instar#1069: measured detect wall-clock (poller early-warns at 50% of detectTimeoutMs). */
    detectDurationMs?: number;
    /** fix instar#1069: detect health for the snapshot + poller. */
    detectStatus?: LastDetectStatus;
}
export declare class CartographerSweepEngine {
    private readonly d;
    private readonly now;
    private readonly log;
    /** Engine-level single-flight: one in-flight pass / one detect worker at a time. */
    private inflight;
    constructor(deps: SweepEngineDeps);
    /**
     * Probe the effective routing for the sweep. Refuses (returns a reason) when the
     * resolved framework IS the default (Claude) framework — meaning off-Claude
     * routing isn't configured — or when the resolved non-default framework's binary
     * is unavailable. `available` is reported true when framework === default, so the
     * refusal tests the FRAMEWORK field, not `available` alone.
     */
    probeRouting(): {
        ok: true;
        framework: string;
    } | {
        ok: false;
        reason: string;
        framework: string;
    };
    runPass(): Promise<SweepPassResult>;
    private runPassInner;
    private detectInput;
    /** Run detect off-thread (worker) or synchronously (rollback) — SAME bounded module. */
    private detect;
    private refusedDetect;
    /** Apply the pass's batched summary deltas off-thread (worker) or synchronously (rollback). */
    private applyDeltas;
    private detectStatus;
    /** Persist (or update) the per-host snapshot every /cartographer/* read route serves from. */
    private persistSnapshot;
    /** Minimal env allowlist for a spawned worker — NEVER the parent process.env. */
    private workerEnv;
    /** Spawn the detect/write worker, await its single message, bound by detectTimeoutMs. */
    private runWorker;
    private authorNode;
    private persistAuthored;
    private callAuthor;
    private revalidateSample;
    /** Record one author failure; returns true if the node just crossed into quarantine. */
    private recordFailure;
    private buildLeafPrompt;
    private buildDirPrompt;
    private cursorPath;
    private loadCursor;
    private checkpoint;
    private clearCursor;
    private isAbort;
}
//# sourceMappingURL=CartographerSweepEngine.d.ts.map