/**
 * design/182 §7 / design/389 — the ORG partition of the permission-rule store: core's half of the contract.
 *
 * Org rules and personal rules are opposite in polarity (deny/ask vs allow), authority (a server-side
 * administrator publish vs one human click per add) and evolution (whole-snapshot replacement vs
 * convergent merge). So the org layer has NO CRDT, no tombstones and no join: the server is the single
 * authority, a client holds a read-only versioned snapshot, an update is a whole replacement (revision
 * strictly ordered), and a rollback is a NEW revision carrying old content. Cross-layer tombstones are
 * structurally impossible — an org rule never enters `PersistedRule`, and an org snapshot replace
 * never touches a personal store's bytes. The two layers meet only at the CONSUMPTION site, where org
 * deny/ask folds strict-side: **org deny > org ask (non-dismissable) > personal allow rule > bare ask**.
 *
 * ## Availability semantics (the fail-closed shape, ruled through three review rounds)
 *
 * A deployment DECLARES governance by handing `createPermissionRuleStoreProvider` an `org` partition
 * config — governance is never inferred from a provider happening to be wired somewhere, and a config
 * naming no snapshot source is a loud boot contradiction instead of a silently ungoverned deployment.
 * Under that declaration the org adjudication surface must ALWAYS be effective:
 *  - the last successfully installed snapshot persists durably (`PersistedOrgRuleState`) and keeps
 *    adjudicating while the provider is unreachable, up to a deployment-configured staleness bound;
 *  - beyond the bound (or before any snapshot was ever installed) the resolution is `unavailable`, and
 *    the CONSUMING gate must fail the ENTIRE decision boundary closed: every terminal allow — policy
 *    allow and default allow included — tightens to an ask carrying `decisionReason: "org_unavailable"`
 *    AND `requiresRealApproval: true` (the same non-dismissable bit an org ask itself carries; without
 *    it a blanket `onAsk: "allow"` deployment would clear the synthetic ask — a third fail-open path),
 *    with the personal-rule lane and the auto-mode classifier both disarmed. That obligation lives at
 *    the gate integration; THIS module's contract is to report `unavailable` honestly and never lapse
 *    into an empty-rules answer that reads as "not governed".
 *
 * ## Anti-rollback
 *
 * `revision` is an orderable server-monotone number, and the installed high-water mark persists with
 * the snapshot in ONE atomic write: a replayed older snapshot (fresh `fetchedAtMs`, old content) is
 * refused and disclosed — identity comparison alone cannot catch it, and an in-memory-only mark would
 * accept revision N−1 after a restart. Signature / predecessor chaining belongs to the privilege-
 * separation ticket; the high-water mark is the floor that needs no key distribution.
 *
 * ## One reading of a row
 *
 * A snapshot is installed and served on its ENVELOPE ({@link validateOrgSnapshot}: revision, observation
 * time, a rules list) and the anti-rollback fence; what its rows say never decides which snapshot is in
 * force. Whether the rules are a list is judged in ONE place ({@link listRefusalOf}) for the partition and for
 * every store that hands a resolution over — rules that are not a list, or that carry more places than a rule set may
 * (the same cap the rule compiler holds a set to), are governance nobody can read (the
 * partition refuses the snapshot; the org lane answers unavailable), never a policy of zero rows — and ONE reader
 * ({@link orgRuleListOf}) copies the whole list in one receipt: a member of a row that cannot be read is left out of
 * that row's copy alone, and every row is judged on its copy. A snapshot the partition holds — fetched or read back
 * from its persistence — is that same copy ({@link orgSnapshotCopyOf}). Every row is then read by ONE reader
 * ({@link readOrgRules}), the same for every store that hands a resolution over, on its policy members
 * ({@link ORG_ROW_POLICY_MEMBERS}): a row is READ when its behavior is `deny` or `ask` and its text is a shell command
 * rule under that behavior. Any other row — another grammar's rule, a shell rule the validator refuses, a row
 * with no text, a behavior this layer has no bucket for — is UNREADABLE, and stands at its strictest
 * reading over the calls it may reach ({@link OrgRowReach}): an `ask` row asks a person, every other row
 * refuses. Readable deny and ask rows hold as published beside it. One unreadable row therefore never
 * takes the rest of the policy down with it, and never turns a published deny into a question; the
 * snapshot is served DEGRADED, and every resolution and every adjudication over it names the unreadable
 * rows ({@link describeUnreadableOrgRows}).
 */
