Spaces:
Running on Zero
Running on Zero
| """Cross-artifact validation for SignalBundle and CallDecision.""" | |
| from .decisions import signal_bundle_sha256 | |
| from .schemas import CallDecision, SignalBundle | |
| def validate_decision_references( | |
| decision: CallDecision, | |
| bundle: SignalBundle, | |
| ) -> CallDecision: | |
| """Ensure every decision citation resolves inside its signal bundle.""" | |
| if decision.call_id != bundle.call_id: | |
| raise ValueError("decision and signal bundle call_id values do not match") | |
| if decision.signal_bundle_schema_version != bundle.schema_version: | |
| raise ValueError("decision references an incompatible signal bundle schema") | |
| if ( | |
| decision.signal_bundle_sha256 | |
| and decision.signal_bundle_sha256 | |
| != signal_bundle_sha256(bundle) | |
| ): | |
| raise ValueError("decision signal bundle hash does not match") | |
| segment_ids = {segment.segment_id for segment in bundle.segments} | |
| signal_ids = {signal.signal_id for signal in bundle.signals} | |
| episode_ids = {episode.episode_id for episode in bundle.episodes} | |
| findings = decision.triggered_findings + decision.positive_findings | |
| for finding in findings: | |
| unknown_rule_signals = ( | |
| set(finding.detection_rule.signal_ids) - signal_ids | |
| ) | |
| if unknown_rule_signals: | |
| raise ValueError( | |
| f"finding {finding.finding_id!r} rule references unknown signals: " | |
| f"{sorted(unknown_rule_signals)}" | |
| ) | |
| for evidence in finding.evidence + finding.counter_evidence: | |
| unknown_segments = set(evidence.segment_ids) - segment_ids | |
| unknown_signals = set(evidence.signal_ids) - signal_ids | |
| unknown_episodes = set(evidence.episode_ids) - episode_ids | |
| if unknown_segments or unknown_signals or unknown_episodes: | |
| raise ValueError( | |
| f"evidence {evidence.evidence_id!r} has unresolved references" | |
| ) | |
| for uncertainty in decision.uncertainties: | |
| unknown_signals = set(uncertainty.affected_signal_ids) - signal_ids | |
| if unknown_signals: | |
| raise ValueError( | |
| f"uncertainty {uncertainty.code!r} references unknown signals" | |
| ) | |
| unknown_findings = ( | |
| set(uncertainty.affected_finding_ids) | |
| - {finding.finding_id for finding in findings} | |
| ) | |
| if unknown_findings: | |
| raise ValueError( | |
| f"uncertainty {uncertainty.code!r} references unknown findings" | |
| ) | |
| return decision | |