/**
 * AuthorizationRequestStore — the "agent proposes, operator approves" primitive.
 *
 * Spec: docs/specs/OPERATOR-AUTHORIZATION-REQUEST-SPEC.md (converged 2026-06-13).
 *
 * The agent (Bearer-auth) registers a STRUCTURED request; a pending request confers
 * ZERO authority (it is inert). The operator approves it with their dashboard PIN, and
 * ONLY then — inside the PIN-gated route — does the server execute the structured
 * proposal (issue the floor-action grant via the existing signed MandateStore path).
 *
 * Safety invariants this store upholds:
 *  - requester ≠ authorizer: the store never confers authority; `approve()` runs an
 *    INJECTED `execute` callback (the PIN-gated route wires it to MandateStore) — the
 *    store itself only manages request lifecycle + the atomic status transition.
 *  - display integrity: the store carries the STRUCTURED `proposal` (the only thing
 *    executed) + its content hash. The operator-facing text is rendered SERVER-SIDE
 *    from the proposal (see renderAuthorizationCard); agent free-text (`reason`) is
 *    carried but is never the authority headline.
 *  - TOCTOU: `proposalSha256` is fixed at create and re-verified at approve, so the
 *    proposal cannot be mutated between display and approval.
 *  - atomicity/idempotency: `approve` is serialized per-request and idempotent (a second
 *    approve of an already-approved request returns the same result, never a 2nd grant).
 *
 * File-based JSON store (no DB), mirroring MandateStore. Pure + injectable (now/genId)
 * so it unit-tests with fakes and never reaches the real clock in tests.
 */
/** The floor actions an agent MAY propose via this path. EXCLUDES 'grant-authority'
 *  (the meta-escalation stays manual-only — the Advanced mandate form). FD-8. */
export declare const PROPOSABLE_FLOOR_ACTIONS: readonly string[];
/** Human labels for the server-authored headline (FD / display-integrity rule). */
export declare const FLOOR_ACTION_LABELS: Record<string, string>;
export declare const MIN_GRANT_DURATION_MS = 60000;
export declare const MAX_GRANT_DURATION_MS = 86400000;
export declare const REQUEST_TTL_MS = 86400000;
export declare const DEFAULT_PENDING_CAP_PER_AGENT = 10;
export declare const RESOLVED_RETENTION_MS = 2592000000;
export declare const REPROPOSE_COOLDOWN_MS = 3600000;
export type AuthorizationRequestStatus = 'pending' | 'approved' | 'denied' | 'expired' | 'withdrawn';
export interface UserFloorGrantProposal {
    floorAction: string;
    grantedToSlackUserId: string;
    durationMs: number;
}
export interface AuthorizationRequest {
    id: string;
    createdAt: string;
    createdByAgent: string;
    createdOnMachine: string;
    status: AuthorizationRequestStatus;
    kind: 'user-floor-grant';
    proposal: UserFloorGrantProposal;
    proposalSha256: string;
    reason?: string;
    requestExpiresAt: string;
    resolvedAt?: string;
    resolvedBy?: 'operator';
    resultMandateId?: string;
    denyReason?: string;
}
/** Content-address a proposal (fixed at create, re-checked at approve — TOCTOU guard). */
export declare function hashProposal(p: UserFloorGrantProposal): string;
/** A plain-language duration for the server-authored headline. */
export declare function humanDuration(ms: number): string;
/**
 * The SERVER-AUTHORED card the operator sees. Built ONLY from the structured proposal
 * + the trusted display name resolved upstream (never from agent free-text). The
 * `reason` is returned separately so the UI can render it as a clearly-secondary,
 * escaped line — never the headline. This is the display-integrity fix.
 */
export declare function renderAuthorizationCard(req: AuthorizationRequest, grantedToDisplay: string): {
    headline: string;
    reason?: string;
};
export interface AuthorizationRequestStoreDeps {
    filePath: string;
    now?: () => number;
    genId?: () => string;
    pendingCapPerAgent?: number;
}
export interface CreateRequestInput {
    createdByAgent: string;
    createdOnMachine: string;
    proposal: UserFloorGrantProposal;
    reason?: string;
}
export type CreateResult = {
    ok: true;
    request: AuthorizationRequest;
    deduped?: boolean;
} | {
    ok: false;
    status: number;
    error: string;
};
export type ApproveResult = {
    ok: true;
    request: AuthorizationRequest;
    alreadyApproved?: boolean;
} | {
    ok: false;
    status: number;
    error: string;
};
export declare class AuthorizationRequestStore {
    private readonly d;
    private readonly cap;
    constructor(deps: AuthorizationRequestStoreDeps);
    private nowMs;
    private nowIso;
    private readAll;
    private writeAll;
    /** Lazily age out past-TTL pending requests on every read-modify path (also driven by an hourly sweep). */
    private ageExpired;
    /** Validate + create a pending request. Confers no authority. Dedup + flood-capped. */
    create(input: CreateRequestInput): CreateResult;
    get(id: string): AuthorizationRequest | undefined;
    list(status?: AuthorizationRequestStatus): AuthorizationRequest[];
    /**
     * Approve a request — the ONLY authority-conferring path, and ONLY callable from the
     * PIN-gated route. `execute(proposal)` issues the carrier mandate + grant via MandateStore
     * and returns the resultMandateId; it runs AFTER the status + hash + (caller's) allowlist /
     * registry re-checks, and BEFORE the commit, so a thrown execute aborts cleanly (request
     * stays pending). Idempotent: re-approving an already-approved request returns its result.
     */
    approve(id: string, opts: {
        execute: (proposal: UserFloorGrantProposal) => string;
    }): ApproveResult;
    /** Operator declines — reason REQUIRED (FD-10). */
    deny(id: string, denyReason: string): ApproveResult;
    /** The proposing agent withdraws its OWN still-pending request. Mutually exclusive with approve. */
    withdraw(id: string, byAgent: string): ApproveResult;
    /** Hourly sweep: age out past-TTL pending + prune resolved older than the retention window (FD-11). */
    sweep(): {
        expired: number;
        pruned: number;
    };
}
//# sourceMappingURL=AuthorizationRequestStore.d.ts.map