feat(stage21): implement reproducibility — research_run_hash, full provenance tracking

- compute_research_run_hash(): deterministic SHA256 from query+budget+created_at
- ProvenanceEntry / ProvenanceLog: step-by-step trace with inputs, outputs, metadata, errors
- ResearchRun model: research_run_hash field (64-char hex)
- ResearchRunProvenance SQLAlchemy table for DB persistence
- Orchestrator: auto-log provenance before/after each pipeline step
- 35 tests: hash determinism, entry/log methods, storage model, integration
This commit is contained in:
NSCT Agent
2026-09-05 14:27:45 +00:00
parent f9b761ced7
commit 8ea6269f9a
6 changed files with 800 additions and 2 deletions

View File

@@ -754,4 +754,30 @@ class AudioClaimModel(Base):
Index("ix_audio_claims_transcript_id", "transcript_id"),
Index("ix_audio_claims_claim_type", "claim_type"),
Index("ix_audio_claims_speaker_id", "speaker_id"),
)
# ---------------------------------------------------------------------------
# Stage 21 — Research Run Provenance (Reproduzierbarkeit)
# ---------------------------------------------------------------------------
class ResearchRunProvenanceModel(Base):
"""Provenance-Table für vollständige Nachverfolgbarkeit aller Schritte (Stage 21)."""
__tablename__ = "research_run_provenance"
id = Column(BigInteger, primary_key=True, autoincrement=True)
research_run_id = Column(String(36), nullable=False, index=True)
research_run_hash = Column(String(64), nullable=False, index=True)
step = Column(String(128), nullable=False)
timestamp = Column(DateTime, nullable=False, default=datetime.utcnow)
inputs_json = Column(JSON, nullable=True)
outputs_json = Column(JSON, nullable=True)
error_json = Column(JSON, nullable=True)
metadata_json = Column(JSON, nullable=True)
__table_args__ = (
Index("ix_provenance_run_step", "research_run_id", "step"),
Index("ix_provenance_run_timestamp", "research_run_id", "timestamp"),
)