import type { RunnerDeps } from "../types.js";
import type { ExecutionEnv } from "../../internal/harness.js";
import type { PathRuleBases } from "../permission-rule-model.js";
import type { ChildPlacement, InheritedGate, RunInternals } from "./contracts.js";
import type { ToolPolicy } from "../tool-policy.js";
import { CheckpointError } from "../checkpoint-store.js";
/**
 * Whether this deployment can place a child agent in a tree OTHER than the caller's — the one fact behind
 * every request of that shape: an explicit `cwd`, a workflow agent's `isolation: "worktree"`, and the
 * delegation tool's per-call or per-definition `isolation: "worktree"`.
 *
 * Only an `executionEnvFactory` can: it builds one execution env per task, so a child can be rooted
 * wherever the request says. A static `executionEnv` is ONE shared env with ONE cwd — every child that
 * runs on it runs in the caller's root, whatever tree it was asked to work in. A request the deployment
 * cannot honor is refused before the child starts (and, for a worktree, before one is minted); each site
 * keeps its own code and sentence for the refusal, but none decides the condition itself.
 */
export declare function deploymentCanRerootChild(deps: Pick<RunnerDeps, "executionEnvFactory">): boolean;
/**
 * Where a child the caller asked to place at `asked` actually landed (`childRoot`, the root its environment gave it) — the
 * ONE judgment every reader of that fact takes
 * (the delegation tool's worktree request, and the anchors of the rules the child inherits):
 *  · `honored` — the environment's root is where the child was asked to be (canonical on both sides);
 *  · `caller_tree` — it is not, and it lies inside the caller's own tree (`callerRoot`): the same filesystem, the wrong
 *    directory — a worktree request then fails (the child would write the caller's checkout);
 *  · `elsewhere` — neither: another filesystem namespace (a sandbox the factory minted). The child runs there, it is not
 *    in the worktree it was offered, and it takes the caller's path rules again at its own anchors.
 * A path the environment cannot canonicalize is compared as spelled. Residual: two namespaces that hold the same path
 * string, with a factory claiming to honor it, read `honored`.
 */
export declare function childPlacementOf(env: Pick<ExecutionEnv, "canonicalPath">, childRoot: string, asked: string | undefined, callerRoot: string): Promise<ChildPlacement>;
/** A delegated leg's placement: the place asked for is the hint (a minted worktree, an explicit cwd, the caller's own cwd)
 *  — or, for a worktree the factory mints itself (`isolation`), that worktree on the caller's host (a remote environment's
 *  is another namespace). A leg no delegation caller placed (no `callerRoot`) has no placement and reads nothing. */
export declare function childPlacementOnLeg(env: ExecutionEnv, internals: Pick<RunInternals, "isolation" | "parentCwd"> & {
    readonly callerRoot: string;
}, root: string): Promise<ChildPlacement>;
/** The refusal of a worktree the caller minted for a child its environment placed in the caller's own tree. */
export declare function worktreeNotHonored(cwd: string): Error & {
    code: "isolation.unavailable";
};
/**
 * The chain's top leg's anchors as THIS leg reads them (the person's global / session path rows and every `~/` row anchor
 * there): the chain's own (`live` as recorded, else the checkpoint's `seed` rebased — {@link recordedAnchors}), unless this
 * leg is a child placed `elsewhere` or no chain names one — then this leg is the top. A recorded root that is not an
 * absolute path anchors nothing: the rows it would anchor read `unreadable`.
 */
export declare function chainTopAnchors(cfg: {
    leg: PathRuleBases;
    live: InheritedGate["pathRuleAnchors"];
    seed: InheritedGate["pathRuleAnchors"];
    placement: ChildPlacement | undefined;
    rebase: (p: string) => string;
}): PathRuleBases;
/** The installation records a leg reads: the live chain's (as recorded), else the checkpoint's (through the workspace rebase). */
export interface ChainInstallations {
    readonly live: InheritedGate["pathRuleInstallations"];
    readonly seed: InheritedGate["pathRuleInstallations"];
}
/** Why no usable record says where a chain entry was installed: no record (a chain written before the record existed), a
 *  record that does not cover the chain position for position, or a member that names no absolute root. */
export type ChainInstallationGap = "absent" | "misaligned" | "invalid";
/**
 * The chain entries a leg could not install where they were installed: each UNINSTALLED entry (a host re-supplying a
 * chain) whose path rules depend on the installing leg, with no usable record of that leg. Such a chain is refused —
 * installing those entries anywhere else (the chain's top leg, this leg) would move what they protect. Entries whose rules
 * do not depend on it, and installed entries, never need a record.
 */
export declare function chainInstallationGaps(chain: readonly ToolPolicy[], installations: ChainInstallations, rebase: (p: string) => string): Array<{
    readonly position: number;
    readonly gap: ChainInstallationGap;
}>;
/** The refusal of a chain with {@link chainInstallationGaps} (`resume.parent_constraint_mismatch`, `detail.reason` naming
 *  the first gap's form); `pending` says the checkpoint is still pending (the refusal came before the claim). */
export declare function chainInstallationRefusal(gaps: ReadonlyArray<{
    readonly position: number;
    readonly gap: ChainInstallationGap;
}>, pending: boolean): CheckpointError;
/**
 * How a leg holds a caller policy — its own (`TaskSpec.toolPolicy` / `RunnerDeps.toolPolicy`) or one its delegation chain
 * hands it: a policy is installed where it ENTERS the chain, and a child holds its ancestor's installation (one object,
 * the same anchors) — its own caller slot included when that slot names the policy an ancestor installed. Installed again:
 * on a child placed `elsewhere` (another filesystem namespace — the ancestor's anchors name another namespace's files), at
 * this leg's anchors; a chain entry handed uninstalled (a host re-supplying a chain), where its installing leg recorded it
 * (`InheritedGate.pathRuleInstallations`, live or from the checkpoint). An uninstalled entry whose rules depend on that
 * leg and whose record is not usable refuses the leg ({@link chainInstallationRefusal}); one whose rules do not, reads
 * the same wherever it is installed (the chain's top leg).
 */
export declare function chainPolicyOnLeg(cfg: {
    leg: PathRuleBases;
    chainTop: PathRuleBases;
    placement: ChildPlacement | undefined;
    chain: readonly ToolPolicy[];
    installations: ChainInstallations;
    rebase: (p: string) => string;
}): {
    own: (policy: ToolPolicy | undefined) => ToolPolicy | undefined;
    chained: (policy: ToolPolicy, position: number) => ToolPolicy;
};
/** The installation record of a chain entry (its root and home), `null` for an entry with no path rules installed. */
export declare function installationRecordOf(policy: ToolPolicy): {
    readonly root: string;
    readonly home?: string;
} | null;
/** What a leg hands its children about anchors (data half): the chain's top leg's anchors — the person's global / session
 *  rows and every `~/` row anchor there — and where each entry handed down was installed, position for position (a chain
 *  re-supplied uninstalled is installed there again; absent when no entry is an installation). */
export declare function chainAnchorRecords(chainTop: PathRuleBases, chain: readonly {
    readonly policy: ToolPolicy;
}[]): Pick<InheritedGate, "pathRuleAnchors" | "pathRuleInstallations">;
