/**
 * MemoryAuditChain -- Cryptographic continuity chain for cross-session memory.
 *
 * Every mutation to cross-session memory for an (orgId, agentId) namespace
 * produces a SHA-256 chain link bound to the prior state. Tampering with the
 * underlying store between sessions breaks the chain and fires a
 * MEMORY_CHAIN_TAMPERED audit event at severity ERROR.
 *
 * Design -- Merkle-like state commitment per (orgId, agentId):
 *
 *   nextStateHash = sha256(prevStateHash || operationHash || currentStateHash)
 *
 * Where:
 *   operationHash    = sha256(canonicalize({ kind, key, valueHash, scope,
 *                                           packBinding (sorted), seq, timestampNs }))
 *   currentStateHash = sha256(canonicalize(sortedStateEntries))
 *   sortedStateEntries = sorted-by-key list of { key, valueHash, scope, packBinding }
 *   valueHash        = sha256(JSON.stringify(value)) -- raw values NEVER emitted.
 *
 * Canonicalization rules (see canonicalizeJson):
 *   Object keys sorted lexicographically; arrays preserve element order;
 *   applied recursively. A third-party auditor can reproduce by applying the
 *   same sort-keys-and-stringify over the structured data.
 *
 * Attack model:
 *   External tampering: a DB write outside the API inserts a rogue entry.
 *     Detection: the next recordOperation recomputes currentState and finds
 *     the rogue entry; stateHash diverges from the chain.
 *   Replay attack: attacker replays a stale link (seq N) after the chain
 *     is at seq M > N. isReplay() check rejects seq !== M+1.
 *   Forgery: fabricated chain link without correct prevStateHash causes
 *     hash divergence at the next legitimate operation.
 *   Genesis spoofing: attacker fabricates a genesis for a different agentId.
 *     genesis = sha256('memory-chain-genesis-' + orgId + ':' + agentId),
 *     so a wrong agentId produces a wrong genesis and verification fails
 *     at the first real operation.
 *
 * Compliance bindings:
 *   HIPAA 164.312(c)(1): integrity controls for PHI in cross-session memory
 *   SOC 2 CC7.2: monitoring system components for tampering
 *   EU AI Act Art. 12: record-keeping requirements
 *   ISO 42001 A.9.1: AI system monitoring
 *
 * Storage:
 *   Chain links are stored as MEMORY_CHAIN_LINK audit events through the
 *   provided AuditSink. No new storage tier required -- the same Splunk HEC /
 *   Syslog RFC 5424 destinations used for governance events accept these.
 *
 * @connexum/ai-governance P3-T1
 */
/**
 * Sort all keys of an object recursively, then serialize to JSON.
 * Ensures determinism across key insertion order.
 *
 * Rules:
 *   1. Object keys are sorted lexicographically (Unicode code point order).
 *   2. Arrays preserve element order (element order is semantically meaningful).
 *   3. null / primitives serialise as standard JSON.
 *   4. Canonicalization applied recursively to nested objects.
 *
 * A third-party auditor can reproduce:
 *   (1) Parse the stored canonical string back to JSON.
 *   (2) Apply this function to reserialise with sorted keys.
 *   (3) SHA-256 hash the result.
 */
export declare function canonicalizeJson(value: unknown): string;
export type MemoryOperationKind = 'set' | 'delete';
export interface MemoryOperation {
    kind: MemoryOperationKind;
    key: string;
    /** Present for 'set' operations; absent for 'delete'. NEVER stored in audit. */
    value?: unknown;
    scope: string;
    /** Must be non-empty -- pack-binding primacy rule. */
    packBinding: string[];
    /** Nanoseconds since epoch as a string (use process.hrtime.bigint().toString()). */
    timestampNs: string;
}
/** One entry in the per-agent state snapshot. No raw values. */
export interface MemoryStateEntry {
    key: string;
    /** sha256(JSON.stringify(value)) -- raw value absent. */
    valueHash: string;
    scope: string;
    packBinding: string[];
}
/**
 * A single audit event representing one chain link.
 * Raw memory values NEVER appear here. Only valueHash.
 */
