/**
 * The permission-rule LANES the unified store feeds (prepare-path machinery): the two gate
 * lanes, and — since the policy-chain phase took the chain assembly — the rule-offer factory every ask-mint site calls.
 *
 * `prepareTask` used to assemble the personal lane inline (a store read + a hand-spliced session
 * overlay + two admission arms) and the org lane from a second seam. Both now read the ONE store query —
 * `PermissionRuleStore.effective({ sessionId })` — and this module is where that read is taken and how it
 * is shared between the two lanes of one adjudicated call.
 *
 * ## One read per adjudicated call
 *
 * The gate consults the org lane (`orgRules.adjudicate`) and then the personal lane
 * (`persistedRules.adjudicate`) on every decision, in that order (the personal lane's deny/ask rows must
 * be able to tighten an allow, so it can no longer wait for a surviving ask). The org lane's read is
 * HANDED to the personal lane by `toolCallId` (taken once, then forgotten), so a governed deployment pays
 * one store query — one org-source fetch — per call, exactly as it did with two seams. An entry the
 * personal lane never claims (a call on a tool it does not speak for) is evicted first-in-first-out past
 * a small bound; an evicted or never-handed entry simply costs the personal lane its own read. The
 * handoff is a cost device, not a semantic one: both lanes judge one snapshot, which is the honest shape
 * for one decision.
 *
 * ## Where the lanes do NOT go
 *
 * Neither is a `ToolPolicy`, and neither joins `policyLayers`: inside the fold an allow is the lowest
 * position (a permanent no-op) and a layer's mere presence flips `hasEffectAwareGate`, which would
 * silence the ungated-write warning for deployments that wired no policy at all.
 */
import type { AskRuleEvidence, ToolCallRequest } from "../tool-policy.js";
import { persistedRuleMandateOf, type RuleClearanceFacts } from "../ask-origin.js";
import { type OrgGateVerdict, type PersistedRuleAnswer, type PersistedRuleHit, type PersistedRuleUnreadable } from "../hooks.js";
import type { PersistedRule, PersistedRuleVerdict, RuleOffer, SegmentCoverage } from "../permission-rule-model.js";
import { type ToolCallLike } from "../tool-registry.js";
import { type OrgRuleResolution } from "../permission-rule-org.js";
import { type EffectivePermissionRules, type PermissionRuleStoreProvider } from "../permission-rule-provider.js";
/** The one SHELL tool the persisted-rule lane's COMMAND grammar speaks for (the rule-offer face mints for
 *  it alone). The PATH grammar's tools are derived from the catalog (`ruleToolGrammarOf`). */
export declare const PERSISTED_RULE_TOOL = "Bash";
/**
 * The evidence an INHERITED-lane ask carries.
 *
 * The three inherited mint sites present an ANCESTOR policy's own decision, resolved at the ancestor's
 * approver, from inside the policy fold — upstream of the gate's org layer and its rule lane, neither of
 * which has spoken for this call at that point. So the record is stamped rather than omitted (every ask
 * the engine mints carries one, and a consumer never has to tell a missing field from a field that means
 * something), and each half names the accurate absence for THIS deployment: a partition that is not
 * configured at all reads `"not_wired"`, and one that exists but has not adjudicated this ask reads
 * `"not_adjudicated"`. Reporting the second for a deployment that has neither would assert a governance
 * layer that does not exist.
 *
 * FROZEN: one record is handed to every inherited ask on this leg, and `resolveAsk` shallow-spreads the
 * request — so an `onAsk` consumer holding `req.ruleEvidence` would otherwise be able to edit what the
 * next ask on this leg reports.
 */
export declare function inheritedAskRuleEvidence(provider: PermissionRuleStoreProvider | undefined): AskRuleEvidence;
/**
 * The snapshot REVISION an org answer was read off, screened before it becomes
 * evidence.
 *
 * The org partition's own install and serving gates screen a snapshot's revision,
 * so a healthy in-tree partition cannot reach here with junk; a FOREIGN store (the interface is public)
 * can. A non-finite value is refused rather than carried — an evidence field is worthless if `NaN` can
 * wear the same shape as revision 41 — and the defect is announced through `onDefect` instead of quietly
 * becoming "this deployment reported no revision".
 *
 * The ADJUDICATION is untouched either way: the caller's verdict is the whole decision, and a
 * defective ATTRIBUTION must never change what a governance layer decided.
 */
