/**
 * RagCitationEnforcer -- Post-retrieval citation chain-of-custody enforcement.
 *
 * When an agent produces output that cites sources, every cited (sourceId,
 * chunkRef) pair MUST appear in the retrieval pool for the current cycle.
 * A citation that references a source never retrieved in this cycle is a
 * phantom citation -- the canonical OWASP LLM A05 (Cascading Hallucination)
 * attack vector. This class closes that gap.
 *
 * Relationship to PR #18 RagSourceAllowlist:
 *   RagSourceAllowlist (pre-retrieval):  which sources may be queried.
 *   RagCitationEnforcer (post-retrieval): which citations are provably from
 *     the retrieval pool. Together they form chain-of-custody: only allowlisted
 *     sources can be retrieved, and only retrieved chunks can be cited.
 *
 * Citation schema:
 *   Citation = {
 *     sourceId:   string   -- matches a source registered in the retrieval pool
 *     sourceKind: RagSourceKind
 *     chunkRef:   string   -- identifies the specific chunk (non-empty required)
 *     quotedSpan: string   -- optional verbatim excerpt for provability
 *   }
 *
 * Retrieval-pool tracking (in-memory, per-cycle):
 *   When an agent retrieves from a source (post allowlist gate), the caller
 *   invokes recordRetrieval(). The pool for that cycle is the union of all
 *   recorded retrievals. Pool is released via clearCycle() at cycle end.
 *
 * Strict-mode packs -- same five packs as RagSourceAllowlist PR #18:
 *   hipaa, gdpr, pci-dss, hmda, dora
 *   For these packs, output MUST include at least one Citation or
 *   CitationRequiredError is thrown (requiresCitations: true in pack metadata).
 *
 * Quoted-span verification (v0):
 *   If quotedSpan is provided AND the pool entry includes chunkText, the span
 *   is verified as a substring. If chunkText is absent from the pool entry,
 *   a CITATION_QUOTED_SPAN_MISMATCH warning is emitted and the output passes
 *   (best-effort). v1 plan: require chunkText at recordRetrieval time for all
 *   strict-mode packs.
 *
 * Audit events emitted:
 *   CITATION_OUTSIDE_POOL           severity ERROR  -- phantom citation attack
 *   CITATION_REQUIRED_MISSING       severity ERROR  -- strict pack, no citations
 *   CITATION_MISSING_CHUNK_REF      severity ERROR  -- citation lacks chunkRef
 *   CITATION_QUOTED_SPAN_MISMATCH   severity WARNING -- span absent from chunk
 *   CITATION_VALIDATED              severity INFO   -- all citations ok
 *
 * Output text is NEVER written to the audit chain. SHA-256 hash only.
 * Pack-binding is mandatory on every call (UnboundDataError if empty).
 *
 * Pen-test gates:
 *   PT-RAG-CITATION-1: phantom-citation attack -- agent cites a sourceId on
 *     the allowlist but never retrieved this cycle. Pool check fires.
 *   PT-RAG-CITATION-2: chunk-id confusion -- pool has "c123", agent cites
 *     "c123 " (trailing whitespace). Exact match required, confusable rejected.
 *   PT-RAG-CITATION-3: cross-cycle pool leakage -- cycle X retrieves chunk cA.
 *     Agent in cycle Y cites cA. Cycle Y pool lacks cA, so citation rejected.
 *
 * BUILD_PLAN reference: line 247 "Citation requirement enforcement (OWASP A05
 * cascading hallucination)".
 *
 * @connexum/ai-governance
 */
import { type RagSourceKind } from './rag-source-allowlist';
/**
 * Packs that REQUIRE at least one citation on every agent output.
 * These are the same packs that force fail-closed on retrieval source
 * allowlisting (PR #18). Together they form the strict RAG governance posture.
 *
 * hipaa   -- HIPAA §164.312(a)(1): PHI claim provenance must be traceable to
 *            verified clinical-record sources, not unattributed inference.
 * gdpr    -- GDPR Art. 5(1)(a) lawfulness, Art. 5(1)(d) accuracy: agents
 *            making claims about data subjects must cite the record used.
 * pci-dss -- PCI DSS Req 12.3 targeted risk analysis: risk claims must cite
 *            the specific assessment or evidence document.
 * hmda    -- HMDA Reg C §1003: GMI data usage must be traceable to the
 *            verified collection form, not synthesised from model weights.
 * dora    -- DORA Art. 9 ICT risk: incident and risk claims must be grounded
 *            in retrieved ICT register or incident data.
 */