export interface MemoryChainLink {
    type: 'MEMORY_CHAIN_LINK';
    orgId: string;
    agentId: string;
    seq: number;
    prevStateHash: string;
    operationHash: string;
    stateHash: string;
    timestamp: string;
    packBinding: string[];
    kind: MemoryOperationKind;
    key: string;
    /** sha256 of the raw value -- raw value never included. */
    valueHash: string;
    scope: string;
    timestampNs: string;
}
export interface MemoryChainTamperedEvent {
    type: 'MEMORY_CHAIN_TAMPERED';
    severity: 'ERROR';
    orgId: string;
    agentId: string;
    brokenAt: number;
    expectedStateHash: string;
    actualStateHash: string;
    timestamp: string;
}
export interface VerifyChainResult {
    valid: true;
}
export interface VerifyChainFailure {
    valid: false;
    brokenAt: number;
    expected: string;
    actual: string;
}
export type VerifyChainOutcome = VerifyChainResult | VerifyChainFailure;
/**
 * Controls how often verifyChain is triggered on reads.
 *   'always' -- every read triggers full chain verification (max security)
 *   'sample' -- sampleRate fraction of reads trigger verification (default 10%)
 *   'never'  -- read-time verification disabled
 */
export type VerifyOnReadPolicy = 'always' | 'sample' | 'never';
export interface MemoryAuditChainConfig {
    verifyOnRead?: VerifyOnReadPolicy;
    /**
     * Fraction [0,1] of reads that trigger verification when verifyOnRead='sample'.
     * Default: 0.10 (10%). Rationale: bounds overhead on high-throughput read
     * paths while still surfacing tampering within O(1/rate) reads.
     */
    sampleRate?: number;
    /** Verify all registered agents on startup. Default: true. */
    verifyOnStartup?: boolean;
    /**
     * Seeded RNG for deterministic sampling in tests.
     * Default: Math.random.
     */
    rng?: () => number;
}
export type AuditSink = (event: MemoryChainLink | MemoryChainTamperedEvent) => void;
export declare class MemoryAuditChain {
    private readonly cfg;
    private readonly sink;
    private readonly chains;
    constructor(config?: MemoryAuditChainConfig, sink?: AuditSink);
    /**
     * Genesis hash is a pure function of (orgId, agentId).
     * An attacker who fabricates a genesis using a different agentId will
     * produce a different genesis, causing verification failure at the first
     * real operation.
     */
    getGenesisHash(orgId: string, agentId: string): string;
    getCurrentStateHash(orgId: string, agentId: string): string;
    /**
     * Record a mutation to cross-session memory and emit a chain link.
     *
     * Must be called by CrossSessionMemoryStore on every write and delete.
     *
     * MANDATORY: packBinding must be non-empty.
     * Raw values NEVER appear in any audit payload; only valueHash is stored.
     *
     * Returns the new state hash.
     */
    recordOperation(orgId: string, agentId: string, op: MemoryOperation): string;
    /**
     * Replay all recorded links from genesis and recompute each stateHash.
     * Any divergence indicates tampering.
     *
     * On tamper detection:
     *   Emits MEMORY_CHAIN_TAMPERED event at severity ERROR.
     *   Returns { valid: false, brokenAt: seq, expected, actual }.
     *
     * On success:
     *   Returns { valid: true }.
     */
    verifyChain(orgId: string, agentId: string): VerifyChainOutcome;
    /**
     * Returns true if this read should trigger verifyChain().
     * Caller is responsible for calling verifyChain when this returns true.
     *
     * Default policy 'sample' at 10%: bounds overhead on high-throughput read
     * paths while still surfacing tampering within O(10) reads on average.
     * For HIPAA deployments, set verifyOnRead: 'always'.
     */
    shouldVerifyOnRead(): boolean;
    /**
     * Returns true if the given seq is a replay (already processed or
     * out-of-expected-order) for this (orgId, agentId) chain.
     *
     * Expected next seq = current link count + 1.
     * Anything else is a replay or injection attempt.
     */
    isReplay(orgId: string, agentId: string, seq: number): boolean;
    /**
     * Tamper a stored link's stateHash directly.
     * Simulates an out-of-band write that corrupts the chain.
     * Only for test use -- DO NOT call in production code.
     */
    _tamperLink(orgId: string, agentId: string, seq: number, newStateHash: string): void;
    /** Returns a copy of the chain links for a given (orgId, agentId). */
    _getLinks(orgId: string, agentId: string): MemoryChainLink[];
    private chainKey;
}
export declare class EmptyPackBindingError extends Error {
    constructor(key: string, orgId: string, agentId: string);
}
//# sourceMappingURL=memory-audit-chain.d.ts.map