Paraphase STRC rewrite validation

This lane tests whether Paraphase’s Rust rewrite preserves the last Python STRC/STRCP1 caller on public data. It deliberately separates four questions:

  1. v3.1.2 (f4630d2) — baseline used for the published Paraphase validation.
  2. v3.5.0 (c8016df) — immediate pre-Rust parity oracle.
  3. v4.0.0 (324b00e) — tagged Rust rewrite.
  4. main (68abd72 at intake) — current upstream code.

A v3.1.2/Rust difference can be an intentional Python-era change. A v3.5.0/Rust difference is the rewrite-regression gate.

Public fixture

Sample: HPRC/HGSVC HG00733.

Source BAM:

https://s3-us-west-2.amazonaws.com/human-pangenomics/working/HPRC_PLUS/HG00733/analysis/aligned_reads/hifi/GRCh38/HG00733_aligned_GRCh38_winnowmap.sorted.bam

Source BAM MD5: 871ee1d8f75241a9087fc08845a46c9d.

The repository already ships tests/data/jsons/HG00733.json.xz, whose STRC call is a 2+2 result: two STRC copies, two STRCP1 copies, and intergenic depth 35. It does not ship the matching STRC BAM fixture or test.

Two fixture modes are generated:

  • locus: STRC, STRCP1, and intergenic region (chr15:43599000-43719466). Small enough for an upstream regression test with injected genome depth.
  • depth-union: locus plus every genome-depth probe used by the pinned Python and Rust versions, including each probe’s +1600 position. This is the compact CLI differential input.

The upstream-sized locus fixture has 328 reads. Its deterministic hashes are:

  • BAM SHA-256: 5921d64fc38ed81b99624b1eacfd557f28edf65b1cde624ee09fb2daf917cfc6
  • BAI SHA-256: bbde38b71970c41ad68da4c81bc299711f9a537d1f941186210254090d810a92

Two independent rebuilds produced identical BAM and BAI bytes. The generator uses one sort thread and suppresses the path-bearing sort @PG record.

Generate the full compact fixture with the pinned Python environment:

worktrees/v3.5.0/.venv/bin/python scripts/fetch_fixture.py \
  --mode depth-union \
  --output data/fixtures/HG00733.strc-depth.GRCh38.bam

HG005 locus/CN truth gate

HG005 adds an orthogonal identity gate after PR #83. The public input is NIST GIAB’s approximately 30-fold Sequel II CCS (HiFi) alignment, generated with the pbmm2 CCS preset against GRCh38_no_alt_analysis and haplotagged with WhatsHap:

https://ftp.ncbi.nlm.nih.gov/ReferenceSamples/giab/data/ChineseTrio/HG005_NA24631_son/PacBio_SequelII_CCS_11kb/HG005_GRCh38/HG005_GRCh38.haplotag.10x.bam
  • Published BAM MD5: ec0bbf687f0fd5d0053cbeb761111deb.
  • Published and locally verified BAI MD5: b1c28c3258e4f0f097ff6a4c6fa3ed43.
  • Official checksum manifest: md5sum.txt.
  • Official alignment methods: README.txt.
  • Raw-read BioProject: PRJNA540706.

The generator downloads the 11 MiB BAI, verifies it, and uses indexed HTTPS range requests. It does not download the 65,301,662,997-byte source BAM. The commit-depth mode includes the complete STRC/STRCP1/intergenic locus plus both depth positions used for every genome probe embedded at Paraphase commit 6e36104a8d9762a17ac373a0d163293ec49451c3:

worktrees/v3.5.0/.venv/bin/python scripts/fetch_fixture.py \
  --sample HG005 \
  --mode commit-depth \
  --paraphase-commit 6e36104a8d9762a17ac373a0d163293ec49451c3 \
  --output data/fixtures/HG005.strc-depth.GRCh38.bam

The truth target comes from the MLPA- and divergent-marker-refined NIST sample benchmark in Tsai et al.: total CN 4, STRC CN 3, STRCP1 CN 1, and NM_153700.2:c.5125A>G (GRCh38 chr15:43600074 T>C) on exactly one STRC copy. This is a locus/CN identity gate only. It makes no assertion about pathogenicity.

Run an isolated local clone detached at the exact commit twice and check the gate:

scripts/run_hg005_gate.sh

To validate a later compatible commit, pin its full SHA explicitly:

PARAPHASE_COMMIT=<full-commit-sha> scripts/run_hg005_gate.sh

The checker derives Paraphase’s genome-depth probe intervals from that exact commit and rejects a fixture whose interval hash does not match. This prevents a green result obtained with fixture bytes prepared for different depth probes.

The 2026-08-08 gate passed without discrepancies:

  • The 7,463-read commit-depth fixture is 51,665,750 bytes. BAM SHA-256: 7d66b7eaedaeabd63085a247baf0b56789af99c3a89df23de1a4810c04312dd2; BAI SHA-256: c9bdee86495bcbea6e8c98aaada7d02c578b2c75545a320e5fe3157bd9288020.
  • Two exact-commit runs produced byte-identical JSON (SHA-256 1b6fc27923f611f74dc0f02c28f67ebf1054c9971be611d4759adb003e1d073b).
  • Both runs called total CN 4, STRC CN 3, STRCP1 CN 1, genome depth 34, intergenic depth 34, and 43600074_T_C on exactly one STRC copy (strc_strchap3).
  • A local replay of the complete extraction produced byte-identical BAM and BAI files. This is an idempotence check, not a second remote extraction.

For an upstream test with injected genome depth 34, derive the locus-only file locally from the complete fixture:

worktrees/v3.5.0/.venv/bin/python scripts/fetch_fixture.py \
  --sample HG005 \
  --mode locus \
  --source-path data/fixtures/HG005.strc-depth.GRCh38.bam \
  --output data/fixtures/HG005.strc.GRCh38.bam

The locus fixture has 524 reads and is 3,563,831 bytes. BAM SHA-256: 030e1e35b2c6d8c11b07c0580bb1aa929d199c0026f83b1e67a7bca9860efc6e; BAI SHA-256: 8afb34b8910163db60367f815ac6ddffb0552d39234e344ac402cfe93350c446. Two local builds were byte-identical. It is suitable for the same injected-depth integration-test pattern used by PR #83 and is the same size class as the existing HG00733 fixture. The exact-commit library test passed directly:

scripts/run_hg005_locus_gate.sh

Result: one test passed, zero failed, with genome depth 34 injected into the 524-read locus fixture.

The complete machine-readable receipt is evidence/2026-08-08-hg005-truth-gate.json.

Exact reference

Use PacBio’s GRCh38 no-alt analysis set:

https://downloads.pacbcloud.com/public/reference-genomes/human_GRCh38_no_alt_analysis_set.tar.2023-12-04.gz

FASTA MD5: 30f1a99359a5993edbf8c8bc885825a7.

Run

scripts/run_matrix.sh

The runner creates a new timestamped output directory, executes each version twice with one thread, and writes normalized comparisons. It never deletes or reuses an existing run directory.

Result

The 2026-08-08 matrix passed every required gate on the 6,463-read depth-union fixture:

  • Each of v3.1.2, v3.5.0, v4.0.0, and main reproduced exactly across two runs.
  • v3.5.0, v4.0.0, and main were semantically identical after canonicalizing haplotypes by sequence instead of numeric label.
  • All three called total CN 4, STRC CN 2, genome/intergenic depth 31, region depth 71/82, and one two-copy STRCP1 haplotype.
  • v3.1.2 differed from v3.5.0 in sites and haplotype details before the Rust rewrite; this is not a rewrite regression.
  • Maternal and paternal phased assemblies each had one primary MAPQ-60 alignment with aligned bases across the complete STRC and STRCP1 targets.

The repository’s older HG00733.json.xz is not a byte-matched oracle for this fixture. Its STRC reads come from the m64076_2021 campaign; the public aligned BAM used here contains m54329U_2019 reads, with zero read-name overlap. The apparent depth delta (35 versus 31) and apparent extra indel were cross-input differences. Same-input Python v3.5 and Rust both report depth 31 and include 43605121_CAG_C.

The replacement v3.5 same-input oracle has uncompressed SHA-256 8429a32ec7f2990480f5a0803b21b0f32db891a7f6a483da347e2fcbd2680156 and records genome/intergenic depth 31 from the current public input.

Concise evidence is in evidence/2026-08-08-parity-summary.json; the complete normalized report is in outputs/run-20260808T024621Z/comparison.json.

The test-only contribution is published as PacificBiosciences/paraphase#83 at commit c0f31672dc8ebbc727aba830f911dfb23183cc36. It now also requires every emitted locus label to agree with the two configured identity markers.

The production abstention fix and independent HG005 truth test are published as PacificBiosciences/paraphase#84 at commit 0063b992032e5bb0f297a492d43683b5005309e7. Its full exact-reference suite passed 145 tests. A detached clone of the published head reproduced the HG005 call byte-for-byte across two runs; the concise receipt is evidence/2026-08-08-pr84-validation.json.

Contribution gate

  • If v3.5.0, v4.0.0, and main agree: prepare a test-only PR with the public locus BAM/BAI and a focused strc_ok integration test using a same-input v3.5 oracle.
  • If they differ: minimize the discrepancy, use the phased HG00733 assembly alignments as truth, and include only the fixture, failing regression, and minimal production fix.
  • Agreement is compatibility evidence, not independent biological validation.