import { type ParsedRule, type PersistedRule, type RuleRejectCode } from "./permission-rule-model.js";
import type { DenyFace } from "../tools/fs/read-deny.js";
import type { PermissionRuleStore } from "./permission-rule-provider.js";
/** One org rule. There is structurally no allow bucket (design/179 §9: the org layer only tightens). */
export interface OrgPermissionRule {
    rule: string;
    behavior: "deny" | "ask";
}
/** The read-only versioned snapshot a client holds. */
export interface OrgRuleSnapshot {
    /** Server-monotone orderable revision. A snapshot below the persisted high-water mark is refused. */
    revision: number;
    rules: OrgPermissionRule[];
    /** Reserved for the privilege-separation ticket's signed-snapshot contract. Carried, not verified here. */
    signature?: string;
    /** Observation timestamp (epoch ms) — staleness input only, never adjudication input. */
    fetchedAtMs: number;
}
/** Where the deployment fetches the current snapshot. `undefined` = the provider has none to give. */
export interface OrgRuleSnapshotProvider {
    current(): Promise<OrgRuleSnapshot | undefined>;
}
/**
 * The durable org state: last-known-good snapshot + the anti-rollback high-water mark, installed in one
 * atomic write. SQL twin note (server/org ticket): `revision_high_water` and `installed_at_ms` are
 * structured columns (`_ms` suffix for epoch milliseconds); the snapshot itself is a JSON blob — it is
 * installed and read whole, never row-queried.
 */
export interface PersistedOrgRuleState {
    revisionHighWater: number;
    snapshot: OrgRuleSnapshot;
    installedAtMs: number;
}
/** The durable home of {@link PersistedOrgRuleState}. The file backend implements it over a
 *  deployment-level `org.json` published with the same O_EXCL/fsync/rename discipline as the rule files
 *  (`FileDurableRulePartitionProvider.orgStatePersistence()`); a SQL twin keeps one blob row.
 *
 *  CONTRACT: `installOrgState` must REFUSE (throw) an install that would LOWER the persisted
 *  `revisionHighWater` — the overlay serializes its own resolves, but two overlay instances over one
 *  durable home can interleave read-then-write, and the backend's atomic write is the one place the
 *  lowering can be caught. The file backend enforces this under its write serialization. */
export interface OrgRuleStatePersistence {
    readOrgState(): Promise<PersistedOrgRuleState | undefined>;
    installOrgState(state: PersistedOrgRuleState): Promise<void>;
}
/** The `decisionReason` the consuming gate stamps on the synthetic asks it mints while org adjudication
 *  is unavailable. Exported so the gate integration and its tests share one spelling — and TYPED as the
 *  member of {@link import("./tool-policy.js").DecisionReason} it must equal, so the constant and the
 *  vocabulary cannot drift into two spellings of one word. */
export declare const ORG_UNAVAILABLE_DECISION_REASON: Extract<import("./tool-policy.js").DecisionReason, "org_unavailable">;
/**
 * How long a single org adjudication may take before the consuming gate stops waiting and reads the
 * answer as UNAVAILABLE (its fail-closed word).
 *
 * A bound is MANDATORY rather than optional because of where this call sits: on the hot path of every
 * governed tool call, and — on the durable resume leg — after the checkpoint has been consumed and the
 * start frame emitted. A provider that never settles would otherwise wedge the call past any task
 * deadline (tasks carry no walltime by default), leaving the frame unpaired and the approval spent with
 * nothing retryable. A hang is the one outcome worse than either verdict.
 *
 * The value matches the auto-mode classifier's per-round-trip cap — the other model/network call the
 * permission path makes — because the reasoning is the same: a governance lookup that takes longer than
 * this is indistinguishable from an outage, and an outage is exactly what the unavailable arm is for.
 * The task's own abort signal still applies in parallel; whichever fires first ends the wait.
 */
