/**
 * WS5.2 R7a — grant / lease-slice primitives for account follow-me.
 *
 * Two load-bearing properties for a SHARED account spread across N machines:
 *  - SINGLE-USE GRANTS: each credential share carries a one-time grant; a replayed (already
 *    consumed) grant is refused (R3 — consumed at the `account-credential-share` gate).
 *  - SUM-OF-LEASES SPEND BOUND: each grant reserves a SLICE of the account's spend ceiling; the
 *    sum of OUTSTANDING slices for an account can never exceed the ceiling, regardless of issue
 *    order, and the bound is RE-DERIVABLE from the durable ledger so a fenced-lease-holder
 *    FAILOVER cannot double-allocate (a new holder rebuilds outstanding from the ledger before
 *    issuing). Slices are LEASE-EPOCH-FENCED: a slice stamped with a stale epoch is void at a
 *    newer epoch (the single-writer-by-fenced-lease guarantee).
 *
 * PR1 scope: the durable ledger + accounting logic, with an injected store seam (production wires
 * a durable JSON/SQLite store; tests use in-memory). The fenced-lease HOLDER election + the live
 * placement wiring are integration-layer (later PR); this module enforces the math the holder runs.
 */
export type GrantStatus = 'outstanding' | 'consumed' | 'released' | 'expired';
export interface GrantRecord {
    grantId: string;
    mandateId: string;
    accountId: string;
    targetFingerprint: string;
    /** This grant's slice of the account spend ceiling (provider quota-fraction, 0..ceiling). */
    amount: number;
    /** Fenced-lease epoch this slice was issued under — stale-epoch slices are void (R7a). */
    leaseEpoch: number;
    issuedAt: number;
    expiresAt: number;
    status: GrantStatus;
}
export interface GrantLedgerData {
    grants: Record<string, GrantRecord>;
}
/** Durable persistence seam (production: JSON/SQLite; tests: in-memory). */
export interface GrantStore {
    read(): GrantLedgerData;
    write(data: GrantLedgerData): void;
}
export declare function inMemoryGrantStore(): GrantStore;
export interface IssueSliceArgs {
    grantId: string;
    mandateId: string;
    accountId: string;
    targetFingerprint: string;
    amount: number;
    /** The account's spend ceiling (provider quota-fraction). */
    ceiling: number;
    /** Current fenced-lease epoch (the accountant must be the lease holder). */
    leaseEpoch: number;
    expiresAt: number;
}
export type IssueResult = {
    ok: true;
    grant: GrantRecord;
} | {
    ok: false;
    reason: string;
};
export type ConsumeResult = {
    ok: true;
} | {
    ok: false;
    reason: string;
};
/**
 * Per-account spend accountant + single-use grant ledger. ALL outstanding state is re-derived
 * from the durable store on every call, so a fresh instance after a lease-holder failover sees
 * the exact same outstanding set (no double-allocation).
 */
export declare class AccountFollowMeGrantLedger {
    private readonly store;
    private readonly now;
    constructor(store: GrantStore, now?: () => number);
    /** Sum of OUTSTANDING (live, unexpired) slices for an account — the spend currently committed. */
    outstandingFor(accountId: string): number;
    /**
     * Issue a single-use grant reserving `amount` of the account ceiling. Refused when:
     * the grant id already exists; the amount is non-positive/over-ceiling; or the new sum-of-
     * outstanding would exceed the ceiling (R7a). Idempotent against the durable ledger.
     */
    issue(args: IssueSliceArgs): IssueResult;
    /**
     * Consume a single-use grant at the credential-share gate. Refused when: unknown; wrong
     * mandate; expired; issued under a STALE lease epoch (void at the current epoch); or already
     * consumed/released (replay defeat — R3). On success the grant flips to `consumed`.
     */
    consume(grantId: string, mandateId: string, currentLeaseEpoch: number): ConsumeResult;
    /** Release a slice (revocation / completion) — frees its spend back to the ceiling. */
    release(grantId: string): ConsumeResult;
}
//# sourceMappingURL=AccountFollowMeGrants.d.ts.map