/**
 * The vault deploy lane, supplied at last (change `vault-deploy-lane`).
 *
 * `add-vault` 5.6 built `runVaultDeploy` with the lane INJECTED and never
 * supplied one, so a project whose `vault_policy` is `required` could not be
 * deployed by any published client. This module is that supplier, plus the
 * entry point the CLI calls in place of a bare `apply()`:
 *
 *   - {@link createApplyDeployLane} drives the shipped `/apply/v1` routes —
 *     plan carrying `{capture_id, snapshot_oid_hmac}`, content upload, then a
 *     commit carrying the activation token — by REUSING `Deploy.apply()` rather
 *     than reassembling it. Warning gating, CAS dedup, event emission, asset
 *     re-plan, and terminal polling are the same code every other deploy runs;
 *     the only difference is two extra wire fields.
 *   - {@link applyWithVault} decides whether any of that happens at all. A
 *     project that is not `required` takes the untouched path: no capture, no
 *     token, no extra refusal, one policy read.
 *
 * THE COROUTINE, because it is the non-obvious part. `runVaultDeploy` wants
 * two separable steps (plan, then commit) with the vault push running between
 * them; `Deploy.apply()` is one call. The lane bridges them with a pair of
 * deferreds: `apply()`'s `authorize` hook fires once the plan exists and its
 * content is uploaded, which RESOLVES `lane.plan(...)`; it then waits for
 * `lane.commit(...)` to hand back the activation block. If no commit is ever
 * coming — the push failed, or correspondence refused — {@link abandon} rejects
 * that wait so the apply unwinds with nothing committed.
 */
import { type NextAction } from "../errors.js";
import type { Deploy } from "../namespaces/deploy.js";
import type { Repos } from "../namespaces/repos.js";
import type { ApplyOptions, DeployResult, LegacyWarningEntry, ReleaseSpec } from "../namespaces/deploy.types.js";
import type { VaultDeployLane, VaultDeployResult } from "./vault-deploy.js";
export interface ApplyDeployLaneOptions {
    /** The apply engine (`r._applyEngine`). */
    engine: Deploy;
    spec: ReleaseSpec;
    /** Everything a normal `apply()` takes: events, idempotency key, warning wallets. */
    apply?: Omit<ApplyOptions, "vault">;
}
/** A lane that is also cancellable, because `runVaultDeploy` may never commit. */
export interface ApplyDeployLane extends VaultDeployLane {
    /**
     * Tell the in-flight apply that no commit is coming. Safe to call always —
     * a no-op once the apply has settled — and safe to call twice.
     */
    abandon(reason: unknown): void;
    /** The `DeployResult`, once a commit landed. `null` on every other path. */
    result(): DeployResult | null;
}
export declare function createApplyDeployLane(options: ApplyDeployLaneOptions): ApplyDeployLane;
/** What the deploy did about vault, and why. */
export type VaultApplyMode = 
/** No vault, or the policy read did not resolve — the plain path ran. */
{
    kind: "none";
    reason: "no_vault" | "policy_unreadable";
}
/** A vault exists but the policy is `grandfathered` — the plain path ran. */
 | {
    kind: "grandfathered";
    repo_id: string;
}
/**
 * A vault exists but `vault_policy` was never set either way — D3:
 * allocating a vault no longer flips the policy, so this is the ordinary
 * shape for a project whose vault came from `run402 repos create` (or a
 * lazy first push) and nobody has opted into gating deploys yet. The plain
 * path ran, and the DeployResult carries the offer/warning (see
 * {@link decorateUngatedResult}).
 */
 | {
    kind: "ungated";
    repo_id: string;
}
/** The policy is `required` — capture, token, and commit ran. */
 | {
    kind: "vaulted";
    repo_id: string;
};
/** `run402 repos policy required` — the offer D3 attaches to every ungated deploy. */
export declare function vaultPolicyRequiredNextAction(repoId: string): NextAction;
/** The standing `warnings[]` entry D3 attaches to every ungated deploy, until the policy is set either way. */
export declare function vaultUngatedWarning(repoId: string): LegacyWarningEntry;
export interface ApplyWithVaultResult {
    mode: VaultApplyMode;
    /** The deploy result. `null` when a vaulted deploy did not reach a commit. */
    deploy: DeployResult | null;
    /** The five-outcome envelope. `null` on every non-`required` path. */
    vault: VaultDeployResult | null;
}
export interface ApplyWithVaultOptions {
    sdk: {
        _applyEngine: Deploy;
        repos: Repos;
    };
    spec: ReleaseSpec;
    apply?: Omit<ApplyOptions, "vault">;
    /** The work tree to capture. Defaults to the process cwd. */
    repo_dir?: string;
    /** Override the keystore root (tests, non-default profiles). */
    keystore_root?: string;
    /** The audited unvaulted override — requires `gitvault.override_unvaulted`. */
    allow_unvaulted?: {
        reason: string;
    };
    /**
     * Capture a dirty tree anyway. Default `false` — a dirty work tree refuses
     * `SNAPSHOT_DIRTY_TREE` before this deploy's capture runs at all (same
     * default as the manual `repos capture` lane; see `vault-snapshot.ts`).
     * Has no effect on a `none`/`grandfathered`/`ungated` deploy, which never
     * captures.
     */
    allowDirty?: boolean;
    /** Receives the `vault_commit` line the moment the snapshot exists. */
    onCommitLine?: (line: string) => void;
    /** Target passthrough; a Core target never engages the vault lane. */
    target?: "cloud" | "core";
}
/**
 * Deploy, taking the project's `vault_policy` into account.
 *
 * NOT `required` — no vault, an unreadable policy, a Core target, or an
 * explicit `grandfathered` — runs `apply()` with the caller's own options and
 * nothing else. That path must stay byte-identical: it is every non-vault
 * user's deploy, and the only cost this function may add to it is the single
 * policy read that determines the project is not `required`.
 */
export declare function applyWithVault(options: ApplyWithVaultOptions): Promise<ApplyWithVaultResult>;
//# sourceMappingURL=vault-apply.d.ts.map