export declare const ORG_ADJUDICATION_TIMEOUT_MS = 15000;
/**
 * Await `p`, but settle with `fallback` if the deadline elapses or the signal fires first.
 *
 * Shared by both org consumption sites so one bound cannot drift into two. Deliberately NOT `.unref()`
 * on the timer: this is a foreground rescue timer, and the caller is awaiting it inside the control
 * flow — an unref'd timer stops firing in exactly the situation it exists for (an otherwise idle loop).
 * A rejecting `p` also lands on the fallback: the callers' fail-closed word is the same either way, and
 * an escaping rejection here would turn a dependency failure into a task crash.
 */
export declare function settleOrgVerdictWithin<T>(p: Promise<T>, fallback: T, opts: {
    signal?: AbortSignal;
    timeoutMs: number;
    /**
     * backlog #136④ — which arm WON, reported at the moment it won. A consumer that wants to tell a
     * cancelled wait from an unreadable provider cannot get that by sampling `signal.aborted` after
     * the await: a cancellation queued between the settlement and the continuation reads identically
     * to one that actually ended the wait, and the operator-facing account would name the wrong
     * cause. Called at most once, before `p` resolves, and only for the two non-provider arms —
     * absent call ⇒ the awaited promise itself settled.
     */
    onFallback?: (cause: "aborted" | "timeout") => void;
}): Promise<T>;
/** The `decisionReason` of a decision an ORG RULE produced (a deny, or a non-dismissable ask). Same
 *  single-spelling contract as {@link ORG_UNAVAILABLE_DECISION_REASON}. */
export declare const ORG_RULE_DECISION_REASON: Extract<import("./tool-policy.js").DecisionReason, "org_rule">;
/** How far into the future a snapshot's `fetchedAtMs` may sit before it is refused — ordinary NTP-level
 *  clock skew passes; a far-future timestamp (which would satisfy the staleness bound INDEFINITELY,
 *  turning fail-closed into evergreen freshness) does not. */
export declare const ORG_FETCHED_AT_SKEW_ALLOWANCE_MS: number;
/** The org partition's resolution word. `ungoverned` is the store's answer on a deployment that
 *  configured no org partition — a fourth member so "no org layer here" is never spelled as an
 *  empty `fresh` snapshot. */
export type OrgRuleStatus = "fresh" | "last-known-good" | "unavailable" | "ungoverned";
/** What one resolution reports. `rules` is empty ⟺ status `unavailable`/`ungoverned` or the snapshot
 *  is empty — the cases are distinguished by `status`, never by the emptiness of the list. */
export interface OrgRuleResolution {
    source: "org";
    status: OrgRuleStatus;
    rules: OrgPermissionRule[];
    revision?: number;
    /** Honest-disclosure lines: source failures, refused snapshots, rollback refusals. */
    disclosures: string[];
}
/** The org partition engine the unified store composes (design/389): fetch → validate → install-if-newer
 *  → judge freshness, one serialized chain per deployment. */
export interface OrgRulePartition {
    resolve(): Promise<OrgRuleResolution>;
}
/** The partition config a deployment hands to `createPermissionRuleStoreProvider({ org })`. Its
 *  PRESENCE is the governance declaration. */
export interface OrgRulePartitionConfig {
    /** Where the deployment fetches the current snapshot. Required — a governed declaration without a
     *  source is a configuration contradiction and refuses to boot. */
    source: OrgRuleSnapshotProvider;
    /** Durable LKG + high-water home. Omitted ⇒ process-local only, DISCLOSED on every resolution: a
     *  restart then forgets both the last-known-good snapshot and the anti-rollback mark. */
    persistence?: OrgRuleStatePersistence;
    stalenessBoundMs: number;
    now?: () => number;
}
/** The ungoverned resolution — what a store with no org partition answers. */
export declare const UNGOVERNED_ORG_RESOLUTION: Readonly<OrgRuleResolution>;
/**
 * Construct the org partition engine for a GOVERNED deployment. This constructor IS the boot gate:
 *  - a declaration WITHOUT a snapshot source is a configuration contradiction and refuses to boot —
 *    a silently ungoverned "governed" deployment is precisely the failure this bit exists to prevent
 *    (the type requires `source`; the check is executed for a JavaScript caller);
 *  - `stalenessBoundMs` follows the knob discipline: a non-number, NaN, non-finite or non-positive
 *    bound is refused loudly, never coerced.
 */
