from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field from datetime import datetime class Source(BaseModel): type: str uri: str confidence: Optional[float] = None class Signal(BaseModel): name: str value: float provenance: Optional[dict] = None class Provenance(BaseModel): trace_id: str signer: Optional[str] = None ledger_anchor: Optional[str] = None class NarrativeBlock(BaseModel): model_config = ConfigDict() id: str topic: str timestamp: datetime sources: List[Source] = Field(default_factory=list) signals: List[Signal] = Field(default_factory=list) sentiment: Optional[float] = None risk_factors: List[str] = Field(default_factory=list) scenario_flags: List[str] = Field(default_factory=list) provenance: Optional[Provenance] = None class EvidenceToken(BaseModel): kind: str uri: str confidence: Optional[float] = None metadata: Dict[str, Any] = Field(default_factory=dict) class Claim(BaseModel): id: str statement: str evidence: List[EvidenceToken] = Field(default_factory=list) confidence: Optional[float] = None signer: Optional[str] = None signature: Optional[str] = None class ClaimGraph(BaseModel): block_id: str claims: List[Claim] = Field(default_factory=list) provenance: Optional[Provenance] = None class NarrativeDiff(BaseModel): left_block_id: str right_block_id: str changed_fields: List[Dict[str, Any]] = Field(default_factory=list) added_claims: List[Claim] = Field(default_factory=list) removed_claims: List[Claim] = Field(default_factory=list) modified_claims: List[Dict[str, Any]] = Field(default_factory=list)