import type { Finding } from "audit-tools/shared"; import type { ItemSpec } from "../state/types.js"; import { type FindingRiskTier } from "../steps/stepUtils.js"; /** * The enumerated change-kinds. Only the kinds in {@link SAFE_CHANGE_KINDS} are * auto-approvable. The list is a CLOSED enumeration: anything that does not * positively classify into one of the allowlisted kinds is `unknown` and * therefore excluded (fail-closed). */ export type ChangeKind = "add_test" | "add_doc" | "additive_config_key" | "narrowly_localized_reversible_edit" | "inplace_semantic_edit" | "deletion" | "unknown"; /** * Fail-closed ALLOWLIST of provably-safe change-kinds — enumerated as an * explicit positive set, not a denylist. A change-kind is auto-approvable ONLY * if it is a member of this set; the membership test is `SAFE_CHANGE_KINDS.has(kind)`, * so a future change-kind added to the `ChangeKind` union is excluded by default * until it is deliberately added here. * * Why these four: * - `add_test` — adds a new test; no existing behavior to regress. * - `add_doc` — adds documentation/comments; no runtime behavior at all. * - `additive_config_key` — introduces a NEW config key with a default; does * not change the value of an existing key. * - `narrowly_localized_reversible_edit` — a small, single-site, additive guard * (e.g. a null/bounds check added before existing logic) that does not rewrite * an existing semantic decision and is trivially revertible. */ export declare const SAFE_CHANGE_KINDS: ReadonlySet; /** A change-kind classification carrying the matched kind and a deterministic reason. */ export interface ChangeKindClassification { change_kind: ChangeKind; /** Whether the kind is positively on the fail-closed allowlist. */ allowlisted: boolean; reason: string; } /** * Classify a finding's change-kind deterministically (fail-closed). The order * matters: any deletion or in-place-semantic signal disqualifies the finding * BEFORE the additive kinds are considered, so a finding that both "adds a test" * and "removes the legacy parser" classifies as `deletion`, never `add_test`. */ export declare function classifyChangeKind(finding: Finding, spec?: ItemSpec): ChangeKindClassification; /** * Whether a single finding is auto-approvable in autonomous mode: tier "safe" * AND a positively-allowlisted change-kind. Both are necessary; the * change-kind allowlist is the hard, fail-closed non-destructiveness gate. */ export interface AutonomousFindingVerdict { finding_id: string; approved: boolean; tier: FindingRiskTier; change_kind: ChangeKind; reason: string; } export declare function evaluateAutonomousFinding(finding: Finding, spec?: ItemSpec): AutonomousFindingVerdict; export interface AutonomousReviewDecision { /** Findings auto-approved to proceed to implementation. */ approved_ids: string[]; /** Findings left LIVE (re-emitted as a deliverable; never durably rejected). */ leftover_ids: string[]; /** Full per-finding verdicts, for the durable record + diagnostics. */ verdicts: AutonomousFindingVerdict[]; } /** * Build the autonomous review decision over the survivor finding set. Pure and * deterministic — the same findings always yield the same split. Re-evaluated * FRESH each call (no memory of a prior run's verdict), so a leftover that * drifted across the "safe" boundary is re-checked on the next nightly run. * * `specs` is an optional map from finding id to its documented ItemSpec; when a * spec is present it sharpens the classification, but the decision works without * any specs (the gate fires before the document phase). */ export declare function buildAutonomousReviewDecision(survivors: readonly Finding[], specs?: ReadonlyMap): AutonomousReviewDecision; //# sourceMappingURL=autonomousGate.d.ts.map