/**
 * The shell read JUDGE and its DECISION TABLE — the one place a shell command's read candidates become a
 * verdict, for every shell face (the full `Bash`, the read-only `Bash`, `Monitor`) and both moments (the
 * gate station before approval, the rewrite re-judge after it).
 *
 *  · `judgeRead` judges ONE established candidate: the deny half first, over every view the candidate has
 *    (its canonical target, its folded spelling, the kernel spelling of a `..` operand, the folded spelling
 *    of a candidate that could not be established), then containment over the canonical target alone. The
 *    deny judge is the boundary's own `denyMatch` closure (`readDenySeat`, read-deny.ts) — the same function
 *    object every read face mounts; nothing here compiles a pattern or re-derives a view set. The containment
 *    judge is `withinAnyRoot` over the roots the boundary declares — a WRITE target's over the write roots, at the
 *    seat it is written, under the write face in force ({@link judgeWrite}).
 *  · `foldShellReadFindings` folds a command's findings — every segment, every nested plan — to ONE word by
 *    the priority `identity_changed > deny_hit > unanswered > outside_roots > unestablishable > declined > none`.
 *  · `SHELL_READ_DECISION` is the total table (finding × seat → disposition) that is the ONLY source of
 *    "refuse / mandated ask / ordinary ask / vouch" for a shell read. A seat is a FACE word, not a tool name
 *    and not a permission mode: which shell face the call runs on (the full shell, the read-only shell) or
 *    which moment judges it (the re-judge after approval). The permission mode is not read here — what a
 *    mode does with the ask this table mints is decided once, downstream, where every ask is arbitrated.
 *
 * The floor this module is (`shell.read_boundary.friction_floor`) is stated on {@link judgeRead}.
 */
import type { BashReadonlyRootBoundary } from "./bash-readonly-classifier.js";
import type { ReadCandidate, ShellReadPlan, ShellReadSegment } from "./shell-read-plan.js";
import type { Incomplete, ObservedFilesystem } from "./shell-read-environment.js";
import type { WriteSeat } from "./shell-read-write-targets.js";
import { type ContainmentFace } from "./containment-face.js";
import type { AssertAllKeysHandled } from "../../core/ask-origin.js";
/** WHAT the judge found about a command — a closed set, registered in `docs/CLOSED-SETS.md`. */
export declare const SHELL_READ_FINDINGS: readonly ["deny_hit", "outside_roots", "unestablishable", "declined", "identity_changed", "unanswered", "none"];
export type ShellReadFinding = (typeof SHELL_READ_FINDINGS)[number];
/** WHERE a read is judged — the seats the decision table is keyed on, one per FACE: `full_shell` the
 *  writable shell (`Bash`, `Monitor`) under every permission mode and every shell-gate floor; `readonly`
 *  the read-only shell face (`handsReadOnly`); `rejudge` the post-approval re-judgment of rewritten bytes
 *  and the pre-spawn identity re-check. */
export declare const SHELL_READ_SEATS: readonly ["full_shell", "readonly", "rejudge"];
export type ShellReadSeat = (typeof SHELL_READ_SEATS)[number];
/** The fold priority: a command's finding is the highest-ranked finding of any candidate in it. */
export declare const SHELL_READ_FINDING_RANK: {
    readonly identity_changed: 6;
    readonly deny_hit: 5;
    readonly unanswered: 4;
    readonly outside_roots: 3;
    readonly unestablishable: 2;
    readonly declined: 1;
    readonly none: 0;
};
/** Compile-time fence: `never` while every finding has a rank. */
export type RankTableCoversEveryFinding = AssertAllKeysHandled<Exclude<ShellReadFinding, keyof typeof SHELL_READ_FINDING_RANK>>;
/** What a seat does with a finding. `refuse` = a deny at the station (or a veto after a person's yes);
 *  `mandated` = an ask no automatic lane may clear; `ordinary` = an ask any answerer may clear (a person,
 *  the auto-mode classifier, a stored allow rule) but no answerless engine table may; `vouch` = the station
 *  has no question. */
export type ShellReadDisposition = "refuse" | "mandated" | "ordinary" | "vouch";
/** One cell of the decision table: a disposition, or — where the FORM of the question decides it — its readings: `narrowed` (raised
 *  under the `roots` read face: the fence the deployment narrowed, and the engine default), `open` (under the open read face, or a
 *  written target alone) and, where it differs, `redirect` (every containment finding is an output redirection outside the write
 *  roots). */
export type ShellReadCell = ShellReadDisposition | {
    readonly narrowed: ShellReadDisposition;
    readonly open: ShellReadDisposition;
    readonly redirect?: ShellReadDisposition;
};
/** A cell, read for the form of the question ({@link ShellReadCellContext}): the redirect reading where the cell has one and every
 *  containment finding is a redirection, otherwise the read face's (absent ⇒ narrowed, the engine default). */
export declare function dispositionOfCell(cell: ShellReadCell, context?: ShellReadCellContext): ShellReadDisposition;
/**
 * THE decision table — total over findings × seats; no cell is n/a. Row by row:
 *  · `deny_hit` — refused on every seat, for a spelling the station can establish: a deny row is a floor
 *    no root grant and no approval moves. A spelling the station cannot establish is not a deny hit (it is
 *    the `unestablishable` row) — the floor holds what it can place, and says so rather than guessing.
 *  · `outside_roots` — asked where a person can be asked (the full shell), refused where none can (the
 *    read-only face has no approval channel; a rewrite that leaves the roots after approval was seen by
 *    nobody). The full shell's ask is MANDATED, except for a command whose every containment finding is an OUTPUT
 *    REDIRECTION outside the write roots (the cell's `redirect` reading): the permission question a stored allow answers,
 *    the ORDINARY ask. The reference implementation's redirection check (CC 2.1.296 `lvr` (cli296.js:249645) @18502854,
 *    called @18508831) asks such a target as a plain permission ask that is not rule-overridable: a whole-tool `Bash` allow
 *    (`$pn` @18717070) and bypass (`$pn` @18716980) release it, a prefix allow does not (`vX`'s ask returns before the allow
 *    rules, @18567915). A command that also reads outside the roots, or writes a program operand there (`tee`, `cp`, …),
 *    keeps the mandate.
 *  · `unestablishable` — the floor could not say where the command reads, so it is not vouched anywhere: asked
 *    where a person can be asked (the full shell), refused where none can be asked. The full shell's cell is read by the read face
 *    the question was raised under: on a NARROWED (`roots`) face — the engine default — the deployment asked to be asked, so the
 *    ask is MANDATED and no automatic lane answers; on the OPEN face (where the station asks only because a deny list has
 *    rows), and for a written target alone (a narrowed WRITE face fences what is written; it is no request to be asked about
 *    every word the floor cannot place), it is the ORDINARY ask — the reference implementation's plain permission ask (CC
 *    2.1.296 `sR` (cli296.js:242691) @13116941, reason `other`), which a whole-tool allow (`N9` (cli296.js:249675) @18717070), bypass (`$pn` (cli296.js:249675) @18716980)
 *    and the auto-mode classifier release and a prefix allow does not.
 *  · `declined` — the one deliberate fail-open of this table: the scan could not read the program bash
 *    will run, or the operands arrive on a stream. On the full shell it is an ORDINARY ask — an answerer
 *    may settle it, and an out-of-root read hidden inside such a command is then not asked again. The
 *    read-only face refuses: its allowlist is a deployment knob, so this cell is reachable and must not be
 *    n/a.
 *  · `identity_changed` — a candidate established at approval time resolves elsewhere at spawn time:
 *    refused everywhere (it is only ever produced on the `rejudge` seat).
 *  · `unanswered` — the judge did not FINISH: it threw or timed out, the lookup it stands on was absent, or — recorded at the
 *    one door to the environment ({@link import("./shell-read-environment.js").Incomplete}) — an environment lookup gave no
 *    answer (an error that is no conclusive "not there"), the station stopped at its own bound (more directories or names than
 *    it enumerates, a link chain past its hop bound), or a home view could not be read — or a recursive read's root may hold a
 *    home-anchored deny row that no home places (the environment declares none, or its placement did not answer), a home the
 *    station cannot place either. Any one makes the whole command
 *    `unanswered`, whatever the other words found. Not a fact about the command but the state of the station, so it is not
 *    the `unestablishable` row's question (a text the station cannot place — a word the shell rewrites, a lost working
 *    directory, a pattern its matcher does not model). Absence is not
 *    "nothing there": the full shell asks it MANDATED on every read face — a standing allow was given on the premise that the
 *    judge works, and a broken judge is not cleared by it — and the read-only face refuses.
 *  · `none` — vouched: the station has no question (the full shell's shape tier may still ask).
 */
export declare const SHELL_READ_DECISION: {
    readonly deny_hit: {
        readonly full_shell: "refuse";
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly outside_roots: {
        readonly full_shell: {
            readonly narrowed: "mandated";
            readonly open: "mandated";
            readonly redirect: "ordinary";
        };
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly unestablishable: {
        readonly full_shell: {
            readonly narrowed: "mandated";
            readonly open: "ordinary";
        };
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly declined: {
        readonly full_shell: "ordinary";
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly identity_changed: {
        readonly full_shell: "refuse";
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly unanswered: {
        readonly full_shell: "mandated";
        readonly readonly: "refuse";
        readonly rejudge: "refuse";
    };
    readonly none: {
        readonly full_shell: "vouch";
        readonly readonly: "vouch";
        readonly rejudge: "vouch";
    };
};
/** Compile-time fence: `never` while every finding has a row. */
export type DecisionTableCoversEveryFinding = AssertAllKeysHandled<Exclude<ShellReadFinding, keyof typeof SHELL_READ_DECISION>>;
/** Compile-time fence: `never` while every seat has a cell on the `none` row (the `satisfies` above holds
 *  every other row to the same shape). */
export type DecisionTableCoversEverySeat = AssertAllKeysHandled<Exclude<ShellReadSeat, keyof (typeof SHELL_READ_DECISION)["none"]>>;
/** The disposition of one command-level finding on one seat — the table, read. A seat word outside
 *  {@link SHELL_READ_SEATS} (an untyped caller, or one still passing a retired word) is refused loudly: an
 *  absent disposition would read as "no verdict", which no caller can act on safely. */
export declare function decideShellRead<F extends ShellReadFinding>(finding: F, seat: ShellReadSeat, context?: ShellReadCellContext): RowDisposition<F>;
/** The dispositions the table's row for `F` holds — on any seat, under any form of the question (the table's own literal words). */
export type RowDisposition<F extends ShellReadFinding> = CellWords<(typeof SHELL_READ_DECISION)[F][ShellReadSeat]>;
/** What the table is read for beyond (finding, seat): the two facts of a judged command a cell can depend on. */
export interface ShellReadCellContext {
    /** Every containment finding is an output redirection outside the write roots (a cell's `redirect` reading). Absent ⇒ no. */
    readonly redirectsOnly?: boolean;
    /** The question was raised under a NARROWED (`roots`) read face — a read candidate or the text's own structure while the read
     *  face runs the roots containment; `false` for the open face and for a written target alone. Absent ⇒ narrowed, the engine default. */
    readonly narrowedReadFace?: boolean;
}
/** Every disposition the table gives `finding` — on any seat, under any form of the question; empty for a word outside
 *  {@link SHELL_READ_FINDINGS}. A disposition outside it is no reading of the table: what a reader of a station's answer
 *  checks the answer against. */
export declare function dispositionsOfRow(finding: string): ReadonlySet<ShellReadDisposition>;
/** The words a cell can read as. */
type CellWords<C> = C extends string ? C : C[keyof C];
/** The findings whose row the table vouches on, on any seat and under any form. */
type FindingsTheTableVouches = {
    [F in ShellReadFinding]: "vouch" extends RowDisposition<F> ? F : never;
}[ShellReadFinding];
/** Compile-time fence: `never` while `vouch` is a cell of the `none` row alone — what lets a vouch carry the finding `none` and
 *  nothing else ({@link import("./shell-read-check.js").ShellReadVerdict}). */
export type VouchOnlyOnTheNoneRow = AssertAllKeysHandled<Exclude<FindingsTheTableVouches, "none">>;
/**
 * The boundary a shell read is judged against: the declared roots (canonical), the working directory and
 * home the plan's bases start from, the deny seat (the SAME `denyMatch` closure every read face mounts),
 * the containment face, and — for the read-only face — the engine's own overflow-spool fence as one more
 * member of "inside" (`alsoInside`), asked once per target that landed outside the roots.
 */
export interface ShellReadBoundary extends BashReadonlyRootBoundary {
    readonly alsoInside?: (canonicalTarget: string) => Promise<boolean>;
    /** A partition of the rules the deny seats are compiled from could not be read: a guard of unknown reach. The station
     *  guards ({@link stationGuards}) and vouches for nothing against this boundary — what it would vouch for is answered as
     *  a judgment it could not make. */
    readonly unreadPartitions?: true;
    /** The deny table's WRITE face (`compileWriteDeny`, read-deny.ts): judges a command's write targets (candidates marked
     *  `face: "write"`) and returns the matched row's rule, or null. PRESENT-IFF there is something to judge. */
    readonly writeDenyMatch?: (resolvedPath: string) => string | null;
    /** The read table's rows AT or BELOW a path (`readDenySeat`'s `denyAtOrBelow`, read-deny.ts): read by the station's
     *  `writesPlaced` fact only, through {@link denyRowAtOrBelow}. */
    readonly denyAtOrBelow?: (resolvedPath: string) => string | null;
    /** The WRITE roots (canonical) — the task root and every additional working directory, never a read-only grant: where a
     *  command's write targets must land ({@link judgeRead}'s write face: a target written outside them is an
     *  `outside_roots` finding), and so where a mode that accepts file commands may place them. Absent ⇒ where a write may
     *  land is unknown: a written target is `unestablishable` and nothing is placed. */
    readonly writeRoots?: readonly string[];
    /** The WRITE face in force — the same seat the structured write tools read (the run's resolved write face, read once per
     *  judgment where the boundary is built): `"open"` skips the write roots' containment for a finding, as it skips the
     *  structured tools' root fence ({@link skipsRootsContainment}; absent ⇒ roots). Placement still reads the write roots:
     *  a mode accepting file commands accepts them inside its own directories, whatever the face. */
    readonly writeFace?: ContainmentFace;
    /** The leg's ONE write judgment of an ABSOLUTE write target — the one a write tool's target meets (its spelling, its real
     *  target and every hop of its symlink chain, under the leg's one exempt root), over the write-protection TABLE and the
     *  deployment's guarded write rows (`ToolPolicy.writeGuardRows`, every policy of the leg's chain) together; `canonical` ⇔
     *  the path is a key the station established (judged as a key, never as a spelling). `"protected"`: the table covers it —
     *  the target is not placed and the verdict says so ({@link import("./shell-read-check.js").ShellReadVerdict.writeProtected});
     *  `"guarded"`: a deployment row covers it — the target is not placed; `undefined`: nothing covers it. Read by the
     *  station's write facts only. A judgment that throws fails the station's answer (the caller's fail-closed arm). Every lookup
     *  it makes goes through `fs` — the command's door — and through no environment of its own: the station's one decision about
     *  what a silence means reads the answers the judgment got as well as the ones it did not. */
    readonly writeTargetJudge?: (target: string, opts: {
        readonly fs: ObservedFilesystem;
        readonly signal?: AbortSignal;
        readonly canonical?: true;
    }) => Promise<"protected" | "guarded" | undefined>;
}
/** How far one candidate got before it was judged. `lexical` = the folded spelling is the judged target
 *  (an isolated sandbox, or a resolver that declares no authority and did not answer); `canonical` = the
 *  environment resolved it; `expansion` = one path a pattern expanded to or a traversal enumerated;
 *  `unestablishable` = the floor could not say where it lands (`cause` says why). */
export type ReadEstablishment = "lexical" | "canonical" | "expansion" | "unestablishable";
export interface EstablishedRead {
    readonly candidate: ReadCandidate;
    readonly established: ReadEstablishment;
    /** The judged target: an absolute path (canonical where established so, the folded spelling otherwise).
     *  Absent exactly when `established === "unestablishable"`. */
    readonly target?: string;
    /** Every spelling the deny judge sees BESIDE the target: the folded spelling, the kernel spelling of a
     *  `..` operand, the pattern an expansion came from, the placeholder-carrying fold of a substitution. */
    readonly spellings: readonly string[];
    /** The pattern or traversal root an `expansion` came from, as folded. */
    readonly origin?: string;
    /** What the environment said the target IS, where a read asked — only a traversal root asks (it lists the root
     *  once; a link's answer is its target's). Absent = nothing asked; a plain read never lists. */
    readonly node?: "directory" | "file";
    /** Why the candidate could not be established. */
    readonly cause?: string;
    /** The candidate's spelling WAS placed and the environment could not resolve where it leads (the whole chain unanswered by
     *  a resolver that declares itself authoritative, or a component it could not follow) — the reading's
     *  `target_unresolved` fact, as opposed to a text the station cannot read (a rewritten word, an unsettled working
     *  directory). Present only on an `unestablishable` read. (That the environment gave no answer is the establishment's
     *  `incomplete`, which makes the command `unanswered` whether or not a candidate carries this mark.) */
    readonly unresolved?: true;
    /** WHERE the command's program writes this target — present only on a write target the program itself writes, at the
     *  seat this read was established at (`landing`: through the path's links; `entry`: the directory entry, a link there
     *  not followed). Absent on a read, and on a write-face target the program only names (a copy's source). `child`: the
     *  candidate's own mark ({@link import("./shell-read-write-targets.js").JudgedCandidate.child}), carried to the read. */
    readonly written?: {
        readonly seat: WriteSeat;
        readonly child?: true;
    };
}
/** What the judge found about ONE candidate. `kind` is one of the five candidate-level findings (`declined` is a segment fact,
 *  `identity_changed` a re-establishment fact — neither is a candidate's; `unanswered` is a fact of the whole establishment, and
 *  a candidate's where a recursive read's root may hold a deny row no home places, {@link judgeRead}). */
export interface ReadFinding {
    readonly read: EstablishedRead;
    readonly kind: Extract<ShellReadFinding, "deny_hit" | "outside_roots" | "unestablishable" | "unanswered" | "none">;
    /** The deny row that matched, the view it matched on, and — for a write target — the face (`write`) that refused. */
    readonly deny?: {
        readonly pattern: string;
        readonly matchedView: string;
        readonly face?: "write";
    };
    readonly containment: "inside" | "outside" | "open" | "unknown";
}
/**
 * Judge ONE established candidate. Deny first, over every view (a hit on any view decides — a symlink whose
 * SPELLING names a guarded path is refused even when its target is elsewhere, and a substitution's folded
 * spelling is judged although the candidate could not be established); containment over the canonical
 * target alone, and only where the boundary's face closes it.
 *
 * @contract shell.read_boundary.friction_floor — what this judge answers is a question about TEXT and the
 * FILESYSTEM the command will run in: which files the words of a command may name, resolved against the
 * declared roots, the declared home and the observed working directory, and — where the environment can
 * answer — where those spellings really land (symlinks resolved, patterns expanded, traversal roots
 * enumerated, each within a bound). It is not a question about what the process will open. A deployment's
 * containment for what a shell may reach is the `ExecutionEnv` the command runs in (a sandbox, a
 * container, a remote adapter); everything here is the friction floor under that containment. Under an
 * isolated sandbox the floor is lexical (the sandbox is the boundary and its filesystem is not this
 * process's to resolve). A deny-listed read is REFUSED on every seat; an out-of-root read asks where a
 * person can be asked and is refused where none can; a read the floor cannot establish (an expansion it
 * cannot finish, a spelling the shell rewrites, a working directory it cannot place) is asked or refused
 * the same way — never vouched. Containment judges what a READ program opens: a program path is executed,
 * not disclosed, and a leading environment word's value reaches the program through its environment, so
 * neither is a containment candidate — both still meet the deny judge, on every spelling.
 */
export declare function judgeRead(read: EstablishedRead, boundary: ShellReadBoundary): ReadFinding;
/**
 * Does a deny row lie AT or BELOW this write target, on any view the judge reads? Then a command that moves, copies or
 * removes the target changes what the row covers, and a mode must not answer it unasked. WHICH tables answer is what the
 * command does to the content below the target: a move or a copy carries it somewhere else (`mv .docker d` leaves
 * `d/config.json` outside `.docker/config.json`; `mv <home> x` takes every home-anchored row's file along), so the READ
 * table's rows answer too (`carriesContent`); a removal carries nothing anywhere — it is a write and nothing else, and
 * only the write table answers it (the reference implementation's path check reads the read rows for a copy's or a
 * move's sources and for sed, never for `rm` / `rmdir`). The read table answers per row (`denyAtOrBelow`); the write
 * table's rows are rule rows, whose reach below a path is not enumerable, so any of them answers.
 */
export declare function denyRowAtOrBelow(read: EstablishedRead, boundary: ShellReadBoundary, carriesContent: boolean): boolean;
/**
 * The deny floor of every home word the plan does not place: each candidate carrying a `floorSpelled` (the word
 * spelled with the DECLARED home) gets a SHADOW candidate at that spelling, established exactly as a read is — the
 * canonical target, a pattern's matches (a glob the word carries unquoted), a traversal root's tree — and judged for
 * deny rows only (`denyOnly`). A deny row is a floor the text's rebinding may never reach past; the shadow adds no
 * other finding, so a read that is not a deny row still asks through its own unplaced candidate.
 */
export declare function denyFloorShadowsOf(candidates: readonly ReadCandidate[]): ReadCandidate[];
/** One segment's judged reads and declines, with its nested plans judged the same way. */
export interface JudgedSegment {
    readonly segment: ShellReadSegment;
    readonly findings: readonly ReadFinding[];
    readonly nested: readonly JudgedPlan[];
}
export interface JudgedPlan {
    readonly plan: ShellReadPlan;
    readonly segments: readonly JudgedSegment[];
    /** {@link stationGuards} of the boundary the plan was judged against — what a READ finding folds by. */
    readonly guards: boolean;
    /** {@link writeFaceGuards} of the same boundary — what a WRITE target's finding folds by. */
    readonly writeGuards: boolean;
    /** What the command could not finish (the station's one door, decided after the write guards asked); on the top plan only. */
    readonly incomplete?: readonly Incomplete[];
}
/**
 * Does the station GUARD anything for this boundary — a closed face (roots: containment is what it guards; an absent
 * face reads as roots, as {@link containmentOf} does), or a deny table with rows (`denyMatch` is present exactly then),
 * or rows it could not read (`unreadPartitions`: a guard of unknown reach)?
 * Where it guards nothing (an open face, no deny row), a read it could not establish has nothing to be confirmed
 * against: no finding. The deny judgment itself is untouched (with no row there is nothing to hit). The READ face's
 * question only: a write target folds by {@link writeFaceGuards}.
 */
export declare function stationGuards(boundary: Pick<ShellReadBoundary, "face" | "denyMatch" | "unreadPartitions">): boolean;
/**
 * Does the station guard anything on the WRITE face — the same shape for the write seats: the write face in force runs
 * the roots-containment step ({@link skipsRootsContainment}, the structured write tools' reading; absent ⇒ roots), or
 * the write deny table has rows. Where it guards nothing (an open write face, no write row), a write target the station
 * could not establish has nothing to be confirmed against — as a structured write under that face is not fenced.
 */
export declare function writeFaceGuards(boundary: Pick<ShellReadBoundary, "writeFace" | "writeDenyMatch">): boolean;
/** Does the station guard anything on EITHER face? What a finding about the text's own structure folds by — a text the
 *  lexer could not read, a program it cannot name, program text it does not read, a working directory it lost, a text the
 *  shell re-enters — since what such a text reads AND what it writes are both unknown. */
export declare function anyFaceGuards(boundary: Pick<ShellReadBoundary, "face" | "denyMatch" | "unreadPartitions" | "writeFace" | "writeDenyMatch">): boolean;
/** The command-level fold and the finding that produced it. `witness` is absent for `none`; for `declined`
 *  the segment that declined stands in for a candidate. */
export interface ShellReadFold {
    readonly finding: ShellReadFinding;
    readonly witness?: ReadFinding;
    readonly declined?: ShellReadSegment;
    /** What the judge did not finish, for an `unanswered` finding: the first thing the establishment recorded ({@link Incomplete.detail}). */
    readonly cause?: string;
    /** Some read of the text could not be established (an `unestablishable`, `unanswered` or `declined` finding anywhere, winning or not). */
    readonly unestablished?: true;
    /** Some `unestablishable` finding anywhere is about the READ face — a read candidate, or the text's own structure (a rewritten
     *  word, a re-entered shell text) — rather than a written target alone. The cell of the row reads it with the read face in force
     *  ({@link decideShellRead}). */
    readonly unplacedRead?: true;
}
/**
 * Fold a judged plan to ONE finding by {@link SHELL_READ_FINDING_RANK}, over every segment and every nested
 * plan. Where the station guards nothing an `unestablishable`, `unanswered` or `declined` finding is no finding: there is nothing to
 * confirm it against. Which guard is asked is the face the finding is about — a read candidate's by the read face's
 * ({@link JudgedPlan.guards}), a write target's by the write face's ({@link JudgedPlan.writeGuards}), and a finding about
 * the text's own structure (no candidate stands in for it) by either ({@link anyFaceGuards}). Two structural rules ride the fold:
 *  · a plan the lexer refused (`unreadable`) is `unestablishable`, unconditionally — a quote-blind re-read
 *    yields more words, never zero, so an unreadable text is never "no candidates";
 *  · a SHELL re-entry segment (`sh -c S`, `eval S`, `env -S 'S'`, a launcher handing text to a shell) is at
 *    least `unestablishable` — what runs is text the shell parses, not this plan — and its nested plan may
 *    only RAISE that: the nested text's deny-relation answers count — a deny hit (a refusal is a refusal whatever
 *    runs it) and a root that may hold a row no home places — its containment and its other silence do not (an inner
 *    `cat inside.txt` vouches nothing about the outer text). A substitution body (`$(…)`, a backtick, `<(…)`) is nested
 *    WITHOUT re-entry and folds in full.
 */
export declare function foldShellReadFindings(judged: JudgedPlan): ShellReadFold;
/** Judge every established read of a plan, in place. `establish` runs per segment so a caller can bound it. */
export declare function judgeEstablishedPlan(plan: ShellReadPlan, established: ReadonlyMap<ShellReadSegment, readonly EstablishedRead[]>, boundary: ShellReadBoundary, nestedOf: (plan: ShellReadPlan) => JudgedPlan): JudgedPlan;
/** Every finding of a judged plan, flattened (segments and nested plans alike). */
export declare function allFindings(judged: JudgedPlan): ReadFinding[];
/** One lexical step up, family-aware. A family ROOT is its own parent — the fixpoint the climb below ends
 *  on, and the one spelling this file can recognise as "the whole filesystem" without I/O. */
export declare function parentDirLexically(p: string): string;
/**
 * The deepest directory containing both, or `undefined` when they share none (two path families).
 *
 * LINEAR, and that is the point: both paths are already folded, so the answer is their common prefix cut
 * at a separator. Climbing one directory at a time re-folds the whole remaining path each step — the same
 * answer at quadratic cost, measured at 4.9 s of synchronous work for one 32 KB command naming a
 * 16 000-segment operand. The family-aware comparator keeps the last word: a prefix it cannot confirm
 * contains both paths yields no candidate.
 */
export declare function deepestCommonDir(a: string, b: string): string | undefined;
/**
 * The ONE directory whose addition to the declared roots would answer every `outside_roots` finding of a
 * command — offered only when re-judging the same established reads with that root added leaves no
 * finding at all (MEASURED, not argued: a deny row or an unestablishable candidate beside the out-of-root
 * one leaves the ask standing whatever root is granted, and then nothing is offered; so does a target written outside
 * the WRITE roots, which no read root answers — a read grant grants no write). `exact` ⇒ the value
 * is the one path the command NAMED, offered verbatim, because the containing directory would hand out the
 * home or a root. A `..` spelling gets no offer: the folded and the kernel reading of it can disagree about
 * whether the target is back inside, which no replay of the text settles.
 */
export declare function readRootGrantCandidateOf(judged: JudgedPlan, boundary: ShellReadBoundary): {
    readonly dir: string;
    readonly covers?: "exact";
} | undefined;
/**
 * The grant a read-root card offers for the directory `candidate` it would add. A directory that would hand out more
 * than was read is not offered: a family root grants the whole filesystem, and one CONTAINING the declared home or a
 * root grants the workspace. ONE fallback for both rather than no offer at all — the single path that WAS read
 * (`single`), named VERBATIM (`covers: "exact"`); with several paths read, no offer.
 */
export declare function grantOfferFor(candidate: string, single: string | undefined, bounds: Pick<ShellReadBoundary, "roots" | "homeDir">): {
    dir: string;
    covers?: "exact";
} | undefined;
/** The same judged plan under another boundary — the established reads are kept, only the judgment reruns. */
export declare function rejudge(judged: JudgedPlan, boundary: ShellReadBoundary): JudgedPlan;
export {};
