/**
 * vault — vault-gated deploy (protocol rev 41 §6.5; task 5.6, lane supplied
 * by change `vault-deploy-lane`).
 *
 * Every deploy has a commit, and the artifacts it ships CORRESPOND to it:
 *   1. snapshot (§6.6) → the `vault_commit`, printed ALWAYS, never sent,
 *      plus a digest over the captured file set;
 *   2. a fresh `capture_id` before BOTH lanes;
 *   3. the deploy lane collects artifacts from the work tree and produces the
 *      canonical plan digest (`apply_plan_sha256`, null when the build fails
 *      before a plan exists) — concurrently, the push lane prepares the
 *      publication;
 *   4. the push's head carries `capture_binding {capture_id, apply_plan_sha256|null,
 *      snapshot_oid_hmac}` — capture-the-attempt survives a failed build; no
 *      token is mintable from a null digest;
 *   5. BEFORE any plan commits, the captured-set digest is RE-DERIVED. A
 *      difference is `SNAPSHOT_MOVED_DURING_DEPLOY`: the deploy stops, naming
 *      the changed paths, and commits nothing;
 *   6. with a digest and an admitted head, the capture receipt is exchanged
 *      for an activation token, and the apply commit is submitted ONLY with it;
 *   7. the outcome is one of the CLOSED five: `DEPLOYED_AND_VAULTED`,
 *      `DEPLOY_BLOCKED_PUSH_FAILED`, `DEPLOY_FAILED_VAULTED`,
 *      `DEPLOY_FAILED_UNVAULTED`, `DEPLOYED_UNVAULTED_OVERRIDE`.
 *
 * WHAT CORRESPONDENCE MEANS, AND WHAT IT DOES NOT. Step 5 establishes that the
 * captured source did NOT change while the artifacts were produced. It does
 * NOT establish that the artifacts are a reproducible function of that source:
 * nothing here ties a gitignored `dist/` to the `src/` it came from, and the
 * captured set deliberately excludes gitignored paths so a project with a
 * build step stays deployable. The stronger property — build inside an
 * isolated materialization, making artifacts a function of the snapshot — is a
 * recorded forward TODO, not a thing this module quietly delivers.
 *
 * REFUSE, NEVER REPAIR. On a detected move the deploy stops rather than
 * re-capturing: a second capture publishes a generation whose relationship to
 * the artifacts already collected is exactly what is in doubt, and a
 * capture→collect→capture loop churns generations. The caller re-runs.
 *
 * The push is never gated on deploy success. The unvaulted override
 * (`allow_unvaulted`) is journaled crash-safely BEFORE the commit with the
 * full §6.5 contents; any later invocation drains the journal by pushing the
 * journaled snapshot and presenting the capture receipt to the
 * override-completion route — equality on EVERY field or no clear.
 */