export declare function orgRevisionEvidenceOf(resolution: OrgRuleResolution, onDefect: (message: string) => void): {
    revision?: number;
};
/**
 * Project the model's verdict onto the gate's rule-lane answer: the
 * behavior that spoke, and each member's canonical text plus its own add DOTS. For an allow the set is
 * the admitting COVERAGE SET (a single rule admitting the whole command is a one-element set; a compound
 * admitted by the per-segment conjunction is the set of covering rules in segment order — the model's
 * own reporting-order contract); for a deny/ask it is the one reaching rule the precedence walk chose.
 *
 * `adds` on a listed rule are the LIVE adds — the store's read already dropped tombstoned dots — so
 * this is the set that actually decided the call, which is the identity a later audit reconciles a
 * shadowed ask against. The sanitized display text deliberately is not one. Copied rather than
 * aliased: the evidence must not change under a store that reuses its row objects.
 */
export declare function persistedRuleHitOf(verdict: PersistedRuleVerdict | undefined): PersistedRuleHit | undefined;
/** The COMMAND arm's projection of a verdict: a call the lexer could not read against a standing deny/ask
 *  row is the lane's UNREADABLE answer carrying the lexer's reason — it fails closed (a real-approval ask no
 *  automatic lane clears) — never a matched ask rule, which would let a blanket `onAsk: "allow"` clear a
 *  question nobody can answer. Every other verdict is {@link persistedRuleHitOf}'s hit. */
export declare function persistedRuleAnswerOf(verdict: PersistedRuleVerdict | undefined): PersistedRuleHit | PersistedRuleUnreadable | undefined;
/**
 * Widened to every path-targeting tool — the persisted-rule lane's PATH arm: the call's
 * target path in the SAME lexical identity the rule family is defined over, resolved by the ONE reader every
 * fence and every tool goes through (`effectivePathTargetOf`), so the lane judges the path the tool will
 * really open. The tool's own declaration decides which base a relative spelling takes and what an ABSENT
 * slot means — the lane no longer guesses `liveCwd ?? root` for every tool, which was wrong for the two
 * search tools in three separate shapes (see effective-path-target.ts). Still zero IO.
 *
 * TWO readings of the call's path slot, one per direction: the tightening arms judge
 * the PROTECTIVE target (the object face's declaration, the catalog's for the name as the floor — reading
 * the catalog for an undeclared same-name tool can only tighten a deny); the allow arm judges the DECLARED
 * target (the face's OWN declaration only — a same-name tool that declares no path target is unconfirmable
 * and no grant admits it). The precedence walk, the admission predicates and the Read-only allow are the
 * model's (`adjudicatePersistedPathRules`). An ALLOW here clears ASKS only — the read fences (workspace
 * containment, the sensitive-read deny face) judge inside the tool exactly as they would with no rule
 * anywhere — and an unresolvable path is simply no verdict (fail toward asking on the allow side, no
 * refusal on the tightening side: a rule about a path speaks about no other shape).
 */
export declare function pathRuleLaneAnswer(table: readonly PersistedRule[], req: Pick<ToolCallRequest, "toolName" | "args" | "face">, ctx: {
    root: string | undefined;
    sessionId: string | undefined;
    liveCwd: string | undefined;
    home: string | undefined;
}): PersistedRuleHit | PersistedRuleUnreadable | undefined;
/** The two lanes prepare hands the gate. Each is `undefined` when its partition is not configured, so
 *  a deployment without one keeps a decision path byte-identical to a build without the feature. */
export interface PermissionRuleLanes {
    personal: {
        adjudicate: (req: ToolCallRequest) => Promise<PersistedRuleAnswer>;
    } | undefined;
    org: {
        adjudicate: (req: ToolCallRequest) => Promise<OrgGateVerdict>;
    } | undefined;
}
/** The ORG lane: the org's verdict about one call, off the store view `read` supplies — the gate's `orgRules` face over the
 *  per-call handoff ({@link createPermissionRuleLanes}), and {@link orgVerdictBeforeClaim} over a view of its own. */
export declare function orgRuleLane(cfg: {
    read: (toolCallId: string) => Promise<EffectivePermissionRules>;
    questionToolMounted: boolean;
    questionToolName: string;
    onRevisionDefect: (message: string) => void;
}): NonNullable<PermissionRuleLanes["org"]>;
/** The org's CURRENT verdict about a parked call, read by the resume entry before the claim (the row's session and principal,
 *  bounded like the gate's wait; unreadable ⇒ unavailable). The mount and a revision defect are the resumed leg's facts, so
 *  the reserved name is exempted and the defect left to that leg: this read can leave a question unasked, never invent one. */
