/**
 * Brownfield policy + status classifier.
 *
 * The matcher in `git-aware-match.ts` emits raw `MatchPair`s with one
 * of four statuses (persisted / relocated / added / removed) plus a
 * confidence score and structured reasons. The guardrail check needs
 * a richer taxonomy — the difference between "developer introduced
 * a new finding" and "a scanner update surfaced a finding that was
 * always there" matters enormously for whether to block a PR.
 *
 * This module is the bridge. It takes a `MatchPair` plus optional
 * context (severity, scanner-version diff, config diff) and a
 * `BrownfieldPolicy`, then emits a `ClassifyResult` carrying the
 * post-policy `FindingStatus`, the block/warn verdict, and the
 * composed reason chain.
 *
 * Pure module — no I/O, deterministic over its inputs.
 *
 * Producer wiring note: today's classifier emits a subset of the full
 * `FindingStatus` taxonomy. Reservations for `probable_existing`,
 * `newly_detected`, and `fixed` are declared in the type space so
 * Phase 3's baseline-metadata work can light them up incrementally
 * without re-shaping consumer code.
 */
import type { BaselineMode } from './modes';
import type { FindingSeverity, FindingStatus, MatchPair, MatchReason } from './types';
/**
 * Optional `baseline.*` block in `.dxkit/policy.json`. Pins the
 * mode + (when ref-based) the comparison ref repo-wide so every
 * developer + every CI job uses the same posture. Both fields are
 * optional; when absent the resolver in `./modes.ts` falls back to
 * visibility-derived defaults.
 *
 * Schema example:
 *
 *   {
 *     "baseline": {
 *       "mode": "ref-based",
 *       "ref": "origin/main"
 *     }
 *   }
 */
export interface BaselineSection {
    readonly mode?: BaselineMode;
    /** Git ref to compare against in `ref-based` mode. When absent,
     *  the resolver probes `origin/HEAD` and falls back to
     *  `'origin/main'`. */
    readonly ref?: string;
}
/**
 * Per-finding-kind overrides that escalate specific guardrail rules
 * beyond the generic `block` / `warn` lists. Each rule maps to a
 * common product-level concern; the classifier checks them when the
 * relevant context fields are present.
 */
export interface BrownfieldBlockRules {
    /** Block any newly-introduced secret regardless of confidence. */
    readonly newSecret?: boolean;
    /** Block any newly-introduced critical security finding. */
    readonly newCriticalSecurity?: boolean;
    /** Block any newly-introduced high-severity security finding. */
    readonly newHighSecurity?: boolean;
    /** Block any newly-introduced critical dependency vulnerability. */
    readonly newCriticalDependencyVulnerability?: boolean;
    /** Block any newly-introduced high-severity reachable dep vuln. */
    readonly newHighReachableDependencyVulnerability?: boolean;
    /** Block when an untested source file is added in a changed file. */
    readonly newUntestedChangedSource?: boolean;
    /** Block any newly-introduced severe quality issue in changed files. */
    readonly newSevereQualityIssueInChangedFiles?: boolean;
}
/**
 * Brownfield-mode policy. The product promise — "existing debt is
 * allowed; new regressions are blocked" — flows from these settings.
 */
export interface BrownfieldPolicy {
    readonly mode: 'brownfield';
    /** Statuses that fail the guardrail check (non-zero exit code). */
    readonly block: ReadonlyArray<FindingStatus>;
    /** Statuses that emit a warning but don't fail. */
    readonly warn: ReadonlyArray<FindingStatus>;
    /**
     * Per-severity confidence thresholds. A `relocated` or `persisted`
     * match with confidence below the per-severity threshold demotes
     * to `'uncertain'` — the policy can warn rather than silently
     * accept a low-confidence pairing.
     */
    readonly confidence: Readonly<Record<FindingSeverity, number>>;
    /** Per-kind block-on-new overrides. */
    readonly blockRules: BrownfieldBlockRules;
    /**
     * Finding kinds whose `added` classification only blocks when the
     * finding overlaps lines actually changed in the current diff.
     *
     * Some upstream scanners (notably semgrep on large codebases) are
     * non-deterministic across runs — parallel rule execution + per-
     * rule timeouts mean each run discovers a slightly different
     * subset of the full match space. When the baseline missed a real
     * finding and a later scan catches it on UNCHANGED code, the
     * matcher legitimately reports `added` — but the developer
     * didn't introduce it.
     *
     * For kinds listed here, an `added` finding outside the diff's
     * changed lines gets demoted to `uncertain` (a warn status).
     * Findings inside changed lines still block — that's where the
     * developer actually wrote code.
     *
     * Default: `['code', 'hygiene']` — the kinds with confirmed
     * scanner-wobble risk. Customers can extend (`'duplication'`,
     * `'large-file'`) or clear it (block on everything regardless of
     * diff overlap) via `.dxkit/policy.json`.
     */
    readonly addedRequiresChangedLines: ReadonlyArray<string>;
    /**
     * Baseline-mode pinning. When absent, the resolver in `./modes.ts`
     * falls back to visibility-derived defaults
     * (`'public'` → `ref-based`; `'private'` / `'internal'` /
     * `'unknown'` → `committed-full`). Customers pin this to lock the
     * posture across all developers + CI jobs:
     *
     *   - `'committed-full'`: rich entries committed (default for
     *     private repos with small teams).
     *   - `'committed-sanitized'`: stripped entries committed
     *     (compliance-conscious private repos).
     *   - `'ref-based'`: no committed baseline; computed from a git
     *     ref at check time (default for public repos).
     */
    readonly baseline?: BaselineSection;
}
/**
 * Default brownfield policy. Captures the conservative posture from
 * the agentic-brownfield strategy: block only on high-confidence new
 * regressions; warn on the categories that suggest a problem might
 * be real but might also be drift; legacy debt is permitted.
 *
 * Confidence thresholds: secrets + critical security demand a tight
 * confidence threshold (a low-confidence persisted secret pairing
 * gets demoted to uncertain and warned, not blocked). Lower-severity
 * findings can pair on weaker signal because the cost of a false
 * "secret is new" event is much higher than a false "TODO is new."
 */
