/**
 * MandateStore — persists Coordination Mandates and verifies their authorship.
 *
 * A mandate is valid only if its `authProof` verifies (threat-model T1/T2): the proof
 * is produced ONLY by the PIN-gated issuance path (the human-authenticated surface,
 * Justin's decision A on issuance), so an agent holding only its Bearer token cannot
 * mint or widen a mandate. The proof covers the AUTHORED, immutable fields; `revoked`
 * is a store-managed flag (a later mutation), so it is excluded from the proof and
 * checked separately on every gate evaluation.
 *
 * The signer/verifier are INJECTED (like the other signed stores): tests use a
 * deterministic stub; production uses an HMAC over the server's issuance secret.
 *
 * Trust boundary (stated, not hidden): integrity of the on-disk mandate + revocation
 * flag against an attacker with LOCAL write access is the same trust root as today
 * (threat-model T12, out of scope) — the proof stops a forged/edited AUTHORED mandate;
 * local-file tamper of server-managed state is the baseline trust boundary.
 */
import type { Authority, CoordinationMandate, UserAuthorityGrant } from './types.js';
/**
 * Canonical bytes the authProof covers — the AUTHORED fields only (proof + revoked excluded).
 *
 * BACKWARD-COMPAT (non-negotiable): `grants` is appended to the byte sequence ONLY
 * when it is present AND non-empty. A mandate with no grants (the pre-extension shape,
 * `grants` undefined OR `[]`) therefore canonicalizes to the EXACT same bytes as before
 * this extension existed — so every previously-signed mandate's stored `authProof`
 * keeps verifying. When grants ARE present, they extend the canonical bytes (each grant
 * as a field-ordered tuple), so the proof covers them and a grant cannot be forged or
 * added without re-signing through the PIN-gated path.
 */
export declare function canonicalMandate(m: Omit<CoordinationMandate, 'authProof' | 'revoked'>): string;
export interface MandateStoreDeps {
    /** Absolute path to the mandates JSON file. */
    filePath: string;
    /** Sign the canonical mandate bytes (HMAC over the issuance secret in production). */
    sign: (canonical: string) => string;
    /** Verify a proof against the canonical mandate bytes. */
    verifySig: (canonical: string, proof: string) => boolean;
    now?: () => number;
    /** Mandate id generator (default: random). Injected for deterministic tests. */
    genId?: () => string;
}
export interface IssueMandateInput {
    scope: string;
    agents: [string, string];
    authorities: Authority[];
    author: string;
    expiresAt: string;
    id?: string;
    createdAt?: string;
    /** Optional user→agent authority grants signed into the mandate at issuance. */
    grants?: UserAuthorityGrant[];
}
export declare class MandateStore {
    private readonly d;
    constructor(deps: MandateStoreDeps);
    private nowIso;
    private readAll;
    private writeAll;
    /**
     * Issue (author) a mandate. ONLY the PIN-gated route should call this. Signs the
     * authored bytes, persists, returns the mandate.
     */
    issue(input: IssueMandateInput): CoordinationMandate;
    /**
     * Add user→agent authority grant(s) to an existing mandate and RE-SIGN it so the
     * `authProof` covers the new grants (the only path that can sign a grant in — the
     * PIN-gated route is the sole caller). Grants are validated and clamped against the
     * mandate's own expiry: a grant's `expiresAt` may never exceed the mandate's.
     *
     * Returns `{ ok: false }` with a reason for a missing/revoked mandate or an invalid
     * grant; `{ ok: true, mandate }` on success. Never partially applies.
     */
    addGrants(id: string, grants: UserAuthorityGrant[]): {
        ok: true;
        mandate: CoordinationMandate;
    } | {
        ok: false;
        reason: string;
    };
    /** Verify a mandate's authorship proof (T1/T2). */
    verifyAuthorship(m: CoordinationMandate): boolean;
    get(id: string): CoordinationMandate | undefined;
    list(): CoordinationMandate[];
    /** Revoke a mandate (idempotent). Returns the updated mandate, or undefined if absent. */
    revoke(id: string, reason: string): CoordinationMandate | undefined;
}
//# sourceMappingURL=MandateStore.d.ts.map