/**
 * CrossSessionPseudonymizer -- Runtime application of pseudonymize/retain rules
 * for cross-session memory entries.
 *
 * Closes the loop started by PR #15 (SessionMemoryEnforcer gate) and integrates
 * with PR #22 (MemoryAuditChain) for tamper-evident pseudonymization records.
 *
 * Two modes per pack policy (derived from PACK_POLICIES in cross-session-memory.ts):
 *
 *   pseudonymize mode:
 *     - Each identifierField in the policy is replaced with a deterministic
 *       pseudonym: psn_<16-hex-of-sha256(orgId + fieldName + originalValue)>.
 *     - 16 hex chars = 64 bits -- ~2^-64 collision probability per pair.
 *     - Pseudonyms are deterministic within an org (orgId in hash input).
 *     - Cross-org leakage prevented: different orgIds produce different pseudonyms.
 *     - Reverse mapping (pseudonym -> original) stored in a per-org in-memory vault.
 *     - v1 plan: persist vault to operator-side key-manager; vault is NEVER
 *       co-located with the audit chain.
 *
 *   retain mode:
 *     - Value stored as-is; entry bound to retentionDays window.
 *     - On expiry: CROSS_SESSION_MEMORY_RETAINED_EXPIRED (NOTICE) emitted.
 *     - Auto-delete via registered retention timer.
 *     - Early delete requires memory.early-delete permission (PT-PSEUDONYM-3).
 *
 * Audit chain integration:
 *   - applyPolicies() emits a memory-audit-chain 'set' operation after
 *     transformation. The TRANSFORMED value (pseudonymized form) goes to the
 *     chain. The original value NEVER reaches the chain.
 *
 * Pseudonym vault:
 *   - Per-org Map: orgId -> Map<pseudonym, originalValue>.
 *   - deanonymize requires memory.deanonymize permission (OperatorRoles).
 *   - Cross-org resolution rejected at the API level.
 *   - Vault is operator-controlled and out-of-band from audit logs.
 *   - THREAT: if the vault for org A is leaked, pseudonyms in the audit chain
 *     become reversible. Mitigated by keeping the vault separate from audit
 *     chain storage and scoping it per-org. The vault is never logged.
 *
 * Pen-test coverage:
 *   PT-PSEUDONYM-1: Vault-leak threat model (vault is org-scoped; cross-org
 *     leak does not expose org A's mappings from org B context).
 *   PT-PSEUDONYM-2: Pseudonym collision -- 16-hex prefix used (64-bit, ~2^-64
 *     per pair). Collision detection fires PSEUDONYM_COLLISION_DETECTED ERROR.
 *   PT-PSEUDONYM-3: Retention-bypass -- clearAllForAgent mid-retention requires
 *     memory.early-delete permission; rejected without it.
 *
 * BUILD_PLAN_V3_FULL_LIFECYCLE.md line 241.
 *
 * Compliance bindings:
 *   - GDPR Art. 4(5) + Recital 26: pseudonymization as data protection measure
 *   - HIPAA 164.514(b): safe harbour de-identification
 *   - HMDA Reg C 1003.6: data privacy in HMDA reporting
 *   - CCPA 1798.100: right to know / access
 *
 * @connexum/ai-governance P3-T1
 */
