/**
 * design/389 — ONE permission-rule store, partitioned by SOURCE.
 *
 * A rule comes from one of four sources — `org | user | project | session` — and the four differ in
 * polarity, authority and evolution (an org snapshot is replaced whole by a server administrator; a
 * user/project rule is one human click folded into an OR-Set CRDT; a session grant lives exactly as long
 * as its session). Those differences are WRITE LAWS, and each partition keeps its own. What is one is the
 * READ: "which rules stand for this owner, in this session, and what does each one's standing look like"
 * is a single question, so it has a single answer — {@link PermissionRuleStore.effective}, a query the
 * store answers across every partition with each row's `source` and `status`, the org shadow predicate
 * applied inside the store rather than at each caller.
 *
 * ## Composition, not inheritance
 *
 * {@link createPermissionRuleStoreProvider} is the ONE way to build the store. A deployment hands it
 * partition backends — the durable CRDT partition (`DurableRulePartitionProvider`: file, in-memory, an
 * out-of-repo SQL twin), an org partition config (its snapshot source and staleness bound), a session
 * partition — and the engine composes them. The org and session partition LAWS are engine code the
 * backend cannot weaken; the durable partition's law is the exported pure fold every backend runs.
 * A partition a deployment does not configure does not exist: its source answers nothing, and the
 * provider's `partitions` face says so, so a manifest reads a declaration rather than inferring one.
 *
 * ## Source is a projection of the row's address
 *
 * `user` ⟺ scope `global`, `project` ⟺ scope `project`, `session` ⟺ scope `session`. A row never carries
 * a second source byte that could drift from its scope — {@link ruleSourceOf} is the whole mapping.
 *
 * ## One write path, routed by scope
 *
 * `writerOf(store)` hands back a writer whose `apply` routes a `redemption-add` by the delta's scope: a
 * session scope lands in the session partition (idempotent by dot, refused `session_ended` past the
 * session's epoch seal), the two durable scopes take the CRDT partition's compare-and-set. The consent
 * protocol therefore has ONE write path with ONE result vocabulary ({@link RuleWriteOutcome}); the
 * durable backend keeps refusing a session row loudly should one ever reach it — the route is the
 * store's, the fence stays the partition's.
 */
import type { PersistedRule, RuleScope } from "./permission-rule-model.js";
import { type DurableRulePartitionProvider, type QuarantinedRuleAdd, type RuleOwner } from "./permission-rule-store.js";
import { type OrgRulePartitionConfig, type OrgRuleResolution } from "./permission-rule-org.js";
import type { SessionRulePartition } from "./permission-rule-session.js";
import type { StoreDurability, StoreFidelity } from "./checkpoint-store.js";
/** The four sources a rule can come from — CC's settings-layer vocabulary folded onto sema's four. */
export type RuleSource = "org" | "user" | "project" | "session";
/** The source of a row is a projection of its scope — `global` is the `user` source. */
export declare function ruleSourceOf(scope: RuleScope): Exclude<RuleSource, "org">;
/** One live personal rule in the effective view: the row itself, its source, and its standing under the
 *  org partition (`shadowed-by-org` = an org deny reaches an ALLOW row's command pattern; see
 *  `orgRuleShadows` — a personal deny/ask row is never shadowed: it only ever tightens, and the org
 *  partition's power over the personal store is to override an allow, not a refusal). */
export interface EffectivePermissionRule extends PersistedRule {
    source: Exclude<RuleSource, "org">;
    status: "live" | "shadowed-by-org";
}
/** A durable rule identity every add of which is tombstoned — the rule no longer stands, and its
 *  tombstone identity is still visible in the partition. Session rows never appear here (they die
 *  with their session and leave no tombstone). */
export interface RemovedPermissionRule {
    behavior: import("./permission-rule-model.js").RuleBehavior;
    rule: string;
    scope: RuleScope;
    source: "user" | "project";
    status: "removed";
}
/** THE answer of the store's one read query. */
export interface EffectivePermissionRules {
    /** Live personal rows, in reporting order: this session's rows first (the narrowest standing yes), then
     *  the durable partition in its own table order — byte-equivalent to the pre-389 splice. */
    rules: EffectivePermissionRule[];
    /** Tombstoned durable identities (introspection). */
    removed: RemovedPermissionRule[];
    /** The org partition's resolution. `ungoverned` on a deployment with no org partition. */
    org: OrgRuleResolution;
    /** The durable partition's revision — the optimistic-concurrency anchor for its writes. */
    rev: number;
    /** Present iff a PERSONAL partition could not be read — the durable one (its user / project rows; `removed` is then
     *  empty and `rev` 0) or the session one: the failed partition's rows are absent from `rules`, while the rows of the
     *  partition that WAS read stand, and so does the org resolution beside them (a flaky personal store must not become an
     *  org governance outage). The line names the failure (both lines, `; `-joined, when both failed). A consumer that needs
     *  the durable rows treats this as a read failure — {@link effectiveOrThrow} is that reading; the gate's personal lane
     *  and the leg's path-row read skip the failed partition's rows, disclosed, and judge by the rest. */
    unreadable?: string;
    /** Beside {@link unreadable}: the sources whose partition could not be read (`user` and `project` — the durable
     *  partition; `session`), in that order — the rows `rules` does not carry. */
    unreadableSources?: readonly Exclude<RuleSource, "org">[];
    /** Disclosure lines from the personal partitions (a session partition that could not be read, rows it
     *  served that are not canonical session rows of this session). The org partition's lines ride
     *  `org.disclosures`. */
    disclosures: string[];
}
/**
 * The host-visible store, already anchored to one owner. One read verb, which never throws: each
 * partition reports its own failure in the view — a PERSONAL partition's read failure (the durable one's, the
 * session one's) as `unreadable` / `unreadableSources`, with that partition's rows absent and the other's present
 * (served-but-non-canonical session rows stay a `disclosures` line), the ORG partition's as its `status`. The unit
 * that fails is the partition: the org verdict stands while a personal partition is down, each personal partition's
 * rows stand while the other is down, and the personal rows stand while an org source is down.
 */