export declare const CITATION_STRICT_MODE_PACKS: ReadonlySet<string>;
/**
 * Thrown when a citation references a (sourceId, chunkRef) not present in
 * the agent's retrieval pool for this cycle.
 * OWASP LLM A05 (Cascading Hallucination) prevention gate.
 */
export declare class CitationOutsidePoolError extends Error {
    readonly orgId: string;
    readonly agentId: string;
    readonly cycleId: string;
    readonly citationIndex: number;
    readonly sourceId: string;
    readonly chunkRef: string;
    constructor(opts: {
        orgId: string;
        agentId: string;
        cycleId: string;
        citationIndex: number;
        sourceId: string;
        chunkRef: string;
    });
}
/**
 * Thrown when an agent bound to a strict-mode pack produces output with
 * no citations. Strict packs require at least one citation per output.
 */
export declare class CitationRequiredError extends Error {
    readonly orgId: string;
    readonly agentId: string;
    readonly packIds: string[];
    constructor(opts: {
        orgId: string;
        agentId: string;
        packIds: string[];
    });
}
/**
 * Thrown when a citation has an empty or whitespace-only chunkRef.
 * Vague citations (no chunk reference) are rejected: they provide no
 * verifiable provenance and can mask hallucinated source claims.
 */
export declare class CitationMissingChunkRefError extends Error {
    readonly orgId: string;
    readonly agentId: string;
    readonly citationIndex: number;
    readonly sourceId: string;
    constructor(opts: {
        orgId: string;
        agentId: string;
        citationIndex: number;
        sourceId: string;
    });
}
/**
 * Thrown when configure() or recordRetrieval() receives an empty packBinding.
 * Per feedback_pack_binding_primacy.md: every record must carry packBinding.
 */