import type { OperatorRoles } from '../security/operator-roles';
/** Thrown when a cross-session write has pack binding but no applicable policy. */
export declare class NoApplicablePseudonymizeOrRetainPolicyError extends Error {
    readonly orgId: string;
    readonly agentId: string;
    readonly key: string;
    readonly packBinding: string[];
    constructor(opts: {
        orgId: string;
        agentId: string;
        key: string;
        packBinding: string[];
    });
}
/** Thrown when deanonymize is attempted without memory.deanonymize permission. */
export declare class DeanonymizePermissionDeniedError extends Error {
    readonly operatorId: string;
    readonly orgId: string;
    constructor(opts: {
        operatorId: string;
        orgId: string;
    });
}
/** Thrown when deanonymize is attempted for a pseudonym from a different org. */
export declare class CrossOrgResolutionRejectedError extends Error {
    readonly requestingOrgId: string;
    constructor(requestingOrgId: string);
}
/** Thrown when early deletion is attempted without memory.early-delete permission. */
export declare class EarlyDeletePermissionDeniedError extends Error {
    readonly operatorId: string;
    readonly orgId: string;
    readonly agentId: string;
    constructor(opts: {
        operatorId: string;
        orgId: string;
        agentId: string;
    });
}
export interface PseudonymCollisionEvent {
    type: 'PSEUDONYM_COLLISION_DETECTED';
    severity: 'ERROR';
    orgId: string;
    fieldName: string;
    pseudonym: string;
    existingValueHash: string;
    newValueHash: string;
    timestamp: string;
}
export interface RetainedEntryExpiredEvent {
    type: 'CROSS_SESSION_MEMORY_RETAINED_EXPIRED';
    severity: 'NOTICE';
    orgId: string;
    agentId: string;
    key: string;
    packId: string;
    retentionDays: number;
    expiredAt: string;
}
export type PseudonymizerAuditEvent = PseudonymCollisionEvent | RetainedEntryExpiredEvent;
export type PolicyMode = 'pseudonymize' | 'retain';
/** A pack policy that applies to a cross-session write. */
export interface AppliedPolicy {
    packId: string;
    mode: PolicyMode;
    /** Fields replaced (pseudonymize mode) or empty array (retain mode). */
    fieldsTouched: string[];
    /** Retention window in days (retain mode) or undefined (pseudonymize mode). */
    retentionDays?: number;
}
export interface ApplyPoliciesResult {
    transformedValue: unknown;
    appliedPolicies: AppliedPolicy[];
}
/** Callback type for cross-session store mutations (delete on expiry). */
export type CrossSessionDeleteCallback = (orgId: string, agentId: string, key: string) => void;
/** Audit sink for pseudonymizer events. */
export type PseudonymizerAuditSink = (event: PseudonymizerAuditEvent) => void;
/** Audit sink for memory audit chain recordOperation calls. */
export interface MemoryAuditChainSink {
    recordOperation(orgId: string, agentId: string, op: {
        kind: 'set' | 'delete';
        key: string;
        value?: unknown;
        scope: string;
        packBinding: string[];
        timestampNs: string;
    }): string;
}
/**
 * CrossSessionPseudonymizer applies pack policies (pseudonymize or retain) to
 * cross-session memory writes and manages the reverse-lookup vault and
 * retention lifecycle.
 *
 * Integration recipe (PR #15 call site):
 *   After SessionMemoryEnforcer.set() gate passes (scope === 'cross-session'
 *   and hasPseudonymizeOrRetainRule(packBinding)), the call site that persists
 *   to CrossSessionMemoryStore should:
 *
 *     const { transformedValue, appliedPolicies } = pseudonymizer.applyPolicies(
 *       orgId, agentId, key, rawValue, 'cross-session', packBinding,
 *     );
 *     crossSessionStore.write(agentId, key, transformedValue);
 *     // transformedValue (pseudonymized form) goes to audit chain, never rawValue.
 *
 * This PR does NOT modify PR #15 source (SessionMemoryEnforcer) or PR #22
 * source (MemoryAuditChain). It provides the transformer that the integration
 * call site should use.
 */