export declare const DEFAULT_BROWNFIELD_POLICY: BrownfieldPolicy;
/**
 * Contextual signals the classifier reads when available. Every field
 * is optional — pass `{}` for the basic matcher-only classification.
 * Phase 3 baseline-metadata work will populate these from the stored
 * baseline + current scan envelope.
 */
export interface ClassifyContext {
    /** Severity of the underlying finding. */
    readonly severity?: FindingSeverity;
    /** Kind discriminator from `IdentityInput`, for block-rule checks. */
    readonly kind?: string;
    /** True when the baseline's scanner / advisory-db version differs
     *  from the current scan. Reclassifies an `added` finding as
     *  `tooling_drift` rather than blocking it as a new regression. */
    readonly scannerVersionDiffers?: boolean;
    /** True when the baseline's `.dxkit-ignore` / policy hash differs
     *  from the current scan. Reclassifies `added` as `config_drift`. */
    readonly configDiffers?: boolean;
    /** True when the underlying source file's lines overlap lines
     *  changed by the current diff. Used by `newSevereQualityIssueIn
     *  ChangedFiles` and similar rules; absent context is treated as
     *  "we don't know, assume outside changed lines." */
    readonly overlapsChangedLines?: boolean;
    /** True when an `added` dep-vuln is on a reachable code path. */
    readonly reachable?: boolean;
}
/** Verdict + reasoning for one classified pair. */
export interface ClassifyResult {
    readonly status: FindingStatus;
    /** Whether the policy blocks based on the classified status or a
     *  specific block-rule override. */
    readonly blocks: boolean;
    /** Whether the policy warns. */
    readonly warns: boolean;
    /** Reasons backing the status — composed of the matcher's reasons
     *  plus any classification-time additions. */
    readonly reasons: ReadonlyArray<MatchReason>;
}
/**
 * Classify one match pair against a brownfield policy.
 *
 * Pipeline:
 *   1. Start with the matcher's `pair.status` as the candidate
 *      `FindingStatus`.
 *   2. For `added`: check drift context. Scanner-version drift wins
 *      (more specific signal) over config drift; both demote to
 *      drift-bucket statuses regardless of severity.
 *   3. For `persisted` / `relocated`: check confidence against the
 *      per-severity threshold. Below threshold demotes to
 *      `'uncertain'`.
 *   4. Apply block-rule overrides: if a block-rule fires for this
 *      kind+severity combination AND the candidate status is
 *      `'added'`, the result blocks even if `'added'` weren't in the
 *      policy's block list.
 *   5. Apply the policy's `block` / `warn` membership to the final
 *      status to produce the booleans.
 */
export declare function classify(pair: MatchPair, policy?: BrownfieldPolicy, context?: ClassifyContext): ClassifyResult;
/**
 * Convenience: classify every pair in a match result against the
 * same policy. Returns an array aligned with the input pair order
 * so callers can render side-by-side. Per-pair context (severity,
 * kind, drift flags) is supplied via the optional `contextFor`
 * callback — callers map their `FindingId` back to the producer
 * envelope to fill in the fields the classifier reads.
 */
export declare function classifyAll(pairs: ReadonlyArray<MatchPair>, policy?: BrownfieldPolicy, contextFor?: (pair: MatchPair) => ClassifyContext): ReadonlyArray<ClassifyResult>;
/** Conventional location for a per-repo brownfield policy. Loaded
 *  automatically by `resolvePolicy` when present. */
export declare const DEFAULT_POLICY_FILENAME: string;
/**
 * Load a brownfield policy with the three-step resolution order
 * shared by `createBaseline` and `runGuardrailCheck`:
 *
 *   1. `policyPath` (explicit `--policy <p>` flag). Errors if the
 *      path is supplied but unreadable / malformed.
 *   2. `<cwd>/.dxkit/policy.json` (conventional). Silently skipped
 *      when absent so consumers without a policy get the defaults.
 *   3. `DEFAULT_BROWNFIELD_POLICY` (compiled-in fallback).
 *
 * Customer fields shallow-merge over the default. The
 * `confidence` / `blockRules` blocks deep-merge by key. Unknown
 * fields are preserved — the classifier ignores what it doesn't
 * know, so forward-compatible policy files don't break old dxkit.
 */
export declare function resolvePolicy(policyPath: string | undefined, cwd: string): BrownfieldPolicy;
/**
 * Convenience wrapper for callers that don't take a `--policy`
 * override (e.g., `createBaseline`). Loads the conventional file if
 * present; returns defaults otherwise.
 */
export declare function loadPolicyFromCwd(cwd: string): BrownfieldPolicy;
//# sourceMappingURL=policy.d.ts.map