export declare function orgVerdictBeforeClaim(cfg: {
    provider: PermissionRuleStoreProvider;
    principal: string | undefined;
    localOwnerDeclared: boolean;
    sessionId: string;
    signal: AbortSignal | undefined;
}, req: ToolCallRequest): Promise<OrgGateVerdict>;
/**
 * Build the gate's two permission-rule lanes over the unified store, resolved once per task.
 *
 * The LOCAL-OWNER declaration is judged here, at prepare. It is a declaration,
 * so one that cannot be honored is refused LOUDLY rather than degrading into "this deployment's standing
 * approvals silently stopped applying" (the §7.4 org bit's rule, applied to the availability direction:
 * the failure is deterministic and belongs at wiring time).
 */
export declare function createPermissionRuleLanes(cfg: {
    provider: PermissionRuleStoreProvider | undefined;
    localOwnerDeclared: boolean;
    principal: string | undefined;
    sessionId: string;
    /** The isolation-aware task root — the same value the file fence, the prompt cwd and the session rules
     *  use, so a project-scoped rule agrees with every other place that says "this project". */
    root: string;
    /** The LIVE tracked working directory: the base a relative cd resolves against
     *  after an earlier observable `cd`; read per call. */
    liveCwd: () => string | undefined;
    /** The EXECUTION ENVIRONMENT's home directory (`ExecutionEnv.homeDir`, adapter-declared), the base a
     *  `~/` path rule resolves against. `undefined` = the adapter declares none: a `~/` deny/ask row then reads
     *  UNREADABLE for every call (a fail-closed ask), never the engine process's home. A declared value that is
     *  not an absolute path is refused HERE, loudly (a bad declaration is a wiring defect, not an absence). */
    home: string | undefined;
    /** True iff the reserved question-tool NAME resolves to the ENGINE's own content-ask tool on this leg. */
    questionToolMounted: boolean;
    questionToolName: string;
    onRevisionDefect: (message: string) => void;
    /** Sink for the store's disclosure lines (a session partition that could not be read, rows it served
     *  that were dropped) and for a durable read failure — each read's lines are delivered once, whichever
     *  lane took the read. */
    onDisclosure: (message: string) => void;
    /** The person is told their store (or the named sources of it) was skipped for a call (the run's one notice,
     *  `ruleStoreUnreadableNotice`). */
    onStoreUnreadable: (at: "call", sources?: EffectivePermissionRules["unreadableSources"]) => void;
    /** The run's cut: a read it interrupts is abandoned quietly — a cancelled wait is no fact about the store. */
    signal?: AbortSignal;
    /** The allow layer's auto strip over a stored ALLOW row (true ⇒ out of this call's table BEFORE the coverage is chosen). */
    stripsAllow?: (rule: PersistedRule, req: ToolCallRequest) => boolean;
}): PermissionRuleLanes;
/** The closed reason set for the rule-offer factory's empty answer — the same three
 *  spellings the `AskRequest` and durable-row seats declare, kept at the one factory that fills both.
 *  Deliberately not exported: this is a wire vocabulary, and its two faces declare it literally (the
 *  `previewWithheld` precedent) so a consumer reads the closed set on the type it is holding rather
 *  than through an import. */
type RuleOffersAbsence = "mandated" | "lane_cannot_speak" | "shadowed";
/** The surviving-ask facts the rule-offer factory reads (see {@link createRuleOffersOf}): the
 *  synchronous mint sites spread the surviving decision, which carries them; the park leg threads
 *  each as its own parameter. The clearance half is {@link RuleClearanceFacts} — the SAME declaration
 *  the ask's own mandate bit is derived from, so a station cannot hand one face a fact it withheld
 *  from the other. */
