import type { CodeFileGuardrails } from '../parsers.js';
import type { BlobEntityCache } from './indexer.js';
import type { EntityBounds, EntityChangeFlags, EntityChangeType, EntityCounters, EntityRecord, LineageMatchReason } from './types.js';
/**
 * Attribution for entities the indexed window never saw.
 *
 * `blame` and `history` can only speak from lineage events, and those exist only
 * inside the indexed commit window. An entity whose last real change predates
 * the window therefore reported "no history" — an answer that is honest about
 * OCC and wrong about the repository, because the history is right there in git.
 *
 * The fix is a bounded, per-query walk rather than a larger index. Two
 * properties make it affordable enough to run by default:
 *
 * - Every entity in a file shares one path history, so a whole file's blame
 *   costs **one** walk, not one per entity.
 * - `git log --raw` carries both blob ids per commit, so the walk is one git
 *   invocation plus one batched blob read for the entire window.
 *
 * It is deliberately not a fallback that widens the index: nothing is cached,
 * nothing is written, and the cost is paid by the query that asked.
 */
/** How many commits touching a path a single walk-back will examine. */
export declare const ENTITY_WALK_BACK_COMMITS = 40;
/** One semantic change to one entity, found outside the indexed window. */
export interface WalkBackChange {
    commit: string;
    authorName: string;
    authorEmail: string;
    authoredAt: string;
    subject: string;
    changeType: EntityChangeType;
    flags: EntityChangeFlags;
    matchReason: LineageMatchReason;
    previousPath?: string;
    currentPath: string;
    previousName?: string;
    currentName: string;
}
export interface WalkBackResult {
    /** Semantic changes found, newest first, keyed by the entity's state key. */
    byEntity: Map<string, WalkBackChange[]>;
    /** How many commits the walk examined. */
    commitsScanned: number;
    /**
     * True when the walk stopped at its bound rather than at the beginning of the
     * path's history. The distinction is the whole point: it separates "there is
     * nothing older" from "we did not look further".
     */
    exhausted: boolean;
}
export interface WalkBackOptions {
    repoRoot: string;
    relativePath: string;
    /** Where to look back from; the working tree's HEAD unless a ref was asked for. */
    startRef?: string;
    /**
     * How many commits touching the path to examine. Defaults to
     * `ENTITY_WALK_BACK_COMMITS`, and is deliberately not wired to any caller's
     * display limit: how many entries a caller wants back is a different question
     * from how far git has to be searched to find them.
     */
    limit?: number;
    bounds?: EntityBounds;
    guardrails?: CodeFileGuardrails;
    cache?: BlobEntityCache;
    counters?: EntityCounters;
    signal?: AbortSignal;
}
/**
 * Every semantic change to every entity in a path, going back from a ref.
 *
 * Cosmetic edits and pure reorderings are recorded but not reported, for the
 * same reason blame skips them inside the window: "who last changed this" must
 * not answer with whoever most recently reformatted the file.
 */
export declare function walkBackAttribution(options: WalkBackOptions): Promise<WalkBackResult>;
/** The walk-back key for a live entity, so callers need not know how it is built. */
export declare function walkBackKeyFor(record: EntityRecord): string;
