Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
280 commits
Select commit Hold shift + click to select a range
ac4cfa9
feat(variants): combine cis-phased members into one HGVS expression
bencap Jun 7, 2026
dba7bfe
feat(gnomad): migrate gnomAD linkage to the Allele model with version…
bencap Jun 22, 2026
c77c21b
feat: link VEP consequences to alleles with Ensembl-release versioning
bencap Jun 22, 2026
6247680
feat(clinvar): migrate ClinVar annotation onto the allele model
bencap Jun 22, 2026
3d9b5fa
refactor(annotation): retire the HGVS and variant-translation jobs
bencap Jun 23, 2026
c936dd4
feat(alleles): cross-layer allele equivalence query with as_of support
bencap Jun 23, 2026
d397398
feat(annotation): add append-only AnnotationEvent log and status voca…
bencap Jun 30, 2026
5773aa5
refactor(alleles): collapse to one work-unit per allele
bencap Jun 30, 2026
5d35ed0
refactor(annotation): rewrite AnnotationStatusManager to emit events
bencap Jun 30, 2026
aacc13a
feat(gnomad): derive annotation events from link verdicts
bencap Jun 30, 2026
6f0f47f
feat(vep): derive annotation events from resolution outcomes
bencap Jun 30, 2026
ed50102
feat(clingen): emit annotation events from CAR/LDH jobs
bencap Jun 30, 2026
73007fd
feat(clinvar): emit annotation events from ClinVar job
bencap Jun 30, 2026
e31363b
feat(mapping): emit annotation events
bencap Jun 30, 2026
6288f82
feat(reverse-translation): emit annotation events
bencap Jun 30, 2026
cbe0fd9
feat(scripts): add pipeline tracking and event-aware annotations script
bencap Jun 30, 2026
b05d3a3
fix(clingen): re-register existing CAIDs when force_reregister is set
bencap Jun 30, 2026
18ede44
fix(vep): route VEP HTTP rejections to Variant Recoder
bencap Jun 30, 2026
70036d8
fix(vrs): narrow RLE→LSE coercion types to satisfy mypy
bencap Jun 30, 2026
c19e78b
fix(clinvar): supersede links on the DB clock, not naive datetime.now()
bencap Jun 30, 2026
768d372
perf(annotation): index annotation_event.score_set_id
bencap Jun 30, 2026
a768039
chore(alembic): rename closure-tables migration to match its contents
bencap Jun 30, 2026
c1d26a0
test(annotation): restore status-manager query edge-case coverage
bencap Jun 30, 2026
e43f0ea
fix(hgvs): guard accession-less cis-phased split, order joined compon…
bencap Jun 30, 2026
3bf5cdd
fix(tests): update patch target for generate_clinvar_versions lost in…
bencap Jul 9, 2026
36f9389
feat(variants): combine cis-phased members into one HGVS expression
bencap Jun 7, 2026
522b694
feat(clinvar): migrate ClinVar annotation onto the allele model
bencap Jun 22, 2026
644e727
feat(cat-vrs): build categorical variant transit on the fly from live…
bencap Jun 30, 2026
bb62baa
refactor(variants): centralize canonical variant score access
bencap Jul 1, 2026
964a7d8
feat(score-sets): lean whole-set variant view (GET /score-sets/{urn}/…
bencap Jul 1, 2026
f563760
refactor(valid-time): add ValidTime.live_at for uniform temporal filt…
bencap Jul 1, 2026
a5f3da7
refactor(lean_variants): use live_at helper and join-based protein hgvs
bencap Jul 1, 2026
fc6c8ad
perf(lean-variants): materialize protein projection to avoid O(N^2) plan
bencap Jul 6, 2026
b6ea2dc
refactor(score-sets): rename lean_variants module to score_set_variants
bencap Jul 7, 2026
6a6112a
feat(variants): variant detail envelope for GET /variants/{urn}
bencap Jul 7, 2026
3016dc9
refactor(clinical-controls): serve from allele-link substrate with as_of
bencap Jul 7, 2026
a5918d1
refactor(clinical-controls): serve list and options from a shared lib…
bencap Jul 7, 2026
3717f5d
refactor(variants): rename supersededBy to supersededByScoreSet on va…
bencap Jul 7, 2026
ac8f405
fix(mapping): enforce one live authoritative allele link per record
bencap Jul 7, 2026
7b92d69
refactor(calibrations): extract shared calibration-preference and evi…
bencap Jul 8, 2026
e47791c
feat(clingen-alleles): add equivalence-class measurements endpoint
bencap Jul 8, 2026
41ada42
feat(variants): add per-allele identity sidecar to variant detail env…
bencap Jul 8, 2026
031eaab
perf(score-set-variants): split protein projection into separate quer…
bencap Jul 8, 2026
aafe524
feat(annotation): pair c/g projections via projection_group
bencap Jul 9, 2026
feb9c55
feat(allele-measurements): add include_nucleotide_siblings flag and r…
bencap Jul 9, 2026
0a365d0
refactor(annotations): rename AnnotationLayer to SequenceLevel and ty…
bencap Jul 10, 2026
ccf5b69
fix(docs): remove design references from endpoint documentation
bencap Jul 10, 2026
19072d6
feat(allele-measurements): rank current measurements before superseded
bencap Jul 12, 2026
0ff6cd0
feat(clinical-controls): tag control links with annotating allele digest
bencap Jul 13, 2026
bb369d9
refactor(allele-measurements): expose preferred classification, exclu…
bencap Jul 13, 2026
c1fb812
feat(clingen): batch CAR submissions and add HTTP timeouts
bencap Jul 15, 2026
3b9f7da
feat(worker): stop linking protein-level alleles to ClinVar and gnomAD
bencap Jul 15, 2026
4377e72
feat(uniprot): support Ensembl protein accessions in UniProt ID mapping
davereinhart Jul 7, 2026
f1655ee
Add Ensembl transcript (ENST) support to sequence accession inference
davereinhart Jul 8, 2026
b1adc4f
chore(export): add changelog to public data archive and document rele…
bencap Jul 9, 2026
947b744
feat(worker): detect stuck RUNNING jobs via progress heartbeat
bencap Jul 9, 2026
95a2917
Merge branch 'release-2026.2.8' of https://github.com/VariantEffect/m…
bencap Jul 17, 2026
4e1ddf5
feat(uniprot): support Ensembl protein accessions in UniProt ID mapping
davereinhart Jul 7, 2026
97cf2f3
Add Ensembl transcript (ENST) support to sequence accession inference
davereinhart Jul 8, 2026
1bf1c2b
chore(export): add changelog to public data archive and document rele…
bencap Jul 9, 2026
6765600
feat(worker): detect stuck RUNNING jobs via progress heartbeat
bencap Jul 9, 2026
b1c84da
Merge branch 'release-2026.3.0' of https://github.com/VariantEffect/m…
bencap Jul 17, 2026
5751e9c
feat(cat-vrs): add co_encodes relation and convergent derivation
bencap Jul 18, 2026
28f90ea
refactor(annotation): dissolve util.py into cohesive modules
bencap Jul 18, 2026
a8363a6
feat(annotation): serve variant annotation from the Allele substrate
bencap Jul 18, 2026
599c8e0
feat(variants): relocate VA-Spec and VRS-lookup endpoints; drop /mapp…
bencap Jul 18, 2026
275a75a
feat(alleles): add allele-detail endpoint (digest / CAID / PAID)
bencap Jul 18, 2026
193c55f
refactor(workflow): extract shared pipeline-kickoff helper from score…
bencap Jul 20, 2026
a712262
fixup ~2
bencap Jul 20, 2026
c87b72f
feat(scripts): add batch driver for score-set mapping/enrichment pipe…
bencap Jul 20, 2026
4b640e1
fix(variants): accept VariationDescriptor when extracting hgvs from p…
bencap Jul 20, 2026
575a2e2
feat(migration): add manual backfill of allele substrate from mapped_…
bencap Jul 21, 2026
b3fd1ba
feat(serving): rewrite annotation views and stats MV onto mapping_rec…
bencap Jul 21, 2026
9a3ded6
perf(gnomad): batch allele lookup in gnomAD linker to end per-row scans
bencap Jul 22, 2026
0f6ba0b
feat(scripts): gate unenriched selection on a usable transcript
bencap Jul 22, 2026
6f0a8e2
feat(variants): stream variant-details NDJSON, add gnomAD variant links
bencap Jul 23, 2026
cdbaeab
feat(score-sets): rewrite CSV export onto the allele substrate
bencap Jul 23, 2026
d53c273
feat(variants): add migration stubs for retired mapped-variant routes
bencap Jul 23, 2026
fbfd4b9
fix(measurements): reach a CA's protein consequence unconditionally
bencap Jul 24, 2026
a9c2f40
feat(cleanup): extend job timeouts
bencap Jul 24, 2026
7ac0667
feat(cat-vrs): emit spec-alignment ConceptMappings for relation codes
bencap Aug 17, 2026
48b8437
refactor(alleles): rename sibling/cousin terminology to projection/en…
bencap Aug 17, 2026
ca2f727
docs(alleles): trim and correct comments/docstrings across allele views
bencap Aug 17, 2026
6e8f407
fix(refget): declare Content-Length for the bytes actually streamed
bencap Aug 17, 2026
26664e3
chore(tests): sharpen unit and integration markers, extend refget cov…
bencap Aug 17, 2026
db2bb49
fix(worker): clear stale uniprot_id_from_mapped_metadata on remap
davereinhart Aug 18, 2026
5fad56a
Merge branch 'main' into release-2026.3.0
bencap Aug 18, 2026
c72206f
Merge branch 'release-2026.2.8' into release-2026.3.0
bencap Aug 18, 2026
79b3a6b
Clear stale HGNC gene info on remap when mapping returns none
davereinhart Aug 19, 2026
36c1043
Merge branch 'release-2026.3.0' into feature/bencap/allele-centric-ma…
bencap Aug 19, 2026
bef917a
test(worker): cover stale mapped_hgnc_name clearing on remap
davereinhart Aug 20, 2026
62ca7f7
Merge pull request #849 from VariantEffect/fix/davereinhart/794/clear…
davereinhart Aug 20, 2026
0fd9a36
fix(permissions): require ownership to supersede a published score set
bencap Aug 21, 2026
242fada
fix(permissions): serve only published experiments from the public se…
bencap Aug 21, 2026
747d61d
fix(permissions): always filter an experiment's score set URNs in sea…
bencap Aug 21, 2026
f597036
fix(permissions): exclude unpublished score sets from target gene lis…
bencap Aug 21, 2026
1ecd945
chore: bump version to 2026.2.7.2
bencap Aug 21, 2026
3a2ea0c
Merge branch 'release-2026.3.0' into feature/bencap/allele-centric-ma…
bencap Aug 24, 2026
ed9b923
fix(alleles): recompute VRS identity from content on ingest and backfill
bencap Aug 26, 2026
66976f3
fix(annotation): drop wall-clock date from the API contribution
bencap Aug 26, 2026
45050d5
build(dev): replace LocalStack with moto for local S3 emulation
bencap Aug 26, 2026
ccf3eef
fix: return 4XX for malformed input to hgvs/validate
bencap Aug 28, 2026
cff006c
feat(models): add VEP consequence provenance schema
bencap Aug 28, 2026
72a31dc
refactor(vep): delegate resolution to the shared kernel and persist p…
bencap Aug 28, 2026
720c6b4
feat(pipeline): re-enable VEP annotation now that consequences are tr…
bencap Aug 28, 2026
918aed2
feat(reverse-translation): record non-translatable consequences as a …
bencap Aug 28, 2026
d9668d0
fix(dependencies): add moto-init dependency for app and worker services
bencap Sep 2, 2026
5aefb34
Merge pull request #859 from VariantEffect/feature/bencap/768-replace…
bencap Sep 2, 2026
cc762ce
feat(urns): forward URNs retired by publication to the published record
davereinhart Sep 1, 2026
613a177
feat(deprecation): unify RFC 8594 signalling and usage recording acro…
bencap Sep 2, 2026
33e381a
feat(export): make the legacy mapped-variants dump artifact switchabl…
bencap Sep 2, 2026
df3b098
feat(scripts): add backfill campaign coverage map and safe-to-drop re…
bencap Sep 2, 2026
7e7beb9
fix(reverse-translation): anchor cdna transcript resolution to the ma…
bencap Sep 2, 2026
6ecb48d
chore(dev): pin ruff to 0.6.8 to match the pre-commit hook
bencap Sep 2, 2026
39791a6
fix(logging): record the complete request path for variant endpoints
davereinhart Sep 2, 2026
c2153f3
test(urns): guard the forwarding lib tests behind the server extra
davereinhart Sep 8, 2026
32879d2
Fix the outer source not found error in both Method sources and Thres…
EstelleDa Sep 11, 2026
8a4b5e4
Debug for test_create_experiment_rxiv_timeout.
EstelleDa Sep 14, 2026
04fa106
feat(reverse-translation): skip cis-phased multivariant hgvs before rt
bencap Sep 14, 2026
b5d45ca
fix(migration): handle allele cache misses due to VRS id drift
bencap Sep 14, 2026
c2692c3
fix(mapped-variant): read the redirect target from the ASGI scope, no…
bencap Sep 15, 2026
69e035e
fix(score-sets): reject publishing a score set that is already published
davereinhart Sep 15, 2026
df88be3
refactor(urns): defer redirect target visibility to the permission rules
davereinhart Sep 15, 2026
38ca5e4
fix(worker): keep mapping jobs alive during long dcd-mapping calls
bencap Sep 15, 2026
a5c4044
feat(calibration-controls): add status enum and calibration_controls …
bencap Sep 16, 2026
1b6b877
feat(calibration-controls): add view models for controls (#750)
bencap Sep 16, 2026
7aa7e74
test(urns): cover every entity type publication renames
davereinhart Sep 16, 2026
19c0cb0
Merge pull request #863 from VariantEffect/feature/davereinhart/tmp-u…
davereinhart Sep 16, 2026
8fde783
feat(calibration-controls): validate controls belong to the score set…
bencap Sep 16, 2026
cefdc26
feat(calibration-controls): gate publishing on PHI acknowledgment (#752)
bencap Sep 16, 2026
b3c1801
feat(calibration-controls): persist controls on create and modify (#753)
bencap Sep 16, 2026
d5ab9bc
feat(calibration-controls): reset controls_not_phi when controls chan…
bencap Sep 16, 2026
17a2b2d
feat(calibration-controls): CSV validation with 1:1 HGVS resolution (…
bencap Sep 16, 2026
bc47a8b
feat(calibration-controls): wire controls into create/update/read end…
bencap Sep 16, 2026
11ca9a2
feat(calibration-controls): report controlsCount on list responses (#…
bencap Sep 17, 2026
8eee8e9
feat(calibration): model disease as a MONDO-coded concept (#754)
bencap Sep 17, 2026
8c132aa
refactor(annotation): derive the disease condition from the calibrati…
bencap Sep 17, 2026
18b1c8a
feat(calibration-controls): reject controls on score set creation (#754)
bencap Sep 17, 2026
6b387fc
fix(calibration-controls): re-enforce PHI gate on modify, not just pu…
bencap Sep 17, 2026
c29253b
fix(calibration): make MONDO term resolution idempotent
bencap Sep 18, 2026
cbb0c1a
feat(score-set): freeze scores after publish
bencap Sep 18, 2026
ed1debe
feat(calibration-controls): serve each control's functional-classific…
bencap Sep 18, 2026
0f60989
feat(calibration-controls): preserve controls and class bins across a…
bencap Sep 18, 2026
5a13ff1
fix(scripts): let untried score sets claim slots before retrying fail…
bencap Sep 18, 2026
be449bb
build(deps): pin variant-annotation to git tag instead of local path
bencap Sep 18, 2026
f65ac35
Merge pull request #861 from VariantEffect/fix/hgvs-validate-parse-er…
bencap Sep 19, 2026
ab89250
fix(refget): close the review's inverted-range and bounds-checking gaps
bencap Sep 21, 2026
4cf4287
fix(score-sets): index functional classification variant fk to unbloc…
bencap Sep 21, 2026
b25ce83
fix(tests): stop server-extras imports from crashing core-dependencie…
bencap Sep 21, 2026
764375f
fix(mypy): resolve the SQLAlchemy-plugin and Optional-narrowing errors
bencap Sep 21, 2026
e085ba4
fix(calibration): give directly-constructed test calibrations a disea…
bencap Sep 21, 2026
e1732e7
refactor(mondo): split OLS integration out of mondo.py for core-depen…
bencap Sep 21, 2026
4138248
Modify the find_generic_article function.
EstelleDa Sep 23, 2026
a068959
Debug a test.
EstelleDa Sep 23, 2026
8a28b20
feat(reverse-translation): record UTA outages as api_error and reconn…
bencap Sep 24, 2026
5d23963
feat(rls): carry score_set_id on mapping_records and mapping_record_a…
bencap Sep 28, 2026
876deab
Merge remote-tracking branch 'origin/main' into release-2026.3.0
bencap Sep 28, 2026
7acf761
fix(tests): submit a versioned RefSeq accession in the UniProt networ…
bencap Sep 28, 2026
7610d67
Merge pull request #847 from VariantEffect/bugfix/bencap/846/refget-c…
bencap Sep 29, 2026
01eca51
Merge pull request #862 from VariantEffect/fix/davereinhart/logging-f…
bencap Sep 29, 2026
e96248f
perf(db): index variants by score set and variant number
bencap Sep 29, 2026
a318164
fix(db): chain the variant-number index after #874 and follow the mig…
bencap Sep 29, 2026
f9b0a27
fix(db): let the variant-number index tolerate URNs without a number
bencap Sep 29, 2026
4bb07de
Revert "fix(db): let the variant-number index tolerate URNs without a…
bencap Sep 29, 2026
bfea1de
test: build fixture variant URNs from their score set
bencap Sep 29, 2026
7270b8b
fix(refget): return 416 for start > end on a linear sequence
bencap Sep 29, 2026
21ae254
perf(csv): cap concurrent large CSV builds per process
bencap Sep 29, 2026
38dc07f
fix(db): bound API database waits and stop per-request login writes
bencap Sep 29, 2026
d497431
test(csv): skip the build limiter tests without FastAPI
bencap Sep 29, 2026
72c3e8d
fix(migrations): build functional classification variant index withou…
bencap Sep 30, 2026
644b7ea
Merge release-2026.3.0 into feature/bencap/754-calibration-controls
bencap Sep 30, 2026
0e55109
chore(migrations): chain calibration controls migration after the var…
bencap Sep 30, 2026
05d864f
fix(variants): cascade mapping records and annotation events when a v…
bencap Sep 30, 2026
3345661
test(worker): build variant URNs as <score set URN>#<n> in RT fixtures
bencap Sep 30, 2026
c639235
test(variants): publish the score set before its calibration in VA-Sp…
bencap Sep 30, 2026
232f2e1
fix(calibrations): return 422 for an unknown MONDO disease code
bencap Sep 30, 2026
49ab852
fix(worker): keep derived alleles through a UTA outage on a reverse t…
bencap Sep 30, 2026
6b2bbcb
Merge pull request #874 from VariantEffect/bugfix/bencap/677/score-se…
bencap Sep 30, 2026
3af0502
Merge pull request #897 from VariantEffect/bugfix/bencap/881/db-timeo…
bencap Sep 30, 2026
0551a41
Merge pull request #898 from VariantEffect/bugfix/bencap/csv-build-co…
bencap Sep 30, 2026
91e885c
Merge remote-tracking branch 'origin/release-2026.3.0' into bugfix/be…
bencap Sep 30, 2026
3588a2c
Merge pull request #899 from VariantEffect/bugfix/bencap/variant-numb…
bencap Sep 30, 2026
d1bdfa8
Merge pull request #873 from VariantEffect/feature/bencap/754-calibra…
bencap Sep 30, 2026
a5ab47a
Merge release-2026.3.0 into feature/bencap/allele-centric-mapping-and…
bencap Sep 30, 2026
7ca9135
feat(alleles): verify allele refgets against SeqRepo at insert and pi…
bencap Sep 30, 2026
a8a2593
feat(alleles): enforce one allele per HGVS expression
bencap Sep 30, 2026
3af9f4d
fix(alleles): declare Allele columns with Column so the mypy plugin b…
bencap Sep 30, 2026
6c439e7
Merge pull request #791 from VariantEffect/feature/bencap/allele-cent…
bencap Sep 30, 2026
6ae9491
chore(deps): update starlette, fastapi and cryptography to close know…
bencap Sep 30, 2026
2dbf711
chore: bump version to 2026.3.0
bencap Sep 30, 2026
8e8abed
feat(cat-vrs): cross-reference ClinGen, gnomAD and ClinVar records in…
bencap Oct 1, 2026
8108d17
feat(deps)!: upgrade GA4GH models to VA-Spec 1.1.0 and Cat-VRS 1.1.1
bencap Oct 2, 2026
7af2bc8
feat(scripts): audit the mapping and reverse-translation allele graph
bencap Oct 2, 2026
cf63681
fix(clingen): replace stored CAIDs CAR assigns differently on forced …
bencap Oct 2, 2026
efa802b
chore(deps): update variant-annotation to v0.1.0-dev.3
bencap Oct 2, 2026
04055f5
fix(worker): rewrite reverse-translation inversions as delins
bencap Oct 2, 2026
09bbcf6
docs(scripts): explain projection-group and orphaned-allele audit fin…
bencap Oct 2, 2026
993d1ff
chore(deps): update variant-annotation to v0.1.0-dev.5
bencap Oct 2, 2026
208d6fa
fix(scripts): stop round-trip reporting unchanged and start-codon pro…
bencap Oct 2, 2026
30af659
fix(worker): wait out UTA outages longer before failing reverse trans…
bencap Oct 5, 2026
97d8b4d
fix(backfill): skip alleles not on SeqRepo's sequence for their acces…
bencap Oct 5, 2026
6d9b0b6
fix(scripts): run audit_allele_identifiers' CLI when invoked as a script
bencap Oct 5, 2026
abb36e4
Add more except cases and some related tests.
EstelleDa Oct 6, 2026
aaffeb1
Fixed no module fastapi problem in some tests.
EstelleDa Oct 7, 2026
48214a3
Merge remote-tracking branch 'origin/release-2026.3.0' into bugfix/es…
EstelleDa Oct 7, 2026
0e1be4c
Tried to solve the No module named 'biocommons' problem in some tests.
EstelleDa Oct 7, 2026
675cc25
Tried to solve the No module named 'psycopg2' in test_identifiers file.
EstelleDa Oct 7, 2026
a8fa960
fix(publish): serialize URN assignment and return 409 on collision
bencap Oct 7, 2026
561a362
perf(score-sets): keep lean variant lookups as per-variant index probes
bencap Oct 7, 2026
567071a
feat(variant): add a research-use-only classification fallback to all…
bencap Oct 7, 2026
be5aa2c
feat(csv): flag research-use-only calibrations instead of prefixing t…
bencap Oct 7, 2026
6209dc7
fix(uniprot): submit unversioned NM_ accessions to ID mapping
bencap Oct 7, 2026
040a7c0
fix(scripts): separate expected cases from errors in the reverse-tran…
bencap Oct 7, 2026
189125d
feat(calibration-controls): store controls only while PHI is affirmed
bencap Oct 7, 2026
c9c6825
fix(score-calibrations): check READ before ranking a calibration
bencap Oct 7, 2026
205d3ff
feat(alleles): hide alleles that only unreadable score sets link
bencap Oct 7, 2026
6c1a0af
fix(clingen-alleles): reach protein consequences only through readabl…
bencap Oct 7, 2026
b55ce20
fix(seqrepo): match sequence aliases exactly
bencap Oct 7, 2026
4e07de2
fix(permissions): withhold unreadable records from related-record URN…
bencap Oct 7, 2026
a6e08fb
fix(score-sets): check UPDATE before validating a score set update
bencap Oct 7, 2026
cbbff52
fix(collections): report unreadable records as missing when adding me…
bencap Oct 7, 2026
45ad66a
fix(permissions): report unreadable resources as missing in permissio…
bencap Oct 7, 2026
322f52c
fix(measurements): only fall back to an RUO call when no clinical cal…
bencap Oct 8, 2026
99c54c2
feat(variant): score distribution summaries and opt-in research-use-o…
bencap Oct 8, 2026
decd6f0
fix(scripts): commit the score distribution backfill per score set
bencap Oct 8, 2026
d6678a6
Merge pull request #866 from VariantEffect/bugfix/estelle/865/methods…
EstelleDa Oct 9, 2026
5a06525
fix(reverse-translation): keep projection groups stable across reruns
bencap Oct 9, 2026
b425481
feat(logging): count database statements per request
bencap Oct 9, 2026
bbbad58
fix(variants): batch variant detail and annotation reads, label membe…
bencap Oct 9, 2026
9696b18
Merge branch 'release-2026.3.0' of https://github.com/VariantEffect/m…
bencap Oct 9, 2026
ecbce89
fix(clingen): restart cache expiry when warming reads a cached allele
bencap Oct 9, 2026
5a30c32
fix(clinvar): report progress within a version during a refresh
bencap Oct 9, 2026
30cb4cf
chore(deps): pin variant-annotation to v0.1.0-dev.6
bencap Oct 9, 2026
5e763ac
fix(worker): give mapping an hour before its size-aware budget starts
bencap Oct 10, 2026
7f7bb6d
feat(audit): scope audits to current score sets and split codon-strad…
bencap Oct 12, 2026
aff9c82
feat(audit): flag SeqRepo sequences carrying a foreign ga4gh alias
bencap Oct 12, 2026
a938dc5
chore(dev): run local Postgres on 15 to match production
bencap Oct 14, 2026
6580fe9
fix(audit): stream identifier audit rows instead of buffering the result
bencap Oct 14, 2026
4820e1c
fix(tests): make the core-dependency suite collect and pass without s…
bencap Oct 14, 2026
07e01f9
docs: update instructions and worker docs for projection groups and t…
bencap Oct 15, 2026
2c9b19f
fix(mapping): restore mapped coding and protein HGVS with projection …
bencap Oct 15, 2026
61e2b18
fix(worker): run pipeline starts and variant creation on a fast-lane …
bencap Oct 15, 2026
cfbb65b
fix(rt): keep a coding candidate spelled two ways paired with its gen…
bencap Oct 15, 2026
39609ae
fix(tests): expect the unversioned accession in the UniProt network test
bencap Oct 15, 2026
b1eedee
chore(dev): run the fast-lane worker in local compose
bencap Oct 15, 2026
7f49694
fix(cdot): raise on cdot-rest outages instead of reporting transcript…
bencap Oct 15, 2026
1fd39c7
fix(clingen): link CAR's answer when it lists a different spelling of…
bencap Oct 15, 2026
a22b553
fix(projection): project measured variants through variant-annotation…
bencap Oct 15, 2026
104be2f
fix(scripts): keep each score set's modification date in the score di…
bencap Oct 15, 2026
324cee2
fix(variants): keep projectionOf to a nucleotide allele's c<->g count…
bencap Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
43 changes: 17 additions & 26 deletions .github/instructions/api.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ async def publish_score_set(
worker: ArqRedis = Depends(get_worker),
):
# ... validation and DB updates ...
await worker.enqueue_job(
"create_variants_for_score_set",
score_set.id,
correlation_id,
await enqueue_pipeline_for_score_set(
db=db,
redis=worker,
pipeline_name="publish_score_set",
score_set=item,
user=user_data.user,
)
```

Expand All @@ -114,24 +116,20 @@ responses=shared_responses # Defines 4xx/5xx response schemas
Most write operations trigger a multi-step pipeline via the worker:

```python
from mavedb.lib.workflow.pipeline_factory import PipelineFactory
from mavedb.lib.workflow.kickoff import enqueue_pipeline_for_score_set

# In a router endpoint:
pipeline, entrypoint_job_run = PipelineFactory.create_pipeline(
pipeline, job = await enqueue_pipeline_for_score_set(
db=db,
name="validate_map_annotate_score_set",
pipeline_params={
"score_set_id": score_set.id,
"updater_id": user_data.user.id,
"correlation_id": logging_context().get("correlation_id"),
},
redis=worker,
pipeline_name="validate_map_annotate_score_set",
score_set=item,
user=user_data.user,
extra_params={"scores_file_key": scores_file_key, ...},
)
db.commit()

await worker.enqueue_job("start_pipeline", entrypoint_job_run.id)
```

This creates a `Pipeline` with multiple `JobRun` records and `JobDependency` records, then enqueues the pipeline's `start_pipeline` entrypoint in ARQ. The worker coordinates the rest — each job runs after its dependencies complete.
`enqueue_pipeline_for_score_set` is the single kickoff seam shared by routers and scripts. It fills `score_set_id`, `updater_id` and `correlation_id`, uses `PipelineFactory` to create a `Pipeline` with its `JobRun` and `JobDependency` records, then enqueues the pipeline's `start_pipeline` entrypoint in ARQ. A failed enqueue discards the just-created pipeline records. The worker coordinates the rest — each job runs after its dependencies complete.

### Job Function Signature

Expand All @@ -155,18 +153,11 @@ Callers pass only `ctx` and `job_id` when enqueueing. The decorator creates the
Correlation IDs flow from the API request through the pipeline to each job:

```python
# In the router — capture correlation ID from starlette-context
from mavedb.lib.logging.context import save_to_logging_context, logging_context
# In the router — save request context; the kickoff seam reads the correlation ID from it
from mavedb.lib.logging.context import save_to_logging_context

save_to_logging_context({"score_set_urn": urn})
correlation_id = logging_context().get("correlation_id")

# Pass to pipeline via pipeline_params
pipeline, entrypoint = PipelineFactory.create_pipeline(
db=db,
name="validate_map_annotate_score_set",
pipeline_params={"correlation_id": correlation_id, ...},
)
await enqueue_pipeline_for_score_set(db=db, redis=worker, pipeline_name="validate_map_annotate_score_set", ...)
```

Each job retrieves the correlation ID from its `job_params` and uses `job_manager.save_to_context()` for structured logging.
Expand Down
13 changes: 7 additions & 6 deletions .github/instructions/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ MaveDB is a bioinformatics database API for Multiplex Assays of Variant Effect (
### Service Architecture
- **FastAPI application** — `src/mavedb/server_main.py`, router-based endpoint organization
- **Background worker** — ARQ/Redis for async processing (variant creation, mapping, publication, annotation)
- **Multi-container setup** — API server, worker, PostgreSQL, Redis, plus external services (cdot-rest, dcd-mapping, seqrepo)
- **Docker config** — `docker-compose-dev.yml` (6 services), multi-stage `Dockerfile`
- **Multi-container setup** — API server, worker, PostgreSQL 15, Redis, moto (local S3), plus external services (cdot-rest, dcd-mapping, seqrepo)
- **Docker config** — `docker-compose-dev.yml` (9 services), multi-stage `Dockerfile`

### Core Domain Model
- **Hierarchical URN system**: ExperimentSet (`urn:mavedb:00000001`) → Experiment (`00000001-a`) → ScoreSet (`00000001-a-1`) → Variant (ScoreSet URN + `#` + number)
Expand Down Expand Up @@ -41,8 +41,8 @@ src/mavedb/
├── worker/ # ARQ background worker system
│ ├── jobs/ # Job function implementations (by category)
│ │ ├── registry.py # Central registry of all jobs, cron definitions
│ │ ├── variant_processing/ # Variant creation and mapping
│ │ ├── external_services/ # ClinGen, ClinVar, gnomAD, UniProt
│ │ ├── variant_processing/ # Variant creation, mapping, reverse translation
│ │ ├── external_services/ # ClinGen, ClinVar, gnomAD, UniProt, VEP
│ │ ├── pipeline_management/ # Pipeline entrypoint (start_pipeline)
│ │ └── system/ # Cron maintenance (cleanup stalled jobs)
│ ├── lib/ # Infrastructure layer
Expand Down Expand Up @@ -143,7 +143,7 @@ poetry run python -m mavedb.scripts.<script_name>

- [score_set.py](src/mavedb/models/score_set.py) — Primary data model patterns
- [score_sets.py](src/mavedb/routers/score_sets.py) — Complex router with worker integration
- [jobs.py](src/mavedb/worker/jobs.py) — Background processing patterns
- [registry.py](src/mavedb/worker/jobs/registry.py) — Background job registration
- [score_set.py](src/mavedb/view_models/score_set.py) — Pydantic model hierarchy
- [server_main.py](src/mavedb/server_main.py) — App setup and dependency injection
- [authentication.py](src/mavedb/lib/authentication.py) — Auth patterns
Expand Down Expand Up @@ -222,9 +222,10 @@ poetry run python -m mavedb.scripts.<script_name>
- **Key job types**:
- `create_variants_for_score_set` - Parse uploaded CSV, create variant records
- `map_variants_for_score_set` - Map variants via DCD Mapping / VRS
- `reverse_translate_variants_for_score_set` - Derive equivalent nucleotide/protein alleles and projection groups via variant-annotation
- `submit_score_set_mappings_to_car/ldh` - Submit to ClinGen services
- `cleanup_stalled_jobs` - Cron job for recovering stuck jobs
- **Enqueueing pipelines**: Routers call `PipelineFactory.create_pipeline()` then `ArqRedis.enqueue_job("start_pipeline", ...)` with the pipeline's entrypoint JobRun ID
- **Enqueueing pipelines**: Routers and scripts call `enqueue_pipeline_for_score_set()` (`src/mavedb/lib/workflow/kickoff.py`), which creates the pipeline via `PipelineFactory.create_pipeline()` and enqueues its `start_pipeline` entrypoint JobRun
- **Detailed documentation**: See `src/mavedb/worker/README.md` and `.github/instructions/worker.instructions.md`

### View Models (Pydantic)
Expand Down
19 changes: 14 additions & 5 deletions .github/instructions/database.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ applyTo: 'src/mavedb/models/**/*.py,alembic/**/*.py'
## Model Structure

### Base Class
All models use `@as_declarative()` with a shared `Base` class providing:
- `id`: Integer primary key (auto-increment)
- `creation_date` / `modification_date`: Auto-managed timestamps
- `created_by_id` / `modified_by_id`: Foreign keys to users table
All models subclass the `@as_declarative()` `Base` in `src/mavedb/db/base.py`. It declares no columns; it only defaults `__tablename__` to the lowercased class name. Table models declare their own `id` primary key and set `__tablename__` explicitly; view models map `__table__` to a view instead.

### Common Columns
Most resource models include:
- `creation_date` / `modification_date`: `Date` columns defaulting to today (`modification_date` updates on write)
- `created_by_id` / `modified_by_id`: Foreign keys to the users table (user-owned resources: experiment sets, experiments, score sets, calibrations, calibration controls, collections)
- `urn`: Unique string identifier (temporary `tmp:<uuid>` or permanent `urn:mavedb:...`)
- `private`: Boolean flag for visibility control
- `approved`: Boolean for moderation status
Expand Down Expand Up @@ -50,6 +49,16 @@ class ScoreSetPublicationIdentifierAssociation(Base):
primary = Column(Boolean, default=False)
```

### Valid-Time Versioning (`ValidTime`)
Rows that change over time mix in `ValidTime` (`src/mavedb/db/mixins.py`) instead of being updated or deleted in place:
- `valid_from` / `valid_to`: a row is live while `valid_to` is NULL; history is the half-open window `[valid_from, valid_to)`.
- Reads: filter explicitly with `Model.current` or `Model.live_at(as_of)` (`None` means current; also works on `aliased()` classes). Never assume a query returns only live rows.
- Replacing a row: `supersede_with` (one row) or `supersede_live_where` (bulk) retire the old rows and stamp the new rows' `valid_from` with the same timestamp, so the handoff has no gap. Never retire and then insert separately.
- Withdrawing with no successor: `retire` (one row) or `retire_live_where` (bulk UPDATE).
- `__retire_cascade__`: relationship names whose live `ValidTime` children are retired when the parent is (one level deep). `supersede_live_where` raises on a class that declares it; use `supersede_with` per row.
- Each table adds a partial unique index over its natural key `WHERE valid_to IS NULL`, so a second live row raises `IntegrityError`.
- Content-addressed, immutable rows (e.g. alleles) do not use the mixin.

### Enum Columns
Use non-native enums stored as strings:
```python
Expand Down Expand Up @@ -121,4 +130,4 @@ if item.private and not user_has_access(user, item):
```

## Materialized Views
Used for pre-computed aggregations. Refresh via worker cron jobs defined in `src/mavedb/worker/settings.py`.
Used for pre-computed aggregations. Refresh via worker cron jobs defined in `src/mavedb/worker/jobs/registry.py`.
9 changes: 5 additions & 4 deletions .github/instructions/worker.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Always return using factory methods:

```python
return JobExecutionOutcome.succeeded(data={"variants_created": count})
return JobExecutionOutcome.failed(reason="No mapped variants found", data={...})
return JobExecutionOutcome.failed(reason="No mapping records found", data={...})
return JobExecutionOutcome.failed(reason="HGVS parse error", failure_category=FailureCategory.DATA_ERROR)
return JobExecutionOutcome.skipped(data={"reason": "Feature disabled"})
# For unhandled exceptions: let them propagate — the decorator catches and creates .errored()
Expand Down Expand Up @@ -124,11 +124,12 @@ Parameters with `None` values in pipeline definitions are filled at runtime from
- **Slack safety**: `send_slack_job_failure()` and `send_slack_job_error()` catch their own exceptions internally (logging critical on failure), so Slack outages never interfere with job lifecycle management or error recovery in the decorators.
- **Stale RUNNING recovery**: `start_job()` accepts RUNNING as a startable status (alongside QUEUED and PENDING). When ARQ re-delivers a job after a worker crash, `start_job()` logs a warning and resets the start timestamp rather than raising `JobTransitionError`.
- **Concurrency limit**: `max_jobs = 2` in `ArqWorkerSettings` prevents event loop starvation from sync psycopg2 DB calls. With the default `max_jobs=10`, multiple concurrent jobs issuing blocking DB operations can starve the asyncio event loop.
- **Fast lane**: `start_pipeline` and `create_variants_for_score_set` run on a separate queue (`FAST_LANE_QUEUE_NAME`) consumed by a second worker process (`ArqFastLaneWorkerSettings`), so long mapping jobs can't block new pipelines. Every `enqueue_job` and every `arq.jobs.Job(...)` status/abort call must pass `_queue_name=arq_queue_name(job_run)`.

## Pipeline Lifecycle (Brief)

1. Router calls `PipelineFactory.create_pipeline()` → creates `Pipeline`, `JobRun`, and `JobDependency` records
2. Router enqueues the `start_pipeline` entrypoint job in ARQ
1. Router or script calls `enqueue_pipeline_for_score_set()` (`lib/workflow/kickoff.py`) → `PipelineFactory.create_pipeline()` creates `Pipeline`, `JobRun`, and `JobDependency` records
2. The same call enqueues the `start_pipeline` entrypoint job in ARQ
3. `start_pipeline` runs → its `@with_pipeline_management` decorator starts the pipeline and calls `coordinate_pipeline()`
4. `coordinate_pipeline()` finds PENDING jobs whose dependencies are met → marks them QUEUED → enqueues in ARQ
5. Each job runs → after completion, its decorator calls `coordinate_pipeline()` again
Expand Down Expand Up @@ -181,7 +182,7 @@ Pipeline definitions live in `src/mavedb/lib/workflow/definitions.py`. The `Pipe
| `lib/managers/pipeline_manager.py` | Pipeline coordination, dependency resolution, job enqueueing |
| `lib/managers/constants.py` | Status groupings (`TERMINAL_JOB_STATUSES`, `STARTABLE_JOB_STATUSES`, etc.) |
| `lib/managers/exceptions.py` | Exception hierarchy (`JobStateError`, `PipelineCoordinationError`, etc.) |
| `settings/worker.py` | `ArqWorkerSettings` class (ARQ worker configuration) |
| `settings/worker.py` | `ArqWorkerSettings` (main) and `ArqFastLaneWorkerSettings` classes (ARQ worker configuration) |
| `settings/lifecycle.py` | Worker startup/shutdown hooks, `standalone_ctx()` |
| `src/mavedb/lib/workflow/definitions.py` | Pipeline and job definitions (`PIPELINE_DEFINITIONS`) |
| `src/mavedb/lib/workflow/pipeline_factory.py` | Creates Pipeline + JobRun + JobDependency records |
Expand Down
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
VENV := .venv/bin

.DEFAULT_GOAL := help

.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " %-12s %s\n", $$1, $$2}'

.PHONY: dev
dev: ## Install deps including local editable variant-annotation
poetry install --extras server

.PHONY: test
test: ## Run the test suite
$(VENV)/pytest tests/

.PHONY: lint
lint: ## Check code with ruff
$(VENV)/ruff check src/ tests/

.PHONY: format
format: ## Format code with ruff
$(VENV)/ruff format src/ tests/
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ To stop the application when it is running as a daemon, run
docker-compose -f docker-compose-local.yml down
```

`docker-compose-local.yml` configures four containers: one for the API server, one for the PostgreSQL database, one for the
worker node and one for the Redis cache which acts as the job queue for the worker node. The worker node stores data in a Docker
volume named `mavedb-redis` and the database stores data in a Docker volume named `mavedb-data`. Both these volumes will persist
`docker-compose-local.yml` configures five containers: one for the API server, one for the PostgreSQL 15 database, two worker
nodes and one for the Redis cache which acts as the job queue for the workers. The fast worker runs only pipeline starts and
variant creation, on its own queue, so new score sets get variants while mapping jobs occupy the main worker. The worker node stores data in a Docker
volume named `mavedb-redis` and the database stores data in a Docker volume named `mavedb-data-15`. Both these volumes will persist
after running `docker-compose down`.

**Notes**
Expand All @@ -88,6 +89,21 @@ after running `docker-compose down`.
The database username and password should be edited for production deployments. `NCBI_API_KEY` will be removed in
the future. **TODO** Move these to an .env file.

2. Optional database and CSV export tuning variables. Times are in seconds, and setting a timeout or `CSV_BUILD_SLOTS`
to `0` disables it. All of them apply only to the API server; the worker, scripts and migrations run without them.

| Variable | Default | Purpose |
|---|---|---|
| `DB_POOL_SIZE` / `DB_MAX_OVERFLOW` | 5 / 10 | Persistent and burst connections per process |
| `DB_POOL_TIMEOUT` | 10 | Longest wait for a free pooled connection before the request returns 503 |
| `DB_STATEMENT_TIMEOUT_SECONDS` | 30 | Longest single statement before the request returns 503 |
| `DB_CSV_STATEMENT_TIMEOUT_SECONDS` | 45 | The same limit for the score set CSV routes |
| `DB_LOCK_TIMEOUT_SECONDS` | 5 | Longest wait for a row or table lock before the request returns 503 |
| `DB_IDLE_IN_TRANSACTION_TIMEOUT_SECONDS` | 60 | Longest idle gap inside an open transaction before Postgres ends the session |
| `DB_SLOW_STATEMENT_SECONDS` | 5 | Statements slower than this are logged with their route |
| `CSV_BUILD_SLOTS` | 2 | Score set CSV builds of `CSV_BUILD_MIN_ROWS` or more rows each process runs at once |
| `CSV_BUILD_MIN_ROWS` | 10000 | Smaller builds skip the cap. A large build waits up to 10s for a slot, then returns 503 with `Retry-After` |

### Running the API server in Docker for development

A similar procedure can be followed to run the API server in development mode on your local machine. There are a couple
Expand Down
Loading
Loading