interface RuleOffersAskFacts extends RuleClearanceFacts {
    /** The surviving ask's engine-stamped per-segment coverage table — the
     *  batch offer carries exactly the segments this table calls uncovered. Absent ⇒ all
     *  segments read as uncovered (over-offer, the safe direction). */
    segmentCoverage?: readonly SegmentCoverage[];
}
/**
 * The rule forms that could cover this exact call, for a surface's "stop asking me
 * this" option (extracted from the prepare body, the spliceSessionOverlayRows precedent; the maker
 * captures the per-task wiring once and the returned factory serves all five ask-mint sites — the
 * approval-preview field is a standing example of what happens otherwise: it reached two of the
 * five, so a delegated child's card was silently poorer than the top-level one).
 *
 * Empty unless a rule lane is armed — offering an option that redemption would refuse is worse than
 * offering none — and empty for any call the lane cannot speak for (a compound, a redirection, a
 * substitution, or a tool that is not the shell tool).
 *
 * Empty, too, on any ask a persisted rule could never CLEAR — "allow rules silence the classifier's
 * questions, never a mandated one". Two doors, matching the two halves of that boundary:
 *  · the marks half, judged from the SAME resolved sources the gate input is built from, through the
 *    gate's own single-source predicate (an operator's shellGate:"always", the tool's own
 *    egress/irreversibility marks, and — separately — the PER-CALL member that predicate also takes: a
 *    demotion this call's reversibility probe declared structural, read off the ask the gate
 *    stamped rather than off the tool seat, because it is true of one call and not of the seat) —
 *    a drift here would offer a rule the lane then refuses to honor;
 *  · the decision half (`ask`, REQUIRED at every mint site so a site added later cannot skip it):
 *    `requiresRealApproval` (org/governance — only judgment clears it), the shadowed-rule
 *    disclosure (the standing proof that a matching rule does not clear THIS ask), a hook-raised
 *    ask (`decisionReason === "hook"` — the lane's own clearing conjuncts refuse hook asks, so a
 *    rule minted from one would never silence it), an EXPLICIT `ask` rule match (`matchedAskRule`
 *    — see below), and an inherited-unresolved marked call (the
 *    ask is an ANCESTOR's authority, which this task's rule lane never adjudicates). Offering
 *    "stop asking me this" on a card that will keep asking lets a person mint a rule that never
 *    takes effect where they minted it.
 *
 * (CC 2.1.245 toolPolicy 对表, F11: "wildcard `ask` … keeps every matching tool behind a
 * per-call prompt (no persistent always-allow)") — `matchedAskRule` was the one conjunct of the
 * lane's own clearing predicate this door did not mirror, and the asymmetry was live: the
 * persisted-rule lane refuses to clear ANY ask carrying it (`hooks.ts`, the
 * `decision.matchedAskRule === undefined` conjunct on its allow arm), so a person who wrote a
 * standing `Bash` `ask` rule and had no allow rule yet was still offered "allow, and stop asking
 * me this" — and the rule they minted came back on the very next call as a SHADOWED match
 * (the allow layer's disclosure, which this door was already refusing). The offer was only ever
 * suppressed one call too late, after the useless rule existed. The shadowed conjunct stays: it
 * covers the person who ALREADY has the allow rule; this one covers the person about to mint it.
 *
 * Every door above that answers "no offers" now also names WHICH door, on the
 * `ruleOffersAbsence` seat (`AskRequest`'s and the durable row's, ONE factory so the two faces
 * cannot disagree). The doctrine it serves is the loud-bad-value one, applied to an absence: a
 * surface reading an empty card could not tell "there is nothing this lane could offer" from
 * "offers were deliberately suppressed", and a person reading it could not tell "write the rule
 * yourself" from "no rule can excuse this approval". The seat is CLOSED
 * (`mandated | lane_cannot_speak | shadowed`), mutually exclusive with `ruleOffers` by
 * construction, and structural-door silent (see the first two guards).
 */
export declare function createRuleOffersOf(cfg: {
    /** `permissionRuleLane !== undefined` at wiring time — the armed-lane structural door. */
    laneArmed: boolean;
    principal: string | undefined;
    /** `deps.localOwnerRules === true` — the declared local-owner exception to the anonymous floor. */
    localOwnerDeclared: boolean;
    /** The live mark sources the gate input is built from — passed as REFERENCES (read per call, so a
     *  late-registered tool seat is seen exactly as the gate sees it). */
    egressTools: {
        has(name: string): boolean;
    };
    irreversibilityTier: {
        get(name: string): Parameters<typeof persistedRuleMandateOf>[0]["irreversibility"];
    };
    shellGatedTools: {
        has(name: string): boolean;
    };
    toolMarkSources: {
        get(name: string): ReadonlySet<string> | undefined;
    };
    taskRoot: string | undefined;
    /** The live tracked-cwd ref (read per call — the relative-cd resolution base). */
    cwdRef: {
        current: string;
    } | undefined;
    deniesDirectoryRead: ((directory: string) => boolean) | undefined;
}): (call: Pick<ToolCallLike, "toolName" | "face">, args: unknown, ask: RuleOffersAskFacts | undefined) => {
    ruleOffers?: readonly RuleOffer[];
    ruleOffersAbsence?: RuleOffersAbsence;
    execCwd?: string;
};
export {};
