hypothesis_predictions exists (epi-01-PRED) but predictions are
typically written after an analysis is partially run, which is
post-hoc rationalisation, not prediction. Enforce a pre-registration
gate: an analyses row cannot transition from proposed to running
unless ≥ 1 frozen prediction is recorded with cryptographic timestamp
before tools.py executes any data-pulling tool. This is the single
most powerful epistemic intervention on a system that auto-generates
analyses.
analyses.preregistration_id FK to new preregistrations(id PK, analysis_id, predictions_json, hypothesis_id, created_at, content_sha256, on_chain_tx) table.scidex/agora/preregistration.py::freeze(analysis_id, predictions, hypothesis_id) -> prereg_id — predictions must include predicted_outcome, falsification_threshold, effect_size_estimate.analyses.status: proposed → must call freeze() → prereg → running → finalised. Any tool call from tools.py made on an analysis in proposed raises and aborts.q-cw-polygon-testnet-provenance) committed on chain so timestamp can't be back-dated./analysis/{id} page renders the frozen predictions first, then the actual results, with a green/red badge per prediction.preregistration_outcomes(prereg_id, prediction_idx, predicted, actual, matched, computed_at).tools.pubmed_search from within an analysis whose status is proposed — expect PreregistrationRequired. After freeze(), same call succeeds.agent.py debate engine to find the entry path that creates analyses; insert prereg gate immediately after creation.@require_preregistration decorator to data-fetching tools in tools.py (the 58 wrappers); decorator inspects the active analysis context (use a ContextVar).{predictions: [{claim, predicted_outcome, threshold, effect_size, confidence}]} — versioned via schema_version.q-er-calibration-tracker).hypothesis_predictions table (epi-01-PRED done).q-cw-polygon-testnet-provenance for timestamping.