/**
 * Git-aware match — pairs prior-run identities with current-run
 * identities through the lens of `git diff baseSha headSha`.
 *
 * The line-bucket identity scheme used by code/secret/config/hygiene
 * findings tolerates ±2 lines of vertical drift. Anything past that
 * appears to a naive set-diff as "removed + added" even though
 * semantically the finding hasn't changed — it just moved with the
 * surrounding code. This module closes the gap.
 *
 * Algorithm:
 *
 *   1. Exact identity match — every finding present in both runs
 *      under the same fingerprint is `persisted` immediately.
 *
 *   2. For each finding in the `removed` set that carries a file +
 *      line locator: ask git to map its base-line through the diff
 *      to the corresponding head-line. If the `added` set contains
 *      a finding at the same `(file, rule, mappedLine)`, the two
 *      represent the same underlying issue moved by the diff —
 *      move both to `persisted`.
 *
 *   3. Whatever remains in `added` and `removed` is genuinely new
 *      or genuinely gone.
 *
 * Fallback: when git history is unavailable (no `.git`, baseSha not
 * reachable, file deleted, etc.) the module degrades to plain
 * set-diff matching — the same behavior `matchAcrossRuns` produces
 * on its own. Callers in shallow-clone CI or non-git workflows get
 * a working (if less precise) result.
 *
 * Known limitations (Sprint 0 v1):
 *   - File renames are not auto-tracked. A renamed file looks like
 *     "removed prior + added current"; future iterations will use
 *     `git log --follow` or `git diff -M` rename detection to close
 *     this gap.
 *   - Cross-file refactors (function extracted to a new file) are
 *     reported as removed-and-added.
 *   - When the line-bucket mapping fails on context edits (tool
 *     reports finding at a slightly different line in head than the
 *     diff predicts), we fall back to "unmatched." Sprint 0.x adds
 *     a content-hash fallback for this class.
 */
import type { FindingId, MatchResult } from './types';
/**
 * Per-finding identity plus the locator info needed to query git.
 * Producers convert `BaselineEntry` (or any equivalent stored form)
 * into this shape before calling `gitAwareMatch`.
 *
 * `file`, `line`, and `rule` are optional only because some finding
 * kinds (dep-vuln, license) have no file-line locator. Those kinds
 * are handled entirely by step-1 exact-identity match and skipped
 * by the step-2 git fallback.
 */
export interface LocatedIdentity {
    readonly id: FindingId;
    readonly file?: string;
    readonly line?: number;
    readonly rule?: string;
    /** Optional content-hash for the finding's surrounding context.
     *  Producer (Phase 3 baseline-create) computes via
     *  `computeContentHash` and stamps on the entry. When present on
     *  both prior and current sides for a `(canonical-rule, hash)`
     *  pair, the matcher's content-hash pass uses it as a fallback
     *  after the git-aware location pass exhausts. Absent when the
     *  producer can't read the file (binary, deleted, missing). */
    readonly contentHash?: string;
}
export interface GitAwareMatchOptions {
    /** Working directory of the repository under check. */
    readonly cwd: string;
    /** Commit SHA the baseline was created against. The matcher
     *  requires this SHA to be reachable in `cwd`'s git history. */
    readonly baseSha: string;
    /** Commit SHA (or revision spec) to compare against. Defaults to
     *  `'HEAD'` — the current working-tree's last commit. */
    readonly headSha?: string;
}
/**
 * Map a 1-based line number in `baseSha`'s version of `file` to its
 * corresponding 1-based line in `headSha`. Returns `null` when the
 * line was deleted, the file was removed, or git couldn't produce a
 * diff for any reason.
 *
 * Implementation runs `git diff --unified=0 baseSha headSha -- file`
 * and walks the resulting `@@ -A,B +C,D @@` hunks. Pure-ish: the
 * only impurity is the git subprocess; the parser is deterministic
 * over its input.
 */
export declare function mapLineThroughDiff(opts: {
    readonly cwd: string;
    readonly baseSha: string;
    readonly headSha: string;
    /** Path at `baseSha`. May differ from `newFile` if the caller
     *  resolved a rename. Pass-through compat: callers that don't
     *  track renames can use the same value for both. */
    readonly oldFile?: string;
    /** Path at `headSha`. */
    readonly newFile?: string;
    /** Legacy single-file form. When supplied, both `oldFile` and
     *  `newFile` default to this value. Kept for back-compat with
     *  call-sites that pre-date rename support. */
    readonly file?: string;
    readonly baseLine: number;
}): number | null;
/**
 * Composite matcher. Three passes, decreasing in match strength:
 *
 *   1. Location-aware pairing (when git is available): for each
 *      line-anchored prior finding, map its base line to the
 *      corresponding head line via `git diff`, then look up a
 *      current finding at `(effectivePath, rule, mappedLine)`. The
 *      effective path is the prior path translated through the
 *      rename map; status is `'relocated'` when the path changed,
 *      `'persisted'` when it didn't.
 *      Lookups try the exact mapped line first (confidence 0.95),
 *      then a ±2 fuzz window (confidence 0.88).
 *
 *   1.5. Content-hash pairing (when both sides carry content
 *      hashes): match prior+current by `(canonicalRule,
 *      contentHash)`. Runs regardless of git reachability — the
 *      hash is file-content-derived and doesn't need git. Catches
 *      cases git can't (shallow clone, force-pushed baseline) and
 *      cases git misses (line-bucket boundary shifts where the
 *      surrounding context survived intact). Confidence 0.80 — the
 *      policy's per-severity thresholds naturally tune whether to
 *      trust this layer.
 *
 *   2. Multiset exact-identity diff over whatever remains. Catches:
 *        - findings without a file-line locator (dep-vuln, license,
 *          symbol-based coverage-gap, duplication)
 *        - line-anchored findings whose locations didn't survive
 *          the diff but whose fingerprints happen to coincide
 *          across runs
 *        - everything when git history is unreachable (`baseSha`
 *          missing) and pass 1 was skipped
 *
 * Why location-first: the line-bucket fingerprint scheme can produce
 * spurious "persisted" matches when two findings of the same rule
 * in the same file naturally shift into each other's buckets. Pass 1
 * pairs them by real diff position, which is what a developer
 * intuitively expects. Pass 1.5 catches the cases where pass 1 isn't
 * available; pass 2 handles content-independent identity kinds.
 */
export declare function gitAwareMatch(prior: ReadonlyArray<LocatedIdentity>, current: ReadonlyArray<LocatedIdentity>, opts: GitAwareMatchOptions): MatchResult;
//# sourceMappingURL=git-aware-match.d.ts.map