export interface PermissionRuleStore {
    effective(query?: {
        sessionId?: string;
    }): Promise<EffectivePermissionRules>;
    /** design/182 §5.2 — the durable partition's quarantine area, for introspection. */
    quarantined?(): Promise<QuarantinedRuleAdd[]>;
    /** The durable partition's declared durability; an undeclared backend reads fail-closed as `"process-local"`. */
    readonly durability?: StoreDurability;
    readonly fidelity?: StoreFidelity;
}
/**
 * The unified provider — the ONE `RunnerDeps.permissionRuleStore` seam. `partitions` is the declaration
 * face: the wiring manifest's cells and the ask evidence's `not_wired` words read it verbatim instead of
 * inferring from three separate seams.
 */
export interface PermissionRuleStoreProvider {
    /** The store for one verified principal. `undefined` ⇒ zero personal rules — but the org partition
     *  still adjudicates: governance applies to everyone, an anonymous task included. */
    forPrincipal(principal: string | undefined): PermissionRuleStore;
    /** design/182 §4.5 — the identity-less local bucket. Present iff the durable backend has one. */
    forLocalOwner?(): PermissionRuleStore;
    readonly partitions: Readonly<{
        durable: boolean;
        org: boolean;
        session: boolean;
    }>;
}
/**
 * The store one task reads its person's rules from. The unauthenticated floor is enforced HERE, not merely asked of the
 * provider: an absent principal resolves to zero personal rules, and a provider that forgot it would hand one person's
 * standing approvals to an anonymous task. The ONE exception is an explicitly declared LOCAL-OWNER deployment, where "no
 * principal" is the typed absence of identity — the machine owner's own bucket (a provider with no such face resolves
 * the anonymous store; {@link createPermissionRuleLanes} refuses that declaration loudly).
 */
export declare function ownerStoreOf(provider: PermissionRuleStoreProvider, principal: string | undefined, localOwnerDeclared: boolean): PermissionRuleStore;
/** What {@link createPermissionRuleStoreProvider} composes. */
export interface PermissionRuleStoreConfig {
    /** The durable CRDT partition (user + project sources). Absent ⇒ no personal rules exist on this
     *  deployment (the rule lane does not arm), and no session grant can land either (the redemption
     *  dot is minted by the durable replica). */
    durable?: DurableRulePartitionProvider;
    /** The org partition. Its PRESENCE is the governance declaration (design/182 §7.4 D3): under it the
     *  org adjudication surface must always be effective, and an unreadable snapshot fails the whole
     *  decision boundary closed. */
    org?: OrgRulePartitionConfig;
    /** The session partition. Absent ⇒ the session source does not exist: a session-scope redemption is
     *  refused loudly (nowhere to land), and `effective()` carries no session rows. */
    session?: SessionRulePartition;
}
/**
 * Compose the unified store over its partition backends. This is the boot gate of the org declaration
 * (`createOrgRulePartition` refuses a config naming no source) and the ONLY constructor of the store.
 */
export declare function createPermissionRuleStoreProvider(cfg: PermissionRuleStoreConfig): PermissionRuleStoreProvider;
/**
 * The one read query for a consumer that NEEDS the durable rows (a write's optimistic-concurrency anchor,
 * a coverage judgment, a removal): an `unreadable` durable partition is a thrown read failure here, so
 * the caller's existing "could not read the permission-rule store" arm fires — the gate lane is the one
 * consumer that reads the word itself.
 */
export declare function effectiveOrThrow(store: PermissionRuleStore, query?: {
    sessionId?: string;
}): Promise<EffectivePermissionRules>;
/**
 * The one read query, addressed by owner (design/182 §7.3 introspection, design/389 form): resolve the
 * owner's store and ask it. Nothing is assembled here — a consumer that needs the effective view with
 * `source`/`status` per row and the org resolution beside it gets the store's own answer.
 */
export declare function effectivePermissionRules(opts: {
    provider: PermissionRuleStoreProvider;
    principal?: string;
    owner?: RuleOwner;
    sessionId?: string;
}): Promise<EffectivePermissionRules>;
/** Owner routing shared by the introspection entry: either a principal or the local owner, never both. */
export declare function resolveOwnerStore(opts: {
    provider: PermissionRuleStoreProvider;
    principal?: string;
    owner?: RuleOwner;
}): PermissionRuleStore;