import type { VaultActivationToken, VaultCaptureReceipt, VaultHeadTarget } from "../namespaces/vault.types.js";
import { VaultKeystore } from "./vault-keystore.js";
import { Vault } from "./vault-publication.js";
import { type VaultCapturedSetDrift, type VaultSnapshot, type VaultSnapshotOptions } from "./vault-snapshot.js";
export declare const VAULT_DEPLOY_OUTCOMES: readonly ["DEPLOYED_AND_VAULTED", "DEPLOY_BLOCKED_PUSH_FAILED", "DEPLOY_FAILED_VAULTED", "DEPLOY_FAILED_UNVAULTED", "DEPLOYED_UNVAULTED_OVERRIDE"];
export type VaultDeployOutcome = (typeof VAULT_DEPLOY_OUTCOMES)[number];
/** A serializable error summary (never plaintext, never presigned URLs). */
export interface VaultDeployError {
    code: string;
    message: string;
    retryable: boolean;
    details?: unknown;
}
export interface VaultDeployNextAction {
    action: string;
    /** Present when the action needs a capability the caller may lack. */
    requires?: string;
}
interface VaultDeployResultBase {
    outcome: VaultDeployOutcome;
    /** The snapshot commit — ALWAYS present; the `vault_commit` line is derived from it. */
    vault_commit: string;
    vault_commit_line: string;
    snapshot: VaultSnapshot;
    capture_id: string;
    snapshot_oid_hmac: string;
    /** The canonical plan digest — null when the build failed before a plan existed. */
    apply_plan_sha256: string | null;
    operation_id: string | null;
    next_actions: VaultDeployNextAction[];
}
export type VaultDeployResult = (VaultDeployResultBase & {
    outcome: "DEPLOYED_AND_VAULTED";
    generation: string;
    head_sha256: string;
    capture_receipt: VaultCaptureReceipt;
    activation_token: VaultActivationToken;
    commit: unknown;
}) | (VaultDeployResultBase & {
    outcome: "DEPLOY_BLOCKED_PUSH_FAILED";
    push_error: VaultDeployError;
    previous_release_keeps_serving: true;
}) | (VaultDeployResultBase & {
    outcome: "DEPLOY_FAILED_VAULTED";
    generation: string;
    head_sha256: string;
    capture_receipt: VaultCaptureReceipt | null;
    deploy_error: VaultDeployError;
}) | (VaultDeployResultBase & {
    outcome: "DEPLOY_FAILED_UNVAULTED";
    push_error: VaultDeployError;
    deploy_error: VaultDeployError;
}) | (VaultDeployResultBase & {
    outcome: "DEPLOYED_UNVAULTED_OVERRIDE";
    push_error: VaultDeployError;
    override_journal: VaultOverrideJournal;
    commit: unknown;
});
export interface VaultDeployLanePlanInput {
    /**
     * The work tree the snapshot was captured from — collect artifacts from
     * HERE. It is the mutable tree on purpose (a materialization of the snapshot
     * commit holds source and no build output, because build output is
     * gitignored). Correspondence is enforced by re-deriving the captured-set
     * digest before the plan commits, not by isolating this directory.
     */
    source_dir: string;
    capture_id: string;
    snapshot_oid_hmac: string;
}
export interface VaultDeployLanePlan {
    plan_id: string;
    /** The apply operation the token is minted for (the gateway creates it at plan time under the vault gate). */
    operation_id: string;
    /** The canonical `apply_plan_canonical/v1` digest (opaque 32-byte commitment, hex). */
    apply_plan_sha256: string;
}
export interface VaultDeployLaneCommitInput {
    plan_id: string;
    operation_id: string;
    /** Present on the vaulted path. */
    activation_token?: VaultActivationToken;
    /** Present on the override path — requires `gitvault.override_unvaulted` server-side. */
    allow_unvaulted?: {
        reason: string;
    };
}
/** The apply-v1 plan → commit pair, abstracted so the deploy logic is testable without a gateway. */
export interface VaultDeployLane {
    plan(input: VaultDeployLanePlanInput): Promise<VaultDeployLanePlan>;
    commit(input: VaultDeployLaneCommitInput): Promise<unknown>;
}
export interface VaultOverrideJournal {
    version: 1;
    repo_id: string;
    operation_id: string;
    capture_id: string;
    apply_plan_sha256: string;
    snapshot: {
        ref: string;
        oid: string;
        head_target: VaultHeadTarget;
    };
    snapshot_oid_hmac: string;
    /** `pending` → committed unvaulted, not yet pushed; `published` → pushed, completion not yet accepted; `completed` → advisory cleared server-side. */
    publication_state: "pending" | "published" | "completed";
    generation: string | null;
    head_sha256: string | null;
    capture_receipt: VaultCaptureReceipt | null;
    reason: string;
    created_at: string;
    updated_at: string;
}
export declare function overrideJournalDir(keystore: VaultKeystore): string;
export declare function overrideJournalPath(keystore: VaultKeystore, operationId: string): string;
export declare function writeOverrideJournal(keystore: VaultKeystore, journal: VaultOverrideJournal): void;
export declare function readOverrideJournal(keystore: VaultKeystore, operationId: string): VaultOverrideJournal | null;
/** Every override journal not yet `completed` — the doctor-visible advisory list. */
export declare function listPendingOverrideJournals(keystore: VaultKeystore, repoId?: string): VaultOverrideJournal[];
export interface VaultCaptureReceiptMatch {
    equal: boolean;
    mismatched_fields: string[];
}
/** Compare a capture receipt against an operation's journaled binding on EVERY field: repo, capture_id, plan digest, snapshot commitment, head hash. */
export declare function matchCaptureReceipt(receipt: VaultCaptureReceipt, expected: {
    repo_id: string;
    capture_id: string;
    apply_plan_sha256: string | null;
    snapshot_oid_hmac: string;
    head_sha256: string;
}): VaultCaptureReceiptMatch;
/**
 * `authorization_epoch` is compared BYTEWISE against the epoch the client last
 * saw installed (a DR gate mints a fresh one). Any difference — one nibble is
 * enough — is `AUTHORIZATION_EPOCH_STALE`, never a retry under the old epoch.
 */
