Skip to content

Same-haplotype receptor revision: genotype-aware V replacement - #9

Merged
MuteJester merged 12 commits into
masterfrom
genotype-receptor-revision
Jun 18, 2026
Merged

Same-haplotype receptor revision: genotype-aware V replacement#9
MuteJester merged 12 commits into
masterfrom
genotype-receptor-revision

Conversation

@MuteJester

Copy link
Copy Markdown
Owner

Summary

Makes receptor_revision() genotype-aware: when a genotype is attached, the post-recombination V replacement is drawn from the genotype's carried V alleles on the drawn rearrangement chromosome (same_haplotype=True, default), excluding the current V — and the genotype + receptor_revision rejection is lifted. Follow-on #5 (final) of the genotype roadmap, and the first to touch the engine.

This is haplotype-aware V replacement, not a full model of receptor editing (no genomic V order / RSS / upstream-availability realism); it guarantees the replacement is an allele the individual carries on the relevant chromosome.

What's included

Engine (Rust):

  • AlleleInstance.haplotype: Option<u8> (0/1-asserted) — the drawn rearrangement chromosome, stamped on V/D/J by SampleGenotypePass (per-pass traces are isolated, so the chromosome is threaded through the IR).
  • Genotype-aware ReceptorRevisionPass (GenotypeVConstraint): per-haplotype carried-V candidates aggregated by AlleleId, current-V excluded, same-length filtered; same_haplotype true (drawn chromosome) / false (both, a synthetic control). Coin always consumed (RNG parity); applied = coin AND eligible-nonempty (strict errors / permissive applied=false on empty). commit_replacement preserves the original rearrangement chromosome even under same_haplotype=False. Full replay tamper-set validation + constraint-digest parameter_signature. Strict post-event contracts honored (parity with the non-genotype path), fresh and replay.
  • push_genotype_receptor_revision PyO3 builder with boundary validation (prob, V pool, haplotype, allele-id range, weight finiteness/positivity, copies, mass).

Python (DSL):

  • receptor_revision(prob=..., same_haplotype=True) (bool-validated); genotype-aware lowering against the effective refdata (carried novel V alleles are valid targets).
  • Lifted the genotype + receptor_revision rejection in both compile() and run_cohort(); genotype + clonal-fork stays rejected.

Docs: "Receptor revision with a genotype" guide section; removed from Limitations.

Invariants

  • No-genotype receptor_revision is byte-identical to today (genotype_v=None dispatch; non-genotype commit_replacement calls pass haplotype=None).
  • original_v_call / receptor_revision_applied AIRR fields unchanged; v_call/truth_v_call are post-revision.
  • With a genotype, the revised V is always a carried allele on the drawn chromosome (same_haplotype) and differs from the original.

Test plan

  • Rust: 30 receptor_revision unit tests + sample_genotype stamping + AlleleInstance field/assert — candidate restriction, exclude-current, both-haplotype, empty (strict/permissive), replay tamper set (incl. unresolvable id → missing_allele), strict post-event contract rejection (fresh + replay), signature. cargo green across 6 binaries.
  • Python: genotype + receptor-revision truth-based (revised V carried on the drawn chromosome ≠ original), deterministic cross-chromosome pin for same_haplotype=False, novel-allele target, cohort + revision, bool validation, lifted rejections; no-genotype path unchanged.
  • Full Python suite green (2453 passed).
  • Three review rounds (spec-compliance + two critic passes); findings fixed with regression tests.

@MuteJester
MuteJester merged commit 60bc660 into master Jun 18, 2026
13 checks passed
@MuteJester
MuteJester deleted the genotype-receptor-revision branch June 18, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant