/**
 * One deny entry: a `/`-separated run of path SEGMENTS. `*` matches any run of non-separator
 * characters within one segment and is the ONLY metacharacter (everything else is literal). The run
 * may match ANYWHERE in the judged path (`.ssh` covers `~/.ssh/…` and any other `.ssh` directory) —
 * unless the pattern opens with the HOME word ({@link READ_DENY_HOME_WORD}): `~/<run>` matches only where
 * the run starts right below the execution environment's home directory (`~/.sema/settings.json` is the
 * home's file, never a project's `.sema/settings.json`). Only a FIRST segment that is exactly `~` is the
 * word; `~user` and a `~` further along are literal segments.
 * String shorthand ≡ `{ pattern }`. Matching is ASCII-case-insensitive by default (a case-insensitive
 * filesystem serves `.SSH` and `.ssh` as the same directory); `caseSensitive: true` opts a single
 * entry out. Unicode normalization (NFC/NFD) and volume-level case semantics are NOT modeled (v1
 * residual, shared with the write guard; the canonical view — realpath returns the on-disk spelling —
 * covers half of it).
 */
export type ReadDenyEntry = string | {
    pattern: string;
    caseSensitive?: boolean;
};
/** The HOME word of the pattern grammar ({@link ReadDenyEntry}): a FIRST segment spelled exactly this anchors the run
 *  right below the execution environment's home directory. */
export declare const READ_DENY_HOME_WORD = "~";
/** A pattern read as its anchor and its run: `~/a/b` ⇒ the run `a/b`, home-anchored; any other pattern ⇒ itself,
 *  unanchored. The one reader of the home word — the compiler, the traversal globs, the classifier's rendering and the
 *  write face's mirror all take the run from here. */
export declare function readDenyPatternRun(pattern: string): {
    readonly homeAnchored: boolean;
    readonly run: string;
};
/** How many leading segments of a run are LITERAL — the run's head before the first segment carrying `*`. A home-anchored
 *  row's head names one location below the home, which a mount resolves to where it really leads
 *  ({@link compileReadDeny}'s `linked`); the segments after it are matched below that location as the run matches. */
export declare function readDenyRunHead(run: string): number;
/** The normalized (validated, defaulted) form of one entry. */
export interface NormalizedReadDenyEntry {
    pattern: string;
    caseSensitive: boolean;
}
/** A deny verdict: which entry's pattern matched. */
export interface ReadDenyHit {
    pattern: string;
    /** The view string the pattern actually matched (set by {@link CompiledReadDeny.matchTarget}: the
     *  canonical key, or the lexical view when only the SPELLING matched). Disclosure must cite the
     *  matched view — under a symlink/case alias the two strings differ, and naming the other one
     *  sends the reader chasing a path the pattern does not match. */
    matchedView?: string;
}
/** The two faces of the deny table: what a READ must not reach, and what a WRITE must not reach. */
export declare const DENY_FACES: readonly ["read", "write"];
export type DenyFace = (typeof DENY_FACES)[number];
/**
 * A deny row in the rule DSL's PATH grammar — a `Read(<pattern>)` / `Edit(<pattern>)` deny rule, compiled by the
 * rule compiler against its own bases (`createPermissionRulePolicy`). It joins the SAME table as the segment rows: one
 * judge (`matchPath` / `matchTarget`), one refusal sentence, one classifier rendering — only the row's reach is the
 * rule grammar's (the path it names and everything under a directory it names), not a segment run.
 *  · `rule` — the rule as written, the row's name wherever a refusal or the classifier names it;
 *  · `tool` / `pattern` — the rule's two parts, for a rendering that states the pattern inertly;
 *  · `faces` — which faces the row guards (`Read` ⇒ read and write: a path whose reads are denied is not written
 *    either; `Edit` ⇒ write);
 *  · `reaches` — the rule compiler's own reach over an ABSOLUTE path.
 */
export interface PathRuleDenyRow {
    readonly rule: string;
    readonly tool: string;
    readonly pattern: string;
    readonly faces: readonly DenyFace[];
    readonly reaches: (absolutePath: string) => boolean;
    /** The row's HEAD — the absolute location its reach starts at (the rule model's `pathRuleHeadOf`: the pattern's
     *  literal prefix under its base, a directory rule's directory), spelled so the execution environment can resolve it.
     *  A leg judges the row where that location LEADS too ({@link withRuleRowsWhereTheyLead}). Absent on a hand-built
     *  row, or one whose head cannot be read: it is judged as spelled. */
    readonly head?: string;
}
/**
 * The rule rows as a leg judges them: each row as spelled, and — for every location on the way to the row's HEAD (each
 * leading part of it: the anchor's children down to the head itself) that the environment resolves to another spelling
 * (a link or firmlink: `/tmp` → `/private/tmp`, `/var` → `/private/var`, a project root, a home entry or a directory
 * inside the rule reached through a symlink) — the same row at that spelling: a path at or below the resolved location
 * is judged as its spelling at or below that part. Every read and write face judges the CANONICAL key of a target beside
 * its spelled view, so a row whose head is spelled through a link would otherwise never meet a target named by its real
 * location — whether the row was written with the short spelling and the call with the long one, or the reverse. Every
 * part, not the head alone: a link inside the rule's literal prefix that is re-pointed after the rows were placed still
 * meets the row through the parts above it (`<real root>/alias/**` holds when `alias` moves). One rule for every row
 * form (absolute, home, root, working directory, directory): the reference compiles the same "physical twin" of every
 * deny / ask rule's literal prefix (cli280.js `ei` 9766583, compiled in `mt` 9767083). `leadsTo` is the leg's resolution,
 * the one the faces mint their keys with (`undefined` = could not resolve: no twin there); each location is resolved
 * once, and a part that only extends its parent's resolution adds no row.
 */
export declare function withRuleRowsWhereTheyLead(rows: readonly PathRuleDenyRow[], leadsTo: (head: string) => Promise<string | undefined>): Promise<PathRuleDenyRow[]>;
/**
 * The WRITE face of the deny table: the rule rows whose faces include `write` — the judge the shell station reads for a
 * command's write targets (a redirection, `tee`, `sed -i`, `cp` / `mv` / `touch` / `mkdir` / `rm` operands). Same row
 * type, same judgment (`ruleRowHit`) as the read face's rule rows; a hit names the row by its rule text.
 */
export interface WriteDenyMatcher {
    /** Which face this judge is — the write tools' path resolution reads it to word and code the refusal as a write. */
    readonly face: "write";
    readonly ruleRows: readonly PathRuleDenyRow[];
    matchPath(path: string): ReadDenyHit | null;
    /** The target judgment the read face makes, on this face's rows: canonical key, lexical view, the leaf chain's hops. */
    matchTarget(canonicalKey: string, lexicalView?: string, opts?: {
        readonly aliasResolved?: boolean;
        readonly hops?: readonly string[];
    }): ReadDenyHit | null;
}
/** Compile the write face over the rule rows (the rows not on it are dropped here, once). */
export declare function compileWriteDeny(rules?: readonly PathRuleDenyRow[]): WriteDenyMatcher;
/** One compiled ripgrep glob flag for the traversal legs (`--iglob` = case-insensitive entry). */
export interface ReadDenyRgGlob {
    flag: "--glob" | "--iglob";
    glob: string;
}
/**
 * The compiled deny judge — ONE compilation, consumed by every judgment point (target judgment in
 * resolveKey, the JS walker, the rg exclusion/probe legs, the classify operand probe, the ENOENT
 * sibling filter, the attachment reader), so the legs cannot drift apart.
 */
export interface ReadDenyMatcher {
    /** Normalized entries (built-ins first, then additions; exact duplicates folded). The disclosure /
     *  persistence face. */
    readonly entries: readonly NormalizedReadDenyEntry[];
    /** The rule-DSL rows on the READ face ({@link PathRuleDenyRow}), judged after the segment rows. Not persisted:
     *  they are the caller policy's, which a resume re-supplies. Absent on a matcher compiled without rules. */
    readonly ruleRows?: readonly PathRuleDenyRow[];
    /** Judge ONE path view (segment-window semantics). Returns the first matching entry, or null.
     *  `aliasResolved` = the key's MINTER reports the real filesystem already collapsed any win32
     *  component alias in it (canonicalizeTarget's realpath arm); unset ⇒ both readings are judged,
     *  which is the fail-closed default. `walked` = the path is a MEMBER a traversal enumerated below a
     *  root the command's text names, not a spelling of the command: the rule-DSL rows do not judge it (a
     *  `Read(<pattern>)` deny reaches what the command SPELLS — the reference implementation's best-effort
     *  reading of a rule against a command's arguments), while the segment rows (the built-in tiers, the
     *  deployment's patterns) reach every path a read can open. Unset ⇒ every row, the fail-closed default. */
    matchPath(path: string, opts?: {
        readonly aliasResolved?: boolean;
        readonly walked?: boolean;
    }): ReadDenyHit | null;
    /** §3.3 target judgment: canonical view + lexical view + every hop of the leaf symlink chain (`hops`,
     *  each an unresolved spelling some link wrote); ANY hit decides. `aliasResolved` applies to the
     *  CANONICAL arm only — the lexical view and the hops are unresolved spellings. */
    matchTarget(canonicalKey: string, lexicalView?: string, opts?: {
        readonly aliasResolved?: boolean;
        readonly hops?: readonly string[];
    }): ReadDenyHit | null;
    /** Traversal exclusions for the rg legs: `!`-polarity glob pairs — `!**\/<p>` plus `!**\/<p>/…`
     *  (the entry itself and its descendants). An entry placed at a home carries none (a glob is relative to the
     *  search root): `matchPath` judges it on the rg leg's output and in the walker. */
    readonly rgExclusionGlobs: readonly ReadDenyRgGlob[];
    /** Positive-polarity twins of the exclusions, for the bounded existence probe (first hit = entries
     *  matching the deny list exist under the scope and were excluded). */
    readonly rgProbeGlobs: readonly ReadDenyRgGlob[];
    /** Whether an entry that carries NO traversal glob (one placed at a home) can match a path under `scope` (an absolute
     *  directory): the rg leg cannot exclude such an entry, and a search that reads it and prunes afterwards answers
     *  differently by whether the entry's content matched — so a search over such a scope takes the walker, which prunes
     *  by path before reading. A scope that is not rooted answers true. */
    unexcludableUnder?(scope: string): boolean;
    /** A row that lies AT or BELOW `path` — the path is inside one of the row's matches, or a match would run on below the
     *  path from its own segments ({@link rowMeetsPath}) — so moving, copying or removing the path changes what the row
     *  covers. A rule row's reach below a path is not enumerable: any rule row answers. */
    rowAtOrBelow?(path: string): ReadDenyHit | null;
}
/** The DENY HALF of a shell read boundary, in the shape `BashReadonlyRootBoundary` declares it (structural:
 *  this module is the leaf every face depends on). `denyMatch` judges one LEXICALLY RESOLVED operand,
 *  returning the matched pattern or null; PRESENT-IFF there is something to judge. */
export interface ReadDenySeat {
    /** `walked` — the path is a traversal's enumerated member, not a spelling ({@link ReadDenyMatcher.matchPath}). */
    denyMatch?: (resolvedPath: string, opts?: {
        readonly walked?: boolean;
    }) => string | null;
    /** {@link ReadDenyMatcher.rowAtOrBelow} for one lexically resolved path; present exactly when `denyMatch` is. */
    denyAtOrBelow?: (resolvedPath: string) => string | null;
    denyEntries: readonly string[];
}
/** The ONE adapter from a compiled matcher to that seat, so every face mounts it the SAME way and the "wire
 *  the judge only when it has something to judge" rule is spelled once. That rule is load-bearing: the
 *  seat's PRESENCE is itself read as a fact (the recursive-read demotion mints on "a deny judge is wired" =
 *  the check a traversal would outflank is in place), so a judge over an EMPTY set must not be wired. Call
 *  ONCE per mount and reuse the result — the returned closure is then the function OBJECT every face mounted
 *  from that matcher shares, which makes "the same judge" checkable rather than argued. */
export declare function readDenySeat(matcher: ReadDenyMatcher | undefined): ReadDenySeat;
/** The ONE naming of the deny table and the pattern that matched. Every face composes its own SUBJECT and
 *  VERB in front of it and its own DISPOSITION behind it (the verb is not shared: one face names the
 *  target, another the REQUESTED SPELLING under a symlink alias). What must not fork is the naming — a
 *  reader comparing two surfaces about one finding must not be reading two findings. A LIST of patterns is
 *  the same naming in the plural, for the one finding that names no single row: a traversal that goes PAST
 *  the judge names the table IN FORCE, never a match it did not make. Four composers: the
 *  structured read faces' refusal (`safety.ts`), the shell faces' refusal card (`readDenyRefusal`), the
 *  lexical walk's verdict sentence (`bash-readonly-classifier.ts`), and the full shell's MANDATED ask card,
 *  which is approvable and so states the finding without claiming a refusal. NOT composers, each stating
 *  its own fact: the compaction lane's withheld-attachment HTML attribute, and the traversal notes'
 *  withheld-COUNT lines, which name the table and a pattern LIST. */
export declare function sensitivePathDenyList(pattern: string | readonly string[], face?: DenyFace): string;
/** The deny table's REACH: a deny row holds INSIDE the containment roots, so no root grant answers it. */
export declare const SENSITIVE_PATH_DENY_SCOPE = "This list guards credential-class paths and applies regardless of the containment roots.";
/** The write face's reach, in the same place of the sentence: a write deny row holds under every root and every mode. */
export declare const WRITE_DENY_SCOPE = "A write deny row holds regardless of the containment roots and of the permission mode.";
/**
 * THE deny refusal sentence — five segments, one mint, every read face: the ACTION, the ABSOLUTE target as the
 * caller spelled it (with its canonical target in parentheses when the two differ), the DISPOSITION (a deny row is
 * refused, never escalated), the table BY NAME with the PATTERN verbatim ({@link sensitivePathDenyList}), and
 * one sentence of why ({@link SENSITIVE_PATH_DENY_SCOPE}). `matchedView` names the view the pattern actually hit
 * when that is the requested SPELLING rather than the target — under a symlink or case alias the two strings
 * differ, only one matches, and naming the other sends the reader chasing a path the pattern does not match.
 * A face prefixes its own `Error (<tool>): ` and may append its own closing clause; the finding itself is
 * never re-spelled.
 */
export declare function readDenySentence(finding: {
    readonly action?: string;
    readonly target: string;
    readonly canonical?: string;
    readonly pattern: string;
    readonly matchedView?: string;
    /** The table face that refused (default `read`): a write-face hit names the write list and its reach, and writes. */
    readonly face?: DenyFace;
}): string;
/** The per-part budget of the deny sentence — the gate's own card-account cap, not a second number. */
export declare const READ_DENY_SENTENCE_PART_MAX = 200;
/** `s` verbatim when it fits `budget`, else elided in its MIDDLE ({@link elideMiddle}). */
export declare function fitMiddle(s: string, budget: number): string;
/** `s` shortened to `budget` by removing its MIDDLE, marked — cut through the repo's surrogate-safe
 *  primitive, never a raw `slice` (a raw cut leaves half an astral code point on a card and in a durable
 *  row). Under a dozen characters the HEAD is taken. */
export declare function elideMiddle(s: string, budget: number): string;
/**
 * The closed set of built-in tiers. A tier is the deployment's selection unit
 * ({@link ReadDenyBuiltinConfig.tiers}); every {@link READ_FACE_BUILTIN_DENY_TABLE} row belongs to
 * exactly one. Unknown tier names refuse loudly — this array is the validation source and the
 * admin-face vocabulary, never re-spelled downstream.
 */
export declare const READ_DENY_BUILTIN_TIERS: readonly ["credentials", "shell-history", "browser", "wallet", "agent-config"];
/** One member of {@link READ_DENY_BUILTIN_TIERS}. */
export type ReadDenyBuiltinTier = (typeof READ_DENY_BUILTIN_TIERS)[number];
/**
 * One row of the built-in table: the canonical deny pattern (also the row's STABLE NAME — the
 * `readDenyBuiltinExclude` key; renaming a pattern is a semantic change and deliberately invalidates
 * configs naming the old spelling, loudly) and the tier it belongs to.
 */
export interface ReadDenyBuiltinRow {
    readonly pattern: string;
    readonly tier: ReadDenyBuiltinTier;
}
/**
 * READ_FACE_BUILTIN_DENY_TABLE — the FULL built-in table with tier metadata: the material basis of
 * the deployment admin face, what an org administrator "sees" before selecting tiers / excluding
 * rows. Activation is a SEPARATE fact: the tiers of {@link READ_DENY_DEFAULT_TIERS} are active unless the
 * deployment selects otherwise, the rest are inert until a deployment names their tier — so this is the
 * MENU, never the active set. Rows stay curated regardless — the menu has to be worth switching on.
 * The dotenv family is deliberately NOT here — workspace `.env` files are working material for the
 * tasks this engine runs; an `outside_workspace` tier is likewise deliberately absent.
 *
 * Each row states its tradeoff. An unanchored row is matched as a segment run anywhere in the path, so a
 * repo fixture spelled `fixtures/.ssh/id_rsa` is refused too — deliberate: the refusal names the pattern,
 * and a false refusal on a fixture is the cheap direction (deny errs strict). A home-anchored row
 * (`~/…`, {@link READ_DENY_HOME_WORD}) is matched only below the home directory.
 *
 * NOT listed, deliberately: `.env`/`.env.*` (ruled out — workspace material; the WRITE guard still
 * covers them; the ENGINE's own `.env` under its data root is a different file and IS listed, see the
 * agent-config tier); `*.pem`/`*.key`/`*.p12`/`*.pfx` (repo certificates/test keys are routinely
 * READ — refusing them breaks ordinary work, the write guard covers the mutation direction);
 * `.git/hooks`/`.git/config` (reads are harmless; writes are the escalation and stay guarded); the
 * engine's own data root as a WHOLE (transcript integrity policy owns it with an ask on the write
 * face, and the memory library the model is told to read and edit lives under it).
 *
 * agent-config tier — the agent's OWN user-level configuration files whose `env` / server blocks carry API
 * keys in cleartext (the shell's `settings.json` env block, an MCP server env, the engine host's data-root
 * `.env`). Unguarded, a structured read of one of these lands the key verbatim in the tool result and
 * therefore in the session record. Every row is HOME-ANCHORED: the user's own files under the home
 * directory are refused, while a PROJECT's file of the same name (`./.sema/settings.json`, `./.mcp.json`,
 * `./.claude/settings.json`) is working material the person edits with the model and reads normally — its
 * writes are the write faces' business. Rows name FILES, not the config DIRECTORIES: `.sema`/`.claude` also
 * hold agents, skills, hooks and (under the shell's layout, `~/.sema/engine-data`) the engine data root
 * with the memory library — material the model reads and edits as ordinary work, and a directory-wide row
 * would need a data-root passthrough (one more rule) to keep it readable. Token
 * STORES of the same tooling (`.credentials.json`, an agent CLI's `auth.json`, …) are credentials rows, not
 * agent-config rows: a deployment that switches this tier off to debug its agent configuration must
 * not also expose the OAuth stores beside it. The rows' RUNS are ALSO the opt-in write deny set's
 * agent-configuration block ({@link import("../../core/sensitive-path-policy.js").agentConfigDenyPatterns},
 * which reads them from here; contract sentence there), so a row added here is judged by both faces.
 */
export declare const READ_FACE_BUILTIN_DENY_TABLE: readonly ReadDenyBuiltinRow[];
/**
 * The DEFAULT tier selection — what an unconfigured deployment activates: the `credentials` tier (key
 * material, cloud and registry credential files, token stores) and the `agent-config` tier (the agent's own
 * user-level configuration files, home-anchored). The `shell-history`, `browser` and `wallet` tiers are a
 * deployment's opt-in. Activation is a deployment decision with a visible seat, and the leg's wiring
 * manifest reports which tiers it got.
 *
 * The NAMED default rather than an inline literal: `[]` and absence stay separately spellable on the
 * seat, and a deployment profile wanting a different default changes THIS expression, not call sites.
 */
export declare const READ_DENY_DEFAULT_TIERS: readonly ReadDenyBuiltinTier[];
/**
 * The deployment's built-in-table configuration — deployment seat ONLY (RunnerDeps /
 * HandsToolkitOptions; deliberately NOT a TaskSpec key and NOT in the governed workflow whitelist,
 * so no task or governed script can widen below its deployment).
 *  - `tiers` — EXACTLY-these tier selection: listed tiers are active, unlisted ones are not
 *    (`[]` = no built-in tiers at all — an explicit, legal posture; absent = {@link READ_DENY_DEFAULT_TIERS}).
 *  - `exclude` — per-row removal by canonical pattern name, applied AFTER tier selection.
 * Unknown tier names / unknown row names refuse loudly — never silently ignored.
 */
export interface ReadDenyBuiltinConfig {
    tiers?: readonly string[];
    exclude?: readonly string[];
}
/**
 * Resolve the ACTIVE built-in rows under a deployment configuration (validated, loud — all three
 * bad-value states throw: garbage shapes, unknown tier names, unknown row names). The one
 * resolution used by {@link compileReadDeny}; exported so an admin face can preview the effective
 * table under a candidate configuration with the engine's own rules.
 */
export declare function resolveReadDenyBuiltins(config?: ReadDenyBuiltinConfig): readonly ReadDenyBuiltinRow[];
/**
 * The deployment's built-in configuration as ONE validated snapshot, read off the seats' OWN values: each seat is an
 * array of names or absent — any other value (a string, the empty string included) refuses loudly, naming the seat,
 * before anything is spread or copied (a spread string reads as its characters, or as no names at all). The names are
 * then judged by {@link resolveReadDenyBuiltins}. The snapshot holds copies: a caller mutating its arrays afterwards
 * moves nothing, so every compile of one mount reads the same selection.
 */
export declare function readDenyBuiltinConfigOf(seats: {
    readonly tiers?: unknown;
    readonly exclude?: unknown;
}): ReadDenyBuiltinConfig;
/**
 * The tiers a deployment configuration ACTIVATES — the tier names of {@link resolveReadDenyBuiltins}'s
 * surviving rows, in {@link READ_DENY_BUILTIN_TIERS} order (the closed set is the ordering source, so
 * two deployments that select the same tiers in different spellings report the same list).
 *
 * MATERIAL, not intentional: a tier whose every row was removed by `exclude` activates nothing and
 * is NOT reported. An EMPTY result means the built-in table contributes nothing on this leg — the
 * unconfigured default. Same loud validation as the resolution it wraps.
 */
export declare function activeReadDenyBuiltinTiers(config?: ReadDenyBuiltinConfig): readonly ReadDenyBuiltinTier[];
/**
 * READ_FACE_DEFAULT_DENY_ENTRIES — the DEFAULT-ACTIVE built-in set: {@link READ_FACE_BUILTIN_DENY_TABLE}
 * under {@link READ_DENY_DEFAULT_TIERS} — the answer to "what does an unconfigured deployment refuse, from
 * this table". Derived, so it follows the default selection; the tier-annotated table is where a consumer
 * renders "what COULD be switched on".
 */
export declare const READ_FACE_DEFAULT_DENY_ENTRIES: readonly ReadDenyEntry[];
/** A compiled segment-run pattern (shared engine — the write guard delegates here too). */
export interface CompiledSegmentPattern {
    raw: string;
    segments: RegExp[];
    /** Fold BOTH sides through {@link asciiLower} before testing (compile lowered the pattern side). */
    foldAscii: boolean;
    /** The segment lists of the directories the run is ANCHORED at (folded as the pattern folds): the run must start
     *  right after one of them. Absent = the run matches anywhere. */
    anchors?: readonly (readonly string[])[];
    /** Judged in a ROOTED view only: an extra location of a home-anchored row (where its literal head leads). A view that
     *  is not rooted cannot be placed and is covered by the row's own run, held anywhere. */
    rootedOnly?: true;
}
/**
 * Compile one segment-glob pattern (shared engine). `fold`:
 *  · "none"    — byte-exact segments;
 *  · "ascii"   — ASCII-case-insensitive (deny-set contract);
 *  · "unicode" — RegExp `i` flag (the write guard's historical host-keyed behavior — kept for it
 *    byte-identically; NOT used by the deny set).
 * Returns null when the pattern reduces to zero segments — the CALLER owns its loud path (the two
 * consumers refuse with their own surface-specific texts).
 */
export declare function compileSegmentPattern(raw: string, fold: "none" | "ascii" | "unicode"): CompiledSegmentPattern | null;
/**
 * Does the path contain a compiled pattern as a CONTIGUOUS run of full path segments? (Shared engine:
 * `.git/hooks` matches `/repo/.git/hooks/pre-commit`; `.ssh` matches any `.ssh` segment.) An ANCHORED pattern
 * ({@link CompiledSegmentPattern.anchors}) matches only where the path's leading segments are one anchor's and
 * the run starts right after them. Splits on BOTH separator families — win32 canonical keys are backslash-form.
 * Returns the matched raw pattern or null.
 */
export declare function matchSegmentPatterns(path: string, compiled: readonly CompiledSegmentPattern[], opts?: {
    readonly aliasResolved?: boolean;
}): string | null;
/**
 * the PURE validation/canonicality predicate over a PERSISTED deny entry (checkpoint v9
 * face section), for the resume pre-CAS ladder: it must refuse BEFORE the approval CAS everything
 * {@link compileReadDeny} would throw on AFTER it (a post-CAS compile throw consumes the human's
 * approval and strands the row), plus non-canonical spellings (normalizeEntry canonicalizes at every
 * mint, so a persisted non-canonical pattern was not minted by any release = damaged). Returns the
 * refusal reason, or null when the entry is valid.
 */
export declare function persistedReadDenyEntryProblem(e: unknown): string | null;
/** The home spellings a home-anchored row is placed under, judged as given: an array of absolute path strings, loud
 *  otherwise and naming `readDenyHomes` — a relative or empty spelling places the row where no home is, and a bare
 *  string would be read as its characters. */
export declare function checkedReadDenyHomes(homes: unknown, seat?: string): readonly string[];
/**
 * Compile the read-face deny judge: ACTIVE built-in rows ∪ additions. Additions are add-only at every
 * task layer (`[]` additions ≡ absent, deliberately a no-op rather than a refusal: an array API
 * cannot observe a "replace" intent, and union-with-empty is the identity, not a silent fallback);
 * the built-in half is selected by the DEPLOYMENT's `builtin` config (absent = the default tier
 * selection, see {@link resolveReadDenyBuiltins}). A deployment that turned a tier off can still
 * re-add single patterns through the additions seats — they then ride as ordinary additions.
 * Bad entry shapes / zero-segment patterns / unknown tier or row names throw loudly, naming the
 * layer or knob.
 *
 * `homes` — the spellings of the execution environment's home directory a home-anchored entry
 * ({@link READ_DENY_HOME_WORD}) is placed under: the declared home, the account home and, where the environment's
 * canonical spelling of one differs, that one too (the faces judge canonical keys beside the spelled views). Absolute
 * spellings only — any other shape refuses loudly, naming `readDenyHomes`. EMPTY = the environment declares no
 * home: a home-anchored entry then matches its run anywhere — a row that cannot be placed holds wider, never narrower.
 *
 * `linked` — where a home-anchored row's LITERAL HEAD ({@link readDenyRunHead}) really leads, keyed by the row's
 * pattern: the canonical locations a mount resolved (`readDenyHomeLinksOf`, read-deny-home.ts) where one of the
 * head's segments is a link (`~/.sema` linked into a dotfiles directory). The row is placed at each location too —
 * the same row, the same name in every refusal — with the rest of its run matched below it. The read faces judge
 * canonical keys, so every spelling that reaches the linked file meets the row there. Absolute locations only.
 */
export declare function compileReadDeny(additions?: readonly ReadDenyEntry[], layer?: string, builtin?: ReadDenyBuiltinConfig, rules?: readonly PathRuleDenyRow[], homes?: readonly string[], linked?: ReadonlyMap<string, readonly string[]>): ReadDenyMatcher;
