import type { AdmissionResult, ExtractedWriteTarget, ProvenanceLedgerData, ProvenanceTargetEvaluation, ProvenanceRecord, ToolResultPathExtraction, UserMessageExtractionResult } from './protocol/write-provenance-types.js';
export declare function isGateProvenanceEnabled(env?: Record<string, string | undefined>): boolean;
export declare function createEmptyProvenanceLedgerData(): ProvenanceLedgerData;
export declare function canonicalizeProvenancePath(targetPath: string, cwd: string, opts?: {
    homeDir?: string;
}): string;
/**
 * Append `record` under `path`. If a record with the same dedupe key already
 * exists on the path, the new record is dropped (first writer wins).
 * Mutates `data` in place.
 */
export declare function admit(data: ProvenanceLedgerData, path: string, record: ProvenanceRecord): void;
/**
 * Return all records admitted under the exact canonical path.
 * Returns the internal array (callers must not mutate); empty array for
 * unknown paths.
 */
export declare function records(data: ProvenanceLedgerData, path: string): ProvenanceRecord[];
/**
 * Return all records admitted under `dirname(path)` — i.e. the immediate
 * parent directory of `path`. Used by new-file admission to check for
 * `parent_listing` evidence.
 */
export declare function parentRecords(data: ProvenanceLedgerData, path: string): ProvenanceRecord[];
/**
 * Total record count across all paths. For telemetry / dogfood diagnostics.
 */
export declare function size(data: ProvenanceLedgerData): number;
/**
 * Deep-copy a `ProvenanceLedgerData` value. Used for subagent inheritance
 * (parent snapshots ledger at spawn; subagent gets isolated copy that does
 * not write back). Records are shallow-cloned because `ProvenanceRecord` is
 * a flat structure with primitive fields.
 *
 * Per spec §4.3: subagents inherit but do not propagate back; this clone
 * is the boundary.
 */
export declare function cloneProvenanceLedgerData(data: ProvenanceLedgerData): ProvenanceLedgerData;
/**
 * Walk ancestor directories of `path` and return all `user_explicit_deny`
 * records whose `denyScope === 'subtree'`, tagged with the canonical
 * `sourcePath` they were admitted under. Does NOT include denies on the
 * exact path itself — caller handles those via `records(path)`.
 *
 * Used by `evaluateAdmission` Step 1 to implement subtree deny precedence:
 * if any ancestor directory has an active subtree deny, the write to a
 * descendant is blocked regardless of the descendant's own records. The
 * `sourcePath` is required so the caller can look up revoke records on
 * the deny's own path (revokes are scope-matched per spec §16.5).
 *
 * Bounded to 64 levels of ancestry to avoid pathological loops.
 */
export interface AncestorDenyHit {
    sourcePath: string;
    record: ProvenanceRecord;
}
export declare function ancestorDenies(data: ProvenanceLedgerData, path: string): AncestorDenyHit[];
/**
 * Optional input channel for synthetic records — used by PERM-4 to inject
 * settings-driven permission rules into the admission decision without
 * mutating the actual ledger. Synthetic records get prepended to the live
 * records so they're seen first by Step 1 (deny) and Step 2 (admit).
 *
 * Synthetic records with `permanent: true` bypass the revoke-ts check in
 * Step 1 entirely — a conversation-level "算了 改吧 X" cannot lift a deny
 * that came from a settings.json rule.
 */
export interface AdmissionOptions {
    syntheticPathRecords?: ProvenanceRecord[];
    syntheticParentRecords?: ProvenanceRecord[];
}
/**
 * Core admission decision for a write target.
 *
 * STEP 1 — deny precedence (always runs first):
 *   1a. Collect candidate denies:
 *       - exact-scope denies on `path` itself (live + synthetic)
 *       - subtree-scope denies on any ancestor directory (via `ancestorDenies`)
 *   1b. For each candidate, look up revokes on the DENY'S OWN PATH
 *       (not the write target). A deny is "active" iff its ts > latest revoke ts
 *       on the same path. EXCEPTION: records with `permanent: true` skip the
 *       revoke check entirely — settings-driven denies cannot be lifted by
 *       conversation-level revoke (PERM-5).
 *   1c. If any active deny remains, return blocked with `denyActive=true` and
 *       the most recently-timestamped active deny as `activeDenyRecord`.
 *
 * STEP 2 — admit rules (only if no active deny):
 *   - `user_declared_target` on path → admit (live or synthetic)
 *   - new file: `parent_listing` on parent → admit
 *   - existing file: `tool_confirmed_existing` on path → admit
 *   - else block (with diagnostic `availableRecords`)
 *
 * `path` must be canonical (pass through `canonicalizeProvenancePath` first).
 */
