crp.provenance¶
Auto-generated reference for the crp.provenance subpackage.
provenance¶
crp.provenance ¶
Decision Provenance Engine (DPE) - §7.14.3.
Orchestrates claim detection, attribution scoring, provenance chain construction, and report generation for every LLM dispatch window.
Usage::
from crp.provenance import DecisionProvenanceEngine, ProvenanceConfig
dpe = DecisionProvenanceEngine(config=ProvenanceConfig())
report = dpe.analyse(
output_text="The server uses AES-256 encryption...",
packed_facts=envelope_result.packed_facts,
session_id=session.id,
window_id=window.id,
)
AttributionType ¶
Bases: str, Enum
How a claim maps to its knowledge source.
ClaimAttribution dataclass ¶
Attribution result for a single claim in the LLM output.
Attributes:
| Name | Type | Description |
|---|---|---|
claim_text | str | Text of the claim sentence. |
claim_index | int | Zero-based position of the claim in the output. |
claim_type | ClaimType | Classification of the claim. |
attributed_facts | list[FactScore] | Scored facts matched to this claim. |
top_score | float | Highest composite score among matched facts. |
attribution_type | AttributionType | How the claim maps to its source. |
confidence | float | Overall attribution confidence 0.0-1.0. |
ClaimType ¶
Bases: str, Enum
Classification of individual sentences/claims in LLM output.
EntailmentResult dataclass ¶
Semantic entailment verdict for a single claim↔fact pair.
Uses Natural Language Inference (NLI) to determine whether a claim is semantically supported by its attributed source fact - beyond lexical overlap.
FactScore dataclass ¶
Attribution score between a single claim and a single envelope fact.
Attributes:
| Name | Type | Description |
|---|---|---|
fact_id | str | UUID of the attributed fact. |
fact_text_preview | str | First 120 characters of the fact text. |
semantic_similarity | float | Cosine similarity between claim and fact embeddings. |
lexical_overlap | float | N-gram token overlap ratio. |
composite_score | float | Weighted combination of semantic and lexical signals. |
fact_source_window | str | Window ID that produced the fact. |
fact_extraction_stage | int | Pipeline stage (1-6) that extracted the fact. |
FidelityReport dataclass ¶
Complete fidelity verification results for a dispatch window.
Answers: "Given source attribution, did the model faithfully represent the sources, or did it distort, fabricate, omit, or contradict?"
HallucinationRiskReport dataclass ¶
Window-level hallucination risk report.
Answers: "For each claim, how likely is it that the model hallucinated, and what is the overall risk profile of this output?"
ProvenanceChain dataclass ¶
Full provenance chain for one claim - linked list from output to input.
Attributes:
| Name | Type | Description |
|---|---|---|
claim_text | str | Text of the claim being traced. |
claim_index | int | Position of the claim in the output. |
attribution_type | AttributionType | How the claim is attributed. |
links | list[ProvenanceLink] | Ordered list of provenance links from claim to task. |
ProvenanceConfig dataclass ¶
Configuration for the Decision Provenance Engine.
Attributes:
| Name | Type | Description |
|---|---|---|
enabled | bool | Master switch for the entire DPE pipeline. |
min_claim_length | int | Minimum claim text length to analyse. |
max_claims_per_output | int | Maximum claims to process per window. |
similarity_threshold | float | Score below which attribution is PARAMETRIC. |
mixed_threshold | float | Boundary between MIXED and PARAMETRIC attribution. |
min_grounding_semantic | float | Minimum semantic score for grounding. |
min_grounding_lexical | float | Minimum lexical score for grounding. |
min_mixed_semantic | float | Minimum semantic score for mixed attribution. |
lexical_weight | float | Weight applied to lexical overlap. |
semantic_weight | float | Weight applied to semantic similarity. |
generate_report | bool | Whether to emit a structured report. |
fact_preview_length | int | Characters of fact text included in previews. |
entailment_enabled | bool | Whether to run semantic entailment verification. |
entailment_model | str | HuggingFace model id for entailment (if available). |
entailment_contradiction_threshold | float | P(contradiction) threshold for flagging. |
risk_scoring_enabled | bool | Whether to compute hallucination risk scores. |
risk_weight_attribution | float | Weight of attribution signal in risk score. |
risk_weight_fidelity | float | Weight of fidelity signal in risk score. |
risk_weight_entailment | float | Weight of entailment signal in risk score. |
risk_weight_specificity | float | Weight of specificity signal in risk score. |
amplifiers_enabled | bool | Whether regulatory amplifiers are active. |
amplifier_gdpr_pii | float | Multiplier when GDPR PII is present. |
amplifier_eu_ai_act_high | float | Multiplier for high-risk EU AI Act systems. |
amplifier_sector | float | Multiplier for financial/medical domains. |
amplifier_agent_depth | float | Multiplier for deep agent loops. |
amplifier_cross_window | float | Multiplier for cross-window contradictions. |
amplifier_severe_repetition | float | Multiplier for severe repetition. |
rqa_enabled | bool | Whether RQA stages 6-9 run. |
rqa_weight_repetition | float | Weight of repetition in composite quality score. |
rqa_weight_completeness | float | Weight of completeness in composite quality score. |
rqa_weight_flow | float | Weight of flow in composite quality score. |
rqa_weight_coherence | float | Weight of coherence in composite quality score. |
ProvenanceLink dataclass ¶
Single link in a provenance chain - traces from claim → source.
Attributes:
| Name | Type | Description |
|---|---|---|
level | str | Provenance level - "claim", "fact", "window", "envelope", or "task". |
label | str | Human-readable label for this link. |
detail | dict[str, Any] | Arbitrary key-value context for the link. |
ProvenanceReport dataclass ¶
Complete provenance report for a single dispatch window.
Attributes:
| Name | Type | Description |
|---|---|---|
session_id | str | CRP session identifier. |
window_id | str | Dispatch window identifier. |
timestamp | float | Unix timestamp when the report was generated. |
total_claims | int | Total claims detected in the output. |
factual_claims | int | Number of factual claims. |
opinion_claims | int | Number of opinion claims. |
procedural_claims | int | Number of procedural claims. |
hedge_claims | int | Number of hedge claims. |
connective_claims | int | Number of connective claims. |
context_grounded_count | int | Claims grounded in envelope facts. |
parametric_count | int | Claims likely from model parametric knowledge. |
mixed_count | int | Claims with mixed context and parametric support. |
uncertain_count | int | Claims with low-confidence attribution. |
grounding_ratio | float | context_grounded / factual_claims. |
attributions | list[ClaimAttribution] | Per-claim attribution results. |
chains | list[ProvenanceChain] | Provenance chains for attributed claims. |
chain_verified | bool | Whether the provenance chain passed integrity checks. |
output_token_count | int | Approximate output token count. |
envelope_facts_count | int | Number of facts packed into the envelope. |
fidelity | FidelityReport | None | Fidelity verification report (distortions, fabrications, etc.). |
entailment_results | list[EntailmentResult] | Semantic entailment verdicts. |
risk_report | HallucinationRiskReport | None | Hallucination risk assessment. |
coherence | object | None | Cross-window coherence result (RQA stage 6). |
repetition | object | None | Repetition detection result (RQA stage 7). |
completeness | object | None | Completeness result (RQA stage 8). |
flow | object | None | Flow analysis result (RQA stage 9). |
rqa | object | None | Composite RQA quality score. |
amplifier_result | object | None | Regulatory amplifier result. |
quality_tier | str | Final quality tier after downgrade. |
redispatch | object | None | Re-dispatch decision. |
AmplifierContext dataclass ¶
The regulatory/agentic signals that may amplify the composite score.
AmplifierResult dataclass ¶
The outcome of applying amplifiers to a base composite score.
amplified property ¶
Return whether the amplified condition holds.
DetectedClaim dataclass ¶
A single detected claim with its classification.
RQAResult dataclass ¶
The computed RQA quality score and resulting tier cap.
headers property ¶
Return the headers.
RQASignals dataclass ¶
The four RQA-stage inputs (all 0.0–1.0).
CoherenceResult dataclass ¶
CompletenessResult dataclass ¶
FlowResult dataclass ¶
RedispatchDecision dataclass ¶
Whether a window should be re-dispatched and why (§19).
headers property ¶
Return the headers.
RepetitionResult dataclass ¶
ChainIntegrity ¶
Bases: str, Enum
Result of verifying a window provenance chain.
ChainVerification dataclass ¶
Outcome of a chain verification (CRP-SPEC-011 §3.3).
headers property ¶
Return the headers.
WindowChainRecord dataclass ¶
A window's stored HMAC plus the inputs needed to recompute it.
recompute(key, prev_window_hmac) ¶
Recompute this window's expected HMAC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key | bytes | HMAC key bytes. | required |
prev_window_hmac | str | Parent window HMAC (ignored for fan-in windows). | required |
Returns:
| Type | Description |
|---|---|
str | The recomputed HMAC string. |
WindowHmacInput dataclass ¶
Inputs to a window's summary HMAC.
HMAC-SHA256(session_id ‖ window_number ‖ timestamp ‖ response_hash ‖ dpe_report_hash ‖ prev_window_hmac, key) - CRP-SPEC-011 §2.3.
message() ¶
Return the canonical message bytes used for window HMAC computation.
DecisionProvenanceEngine ¶
Main entry point for the Decision Provenance Engine.
Ties together claim detection → attribution scoring → provenance chain construction → report generation into a single analyse() call.
config property ¶
Current provenance configuration.
enabled property ¶
Whether the DPE pipeline is enabled.
analyse(output_text, packed_facts, *, session_id='', window_id='', envelope_saturation=0.0, task_input_preview='', fact_metadata=None, query='', window_number=1, prior_window_texts=None, envelope_tier='', amplifier_context=None, upgrade_on_risk=False, revision_round=0, embedder=None, nli=None) ¶
Run the full DPE pipeline and return a provenance report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_text | str | Raw LLM output text for this window. | required |
packed_facts | Sequence[PackedFact] | Facts that were packed into the envelope. | required |
session_id | str | Current CRP session ID. | '' |
window_id | str | Current dispatch window ID. | '' |
envelope_saturation | float | Envelope token saturation ratio (0.0-1.0). | 0.0 |
task_input_preview | str | First 120 chars of the task input. | '' |
fact_metadata | dict[str, dict[str, object]] | None | Optional mapping of fact_id → metadata dict containing | None |
query | str | Original task query (used for RQA completeness analysis). | '' |
window_number | int | Current window number in the session. | 1 |
prior_window_texts | Sequence[str] | None | Previous window outputs for cross-window analysis. | None |
envelope_tier | str | Envelope quality tier assigned by the packer. | '' |
amplifier_context | AmplifierContext | None | Regulatory amplifier context for risk scoring. | None |
upgrade_on_risk | bool | Whether to trigger re-dispatch on elevated risk. | False |
revision_round | int | Current revision iteration count. | 0 |
embedder | Callable[[str], Sequence[float]] | None | Optional embedding callable for semantic RQA stages. | None |
nli | Callable[[str, str], float] | None | Optional NLI callable for contradiction detection. | None |
Returns:
| Type | Description |
|---|---|
ProvenanceReport |
|
ProvenanceReport | and RQA results. |
generate_markdown(report) ¶
Generate a human-readable markdown provenance report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Provenance report to render. | required |
Returns:
| Type | Description |
|---|---|
str | Markdown-formatted provenance report string. |
generate_json(report) ¶
Generate a machine-readable JSON provenance report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Provenance report to serialise. | required |
Returns:
| Type | Description |
|---|---|
dict | Dict representation of the provenance report. |
apply_amplifiers(base_score, context, *, config=None) ¶
Apply regulatory amplifiers to base_score (CRP-SPEC-005 §17).
Amplifiers are multiplicative and compound; the result is clamped to [0.0, 1.0]. Returns an :class:AmplifierResult recording which amplifiers fired and the resulting risk band.
score_all_claims(claims, packed_facts, *, config=None, _embedder_override=None) ¶
Score all claims against all envelope facts.
Only FACTUAL_CLAIM and HEDGE types are scored against facts. Other types (OPINION, PROCEDURAL, CONNECTIVE) are returned with empty attribution (they don't require source grounding).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
claims | list[DetectedClaim] | All detected claims from claim_detector. | required |
packed_facts | list[PackedFact] | Facts that were packed into the envelope. | required |
config | ProvenanceConfig | None | Scoring configuration. | None |
_embedder_override | Any | Injected embedding model for testing. | None |
Returns:
| Type | Description |
|---|---|
list[ClaimAttribution] | List of ClaimAttribution objects in claim order. |
detect_claims(text, *, min_length=10, max_claims=50) ¶
Detect and classify all claims in LLM output text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text | str | Raw LLM output text. | required |
min_length | int | Minimum character length for a claim (shorter → skipped). | 10 |
max_claims | int | Maximum number of claims to return (safety limit). | 50 |
Returns:
| Type | Description |
|---|---|
list[DetectedClaim] | List of DetectedClaim objects, ordered by position in text. |
detect_contradictions(attributions, *, prior_claims=None, content_overlap_threshold=0.3) ¶
Detect contradictions between claims.
Checks all factual/hedge claim pairs within the current window for three types of contradiction: 1. NEGATION - Same content + negation flip 2. NUMBER_CONFLICT - Same topic + different numbers 3. SEMANTIC - High word overlap + opposing sentiment
If prior_claims are provided, also checks current claims against them for cross-window contradictions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions for the current window. | required |
prior_claims | list[str] | None | Optional list of claim texts from prior windows. | None |
content_overlap_threshold | float | Minimum content word overlap ratio (Jaccard) to consider two claims as discussing the same topic. | 0.3 |
Returns:
| Type | Description |
|---|---|
list[ContradictionResult] | List of ContradictionResult - one per detected contradiction. |
detect_distortions(attributions, packed_facts) ¶
Detect distortions in context-grounded claims.
For each CONTEXT_GROUNDED or MIXED attribution, compares the claim against its top source fact looking for subtle but critical changes: numbers altered, negations flipped, qualifiers dropped, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from attribution_scorer. | required |
packed_facts | list[PackedFact] | All envelope facts (for full-text lookup). | required |
Returns:
| Type | Description |
|---|---|
list[DistortionResult] | List of DistortionResult - one per detected distortion. |
list[DistortionResult] | Empty list means no distortions found (perfect fidelity). |
verify_entailment(attributions, packed_facts, *, config=None, _model_override=None) ¶
Verify semantic entailment between grounded claims and their source facts.
For each CONTEXT_GROUNDED or MIXED claim, runs NLI inference against the top source fact. Returns an EntailmentResult per checked pair.
The NLI model classifies (premise=fact, hypothesis=claim): - ENTAILED: claim logically follows from fact - CONTRADICTION: claim conflicts with fact - NEUTRAL: claim is unrelated to fact
When the NLI model is unavailable, falls back to a heuristic based on word overlap + negation detection. The used_model field in each result indicates which method was used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the DPE pipeline. | required |
packed_facts | Sequence[PackedFact] | All envelope facts (for full-text lookup). | required |
config | ProvenanceConfig | None | ProvenanceConfig (controls model name, thresholds). | None |
_model_override | Any | Override NLI model for testing (internal). | None |
Returns:
| Type | Description |
|---|---|
list[EntailmentResult] | List of EntailmentResult - one per checked claim-fact pair. |
detect_fabrications(attributions, packed_facts) ¶
Detect fabricated entities in claims that appear in no source fact.
Examines FACTUAL_CLAIM and HEDGE claims for specific entities (numbers, percentages, dates, proper nouns, citations) and flags those not found in any envelope fact.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions. | required |
packed_facts | Sequence[PackedFact] | All envelope facts. | required |
Returns:
| Type | Description |
|---|---|
list[FabricationResult] | List of FabricationResult - one per fabricated entity found. |
score_hallucination_risk(attributions, *, fidelity=None, entailment_results=None, config=None) ¶
Score hallucination risk for every claim in the output.
Combines four independent signals per claim
- Attribution - how well-sourced is the claim?
- Fidelity - did lexical checks find distortions?
- Entailment - does NLI confirm semantic support?
- Specificity - how specific (and thus risky) is the claim?
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the DPE pipeline. | required |
fidelity | FidelityReport | None | FidelityReport from the fidelity verification layer. | None |
entailment_results | list[EntailmentResult] | None | EntailmentResults from the entailment verifier. | None |
config | ProvenanceConfig | None | ProvenanceConfig with risk weight configuration. | None |
Returns:
| Type | Description |
|---|---|
HallucinationRiskReport | HallucinationRiskReport with per-claim assessments and aggregates. |
analyze_omissions(attributions, packed_facts, *, attribution_floor=0.2) ¶
Identify envelope facts that the model ignored.
For each packed fact, finds the maximum attribution score any output claim gave it. Facts with a maximum score below attribution_floor are considered omitted.
Results are sorted by fact relevance score descending - the most important omissions first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the attribution scorer. | required |
packed_facts | Sequence[PackedFact] | All facts that were packed into the envelope. | required |
attribution_floor | float | Maximum composite score below which a fact is considered "not used" (default 0.20). | 0.2 |
Returns:
| Type | Description |
|---|---|
list[OmissionResult] | List of OmissionResult sorted by importance (highest first). |
build_all_chains(attributions, *, session_id='', window_id='', envelope_saturation=0.0, envelope_facts_included=0, task_input_preview='') ¶
Build provenance chains for all attributed claims.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | All claim attributions from scorer. | required |
session_id | str | Current session ID. | '' |
window_id | str | Current window ID. | '' |
envelope_saturation | float | Envelope saturation ratio. | 0.0 |
envelope_facts_included | int | Facts in envelope. | 0 |
task_input_preview | str | First 120 chars of task input. | '' |
Returns:
| Type | Description |
|---|---|
list[ProvenanceChain] | List of |
enrich_fact_metadata(attributions, fact_metadata) ¶
Enrich FactScore entries with fact provenance metadata (in-place).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | List of claim attributions to enrich. | required |
fact_metadata | dict[str, dict[str, Any]] | Dict mapping fact_id → metadata dict. Expected keys include | required |
Returns:
| Type | Description |
|---|---|
None | None. Updates |
generate_json_report(report) ¶
Generate a machine-readable JSON provenance report.
Suitable for API responses, database storage, or integration with compliance management systems.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Complete provenance report from the DPE pipeline. | required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | JSON-serializable dictionary. |
generate_markdown_report(report) ¶
Generate a human-readable markdown provenance report.
Suitable for regulatory audit, compliance review, or integration into documentation. Format follows EU AI Act Article 12 logging requirements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Complete provenance report from the DPE pipeline. | required |
Returns:
| Type | Description |
|---|---|
str | Markdown-formatted report string. |
compute_quality_score(signals, *, config=None) ¶
Compute the RQA composite quality score (CRP-SPEC-005 §18.2).
downgrade_tier(envelope_tier, quality_score) ¶
Downgrade envelope_tier if the RQA quality score requires it (§18.4).
The emitted tier is the worse of the envelope tier and the score-derived ceiling - e.g. envelope A with score 0.62 → emitted B.
analyze_flow(current_response, prior_response, *, window_number=2, embedder=None) ¶
Stage 9 (§11): flow & continuity for continuation windows (window>1).
detect_cross_window_contradictions(current_response, prior_window_texts, *, nli=None, threshold=0.75) ¶
Stage 6 (§8): detect contradictions between current and prior windows.
detect_repetition(current_response, prior_responses, *, embedder=None, semantic_threshold=0.92) ¶
Stage 7 (§9): n-gram + semantic overlap with prior responses.
evaluate_redispatch(*, repetition=None, coherence=None, flow=None, risk_upgrade_triggered=False, upgrade_on_risk=False, revision_round=0, max_revisions=2) ¶
Decide whether to re-dispatch a window (§19.1-19.2).
Triggers: upgrade-on-risk + risk threshold, SEVERE repetition, CRITICAL cross-window contradiction, or flow_score < 0.30. Capped at max_revisions per window; re-dispatch does NOT decrement the safety budget (§19.3).
verify_completeness(query, session_responses, *, decompose=None, embedder=None, coverage_threshold=0.7) ¶
Stage 8 (§10): does the cumulative answer cover every sub-query?
build_fan_in_window_hmac(*, session_id, window_number, timestamp, response_hash, dpe_report_hash, parent_hmacs, key) ¶
Compute a fan-in window HMAC merging multiple parents (§9.3).
Parent HMACs are sorted lexicographically and joined with | so the result is deterministic regardless of child completion order.
build_window_hmac(inp, key) ¶
Compute a window summary HMAC (linear chain extension, §9.1).
verify_window_chain(records, key) ¶
Verify a session's complete window chain from root to leaf (§3.1).
Returns UNVERIFIED for an empty/single-root chain that has nothing to chain from, BROKEN (with broken_at_window) on the first mismatch, and VALID when every link verifies.
verify_window_partial(record, parent_window_hmac, key) ¶
Verify a single window against its parent's HMAC (§3.2).
Auditors holding only one window and its parent tip get PARTIAL on success (the full chain was not checked) or BROKEN on mismatch.
collect_quality_headers(report) ¶
Merge every RQA quality/safety header emitted by the stage results.
Includes CRP-Quality-Repetition / -Completeness / -Flow / -Score and CRP-Safety-Contradictions when the corresponding stage ran (CRP-SPEC-005 §8-11, §18, §20).
provenance.amplifiers¶
crp.provenance.amplifiers ¶
Regulatory amplifiers for the hallucination composite (CRP-SPEC-005 §17).
After the base composite hallucination score is computed, regulatory amplifiers multiply it upward when the regulatory context raises the stakes of a given risk level (PII exposure, EU AI Act HIGH-risk domain, financial/medical sector, deep agent chains, cross-window contradictions, severe repetition). The amplified score is capped at 1.0 and may push the window into a higher :class:HallucinationRisk band.
Amplifier values are configuration (kept symbolic in the public spec); the conditions are specified.
AmplifierContext dataclass ¶
The regulatory/agentic signals that may amplify the composite score.
AmplifierResult dataclass ¶
The outcome of applying amplifiers to a base composite score.
amplified property ¶
Return whether the amplified condition holds.
apply_amplifiers(base_score, context, *, config=None) ¶
Apply regulatory amplifiers to base_score (CRP-SPEC-005 §17).
Amplifiers are multiplicative and compound; the result is clamped to [0.0, 1.0]. Returns an :class:AmplifierResult recording which amplifiers fired and the resulting risk band.
provenance.attribution_scorer¶
crp.provenance.attribution_scorer ¶
Attribution Scorer - map claims to envelope facts (§7.14.3).
For each factual claim in the LLM output, scores how likely it came from each envelope fact vs. parametric knowledge. Uses two signals:
- Semantic similarity: When available, uses dense sentence-transformer embeddings (all-MiniLM-L6-v2, 384-dim) for genuine semantic comparison. Falls back to hash-projected bag-of-words when the model is unavailable.
- Lexical overlap: Token-level Jaccard overlap - fast, complements semantic similarity for surface-level attribution.
The composite score is a weighted blend
composite = semantic_weight × semantic + lexical_weight × lexical
Claims with no fact scoring above similarity_threshold are flagged as PARAMETRIC (likely from model training data). Claims with a top score between mixed_threshold and similarity_threshold are MIXED.
score_claim_against_facts(claim, packed_facts, *, config=None, _embedder_override=None) ¶
Score a single claim against all envelope facts.
Attempts to use dense sentence-transformer embeddings for semantic similarity. Falls back to hash-projected bag-of-words if the embedding model is unavailable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
claim | DetectedClaim | Detected claim from claim_detector. | required |
packed_facts | list[PackedFact] | Facts that were packed into the envelope. | required |
config | ProvenanceConfig | None | Scoring configuration (thresholds, weights). | None |
_embedder_override | Any | Injected embedding model for testing. | None |
Returns:
| Type | Description |
|---|---|
ClaimAttribution | ClaimAttribution with ranked fact scores and attribution type. |
score_all_claims(claims, packed_facts, *, config=None, _embedder_override=None) ¶
Score all claims against all envelope facts.
Only FACTUAL_CLAIM and HEDGE types are scored against facts. Other types (OPINION, PROCEDURAL, CONNECTIVE) are returned with empty attribution (they don't require source grounding).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
claims | list[DetectedClaim] | All detected claims from claim_detector. | required |
packed_facts | list[PackedFact] | Facts that were packed into the envelope. | required |
config | ProvenanceConfig | None | Scoring configuration. | None |
_embedder_override | Any | Injected embedding model for testing. | None |
Returns:
| Type | Description |
|---|---|
list[ClaimAttribution] | List of ClaimAttribution objects in claim order. |
provenance.calibration¶
crp.provenance.calibration ¶
Calibration harnesses for CRP scoring thresholds.
Provides ground-truth evaluation of attribution and hallucination risk scorers so that hard-coded thresholds can be tuned against labelled data instead of arbitrary constants.
AttributionExample dataclass ¶
A labelled claim/fact pair for attribution calibration.
HallucinationExample dataclass ¶
A labelled claim for hallucination-risk calibration.
ThresholdMetrics dataclass ¶
CalibrationResult dataclass ¶
Outcome of evaluating a scorer over a labelled dataset.
AttributionCalibrationHarness ¶
Calibrate attribution thresholds against ground-truth labels.
A claim is considered "grounded" if its top composite score is at or above the threshold. Labels must be grounded (positive) or ungrounded (negative).
add(claim_text, facts, label) ¶
Add a labelled claim/fact pair to the calibration set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
claim_text | str | The claim to evaluate. | required |
facts | list[PackedFact] | Candidate facts to attribute the claim against. | required |
label | Literal['grounded', 'ungrounded'] | Ground-truth label, either | required |
score() ¶
Return [(label, top_score), ...] for every example.
evaluate(thresholds=None) ¶
Compute precision/recall/FPR/FNR across thresholds and AUC.
HallucinationCalibrationHarness ¶
Calibrate hallucination-risk thresholds against ground-truth labels.
The risk score (higher = more likely hallucinated) is taken from the window mean risk score produced by :func:score_hallucination_risk. Labels must be hallucinated (positive) or faithful (negative).
add(claim, label) ¶
Add a labelled claim for hallucination-risk calibration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
claim | ClaimAttribution | Claim attribution result to evaluate. | required |
label | Literal['hallucinated', 'faithful'] | Ground-truth label, either | required |
score() ¶
Return [(label, mean_risk_score), ...] for every example.
evaluate(thresholds=None) ¶
Compute precision/recall/FPR/FNR across thresholds and AUC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thresholds | list[float] | None | Thresholds to evaluate. Defaults to a standard set. | None |
Returns:
| Type | Description |
|---|---|
CalibrationResult | Calibration result with per-threshold metrics and best F1 threshold. |
provenance.claim_detector¶
crp.provenance.claim_detector ¶
Claim Detector - segment LLM output into attributable claims (§7.14.3).
Splits model output into individual sentences/claims and classifies each as: - FACTUAL_CLAIM: verifiable factual assertion (requires attribution) - OPINION: subjective view or judgment - PROCEDURAL: action or instruction - HEDGE: qualified/uncertain statement - CONNECTIVE: structural/transitional text
Uses rule-based heuristics - no ML model required for classification, keeping overhead under 5ms for typical outputs.
DetectedClaim dataclass ¶
A single detected claim with its classification.
split_into_sentences(text) ¶
Split text into sentences.
Uses regex-based sentence boundary detection with abbreviation handling and paragraph boundary support.
Returns:
| Type | Description |
|---|---|
list[str] | List of sentence strings, stripped of leading/trailing whitespace. |
classify_claim(text) ¶
Classify a single sentence/claim by type.
Returns:
| Type | Description |
|---|---|
ClaimType | Tuple of (ClaimType, confidence_score). |
float | confidence_score is 0.0-1.0 indicating classification confidence. |
detect_claims(text, *, min_length=10, max_claims=50) ¶
Detect and classify all claims in LLM output text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text | str | Raw LLM output text. | required |
min_length | int | Minimum character length for a claim (shorter → skipped). | 10 |
max_claims | int | Maximum number of claims to return (safety limit). | 50 |
Returns:
| Type | Description |
|---|---|
list[DetectedClaim] | List of DetectedClaim objects, ordered by position in text. |
provenance.contradiction_detector¶
crp.provenance.contradiction_detector ¶
Contradiction Detector - catch self-contradictions in LLM output.
Within the same dispatch window
Claim 2: "The system is secure." Claim 7: "The system has critical vulnerabilities."
Across windows (if prior claims supplied): Window 1: "Revenue increased 10%." Window 3: "Revenue declined significantly."
This module detects contradictions through three signals
- NEGATION conflicts - same content words + negation flip
- NUMBER conflicts - same entity referenced with different values
- SEMANTIC conflicts - high similarity + opposing sentiment signals
detect_contradictions(attributions, *, prior_claims=None, content_overlap_threshold=0.3) ¶
Detect contradictions between claims.
Checks all factual/hedge claim pairs within the current window for three types of contradiction: 1. NEGATION - Same content + negation flip 2. NUMBER_CONFLICT - Same topic + different numbers 3. SEMANTIC - High word overlap + opposing sentiment
If prior_claims are provided, also checks current claims against them for cross-window contradictions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions for the current window. | required |
prior_claims | list[str] | None | Optional list of claim texts from prior windows. | None |
content_overlap_threshold | float | Minimum content word overlap ratio (Jaccard) to consider two claims as discussing the same topic. | 0.3 |
Returns:
| Type | Description |
|---|---|
list[ContradictionResult] | List of ContradictionResult - one per detected contradiction. |
provenance.distortion_detector¶
crp.provenance.distortion_detector ¶
Distortion Detector - catch when grounded claims misrepresent source facts.
The most dangerous failure in AI attribution: a claim is scored as CONTEXT_GROUNDED (high similarity to a source fact) but the model has subtly CHANGED a key detail - a number, a negation, a qualifier. The auditor sees "grounded, confidence 0.89" and trusts it. But the claim is wrong.
This module catches six distortion types
- NUMBER_CHANGED: "10%" → "15%"
- NEGATION_FLIP: "is safe" → "is not safe"
- QUALIFIER_DROPPED: "approximately 10" → "10" (false precision)
- QUALIFIER_ADDED: "10" → "always 10" (over-generalisation)
- SCOPE_CHANGED: "in Q3" → "annually"
- ENTITY_SUBSTITUTED: "Company A" → "Company B"
detect_distortions(attributions, packed_facts) ¶
Detect distortions in context-grounded claims.
For each CONTEXT_GROUNDED or MIXED attribution, compares the claim against its top source fact looking for subtle but critical changes: numbers altered, negations flipped, qualifiers dropped, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from attribution_scorer. | required |
packed_facts | list[PackedFact] | All envelope facts (for full-text lookup). | required |
Returns:
| Type | Description |
|---|---|
list[DistortionResult] | List of DistortionResult - one per detected distortion. |
list[DistortionResult] | Empty list means no distortions found (perfect fidelity). |
provenance.entailment_verifier¶
crp.provenance.entailment_verifier ¶
Semantic Entailment Verifier - ML-powered claim↔fact verification (§7.14.3).
THE PROBLEM rule-based fidelity cannot solve:
Fact: "The treatment significantly reduced patient mortality."
Claim: "The treatment showed some positive outcomes for patients."
Lexically similar. Zero number distortions. No negation flip. But the claim lost critical specificity - a regulator reading the claim would make a DIFFERENT decision than one reading the fact.
Rule-based detectors catch surface edits: 10→25, "safe"→"not safe". They cannot detect: - Specificity loss ("reduced mortality" → "positive outcomes") - Causation inflation ("correlation observed" → "X causes Y") - Scope generalisation ("in clinical settings" → "broadly") - Hedging removal ("might reduce" → "reduces")
THE SOLUTION: Natural Language Inference (NLI).
A lightweight cross-encoder NLI model (~80 MB, CPU-only, <50 ms/pair) classifies each (premise=fact, hypothesis=claim) pair as: - ENTAILED - claim logically follows from the fact ✅ - NEUTRAL - claim is unrelated to the fact ⚠️ - CONTRADICTION - claim conflicts with the fact ❌
This gives CRP a semantic fidelity layer that sits above the lexical layer, catching meaning-level distortions no regex can reach.
When the NLI model is unavailable (not installed, resource-constrained), the verifier degrades gracefully to a heuristic based on bag-of-words similarity - still better than nothing, while flagging that the result is heuristic-only.
reset_model_cache() ¶
Reset the module-level model cache (for testing).
verify_entailment(attributions, packed_facts, *, config=None, _model_override=None) ¶
Verify semantic entailment between grounded claims and their source facts.
For each CONTEXT_GROUNDED or MIXED claim, runs NLI inference against the top source fact. Returns an EntailmentResult per checked pair.
The NLI model classifies (premise=fact, hypothesis=claim): - ENTAILED: claim logically follows from fact - CONTRADICTION: claim conflicts with fact - NEUTRAL: claim is unrelated to fact
When the NLI model is unavailable, falls back to a heuristic based on word overlap + negation detection. The used_model field in each result indicates which method was used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the DPE pipeline. | required |
packed_facts | Sequence[PackedFact] | All envelope facts (for full-text lookup). | required |
config | ProvenanceConfig | None | ProvenanceConfig (controls model name, thresholds). | None |
_model_override | Any | Override NLI model for testing (internal). | None |
Returns:
| Type | Description |
|---|---|
list[EntailmentResult] | List of EntailmentResult - one per checked claim-fact pair. |
provenance.fabrication_detector¶
crp.provenance.fabrication_detector ¶
Fabrication Detector - catch invented entities not in any source fact.
The model outputs "According to the 2024 Johnson report, revenue grew 23%." The envelope contains no entity "Johnson", no year "2024", no number "23". The model fabricated a citation to sound authoritative.
This module extracts specific entities from claims (numbers, percentages, dates, proper nouns, citations) and cross-references them against ALL envelope facts. Entities found in no source are flagged as fabrications.
detect_fabrications(attributions, packed_facts) ¶
Detect fabricated entities in claims that appear in no source fact.
Examines FACTUAL_CLAIM and HEDGE claims for specific entities (numbers, percentages, dates, proper nouns, citations) and flags those not found in any envelope fact.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions. | required |
packed_facts | Sequence[PackedFact] | All envelope facts. | required |
Returns:
| Type | Description |
|---|---|
list[FabricationResult] | List of FabricationResult - one per fabricated entity found. |
provenance.hallucination_scorer¶
crp.provenance.hallucination_scorer ¶
Hallucination Risk Scorer - per-claim composite risk assessment (§7.14.3).
WHY THIS EXISTS
An auditor reviewing AI output asks ONE question:
"How likely is it that THIS claim is a hallucination?"
Currently they must mentally fuse
- Attribution score (was it grounded?)
- Fidelity score (was the source distorted?)
- Entailment verdict (does NLI confirm semantic support?)
- Claim specificity (is this a precise claim that's dangerous if wrong?)
This module fuses those four signals into ONE auditable risk score per claim, with a clear risk level (LOW / MEDIUM / HIGH / CRITICAL) and a list of human-readable risk factors explaining WHY.
RISK FORMULA
risk = 1.0 - (w_a * attribution + w_f * fidelity + w_e * entailment + w_s * (1 - specificity))
Where
- attribution: top_score from DPE (0-1, higher = better sourced)
- fidelity: 1.0 if no distortions/fabrications for this claim, else degraded
- entailment: P(ENTAILED) from NLI (0-1, higher = semantically confirmed)
- specificity: density of specific entities in the claim (higher = riskier)
- w_a, w_f, w_e, w_s: configurable weights (default 0.30, 0.25, 0.30, 0.15)
Risk levels
- risk < 0.25 → LOW
- risk < 0.50 → MEDIUM
- risk < 0.75 → HIGH
- risk ≥ 0.75 → CRITICAL
compute_specificity(claim_text) ¶
Compute how specific a claim is (0.0=vague, 1.0=highly specific).
More specific claims are riskier if unsupported - "Revenue grew 23.4% in Q3 2024 according to Deloitte" is far more dangerous wrong than "Performance improved."
Specificity = min(1.0, entity_count / 5) - normalised density of numbers, dates, proper nouns, and measurements.
score_hallucination_risk(attributions, *, fidelity=None, entailment_results=None, config=None) ¶
Score hallucination risk for every claim in the output.
Combines four independent signals per claim
- Attribution - how well-sourced is the claim?
- Fidelity - did lexical checks find distortions?
- Entailment - does NLI confirm semantic support?
- Specificity - how specific (and thus risky) is the claim?
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the DPE pipeline. | required |
fidelity | FidelityReport | None | FidelityReport from the fidelity verification layer. | None |
entailment_results | list[EntailmentResult] | None | EntailmentResults from the entailment verifier. | None |
config | ProvenanceConfig | None | ProvenanceConfig with risk weight configuration. | None |
Returns:
| Type | Description |
|---|---|
HallucinationRiskReport | HallucinationRiskReport with per-claim assessments and aggregates. |
provenance.omission_analyzer¶
crp.provenance.omission_analyzer ¶
Omission Analyzer - detect when the model silently ignores important facts.
15 high-priority facts went into the envelope. The model used 4 and ignored 11. If Fact #3 was "Product has a known safety defect" and the model never mentioned it - that is a material omission.
This module identifies which envelope facts received NO attribution from any output claim and ranks them by importance (original packing score). High-importance omissions are flagged for manual review.
analyze_omissions(attributions, packed_facts, *, attribution_floor=0.2) ¶
Identify envelope facts that the model ignored.
For each packed fact, finds the maximum attribution score any output claim gave it. Facts with a maximum score below attribution_floor are considered omitted.
Results are sorted by fact relevance score descending - the most important omissions first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | Scored claim attributions from the attribution scorer. | required |
packed_facts | Sequence[PackedFact] | All facts that were packed into the envelope. | required |
attribution_floor | float | Maximum composite score below which a fact is considered "not used" (default 0.20). | 0.2 |
Returns:
| Type | Description |
|---|---|
list[OmissionResult] | List of OmissionResult sorted by importance (highest first). |
provenance.provenance_chain¶
crp.provenance.provenance_chain ¶
Provenance Chain Builder - link claims → facts → windows → tasks (§7.14.3).
Constructs full provenance chains from attribution results, tracing each claim back through the CRP pipeline:
Claim → attributed Fact → source Window → Envelope → original Task
Also enriches FactScore objects with fact metadata (source_window_id, extraction_stage) when a WarmStateStore or fact lookup is available.
enrich_fact_metadata(attributions, fact_metadata) ¶
Enrich FactScore entries with fact provenance metadata (in-place).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | List of claim attributions to enrich. | required |
fact_metadata | dict[str, dict[str, Any]] | Dict mapping fact_id → metadata dict. Expected keys include | required |
Returns:
| Type | Description |
|---|---|
None | None. Updates |
build_provenance_chain(attribution, *, session_id='', window_id='', envelope_saturation=0.0, envelope_facts_included=0, task_input_preview='') ¶
Build a full provenance chain for a single claim attribution.
The chain traces from the claim back to its source
Claim → Fact → Window → Envelope → Task
For PARAMETRIC claims (no supporting fact), the chain is shorter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attribution | ClaimAttribution | Scored claim attribution from attribution_scorer. | required |
session_id | str | Current session ID. | '' |
window_id | str | Current window ID. | '' |
envelope_saturation | float | Envelope saturation ratio. | 0.0 |
envelope_facts_included | int | Number of facts in the envelope. | 0 |
task_input_preview | str | First 120 chars of the task input. | '' |
Returns:
| Type | Description |
|---|---|
ProvenanceChain |
|
build_all_chains(attributions, *, session_id='', window_id='', envelope_saturation=0.0, envelope_facts_included=0, task_input_preview='') ¶
Build provenance chains for all attributed claims.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributions | list[ClaimAttribution] | All claim attributions from scorer. | required |
session_id | str | Current session ID. | '' |
window_id | str | Current window ID. | '' |
envelope_saturation | float | Envelope saturation ratio. | 0.0 |
envelope_facts_included | int | Facts in envelope. | 0 |
task_input_preview | str | First 120 chars of task input. | '' |
Returns:
| Type | Description |
|---|---|
list[ProvenanceChain] | List of |
provenance.report_generator¶
crp.provenance.report_generator ¶
Report Generator - human-readable provenance reports (§7.14.3).
Produces regulator-auditable decision provenance reports in markdown and JSON formats. Reports answer: "For each claim in the AI output, what evidence supported it and how confident are we in that attribution?"
generate_markdown_report(report) ¶
Generate a human-readable markdown provenance report.
Suitable for regulatory audit, compliance review, or integration into documentation. Format follows EU AI Act Article 12 logging requirements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Complete provenance report from the DPE pipeline. | required |
Returns:
| Type | Description |
|---|---|
str | Markdown-formatted report string. |
generate_json_report(report) ¶
Generate a machine-readable JSON provenance report.
Suitable for API responses, database storage, or integration with compliance management systems.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report | ProvenanceReport | Complete provenance report from the DPE pipeline. | required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | JSON-serializable dictionary. |
provenance.rqa¶
crp.provenance.rqa ¶
Response Quality Assurance composite score (CRP-SPEC-005 §18).
The RQA quality score is distinct from the safety hallucination score: safety measures truthfulness, quality measures usefulness. It fuses the four RQA-stage signals - repetition (Stage 7), completeness (Stage 8), flow (Stage 9), and cross-window coherence (Stage 6) - into one CRP-Quality-Score and can downgrade the emitted CRP-Context-Quality-Tier.
quality_score = 0.25·(1−repetition) + 0.35·completeness
+ 0.25·flow + 0.15·(1−contradiction)
RQASignals dataclass ¶
The four RQA-stage inputs (all 0.0–1.0).
RQAResult dataclass ¶
The computed RQA quality score and resulting tier cap.
headers property ¶
Return the headers.
max_tier_for_score(quality_score) ¶
Return the best quality tier permitted by quality_score (§18.4).
compute_quality_score(signals, *, config=None) ¶
Compute the RQA composite quality score (CRP-SPEC-005 §18.2).
downgrade_tier(envelope_tier, quality_score) ¶
Downgrade envelope_tier if the RQA quality score requires it (§18.4).
The emitted tier is the worse of the envelope tier and the score-derived ceiling - e.g. envelope A with score 0.62 → emitted B.
provenance.rqa_stages¶
crp.provenance.rqa_stages ¶
RQA Stages 6-9 + re-dispatch protocol (CRP-SPEC-005 §8-11, §19).
These are the Response Quality Assurance stages that operate across windows in a session (as opposed to the single-window fidelity/attribution stages):
- Stage 6 - Cross-window coherence (§8): contradictions vs prior windows.
- Stage 7 - Repetition (§9): 4-gram + semantic overlap with prior windows.
- Stage 8 - Completeness (§10): sub-query coverage of the cumulative answer.
- Stage 9 - Flow & continuity (§11): opening/topic/register/transition.
- Re-dispatch (§19): trigger conditions + augmented-prompt construction.
The module is callback-pluggable and degrades gracefully. A caller MAY pass an embedder (text → vector) and/or an nli (premise, hypothesis → P(contradiction)); when absent, lexical fallbacks (bag-of-words cosine, Jaccard, 4-gram overlap, rule-based contradiction) are used so the engine never hard-depends on a model.
CoherenceResult dataclass ¶
RepetitionResult dataclass ¶
CompletenessResult dataclass ¶
FlowResult dataclass ¶
RedispatchDecision dataclass ¶
Whether a window should be re-dispatched and why (§19).
headers property ¶
Return the headers.
detect_cross_window_contradictions(current_response, prior_window_texts, *, nli=None, threshold=0.75) ¶
Stage 6 (§8): detect contradictions between current and prior windows.
detect_repetition(current_response, prior_responses, *, embedder=None, semantic_threshold=0.92) ¶
Stage 7 (§9): n-gram + semantic overlap with prior responses.
verify_completeness(query, session_responses, *, decompose=None, embedder=None, coverage_threshold=0.7) ¶
Stage 8 (§10): does the cumulative answer cover every sub-query?
analyze_flow(current_response, prior_response, *, window_number=2, embedder=None) ¶
Stage 9 (§11): flow & continuity for continuation windows (window>1).
evaluate_redispatch(*, repetition=None, coherence=None, flow=None, risk_upgrade_triggered=False, upgrade_on_risk=False, revision_round=0, max_revisions=2) ¶
Decide whether to re-dispatch a window (§19.1-19.2).
Triggers: upgrade-on-risk + risk threshold, SEVERE repetition, CRITICAL cross-window contradiction, or flow_score < 0.30. Capped at max_revisions per window; re-dispatch does NOT decrement the safety budget (§19.3).
build_anti_repetition_prompt(prior_summary) ¶
Augmented system prompt for SEVERE repetition re-dispatch (§9.3).
build_flow_prompt(prior_last_sentences) ¶
Augmented system prompt for flow remediation (§11.5 Option A).
provenance.window_chain¶
crp.provenance.window_chain ¶
Window-level HMAC provenance chain (CRP-SPEC-004 §9, CRP-SPEC-011 §2-3).
Each window in a session carries a summary HMAC that chains from its parent window(s). The chain is tamper-evident: modifying or removing any ancestor invalidates every descendant. This module computes window HMACs (linear and fan-in) and verifies the chain, emitting the CRP-Provenance-Chain-Integrity status defined in CRP-SPEC-011 §3.3.
PRIVATE REFERENCE IMPLEMENTATION - SPEC internals are not published.
ChainIntegrity ¶
Bases: str, Enum
Result of verifying a window provenance chain.
WindowHmacInput dataclass ¶
Inputs to a window's summary HMAC.
HMAC-SHA256(session_id ‖ window_number ‖ timestamp ‖ response_hash ‖ dpe_report_hash ‖ prev_window_hmac, key) - CRP-SPEC-011 §2.3.
message() ¶
Return the canonical message bytes used for window HMAC computation.
WindowChainRecord dataclass ¶
A window's stored HMAC plus the inputs needed to recompute it.
recompute(key, prev_window_hmac) ¶
Recompute this window's expected HMAC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key | bytes | HMAC key bytes. | required |
prev_window_hmac | str | Parent window HMAC (ignored for fan-in windows). | required |
Returns:
| Type | Description |
|---|---|
str | The recomputed HMAC string. |
ChainVerification dataclass ¶
Outcome of a chain verification (CRP-SPEC-011 §3.3).
headers property ¶
Return the headers.
build_window_hmac(inp, key) ¶
Compute a window summary HMAC (linear chain extension, §9.1).
build_fan_in_window_hmac(*, session_id, window_number, timestamp, response_hash, dpe_report_hash, parent_hmacs, key) ¶
Compute a fan-in window HMAC merging multiple parents (§9.3).
Parent HMACs are sorted lexicographically and joined with | so the result is deterministic regardless of child completion order.
verify_window_chain(records, key) ¶
Verify a session's complete window chain from root to leaf (§3.1).
Returns UNVERIFIED for an empty/single-root chain that has nothing to chain from, BROKEN (with broken_at_window) on the first mismatch, and VALID when every link verifies.
verify_window_partial(record, parent_window_hmac, key) ¶
Verify a single window against its parent's HMAC (§3.2).
Auditors holding only one window and its parent tip get PARTIAL on success (the full chain was not checked) or BROKEN on mismatch.