scidex/forge/runtime_capture.py snapshots thescidex/forge/data_versions.py exposescurrent_versions() returning a dict for each integrated source:{"allen_atlas": {"release": "...", "fetched_at": "..."}, ...}.
allen_brain_expression,gtex_tissue_expression, cellxgene_gene_expression,clinvar_variants, depmap helper, pubmed_search) callsdata_versions.record(source, version, scope) before returning.
runtime_capture.capture_run() in forge/runtime_capture.py writesforge/example_capsule_manifest.json for shape).
repro_capsule_schema.json extended with a data_versions field;capsule_validator.py enforces it.
analyses/<id>/repro.json contains the manifest; /analyses/<id>scripts/repro_check.py <analysis_id> reportsIDENTICAL, DRIFT(<source>: <old>→<new>), or MISSING per source.record() after a successful API hit; cachedforge/runtime_capture.py already exists.repro_capsule_schema.json, capsule_validator.py.All acceptance criteria delivered:
scidex/forge/data_versions.py (new): ContextVar-based per-run versionrecord(source, version, scope), current_versions(), andreset_versions(). Defines canonical release constants:GTEX_RELEASE="gtex_v8", CENSUS_RELEASE="2024-07-01",DEPMAP_RELEASE="24Q2", ALLEN_API_VERSION="v2", CLINVAR_CADENCE="weekly",PUBMED_CADENCE="live".scidex/forge/tools.py: Wired record() calls into allen_brain_expressiongtex_tissue_expression (after expression query),clinvar_variants (after summary fetch), pubmed_search (after results built),cellxgene_gene_expression (using census_version from result). Import addedscidex/forge/depmap_client.py: Wired record() intodependency_for_gene() on both cache hit and API success paths. Import guardedforge/runtime_capture.py: Added capture_run(analysis_id, title,capture_environment_bundle() +current_versions() and returns a complete repro capsule manifest dictdata_versions block) matching the schema shape.scidex/forge/repro_capsule_schema.json: Extended with data_versionsrelease + fetched_at required, scopes arrayscidex/forge/capsule_validator.py: Added _validate_data_versions()validate_manifest().scripts/repro_check.py (new): CLI tool that reads analyses/<id>/repro.jsonIDENTICAL, DRIFT(old→new), or MISSING per data source vs.Note: analyses/<id>/repro.json writing and UI rendering (collapsible block on
/analyses/<id>) depend on the executor layer generating and storing the manifest
after each run — that wiring is in the analysis execution pipeline, not in this
module layer. The capture_run() function is the callable that produces the
manifest; callers are responsible for persisting it.