export declare function createOrgRulePartition(cfg: OrgRulePartitionConfig): OrgRulePartition;
/** Whether two snapshots carry the same POLICY: row for row, the same policy members ({@link ORG_ROW_POLICY_MEMBERS}) — never
 *  observation metadata, never a member no judgment reads (which a copy may carry or leave out). The ONE test of "the same
 *  revision, the same content": the partition's equal-revision guard asks it of two snapshots it holds in one form
 *  ({@link orgSnapshotCopyOf}), and a persistence backend asks it of what it stores. */
export declare function sameOrgPolicyContent(a: OrgRuleSnapshot, b: OrgRuleSnapshot): boolean;
/**
 * Which calls an UNREADABLE row may reach — the calls its strictest reading stands over.
 *
 * `"every"` when the row names no tool this layer can place: no rule text, a head the rule syntax cannot read, the lone
 * `*`, or a tool with no rule grammar (a misspelled tool name and a tool this build does not know look the same, and
 * both may be the shell). Otherwise the rule WORD it names — a shell tool's head is the command word, as a call's is —
 * and, for a tool whose path rules speak for a face ({@link PATH_RULE_FACES}), the faces of the column its strictest
 * behavior reads: such a row reaches what a readable rule of its tool could reach, and nothing else.
 */
export type OrgRowReach = "every" | {
    readonly words: readonly string[];
    readonly faces: readonly DenyFace[];
};
/**
 * A row the layer cannot read: its text (as published; the rendering of the scalar its `rule` holds when that is not a string;
 * `<unreadable>` when it holds none — a structure is no value, {@link orgRowPolicyOf}), its 1-based place in the
 * snapshot, why (`code`, and `detail` for a row whose shape — not its text — is at fault), the behavior it stands at, and
 * the calls it reaches. `behavior` is the row's STRICTEST reading: `ask` only when the row says `ask`, `deny` for a row
 * that says `deny` and for one whose behavior cannot be read.
 */
export interface UnreadableOrgRow {
    readonly kind: "unreadable";
    readonly index: number;
    readonly rule: string;
    readonly code: RuleRejectCode;
    readonly detail?: string;
    readonly behavior: "deny" | "ask";
    readonly reach: OrgRowReach;
}
/** A row the layer reads: a shell command rule under the behavior it publishes. */
export interface ReadOrgRow {
    readonly kind: "read";
    readonly index: number;
    readonly rule: string;
    readonly behavior: "deny" | "ask";
    readonly parsed: ParsedRule;
}
/** One call as the org layer judges it: the rule words it answers to (`laneToolNamesOf`; one word is enough), its shell
 *  command when it is the shell tool's, and the face of its path target when it has one (`callPathFaceOf`). */
export interface OrgRuleCall {
    readonly tool: string | readonly string[];
    readonly command?: string;
    readonly face?: DenyFace;
}
/** Every row of a snapshot read once, and the one judgment of a call against them. */
export interface OrgRulesReading {
    readonly rows: readonly (ReadOrgRow | UnreadableOrgRow)[];
    readonly unreadable: readonly UnreadableOrgRow[];
    verdictFor(call: OrgRuleCall): OrgRuleVerdict | undefined;
}
/**
 * The members of an org row the layer reads to judge a call — the row's POLICY. A row IS these members: every reader holds and
 * judges a row as its policy ({@link orgRowPolicyOf}), and two rows with the same policy members are the same policy
 * ({@link sameOrgPolicyContent}). Any other member a row carries is never judged, held, served or persisted (the receipt reads
 * each of a row's own members once — a getter on one runs once — and copies none of what it holds beyond a scalar).
 */