export declare class UnboundCitationDataError extends Error {
    readonly context: string;
    constructor(context: string);
}
/** A single source citation declared in agent output. */
export interface Citation {
    /** Matches a sourceId registered in the retrieval pool via recordRetrieval(). */
    sourceId: string;
    /** The kind of source, for consistency with the pool entry. */
    sourceKind: RagSourceKind;
    /**
     * Specific chunk identifier within the source. Must be non-empty.
     * Chunk-ref matching is exact and whitespace-significant.
     */
    chunkRef: string;
    /**
     * Optional verbatim excerpt from the cited chunk.
     * If provided and the pool entry contains chunkText, the span is verified
     * as a substring. If chunkText is absent from the pool entry, a
     * CITATION_QUOTED_SPAN_MISMATCH warning is emitted and validation passes
     * (v0 best-effort limitation -- see docs/runtime/rag-citation-enforcement.md).
     */
    quotedSpan?: string;
}
/** An entry in the retrieval pool: one retrieval event from one source. */
export interface RetrievalPoolEntry {
    orgId: string;
    agentId: string;
    cycleId: string;
    sourceId: string;
    sourceKind: RagSourceKind;
    /** Set of chunkRefs retrieved from this source in this retrieval event. */
    chunkRefs: string[];
    /**
     * Optional chunk text map for quoted-span verification.
     * Key: chunkRef, Value: raw chunk text.
     * When absent, quoted-span verification is best-effort (v0).
     */
    chunkTexts?: Record<string, string>;
    packBinding: string[];
    retrievedAt: string;
}
/** Output shape passed to validateOutput(). */
export interface AgentOutput {
    /** Output text -- SHA-256 hashed for audit. NEVER stored raw. */
    text: string;
    /** Citations declared by the agent. May be empty for lenient packs. */
    citations: Citation[];
}
export interface CitationOutsidePoolAuditEvent {
    type: 'CITATION_OUTSIDE_POOL';
    severity: 'ERROR';
    orgId: string;
    agentId: string;
    cycleId: string;
    citationIndex: number;
    /** SHA-256 of output text. Raw text never logged. */
    outputHash: string;
    sourceId: string;
    chunkRef: string;
    /** SHA-256 of the previous audit event (chain linkage). */
    prevSha: string;
    timestamp: string;
}
export interface CitationRequiredMissingAuditEvent {
    type: 'CITATION_REQUIRED_MISSING';
    severity: 'ERROR';
    orgId: string;
    agentId: string;
    cycleId: string;
    /** SHA-256 of output text. Raw text never logged. */
    outputHash: string;
    strictPacks: string[];
    prevSha: string;
    timestamp: string;
}
export interface CitationMissingChunkRefAuditEvent {
    type: 'CITATION_MISSING_CHUNK_REF';
    severity: 'ERROR';
    orgId: string;
    agentId: string;
    cycleId: string;
    citationIndex: number;
    outputHash: string;
    sourceId: string;
    prevSha: string;
    timestamp: string;
}
export interface CitationQuotedSpanMismatchAuditEvent {
    type: 'CITATION_QUOTED_SPAN_MISMATCH';
    severity: 'WARNING';
    orgId: string;
    agentId: string;
    cycleId: string;
    citationIndex: number;
    sourceId: string;
    chunkRef: string;
    /**
     * 'no-chunk-text': chunkText absent from pool entry (v0 limitation).
     * 'span-not-found': chunkText present but quotedSpan not a substring.
     */
    reason: 'no-chunk-text' | 'span-not-found';
    timestamp: string;
}
export interface CitationValidatedAuditEvent {
    type: 'CITATION_VALIDATED';
    severity: 'INFO';
    orgId: string;
    agentId: string;
    cycleId: string;
    citationCount: number;
    outputHash: string;
    timestamp: string;
}
export type CitationAuditEvent = CitationOutsidePoolAuditEvent | CitationRequiredMissingAuditEvent | CitationMissingChunkRefAuditEvent | CitationQuotedSpanMismatchAuditEvent | CitationValidatedAuditEvent;
/**
 * Post-retrieval citation chain-of-custody enforcer.
 *
 * Usage (called by the integration layer after PR #18 allowlist gate):
 *
 *   const enforcer = new RagCitationEnforcer(auditSink);
 *
 *   // 1. After allowlist passes and retrieval completes:
 *   enforcer.recordRetrieval('org-a', 'agent-1', 'cycle-42', {
 *     sourceId: 'vs_acme_pubmed',
 *     sourceKind: 'vector-store',
 *     chunkRefs: ['c001', 'c002'],
 *     chunkTexts: { c001: 'Full text of chunk c001...', c002: '...' },
 *   }, ['hipaa']);
 *
 *   // 2. When agent emits output:
 *   enforcer.validateOutput('org-a', 'agent-1', 'cycle-42', {
 *     text: 'The patient record shows...',
 *     citations: [{ sourceId: 'vs_acme_pubmed', sourceKind: 'vector-store',
 *                   chunkRef: 'c001', quotedSpan: 'patient record' }],
 *   }, ['hipaa']);
 *
 *   // Strict-pack gate (requiresCitations check):
 *   enforcer.requireCitations('org-a', 'agent-1', output, ['hipaa']);
 *
 *   // 3. At cycle end:
 *   enforcer.clearCycle('org-a', 'agent-1', 'cycle-42');
 */
