Skip to content

Mint pre-mapped VRS objects for all variants at creation time (independent of dcd-mapping) #795

Description

@bencap

Summary

Give every Variant a stable, pre-mapped VRS allele object plus its ga4gh digest, minted by MaveDB during variant creation, instead of only for variants that flow through the dcd-mapping service. The digest becomes a universal, joinable identifier for search and export; the value lives on Variant, and the disposition/reason lives in the annotation event log.

Problem

Today, pre-mapped ("assay-level") VRS is a byproduct of invoking dcd-mapping. On the allele-centric branch it lands on MappingRecord.pre_mapped, and a MappingRecord is only created for variants in score sets we actually send to dcd-mapping, and only when that service succeeds in constructing the pre-mapped allele.

Consequences:

  • Variants in score sets we never map — or variants where dcd-mapping fails to build the pre-mapped allele — have no VRS identifier at all.
  • There is no universal, stable per-variant VRS digest to search or join on, and nothing clean to hand out for export.
  • Pre-mapped VRS is not deterministically a property of the measurement; it is contingent on an external reference-projection pipeline that has nothing to do with the pre-mapped object itself.

A pre-mapped VRS allele can be constructed from data MaveDB already holds (the variant's hgvs_nt/hgvs_pro plus the target sequence) for the vast majority of variants, without any reference projection. It cannot always be built — the canonical failure is an accession-based intronic variant, where we lack the local intron sequence needed for precise sequence identity — but those are the minority and must be recorded as such rather than silently dropped.

Proposed behavior

Introduce a MaveDB-owned pre-mapped VRS minting step that runs synchronously during variant creation, for every variant, decoupled from dcd-mapping.

Value on the variant. Add columns to Variant carrying only the minted value:

  • pre_mapped_vrs (JSONB) — the pre-mapped VRS allele object.
  • pre_mapped_vrs_digest (string, indexed) — the ga4gh digest; the joinable/searchable identifier that is the primary goal here.
  • pre_mapped_vrs_version (string) — the VRS spec version used to mint.

Status/rationale in the event log. Do not add per-job status/error columns to Variant. Instead record each minting observation in the existing append-only AnnotationEvent log, following the established "value in the domain table, disposition + why + when in the log" pattern:

  • A new AnnotationType, PRE_MAPPED_VRS, distinct from VRS_MAPPING (which remains the dcd reference-projection step). Subject is the variant, so it joins the variant-subject annotation types.
  • disposition + reason capture outcome: successful mint → present; structural inability to build (e.g. accession-based intronic variant, no local sequence) → not_applicable; sequencing-resolution/normalization error → failed.
  • Reuse existing EventReason values where they genuinely apply; add new EventReason value(s) for the pre-mapped-specific structural gaps (e.g. accession-based intronic with no resolvable sequence) where none fit.

Minting mechanism. Port the pre-mapped VRS construction logic that currently lives in the dcd-mapping implementation into MaveDB:

  • Non-accession targets: MaveDB already stores the full target sequence, so compute the Refget ga4gh:SQ digest locally and build the allele on the stored hgvs_nt/hgvs_pro.
  • Accession-based targets: resolve the reference (SeqRepo/CDOT) to obtain the sequence. Where the required sequence is unavailable (e.g. intronic positions outside what we can resolve), emit a not_applicable event and mint no value.

SeqRepo write-on-mint. On a successful mint, register the target sequence into the local SeqRepo instance so its ga4gh:SQ digest resolves for downstream consumers. This must be idempotent (re-minting the same target sequence is a no-op).

Coexistence with dcd-mapping (phased). For now, keep MaveDB's pre-mapped value separate from dcd-mapping's MappingRecord.pre_mapped; do not change the mapping process. The intended end state (follow-up, out of scope here) is that dcd-mapping stops minting pre-mapped VRS entirely and MaveDB's variant-creation-time value becomes authoritative.

Backfill. Provide a one-off backfill (a manual migration, in the same style as the existing allele-substrate migration) that mints pre-mapped VRS and writes the corresponding PRE_MAPPED_VRS annotation events for all existing variants.

Acceptance criteria

  • Variant has pre_mapped_vrs (JSONB), pre_mapped_vrs_digest (indexed), and pre_mapped_vrs_version columns.
  • Creating a score set's variants mints a pre-mapped VRS for every variant synchronously during variant creation, with no dependency on dcd-mapping having run.
  • For a non-accession target, minting succeeds using the DB-stored target sequence with no dcd-mapping call, and pre_mapped_vrs_digest is populated with a valid ga4gh digest.
  • For an accession-based intronic variant that cannot be built, pre_mapped_vrs* columns are left null and a PRE_MAPPED_VRS AnnotationEvent is written with a not_applicable disposition and a reason identifying the structural gap.
  • On a genuine minting/normalization error, a PRE_MAPPED_VRS AnnotationEvent is written with a failed disposition and an error reason; the variant creation as a whole does not fail because one variant could not be minted.
  • Every minting attempt (present, not_applicable, or failed) produces exactly one current PRE_MAPPED_VRS annotation event for that variant, surfaced through v_current_annotation_events.
  • A successful mint registers the target sequence into SeqRepo idempotently; re-running mint for the same target sequence performs no duplicate write and does not error.
  • PRE_MAPPED_VRS is added to the variant-subject annotation types and passes the ck_annotation_event_subject polymorphic-subject constraint (variant_id set, allele_id null).
  • A backfill migration mints pre-mapped VRS and writes PRE_MAPPED_VRS annotation events for all pre-existing variants; variants for which a value cannot be built get a not_applicable/failed event rather than being skipped silently.
  • The dcd-mapping pipeline and MappingRecord.pre_mapped are unchanged by this work.
  • Tests cover: a successful non-accession mint, a successful accession-resolved mint, an accession-intronic not_applicable case, a minting-error failed case, digest determinism (same input → same digest), and idempotent SeqRepo registration.
  • A follow up issue is created to remove pre-mapped VRS generation from the dcd-mapping pipeline and harmonize all pre-mapped VRS references to the canonical value minted during variant creation.

Implementation notes

  • New enum member AnnotationType.PRE_MAPPED_VRS; add it to VARIANT_SUBJECT_TYPES so the polymorphic-subject CHECK admits it. Extend the CHECK constraint accordingly via migration.
  • Add EventReason value(s) for the pre-mapped structural-gap and error cases; reuse existing reasons only where they meuplicating vocabulary).
  • The submitted HGVS lives on the variant as hgvs_nt / hgvs_pro / hgvs_splice; these are the minting inputs (distinct from mapper-derived HGVS on alleles).
  • Do not route pre-mapped VRS through the alleles dedup table — pre-mapped is a per-measurement property and the alleletended for the (post-mapped) reference projection; using it here would be non-idiomatic.
  • Minting is synchronous within the existing variant-creation job loop, before mapping is queued; a per-variant failure must be isolated (recorded as a failed event) and must not abort creation of the rest of the score set.
  • Follow the existing manual-migration pattern (as used for the mapped-variants → allele-substrate migration) for the backfill.

Open questions / follow-ups

  • API surface (not settled): at minimum, expose pre_mapped_vrs and pre_mapped_vrs_digest on the variant view model. Whether/how to surface pre-mapped values (and their annotation-event disposition/reason) through the annotation view, the published-variants materialized view, or a coverage statistic is deferred and should be decided before consumer-facing work.
  • Phase 2 (separate issue): retire pre-mapped VRS minting from the dcd-mapping repo and make MaveDB's variant-creation-time value authoritative, removing the MappingRecord.pre_mapped producer.
  • Confirm the local SeqRepo instance is writable in all deploy environments where variant creation runs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    app: backendTask implementation touches the backendapp: databaseTask implementation requires database changestype: featureNew feature

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions