Patch release. Focus: two additive features (an expanded high-value SNP no-call list and a new chr-prefixed-contig build inference for rsID-less WGS VCFs), two correctness fixes (version-sentinel leak in dev environments, silent-skip ship-gate hole), one partial structural cleanup of enrichment-annotator lifecycle management, and process / docs hardening across the test protocol and README. Cache-format unchanged; existing v2.0.1 caches stay signal-skipped on upgrade.
Upgrade
pip install --upgrade allelix
No cache invalidation. v2.0.2 ships zero schema or interpreter changes — the ClinVar interpreter version stays at 2 (set in v2.0.1). Existing v2.0.1 caches remain current; only the standard allelix db update freshness check runs.
Highlights
- High-value SNP no-call list grows from 12 to 28 entries. Adds thrombophilia (Factor V Leiden, Prothrombin G20210A), hereditary hemochromatosis (HFE C282Y + H63D), cystic fibrosis carrier (CFTR F508del), sickle cell (HBB), BRCA2 Ashkenazi founder, completed warfarin / clopidogrel PGx profiles (CYP2C9*3, CYP2C19*17, VKORC1), CYP2D6*4 (the European LOF allele complementing the existing CYP2D6*10), CYP3A5*3 (tacrolimus, CPIC Level A), TPMT cluster (*3B / *3C for thiopurines), NUDT15 (thiopurine toxicity, East-Asian-enriched), and LRRK2 G2019S (monogenic Parkinson's). Two new clusters surface compound-het patterns the way APOE / MTHFR already do. Data-only — the existing no-call warning machinery consumes the expanded list automatically.
- Build detection gains a chr-prefixed-contig signal for rsID-less WGS VCFs. When rsID-based detection can't converge (variant-caller output has
ID=.) and the header carries no##contig assembly=tag, the parser now records whether contigs were declaredchr1/chrXstyle and uses that as a tertiary signal. Modern callers (DeepVariant, DRAGEN, GATK HaplotypeCaller) overwhelmingly usechr-prefixed contigs on GRCh38; GRCh37 uses bare1/X/MT. The CLI banner now readsBuild: GRCh38 (inferred from chr-prefixed contig names; …)and replaces the previous blind-default warning with a positive informational message that still recommends explicit--buildfor UCSC-hg19 edge cases. Detection covers every standard chromosome (1–22, X, Y, M, MT). --versionand outbound HTTPUser-Agentno longer leak the0.0.0+localsentinel on bare source checkouts. Previously, running Allelix from agit clonewithoutpip install -e .populated the sentinel string into__version__, which then surfaced inallelix --versionoutput and the User-Agent for downloads from NCBI / EBI / HuggingFace. Never visible to users on a normal pip install, but consistently leaked in dev environments. Theimportlib.metadataread stays primary; onPackageNotFoundError, the version is read frompyproject.tomlnext to the package. The sentinel only remains when both paths fail.- No more silent skips on the ship gate. v2.0.1 shipped with "1525 passed, 2 skipped" — the 2 skips were the real-data GWAS Catalog sanity tests silently bypassing when the ~65 MB
test_data/gwas_catalog.zipfixture wasn't downloaded locally. That's a false-clean signal on a release. The fixture now auto-fetches from EBI on first use and caches undertest_data/(gitignored); subsequent runs are offline-fast. Two other defensivepytest.skipguards in the pipeline tests were converted toassert— silent skips would have hidden a real regression there.CONTRIBUTING.mddocuments the new "no silent skips on ship gates" policy.
Known limitations
Carried forward from v2.0.1 — no new structural debt added in this patch.
- ClinVar per-(classification, condition) pairing (v2.1). Multi-SCV variants display the primary aggregate classification plus the union of associated conditions; per-(classification, condition) 1:1 pairing requires the structured
submission_summary.txt.gzexport and is tracked for v2.1. - rsID-bearing input VCFs skip allele-specific GWAS / SNPedia enrichment (v2.1). When on-the-fly rsID resolution doesn't fire because the input already carries rsIDs, the conservative suppress-half stays in effect — restored by the v2.1
Variant.ref/ per-Annotation alt work. - Annotator finalizer cleanup (v2.1). v2.0.2 stack-manages the enrichment annotators inside the analysis pipeline so their cleanup is deterministic, but
Annotator.__del__is retained as a documented safety net until residual ResourceWarnings from code paths outside the main pipeline are audited. - PharmGKB → ClinPGx rebrand (v2.1+). PharmGKB officially rebranded to ClinPGx in July 2025 (redirects live). The allelix-internal annotator name, cache filename, and source string remain
pharmgkbfor backward compatibility; the rename bundles with the next schema-breaking change so users rebuild caches once.
Added
- High-value SNP no-call list: 16 additions. See Highlights above. All 16 verified on at least one consumer-array platform per SNPedia chip listings; all CPIC Level A pharmacogenomic entries are paired with their companion SNPs where the clinical action requires haplotype resolution.
__version__readspyproject.tomlfrom a bare source checkout. Restores accurate version reporting in dev environments without disturbing the standard install path.- Build detection: infer GRCh38 from
chr-prefixed contigs. Tertiary build-detection signal, ordered after override → rsID position-detection →##contig assembly=header, ahead of the previous bare-GRCh37 fallback.
Changed
- Pipeline: enrichment annotators are stack-managed (partial). The analysis pipeline previously context-managed only the primary annotator list; the optional
gnomad=/alphamissense=/cadd=keyword params were used internally but never explicitly closed and relied onAnnotator.__del__for cleanup. All three are now entered into the sameExitStackas the primary annotators.__del__is retained as a documented safety net — see Known limitations. - Test suite: no more silent skips on missing fixtures. See Highlights.
CONTRIBUTING.mdupdated with the new no-silent-skips ship-gate policy.
Fixed — docs / process
- CHANGELOG: duplicate
### Changedsection in the[2.0.1]entry merged. Structural cleanup; no content change. FULL_TEST_PROTOCOL.mdrefreshed across the full v2.0.2 dry-run. Reconciled install-footprint figures (default install ~16 GB, ~22 GB with CADD opt-in), per-source size attributions (gnomAD ~2.7 GB compressed / ~6 GB on-disk, AlphaMissense ~1.8 GB / ~8 GB), Section 19 chr-prefix demo with two new committed fixtures (mock_vcf_no_signal.vcf,mock_vcf_chr_prefix_grch38.vcf), truncation demo using the bundled 3,202-samplethousandG_chr22.vcf.gz, and measured-vs-claimed annotation counts (GIAB GRCh37 ~60-70K vs GRCh38 ~5K reflects upstream NIST file shape — rsID-rich vs rsID-less). Wrong-allele safety check loop now covers all actual battery output filenames; v2.0.2 verification ran 107/107 + 113/113 = 100% allele-direct CADD scores, 0 via-complement.- README Privacy section documents output-file lifecycle. Users know analysis results land on disk under their cwd and persist until they remove them.
Verification
Full pytest: 1540 pass / 0 skip / 0 warnings, 94.13% coverage. Ruff clean. plink2 installed locally so the no-silent-skips invariant was exercised end-to-end on the ship gate.
Real-data battery (FULL_TEST_PROTOCOL.md Section 19) post-db update (upgrade-path verified — only ClinVar refreshed, all others signal-skipped as predicted):
- GIAB GRCh38 truth set (rsID-less, 4,048,342 variants): 4,789 total / 384 default-filter
- GIAB GRCh37 truth set (rsID-rich ~95%, 4,033,796 variants): 65,925 total / 574 default-filter
- HG00187 GATK-HC gVCF (real WGS, 43,737 non-ref from ~19.3M lines): 36 total / 5 default
- 1000 Genomes chr22 multisample (3,202 samples):
MultiSampleErrortruncates correctly;--samplebinding works - Wrong-allele safety invariant (no complement-resolved CADD scores at multi-allelic sites): 107/107 GRCh37 + 113/113 GRCh38 = 100% allele-direct, 0 via-complement