export declare function evaluateAdmission(data: ProvenanceLedgerData, path: string, isNewFile: boolean, opts?: AdmissionOptions): AdmissionResult;
/**
 * Top-level error formatter. Renders deny failures first (highest
 * precedence), then non-deny failures. For multi-target calls, adds a
 * header naming the target count and a closing "resolve each" reminder.
 *
 * Returns the empty string when `failures` is empty so callers can use
 * it unconditionally without an extra length check.
 */
export declare function formatProvenanceError(failures: ProvenanceTargetEvaluation[], context?: {
    command?: string;
}): string;
/**
 * Extract path classifications from a user-originated text message.
 *
 * v1 of this function implements Stage D only (default `user_reference`).
 * Stages A (deny), B (revoke), and C (declared_target) will be layered on
 * in subsequent commits per the S0-3 plan; the public signature is stable.
 *
 * Caller is responsible for:
 * - only calling on user-originated text (assistant text never enters the
 *   ledger per spec §16.6 anti-pattern guard)
 * - building `ProvenanceRecord`s from the returned extractions, stamping
 *   the `ts` / `originIteration` they pass in `opts` onto each record
 *
 * Skipped glob-shaped denies (eg. `不要改 src/*.ts`) are surfaced via the
 * result's `skippedGlobDenies` field for wired telemetry. v1 returns
 * an empty array here; Stage A landing will populate it.
 */
export declare function extractPathsFromUserMessage(text: string, opts: {
    cwd: string;
    ts: number;
    originIteration: number;
    homeDir?: string;
}): UserMessageExtractionResult;
interface ToolResultExtractorOpts {
    cwd: string;
    ts: number;
    originIteration: number;
    homeDir?: string;
}
export declare function extractPathsFromToolResult(toolName: string, input: Record<string, unknown>, result: string, isError: boolean, opts: ToolResultExtractorOpts): ToolResultPathExtraction[];
export declare function extractWriteTargets(toolName: string, input: Record<string, unknown>, cwd: string, opts?: {
    homeDir?: string;
}): ExtractedWriteTarget[];
export interface WriteTargetProvenanceCheck {
    targets: ExtractedWriteTarget[];
    evaluations: ProvenanceTargetEvaluation[];
    failures: ProvenanceTargetEvaluation[];
    bashUnparseable: boolean;
}
/**
 * Optional input channel for settings-driven permission rules (PERM-6).
 * Caller (conversation dispatch) loads `ResolvedPermissions` once per task
 * via `loadResolvedPermissions` and passes it on every gate call. The gate
 * compiles per-target synthetic records via the rule compiler and injects
 * them into `evaluateAdmission` for this one decision.
 *
 * Decoupled via a function-callback so write-provenance.ts can stay free
 * of an import cycle with permission-rules.ts (the rule compiler depends
 * on `canonicalizeProvenancePath` from this module).
 */
export interface WriteTargetProvenanceOptions {
    homeDir?: string;
    /**
     * Returns synthetic records to inject for this (toolName, canonicalPath)
     * pair. When omitted, no rule-driven evidence is consulted (back-compat
     * with pre-PERM-6 callers).
     */
    compileRules?: (toolName: string, canonicalPath: string) => {
        pathRecords: ProvenanceRecord[];
    };
}
export declare function evaluateWriteTargetProvenance(toolName: string, input: Record<string, unknown>, ledger: ProvenanceLedgerData, cwd: string, opts?: WriteTargetProvenanceOptions): WriteTargetProvenanceCheck;
export {};