export declare class RagCitationEnforcer {
    /**
     * Retrieval pool: maps poolKey(org, agent, cycle) -> list of pool entries.
     * Each call to recordRetrieval() appends to this list.
     */
    private readonly pool;
    /**
     * Pack binding index: maps agentKey(org, agent) -> last-known packBinding.
     * Used by requireCitations() when no packBinding is provided on output.
     */
    private readonly agentPackBindings;
    /** SHA-256 of the last emitted audit event (chain linkage). */
    private prevSha;
    private readonly auditSink;
    constructor(auditSink?: (event: CitationAuditEvent) => void);
    /**
     * Register a retrieval event in the pool for this cycle.
     *
     * Must be called AFTER RagSourceAllowlist.guardPreRetrieval() passes and
     * the actual retrieval completes. The pool records which chunks from which
     * sources were actually fetched in this cycle.
     *
     * @param orgId        Operator/tenant identifier.
     * @param agentId      Agent identifier.
     * @param cycleId      Cycle identifier (isolates pool across cycles).
     * @param source       Retrieval source descriptor.
     * @param source.sourceId   Source identifier (vector-store ID, URL, etc.).
     * @param source.sourceKind Kind of source.
     * @param source.chunkRefs  Chunk references retrieved.
     * @param source.chunkTexts Optional chunk text for quoted-span verification.
     * @param packBinding  Pack IDs governing this retrieval. Must be non-empty.
     * @throws UnboundCitationDataError if packBinding is empty.
     */
    recordRetrieval(orgId: string, agentId: string, cycleId: string, source: {
        sourceId: string;
        sourceKind: RagSourceKind;
        chunkRefs: string[];
        chunkTexts?: Record<string, string>;
    }, packBinding: string[]): void;
    /**
     * Validate that every citation in the output references a (sourceId, chunkRef)
     * that was actually retrieved in this cycle's pool.
     *
     * Checks (in order):
     *   1. Each citation must have a non-empty chunkRef. Throws CitationMissingChunkRefError.
     *   2. Each (sourceId, chunkRef) must appear in the cycle pool. Throws CitationOutsidePoolError.
     *   3. If quotedSpan is provided, verify it against chunkText (best-effort). Emits WARNING.
     *
     * Does NOT check requiresCitations (use requireCitations() for that gate).
     *
     * @param orgId       Operator/tenant identifier.
     * @param agentId     Agent identifier.
     * @param cycleId     Cycle identifier.
     * @param output      Agent output with text and citations array.
     * @param packBinding Pack IDs governing this output. Must be non-empty.
     * @throws UnboundCitationDataError if packBinding is empty.
     * @throws CitationMissingChunkRefError if a citation lacks chunkRef.
     * @throws CitationOutsidePoolError if a citation is not in the pool.
     */
    validateOutput(orgId: string, agentId: string, cycleId: string, output: AgentOutput, packBinding: string[]): void;
    /**
     * Strict-pack gate: if any bound pack has requiresCitations: true,
     * the output MUST contain at least one citation.
     *
     * This gate is SEPARATE from validateOutput(). Call requireCitations()
     * BEFORE validateOutput() so an empty citation array fails fast.
     *
     * The five strict packs (hipaa, gdpr, pci-dss, hmda, dora) are hardcoded
     * in CITATION_STRICT_MODE_PACKS. The pack field requiresCitations: true
     * on the CompliancePack interface mirrors this at the metadata layer.
     *
     * @param orgId       Operator/tenant identifier.
     * @param agentId     Agent identifier.
     * @param output      Agent output. Only output.citations.length is checked.
     * @param packBinding Pack IDs governing this output. Must be non-empty.
     * @throws UnboundCitationDataError if packBinding is empty.
     * @throws CitationRequiredError if strict pack bound and zero citations.
     */
    requireCitations(orgId: string, agentId: string, output: AgentOutput, packBinding: string[]): void;
    /**
     * Release the retrieval pool for this cycle. Call at cycle end to prevent
     * cross-cycle pool leakage (PT-RAG-CITATION-3).
     *
     * After clearCycle(), any citation referencing chunks from this cycle will
     * be rejected by validateOutput() since the pool is empty.
     */
    clearCycle(orgId: string, agentId: string, cycleId: string): void;
    /**
     * Returns a read-only snapshot of the retrieval pool for the given cycle.
     * Returns an empty array if no retrievals have been recorded.
     */
    getPool(orgId: string, agentId: string, cycleId: string): ReadonlyArray<RetrievalPoolEntry>;
    /**
     * Find a pool entry that contains the given (sourceId, chunkRef).
     * chunkRef matching is exact and whitespace-significant.
     * Returns the pool entry, or null if not found.
     */
    private findInPool;
    /**
     * Quoted-span verification (v0 best-effort).
     *
     * If the pool entry has chunkText for the cited chunkRef, verify that
     * quotedSpan is a substring. If chunkText is absent, emit a WARNING
     * and allow the citation (v0 limitation).
     */
    private verifyQuotedSpan;
    /**
     * Emit an audit event and advance the prev-SHA chain (for ERROR events).
     * The chain links ERROR events sequentially. INFO/WARNING events do not
     * advance the chain (they are not tamper-evidence targets).
     */
    private emit;
    /**
     * Compute SHA-256 of a string.
     * Used to hash output text for audit logs so raw content never enters
     * the audit chain.
     */
    private sha256;
}
//# sourceMappingURL=rag-citation-enforcement.d.ts.map