export declare class CrossSessionPseudonymizer {
    /** Per-org pseudonym vaults. NEVER co-located with audit logs. */
    private readonly vault;
    /** Retention registrations: (orgId, agentId, key) -> RetentionEntry. */
    private readonly retentions;
    private readonly operatorRoles;
    private readonly auditSink;
    private readonly auditChain;
    private readonly deleteCallback;
    /**
     * @param operatorRoles - Used for deanonymize and early-delete permission checks.
     * @param auditSink - Receives PSEUDONYM_COLLISION_DETECTED and CROSS_SESSION_MEMORY_RETAINED_EXPIRED events.
     * @param auditChain - Optional MemoryAuditChain. When supplied, applyPolicies() emits
     *   a 'set' recordOperation with the TRANSFORMED value (never the original).
     * @param deleteCallback - Called when a retain-mode entry expires (auto-delete).
     */
    constructor(opts: {
        operatorRoles: OperatorRoles;
        auditSink?: PseudonymizerAuditSink;
        auditChain?: MemoryAuditChainSink;
        deleteCallback?: CrossSessionDeleteCallback;
    });
    /**
     * Apply pseudonymize/retain policies to a cross-session write.
     *
     * For each pack in packBinding that has a matching PACK_POLICY:
     *   - pseudonymize: replace identifierField values with psn_<16hex> pseudonyms.
     *   - retain: record a retention window registration; value passed through as-is.
     *
     * Defense-in-depth: throws NoApplicablePseudonymizeOrRetainPolicyError if no
     * policy applies for a cross-session scope (mirrors the PR #15 gate).
     *
     * After transformation, emits a memory-audit-chain 'set' operation with the
     * TRANSFORMED value. The original value NEVER reaches the audit chain.
     *
     * @returns { transformedValue, appliedPolicies }
     */
    applyPolicies(orgId: string, agentId: string, key: string, value: unknown, scope: string, packBinding: string[]): ApplyPoliciesResult;
    /**
     * Resolve a pseudonym back to the original value.
     *
     * Requires:
     *   - operatorId must have memory.deanonymize permission (OperatorRoles).
     *   - The pseudonym must belong to the requesting orgId's vault.
     *     Cross-org resolution is rejected with CrossOrgResolutionRejectedError.
     *
     * Returns undefined if the pseudonym is not found in the org's vault.
     */
    resolvePseudonym(operatorId: string, orgId: string, pseudonym: string): string | undefined;
    /**
     * Clear all cross-session entries for an agent.
     *
     * Pseudonymize mode entries: deleted immediately. Emits a memory-audit-chain
     * 'delete' operation for each key if auditChain is wired.
     *
     * Retain mode entries: deferred to the retention window UNLESS:
     *   (a) the retention window has already elapsed (auto-expired), OR
     *   (b) the operatorId has memory.early-delete permission.
     *
     * Without early-delete permission, retain-mode entries still within their
     * window are NOT deleted -- clearAllForAgent returns them in a
     * deferredKeys list for the caller to surface to the operator.
     *
     * @returns { deletedKeys, deferredKeys } where deferredKeys are retain-mode
     *   entries that could not be deleted without early-delete permission.
     */
    clearAllForAgent(operatorId: string, orgId: string, agentId: string, packBinding: string[]): {
        deletedKeys: string[];
        deferredKeys: string[];
    };
    /**
     * Resolve applicable policies from packBinding.
     * A policy applies when its packId appears in packBinding.
     * Mode: all packs in PACK_POLICIES use 'pseudonymize' mode.
     * Extend here when 'retain' mode packs are added to PACK_POLICIES.
     */
    private resolveApplicablePolicies;
    /**
     * Apply pseudonymization to a value.
     *
     * Walks all string leaf values of the input object (JSON-serialized). For each
     * protected identifier class declared by the policy, replaces matches with
     * deterministic pseudonyms. Pseudonym format: psn_<16hex>.
     *
     * 16 hex chars = 64-bit space. Collision probability per distinct value pair:
     * ~2^-64. Over 10^6 distinct values: ~2^-44 total collision probability.
     * On collision: emits PSEUDONYM_COLLISION_DETECTED severity ERROR.
     *
     * Pseudonym derivation: SHA-256(orgId + '\x00' + fieldName + '\x00' + originalValue).
     * The '\x00' separators prevent concatenation ambiguity.
     */
    private applyPseudonymize;
    /**
     * Derive a deterministic pseudonym for (orgId, fieldName, originalValue).
     * Format: psn_<16hex> (64-bit SHA-256 prefix).
     */
    private derivePseudonym;
    /**
     * Register a pseudonym in the org vault. Detect collisions.
     */
    private registerPseudonym;
    /**
     * Register a retention window for a retain-mode entry.
     * Sets a timer that fires at expiry; emits CROSS_SESSION_MEMORY_RETAINED_EXPIRED
     * and calls deleteCallback.
     */
    private registerRetention;
    private retentionKey;
    private isRetentionExpired;
    /**
     * Force-expire a retention entry (test-only). Fires the expiry callback
     * immediately without waiting for the timer.
     */
    _forceExpireRetention(orgId: string, agentId: string, key: string): void;
    /** Expose vault for test isolation assertions. Returns a read-only snapshot. */
    _getVaultSnapshot(orgId: string): Map<string, string>;
    /** Check if a retention entry exists (not yet expired). */
    _hasRetentionEntry(orgId: string, agentId: string, key: string): boolean;
}
//# sourceMappingURL=cross-session-pseudonymizer.d.ts.map