export declare const ORG_ROW_POLICY_MEMBERS: readonly ["rule", "behavior"];
/** A JSON scalar — the only value a member the partition keeps holds as data. */
type Scalar = string | number | boolean | null;
type ScalarMembers<K extends string> = {
    [P in K]?: Scalar;
};
type OrgRowPolicy = Readonly<ScalarMembers<(typeof ORG_ROW_POLICY_MEMBERS)[number]>>;
/**
 * The envelope's rules LIST, read once: `refused` when it is not a list of at most the cap's places ({@link listRefusalOf} —
 * judged before the list is received, so an oversized or sparse list builds no row) or cannot be received at all;
 * otherwise its rows, each as its policy ({@link orgRowPolicyOf}) — the list received whole in one receipt
 * ({@link ORG_RULES_RECEIPT}), so a row's member that cannot be read is that row's alone, a row that cannot be read at all (and
 * a hole) is a row with nothing in it (`{}`: no rule text, read at its strictest reading) and the rows beside it are untouched.
 * The ONE reader of the list — the partition holds a snapshot's rows as these, fetched and read back alike
 * ({@link orgSnapshotCopyOf}), and every reading of rows ({@link readOrgRules}) reads them through it — so no store's rows can be
 * read two ways, and no row can take the reading of another down with it.
 */
export declare function orgRuleListOf(rules: unknown): {
    readonly rows: readonly OrgRowPolicy[];
} | {
    readonly refused: string;
};
/**
 * The ONE reading of an org snapshot's rows: each row read once ({@link readOrgRow}), and the one judgment of a call
 * against them. Every reader of org rows goes through it — the partition's degraded line, the lane's adjudication,
 * {@link orgRuleVerdictFor}, {@link unenforceableOrgRules} and the shadow view — so no two of them can read one row two ways.
 *
 * A call meets the rows in three answers. DENY: a readable deny reaches one of its program runs, or an unreadable row
 * standing at deny reaches the call — the first such row in snapshot order speaks. ASK: a readable rule the call cannot be
 * READ against (the lexer's reason — a rule that cannot be judged may be a deny, so it outranks a reached ask), else a
 * readable ask reaching it or an unreadable row standing at ask reaching it, the first in snapshot order. Otherwise none.
 * An unreadable row's verdict carries its reason ({@link unreadableOrgRowReason}) beside its text.
 *
 * The rows are read off the one list reader's copy ({@link orgRuleListOf}): rules that are not a list come back `refused` —
 * the org's rules cannot be read, which is never a policy of zero rows — and a row is judged on what its copy holds: a policy
 * member that could not be read is one the row does not have (no `rule` ⇒ no rule text, every call; no `behavior` ⇒ its
 * strictest reading over the calls of the tool it names), read like any other unreadable row while the rows beside it keep
 * their effect.
 */
export declare function readOrgRules(rules: unknown): OrgRulesReading | {
    readonly refused: string;
};
/**
 * Which rows of an org snapshot this layer cannot read, each with its code — the rows that stand at their strictest
 * reading instead of as published. Empty ⟺ every row is read. Every unreadable row is reported, a row with no rule text
 * or a behavior other than deny / ask included (its text rendered when it is not a string). Rules that are not a list, or a
 * list past the cap, throw the one list judgment's sentence ({@link readListedOrgRules}) — never a reading of fewer rows.
 */
export declare function unenforceableOrgRules(rules: readonly OrgPermissionRule[]): Array<{
    rule: string;
    code: RuleRejectCode;
}>;
/** The reason an unreadable row's verdict carries — its place in the snapshot, its code, and the repair. */
export declare function unreadableOrgRowReason(row: Pick<UnreadableOrgRow, "index" | "code" | "detail">): string;
/** The ONE clause for an org verdict that carries an `unreadable` reason — a rule the call could not be read against, or
 *  a row this layer cannot read — on a refusal and on a question alike. */
export declare function orgUnreadableClause(reason: string): string;
/**
 * The ONE line naming a snapshot's unreadable rows (count, the first {@link DISCLOSED_UNREADABLE_ROWS} by place, text and
 * code, the rest summarized), or `undefined` when every row is read. The partition puts it on every resolution that
 * serves such a snapshot, and the org lane hands it to its operator sink on every adjudication over one, so the two seats
 * describe one snapshot in one sentence. Each text is escaped — the characters that most often make a row unreadable are
 * exactly the ones that do not render.
 */
