/**
 * The tracked-cwd liveness probe and its diagnosis, shared by the three sites that spawn into the tracked
 * logical cwd: the shell's foreground and background legs, and the watch tool's background leg. A second
 * copy of either half would be a second answer to "is this directory usable?" and a second refusal
 * wording for the same fact, so both are minted here once and each leg passes only its own tool name.
 */
import type { ExecutionEnv } from "../../internal/harness-types.js";
/**
 * Is `dir` USABLE as a spawn cwd? "Dead" is the whole class, not just deletion: gone, replaced by a FILE
 * of the same name or standing under one, or a symlink that does not resolve to a directory. `fileInfo`
 * is lstat-semantics, so a symlink is judged by FOLLOWING it (`canonicalPath`, then one probe of the
 * target — a link retargeted at a file resolves perfectly well and is still not a cwd).
 *
 * The failure direction is deliberately asymmetric. Where a failure says nothing about the chain (the
 * initial lstat, the target's own), an error means death only when it SAYS so — refusing a command, or
 * resetting somebody's working directory, over one flaky stat would be worse than the failure being
 * diagnosed. The RESOLUTION step is the exception: a chain that will not resolve is no directory by any
 * reading; see {@link resolutionFailureMeansDead} for the one code that step reads as death on top.
 */
export declare function isDeadCwd(env: ExecutionEnv, dir: string, signal?: AbortSignal): Promise<boolean>;
/**
 * Dead-cwd diagnosis for a never-started command (spawn_error / shell_unavailable): a command that
 * DELETED or REPLACED the tracked cwd (e.g. `opam clean` after `cd` into a build dir) leaves the
 * persistent session pinned to a dead directory — every later spawn fails ENOENT/ENOTDIR with a message
 * blaming the SHELL BINARY ("spawn /bin/bash ENOENT"), the model concludes bash is gone, and the run is
 * permanently disabled (TB compile-compcert, 14 contaminated calls). The env can't distinguish this (spawn
 * reports the same code either way), so probe here:
 *  - tracked cwd dead + task root alive → SELF-HEAL: reset the tracked cwd to the root, tell the model
 *    what happened and that a retry works;
 *  - tracked cwd dead + root ALSO dead (never promise a retry that must fail) → honest
 *    unrecoverable verdict;
 *  - cwd IS the root and it's dead (`rm -rf "$PWD"` in place — a diverged-guard would
 *    skip diagnosis entirely) → honest root-gone verdict (no reset target exists);
 *  - the caller knows NO root (`root === undefined` — a direct mount that was never handed one) → say the
 *    cwd is gone and that this tool has no reset target, and stop there. Calling that directory "the task
 *    root" or declaring the tree unrecoverable would both be claims the caller cannot back: the root may
 *    well be alive, and a `cd` to it recovers. Nothing is reset.
 *  - cwd healthy → return undefined (the spawn failure has another cause; keep the original error).
 * Returns the model-facing message, or undefined when this is not a dead-cwd case. Uses only the public
 * env faces (`fileInfo`/`canonicalPath`) — works for any env that maps never-started failures to
 * spawn_error/shell_unavailable (contract note on ExecutionErrorCode).
 *
 * `root` is REQUIRED-but-nullable on purpose (not an optional parameter): a caller without a root has to
 * say so at the call site, so "this mount has no root" can never be spelled the same way as "I forgot".
 */
export declare function diagnoseDeadCwd(env: ExecutionEnv, toolName: string, effectiveCwd: string, root: string | undefined, cwdRef?: {
    current: string;
}, signal?: AbortSignal): Promise<string | undefined>;