export declare function checkAuthorizationEpoch(tokenEpoch: string, installedEpoch: string): void;
/** Verify a minted activation token binds exactly this deploy (before it is ever presented to a commit). */
export declare function checkActivationTokenBinding(token: VaultActivationToken, expected: {
    repo_id: string;
    operation_id: string;
    generation: string;
    head_sha256: string;
    capture_id: string;
    apply_plan_sha256: string;
    snapshot_oid_hmac: string;
}): string[];
export interface VaultDeployOptions {
    vault: Vault;
    lane: VaultDeployLane;
    /** The work tree to snapshot. */
    repo_dir: string;
    snapshot?: Omit<VaultSnapshotOptions, "dir">;
    /** The unvaulted override — requires `gitvault.override_unvaulted` server-side; refused otherwise. */
    allow_unvaulted?: {
        reason: string;
    };
    /** Test/replay hook: pin the capture id. */
    capture_id?: string;
    now?: () => Date;
    /** Called with the `vault_commit` line as soon as the snapshot exists — the CLI prints it. */
    onCommitLine?: (line: string) => void;
}
/**
 * D193's `EPOCH_ROTATION_REQUIRED` names WHICH of three independent causes
 * is outstanding via boolean flags (`migration_required` /
 * `revocation_outstanding` / `exposure_outstanding` — any subset, never
 * mutually exclusive); this decodes them into the exact `repos access`
 * command that remedies each one. Shared with the namespace-level `push()`
 * enrichment (`repos.ts#enrichEpochRotationRequired`) — same three
 * causes, same three commands, one place either could drift from.
 */
export declare function epochRotationRequiredNextActions(e: unknown): {
    action: string;
    why: string;
}[];
/**
 * The correspondence refusal. CLIENT-LOCAL by design: the moved tree is
 * detected before any plan is
 * committed, so this code never crosses the wire and is deliberately absent
 * from the protocol's frozen §11 wire registry. The accepted cost is
 * discoverability — which is why it is named here, in the client's own error
 * surface, rather than left to be found by grep.
 */
export declare const SNAPSHOT_MOVED_DURING_DEPLOY = "SNAPSHOT_MOVED_DURING_DEPLOY";
/** What `SNAPSHOT_MOVED_DURING_DEPLOY` carries in `details`. */
export interface VaultSnapshotMovedDetails extends VaultCapturedSetDrift {
    vault_commit: string;
    capture_id: string;
    captured_digest: string;
    observed_digest: string;
    /** Present when the snapshot reached the vault before the tree moved. */
    generation?: string;
}
/**
 * Run the vault-gated deploy. Throws ONLY for refusals that precede any lane
 * (snapshot refusals such as `SNAPSHOT_CONFLICTED_INDEX`, unsupported
 * repositories), for `SNAPSHOT_MOVED_DURING_DEPLOY` (the tree moved under the
 * capture; nothing is committed), and for `OVERRIDE_NOT_AUTHORIZED`; every
 * other path resolves to one of the five outcomes.
 */
export declare function runVaultDeploy(options: VaultDeployOptions): Promise<VaultDeployResult>;
export interface VaultOverrideDrainReport {
    completed: VaultOverrideJournal[];
    /** Still pending, with the reason the drain could not complete them this time. */
    remaining: Array<{
        journal: VaultOverrideJournal;
        error: VaultDeployError;
    }>;
}
/**
 * Drain every pending override journal for this vault: push the journaled
 * snapshot (same capture binding), verify the receipt against EVERY journaled
 * field + the read-back head hash, present it for completion. Partial matches
 * never clear; the advisory persists until equality.
 */
export declare function drainOverrideJournals(vault: Vault, options?: {
    now?: () => Date;
}): Promise<VaultOverrideDrainReport>;
export {};
//# sourceMappingURL=vault-deploy.d.ts.map