/**
 * The task root's CANONICAL spelling — and the one loud outlet for a host that hands in another one.
 *
 * Containment is judged on the canonical form: the roots fence resolves every target through the same
 * `ExecutionEnv` and compares canonical keys, the shell read boundary compares a command's words
 * against the declared roots, and every refusal message quotes them. A deployment that hands the
 * runner a root which is NOT its own realpath (a symlinked temp directory; `/var` → `/private/var` on
 * macOS) therefore reasons in one spelling while the engine judges in another, and a target the
 * deployment considers inside the root can be judged outside it. Before this seat that difference was
 * SILENT — the engine simply canonicalized and carried on.
 *
 * The bad-value discipline's announcement dialect applies (announce, do not refuse): an existing
 * deployment may well be running correctly on the non-canonical spelling, so the judgment is unchanged
 * and only the difference is disclosed. Nothing here repairs the host's spelling either — the engine
 * cannot know which of the two the deployment's own gates key on, and rewriting one into the other
 * would move a fence nobody asked to move.
 */
import type { ExecutionEnv } from "../../internal/harness.js";
import type { RunnerDeps } from "../runner-deps.js";
/** The canonical root plus whether the difference was announced (the pin's observable). */
export interface TaskRootCanonical {
    /** The spelling every fence judges with — the env's canonical form, or the given spelling when the
     *  env cannot resolve it (an unresolvable root narrows nothing here; the fence's own skip speaks). */
    canonical: string;
    /** True exactly when the given spelling differed and the notice was delivered. */
    announced: boolean;
}
/**
 * Resolve the run's task root to the spelling its fences judge with, announcing a host spelling that is
 * not that spelling.
 *
 * @contract task_root.canonical_is_the_judge — the engine judges containment on the task root's
 * CANONICAL spelling; when the root the host handed in is not its own canonical form the run announces
 * `config.task_root_not_canonical` exactly once, carrying both spellings, and then judges by the
 * canonical form exactly as before. The notice discloses the difference — it never repairs the host's
 * spelling, never narrows the fence, and never fires for a root that already is its own canonical form.
 */
export declare function resolveTaskRootCanonical(input: {
    env: Pick<ExecutionEnv, "canonicalPath">;
    /** The root as the host spelled it (`deps.rootPath` / the restored workspace root). */
    given: string;
    onNotice: RunnerDeps["onNotice"];
    sessionId: string;
    runId: string;
}): Promise<TaskRootCanonical>;