export declare function describeUnreadableOrgRows(unreadable: readonly UnreadableOrgRow[], revision?: unknown): string | undefined;
/**
 * design/182 §7.2 — which org rule speaks for this call, if any: {@link readOrgRules}'s judgment, over a snapshot read for
 * this call alone. Matching uses the SAME parser and the SAME tightening reach the personal deny/ask rows use
 * ({@link programRunReachOf}: an interpreter-headed prefix deny like `Bash(node:*)` is a legitimately wide tightening and
 * matches; a segment hit is a hit; a call the lexer cannot read against a rule is an ASK with the reason — fail closed,
 * never silence), and a row this layer cannot read stands at its strictest reading over the calls it may reach. A caller
 * judging many calls against one snapshot reads it once with {@link readOrgRules} instead. Rules that are not a list, or a
 * list past the cap, throw the one list judgment's sentence ({@link readListedOrgRules}) — never a verdict over fewer rows.
 */
export declare function orgRuleVerdictFor(rules: readonly OrgPermissionRule[], call: OrgRuleCall): OrgRuleVerdict | undefined;
/** The org layer's answer for one call: which rule spoke, with what behavior — and, when the rule could not be judged
 *  against the call, why (`unreadable`): either the call could not be READ against it (the lexer's reason; `behavior` is
 *  then `ask` — the org published a rule that may reach this call, and nobody can say), or the row is not one this layer
 *  reads ({@link unreadableOrgRowReason}; `behavior` is the row's strictest reading). */
export interface OrgRuleVerdict {
    readonly behavior: "deny" | "ask";
    readonly rule: string;
    readonly unreadable?: string;
}
/**
 * design/182 §7.3 / design/389 — the SHADOW predicate the unified store's read face applies to every
 * personal allow row: does an org DENY reach this rule's own command pattern? An org deny does not
 * delete a personal rule — the personal rule is the user's approval record, and the org's power is to
 * OVERRIDE it, not to self-declare its removal — so a shadowed rule reports `shadowed-by-org` and comes
 * back by itself when the org deny is withdrawn.
 *
 * The SAME reach the gate uses ({@link ruleReachesProgramRun}), so the view and the decision cannot
 * disagree about whether a deny touches this rule at all. A personal rule may name a connector chain, and a deny on one
 * of its segments shadows it exactly as a deny on the whole does.
 *
 * WHAT `shadowed-by-org` DOES AND DOES NOT CLAIM: the predicate asks whether the deny reaches the
 * personal rule's own command PATTERN — one exemplar — not whether it covers every call that pattern
 * admits. The two differ for a PREFIX personal rule under a narrower deny: `Bash(git status:*)` with an
 * org deny of exactly `Bash(git status)` reports shadowed, yet `git status --short` is still admitted at
 * the gate. The inverse partial overlap (personal `Bash(git:*)`, org deny `Bash(git status:*)`) reports
 * live while part of its reach is denied. A truthful answer needs pattern CONTAINMENT and a third status
 * for partial overlap, which is an API change with its own design; what the two-value view is honest
 * about today is "this rule is touched by a deny" / "no deny mentions it". The gate is the authority
 * either way. org ASK rules do not shadow: the personal lane never consumes a `requiresRealApproval`
 * ask, so the two never actually meet on one call.
 *
 * An UNREADABLE row standing at deny refuses every call it reaches ({@link readOrgRules}), so it shadows every personal
 * rule of a tool it reaches — by the rule word, or by the face that tool's calls are on — exactly as the gate refuses
 * those calls; one standing at ask does not shadow, as a readable ask does not.
 *
 * design/382 §2.6 — no READABLE org row reaches a Read directory rule in this version: the org layer has no Read
 * grammar, and the rule's `command` is a PATH that must not be fed to the shell lane's segment reader as though it
 * were a command line.
 */
export declare function orgRuleShadows(orgRules: readonly OrgPermissionRule[], rule: Pick<PersistedRule, "tool" | "command">): boolean;
/** The shadow predicate with the org rows read ONCE — what a read over many rows uses. */
export declare function compileOrgShadowPredicate(orgRules: readonly OrgPermissionRule[]): (rule: Pick<PersistedRule, "tool" | "command">) => boolean;
/** Does this store carry a write face? Re-exported convenience for org-ticket integrations that need to
 *  distinguish a read-only projection from a writable personal bucket without importing the writer seam. */
export declare function isWritablePermissionRuleStore(store: PermissionRuleStore): boolean;
export {};
