RM index, items 200–299¶
One page of the RM index, which is paged by number: every item numbered
200–299, under the status or round heading it had when the index was one file. The rules
for adding an entry, and the allocator that claims a number, are on the index page.
⏳ Open, no release decided — ROADMAP.md § Active items¶
Four items as of 2026-08-21 (RM103's manifest half, RM108 and RM110 here, plus RM117's observability half indexed under its own session below), and the heading was kept while it was empty. Three of the four — RM110, RM103's manifest half and RM108 — shipped on 2026-08-31 in the uncut 0.7.0; RM117 is the one still open, and the rows below carry their own status. The count in this sentence is dated on purpose: it says what the decision round left, not what is open now, and the ✅/⏳ on each row is what answers that. It held six until the 2026-08-21 decision round, whose whole content was that every one of them was a decision nobody had made: RM102 closed outright (→ ROADMAP_HISTORY), RM122 parked on demand (→ the deferral file), RM117 narrowed to its free half, and RM103 split, with the refusal moved to ROADMAP § The 1.0 cleanup. What is left is four minors whose shape is settled and whose release nobody has argued — a different thing from what this heading used to hold, and worth the distinction: two of the six were never design-blocked, one by a test that already pinned the answer and one by a record that held no incident. Items whose release nobody has argued yet belong
here rather than in a ROADMAP_0_8/ROADMAP_1_0 file. Nothing is open under this heading as of
2026-09-11 — RM164 was the last, and its section moved to the 0.8 file the day someone asked which
150+ items were open without a release; the heading stays because the allocator writes a new
reservation under it. And the section exists because there was nowhere to index one — every other heading names a release or a terminal state, so RM88 and RM89
would have been filed into a document this index could not point at, which is the exact failure this
file was written to make impossible. Both have now left it: RM89 the next day, closed by the
consumer answer it was waiting on, and RM88 in 0.6.1 once the policy it was really blocked on was
decided. Both stay indexed under their release below, because an item that shipped is exactly what
this index exists to still be able to find — and the heading stays for the next item filed before its
release is argued.
Five of the rows below arrived at once, out of a batch of six: RM163–RM168, the 2026-09-01 source-adoption round. RM168 shipped the same day and is indexed under the 0.7 build round above. They answer one question — what else should we adopt as enrichment sources, besides CIViC and PubMind — and they were unusual for this heading in that none of them had been probed when they were filed. Each stated its measured half (a table kind with no provider, a snapshot's actual contents, a number from a probe already run) separately from its candidate half, and none asserted a licence.
All six were probed the same day, and decided with the maintainer that evening — the round is PROPOSAL_0_7_PT2, which is a record rather than a plan and wins over the entries below. Five build inside the uncut 0.7.0 and RM164 parks on a measured negative, having spun off RM171, which shipped two days later. The keeper from the round: five of the six entries said something their own probe contradicted, and four of the six verdicts the proposal drafted were then overturned in the maintainer pass — so an unprobed entry is a question, and a probed one is still only a proposal.
- ✅ RM299 — SHIPPED 2026-09-27 on
main, uncut — a patch, owner format, severity low.Stats.clinvar_count/pathogenic_count/benign_countdescriptions now say they count authored rows (one per genotype) of a legacy boolean that folds a tier pair; value unchanged. · from S123 · also in CHANGELOG, CONSUMER_SUGGESTIONS_HISTORY - ⏳ RM298 — open, a minor, release undecided, owner format + enricher, severity medium. A per-row source column for
pharm_variants.csv, so the ClinPGx currency check can tell a withdrawn annotation from a row that never cited one; lets RM297's withheld finding block again. · from RM297, S122 · also in CONSUMER_SUGGESTIONS_HISTORY - ✅ RM297 — SHIPPED 2026-09-28 on
main, uncut — a patch (warn, never block; decided 2026-09-27), owner enricher, severity medium. A citedannotation_idthe ClinPGx snapshot lacks stops the lookup and is reported with its three readings; a row citing none is reported on a category/triple difference; neither refuses understrict, both count as findings (ClinPgxResult.withheld). The per-row fix is RM298. · from S122 · also in CONSUMER_SUGGESTIONS_HISTORY - ⏳ RM296 — open, a minor, release undecided, filed only. Owner format + compiler, severity medium. A PRS has no percentile/Z → conclusion table;
pgs.csvrestates the PGS Catalog. AMeasureBinRowkind keyed onpgs_id, with the reference distribution and unit as part of the claim, ancestry mismatch withheld, andresearch_tierconstraining the conclusion. · related RM16, RM47 - ⏳ RM292 — open, a minor, for
0.8, filed only. Owner format + enricher, severity high. Postmortem M3: every check states what it checks and what it checks against; same source reads self-consistent, never verified; a tolerance counts its undecided class. Registry field, roster equality. · related RM267, RM270, RM274 - ✅ RM295 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner docs/reference_examples, severity low.cyp2d6_structural's CYP2D64 row moved from22:42127941(GRCh38 hasG) to22:42128945(rs3892097), example re-closed; it now joins ClinVar in RM291's test. · related* RM291 - ✅ RM291 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch (a test only), owner compiler, severity high. Every GRCh38 reference example is compiled and joined on(chrom, pos, ref, alt)against a bcftools-normalized ClinVar slice, expected set by haplotype equality; 614 distinct allele keys join, the SHOX pair (2) is pinned to RM270; the one ref disagreement it found was RM295, fixed. M4. · related RM270, RM295, RM267, RM273 - ✅ RM290 — SHIPPED 2026-09-29 on
main, uncut — a patch, owner schema + compiler, severity low.OverlayTarget.vindication(sole/withheld/none+ reason) replaces the one-table constant: concordancesole,resolution.csvwithheld, the seven merged tablesnone; no finding moves. Thegene_validitycase is a value comparison, filed as RM311. · related S60, RM117, RM311 - ✅ RM289 — SHIPPED 2026-09-28 on
main, uncut — a patch, owner format + enricher, severity low.PgsRow.training_ancestrynow says developed and evaluated in (the PGS Catalog'sdevandevalstages, which RM163's check compares), and the unknown-terms skip quotes the source's recordednoticeand URL and says no declared use changes it. Postmortem P15. · related RM163, S99 - ⏳ RM288 — open, a minor, release undecided, filed only. Owner enricher, severity low. RM101's exemption block holds the only record:
cpic_build,pharmvar_buildandpgx_draftmake callers enumerate an exception family. One catchable base, or keep the list and record why. Postmortem P14. · related RM101, RM96 - ⏳ RM287 — open, a minor, release undecided, filed only. Owner enricher, severity low. RM39's explicitly requested ClinGen snapshot, never filed: no lane exists, so an offline deployment never runs the dosage pass. Postmortem P14. · related RM39, RM38
- ⏳ RM286 — open, a minor, release undecided, filed only. Owner format + enricher, severity low. RM38 handed PharmVar's research-use/personal-key axis to RM27, which closed record-only without it; the restriction is
noticeprose. A new optionalSourceRowcolumn is minor-legal (RM38's 1.0 sizing rested on digest movement). Postmortem P13. · related RM38, RM27 - ⏳ RM285 — open, a patch, two decisions first, filed only. Owner enricher, severity low. RM171's 'still open' list, never filed: read the legend behind
VUS*, decide whether the unrated-miss identities earn rows. The rCRS anchoring of the:deletions shipped as RM293. Postmortem P12. · related RM171, RM273, RM293 - ⏳ RM284 — open, a minor, release undecided, filed only. Owner format + enricher, severity low. RM72's unopened question: a skip does not displace an earlier answer, so the fact that today's run could not reach a source is dropped; it needs a run-level place. Postmortem P11. · related RM72, RM272
- ⏳ RM283 — open, a minor, release undecided, filed only. Owner enricher, severity medium. RM175's 'honest remainder', unnumbered: the lane records only
CREATED_*.txt, so an archive that stops being rebuilt is invisible. Record S3Last-Modifiedinrelease.jsonand compare it with the sibling archives. Postmortem P10. · related RM175, RM173 - ⏳ RM282 — open, a minor, release undecided, parked on a terms-first survey, filed only. Owner enricher, severity low. RM166's 'its own entry': ClinPGx, CPIC and PharmVar are all CC BY-SA no-sale, so a commercial author has no PGx source. Parked on a survey chosen for terms first, satisfiable now. Postmortem P9. · related RM166, RM281
- ⏳ RM281 — open, a minor, release undecided, filed only. Owner enricher, severity low. RM166's 'its own number': the PGx lane builds from one ClinPGx archive, and
clinicalVariants.zip(~5,190 rows, comma-combiningtype) bears onpharm_variants.csv. Postmortem P9. · related RM166, RM173, RM175, RM282 - ✅ RM280 — SHIPPED 2026-09-28 on
main, uncut — a patch, owner enricher, severity low. grpc's own retry is off on the Atlas channel (it capped at five and would have multiplied under a second layer);AtlasClient._callretries underattempt_floor(5)with upstream's backoff, soJUST_DNA_HTTP_RETRY_ATTEMPTSreaches it, and retries exactly what_translatecallsAtlasUnavailable,INTERNALincluded. The pacing gate is RM307. Postmortem P8. · related RM192, RM194, RM307 - ✅ RM279 — SHIPPED 2026-09-28 on
main, uncut — a patch, owner compiler, severity low. Avariants.csvconclusion that names genotypes at its own locus and never its own is ahint/lint_rowswarning; 10 of 10 real over 653,706 rows after three measured exclusions (an rsID's allele description, a haplotype, the row's gene symbol). D14; postmortem P7. · related S68, RM308, RM309 - ⏳ RM278 — open, a minor, for
0.8, filed only. Owner compiler, severity low. RM218's open question, tracked nowhere:compileexposes neitherensembl_referencenorba1_threshold, so no CLI-compiled manifest can record its reference. Add both or state why not, and maketest_cli_parity.pyassert the decided set. Postmortem P6. · related RM218 - ✅ RM277 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner compiler + enricher, severity low. The literature pass re-fetches a pinned citation whose quote count no longer matchesstudies.csv(recomputing the count in place was refused: it would attach the old verdict to new quotes), soquote_counter_stale's remedy, re-run the pass online, is now true. P5. · related RM119, S56 - ⏳ RM294 — open, a minor, release undecided, owner format/enricher, severity low. Whether STRchive's evidence grade travels into the module (authored column at full price against an open upstream vocabulary, a derived sidecar, or provenance). RM276's minor half. · related RM276, RM170
- ✅ RM276 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity medium.draft-repeatsnames a drafted locus STRchive grades Refuted/Disputed (DMD, DIP2B, NIPA1, POLG) and counts Provisional apart, reading the grade privately off the catalogue file (aStrchiveLocusfield would be minor). P4. · related RM294, RM170, RM165 - ⏳ RM275 — open, a minor (re-sized 2026-09-27: a new warning code is a closed-vocabulary member a 0.7.2 reader refuses), filed only. Owner compiler, severity medium. RM107's unfiled remainder:
frequencies,gene_metrics,literature,gene_validity,clinical_assertions,gwas_effects,expression_effectshave no duplicate key; reproduced with a definitive/refutedgene_validitypair that compiles green under--strict. Warn now, derived from the merge key; refuse at 1.0. Postmortem P3. · related RM107, RM109, RM124, RM130 - ✅ RM274 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity medium. A same-size different-content indel (hosting arm 9) is settled against the GRCh38 reference: the locus event is slid across its repeat and the genotype's payload is looked for among its spellings; kept if found, dropped and named if not, undecided when unreadable. P2. · related RM31, RM272, RM270, RM273 - ✅ RM293 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity low. The miss lane anchors MITOMAP's 39:deletions on the vendored rCRS (checked against it) and joins them: unmintable 47 → 8, rated_miss 1 → 2. The three Principle-2 texts corrected. · related RM273, RM171, RM285 - ✅ RM273 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity high. Three enricher surfaces stop keying an indel on its spelling: the MITOMAP increment joins on events left-aligned against a vendored rCRS (rated misses 6 → 1), CIViC left-aligns a ClinGen-anchored indel, and PubMind's warning states 5,158 of 20,006 indel rows shift left. P1. · related RM270, RM171, RM153, RM134, RM293 - ⏳ RM272 — open, a minor, for
0.8, owner enricher, severity low. The rsIDs RM268 (anchor base unreadable) and RM271 (non-base alleles) withhold are named only by a log warning onmain, since a newEnrichmentResultfield is minor-class; add it besideunreachable_rsids/allele_mismatches. · related RM268, RM271 - ✅ RM271 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity medium. One private predicate at both Ensembl rungs and all four snapshot reads: a non-baseref(dbSNP_novariation,dbSNP_variant, an N-masked chrY ref,<Y>) withholds the locus, a non-base alt (<.>,<R>, empty, anNrun) is dropped, no alt left withholds. REST's all-withheld is the answered-empty[];altsnarrows for e.g.rs33946775. Found closing RM268. · related RM268, RM272, RM267 - ⏳ RM270 — open, a minor, release undecided, owner enricher + compiler, severity high. The format names no indel normalization and the compiler cannot apply one (P2), so an indel's
variant_keyis its source's spelling and a left-aligned VCF misses a respelled row (rs333CCR5-Δ32 among S120's three). The enricher'svrs_idis identical across the two spellings (probed) and distinct for RM267's wrong event, but never reaches a variant parquet. Build: left-normalize enricher fills, carryvrs_idto the parquet, stamp a checked verdict. S120. · related RM267, RM31 - ⏳ RM269 — open, 1.0 (a P8 demotion), owner format, severity low.
haplotype_bis required, so a hemizygous call (G6PD in a male) has nodiplotypes.csvrow, while CPIC's own table spells 187 G6PD rows as one haplotype. A sentinel name is accepted today and indistinguishable from an allele; aploidycolumn would make old readers readB/Bas homozygous. A haplotype-keyed table is the minor-legal fallback if a corpus needs it first. S119. · related RM52 ledger - ✅ RM268 — SHIPPED 2026-09-27 on
main, cut 2026-09-27 asv0.7.3— a patch, owner enricher, severity medium._loci_from_restanchors a one-sided REST indel on the base atstart - 1viaclingen_allele.anchor_indel(probed: insertions-/Cwithstart = end + 1, deletionsAGTAAG/-), sors8176719resolves to9:133257521 T>TC; an unreadable base withholds the locus, and an all-withheld answer is(None, source), named by its own warning (a structured list is RM272, minor). The GraphQL rung hands one-sided nodes to REST. Found reproducing S117. · related RM267, RM153 - ⏳ RM267 — open, a minor, release undecided, owner enricher (+
just-dna-pipelinesupstream), severity high. Ensembl's own VCF dump placesrs8176719(ABO O1) at520 G>GC, a different haplotype from ClinVar/dbSNP/REST's521 T>TC; across seven checked insertions the dump's POS is RESTend− 1. No check here sees it (the anchor base is a real base; RM31 makes indel position differences undecided). A withholding cross-check against ClinVar/REST fits this tier; writing the corrected spelling wants a provenance column, hence minor. S117. S121 (addendum) makes candidate 4 the general rule: ClinVar is loaded in the same run and used only as a fallback, never as a witness, so compare every two-authority placement (byvrs_idwhere mintable) and withhold on disagreement, recording the witness per row. · related RM31, RM268, RM270 - ⏳ RM266 — open, a minor, release undecided, owner compiler, severity low.
diplotype_phase_ambiguousalready computes the phase-confusable pair set (reproduced onhfe_compound_het:C282Y/H63D, C282Y-H63D/wt) but flattens it to a three-example-capped warning string, so a non-caller reader cannot recover it.@dont-discard-computed, not an authored RM28 axis — the set is derived and should be surfaced structurally (a manifest field or small parquet). S116 note 2. · related RM28, ROADMAP § D3/D4 - ⏳ RM265 — open, a minor, release undecided, owner compiler/format, severity medium. On the
replaced=Truebranchpanel_block_deprecatedfires whether or not the author needsgenes/significance/reference_sha256, and there is no "accepted" key: warn forever, or drop provenance the format says has no home. The design question is whetherpanel:is deprecated whole or only its reader; a home for the three fields is the P3-clean minor, a conditional warning the patch stopgap that hides the 1.0 loss. S114. · also in ROADMAP § D19, ROADMAP_1_0 § RM4 row - ✅ RM264 — SHIPPED 2026-09-25 on
main, cut 2026-09-27 asv0.7.3— a patch, owner format, severity medium. The 0.7.x mitigation half of RM256:quotes_found/quotes_uncheckeddescriptions send the reader toabstract_only_countand name no new field; a FAQ entry gives the per-rowquote_sourcereading. Nothing added, removed or retyped. S109. - ⏳ RM263 — open, a minor, release undecided, owner enricher, severity low. DOI → PMID as an RM50-shaped advisory via Europe PMC search; open question is whether a Crossref/PubMed title disagreement warns. S113.
- ✅ RM262 — SHIPPED 2026-09-25 on the
0.8branch, uncut, owner enricher, severity medium.CrossrefClient.work→CrossrefWork: a DOI lookup names the paper off the requestexistsalready made; an HTML 200 now withholds instead of reading asTrue. S113. - 🔵 RM261 — open, deferred by the maintainer as risky, owner enricher, severity low. Stripping comments from the wheel measured −22% zipped; line numbers must be kept, and it reaches the enricher only. Removing the builders from the wheel was refused because
cache rebuildfrom a pip install is a documented deployment. - 🕓 RM260 — the split SHIPPED 2026-09-25 on the
0.8branch, uncut; the shells' removal is 1.0, owner compiler + enricher, severity low.compiler.py(492 KB), the enricher'scli.py(244 KB) andenrich.py(152 KB) are packages under the same import paths; each__init__re-exports every old name, and those shells go at 1.0. - ✅ RM259 — SHIPPED 2026-09-24 on the
0.8branch, uncut, owner enricher, severity low.gene_spans.genes_covering: a GRCh38 position → every MANE gene within the attribution horizon, a query hint never an attribution (50 at HFE H63D). S112. - ⏳ RM258 — open, a minor, release undecided, owner enricher, severity medium. A 5xx reads as "no copy" and the abstract-only row it writes is pinned forever; three candidate repairs, none chosen. Found building RM257 (S110).
- ✅ RM257 — SHIPPED 2026-09-24 on the
0.8branch, uncut, owner enricher, severity medium.PmcBiocClientreads an author manuscript Europe PMC calls closed (tables kept, references dropped) on the E-utilities gate; the licence stays Europe PMC's. S110. - ✅ RM256 — SHIPPED 2026-09-24 on the
0.8branch, uncut, owner compiler, severity medium, sizes as a minor.Literature.quotes_checkedpublishes the quotes a retrieved text settled, from one per-row rule (LiteratureRow.quotes_checked) the enricher's report shares; nulling an abstract miss and redefiningquotes_uncheckedwere both refused. The 0.7.x mitigation split off as RM264 on 2026-09-25 — the field is minor-only, so a patch re-describes the two counters for the released line. S109. - ✅ RM255 — SHIPPED 2026-09-24, released in 0.7.2, owner enricher, severity medium. Frequencies are asked per allele over every locus,
alts=filters, three silent returns became findings, and a population row carries the allele it describes. S108. - ✅ RM254 — SHIPPED 2026-09-21, released in 0.7.2, owner enricher, severity high.
ATLAS_IMPORT_FAILURESbound once and named by all three guards; the[atlas]protobuf floor is the gencode stamp; a third absence sentence. S107. - RM253 — 🔵 open — a minor, release undecided; filed 2026-09-20. Three seams from one report: a repeat count as a defining allele (
<CNV:TR:n>is a length,TA(8)is a count),DEL<bases>/INS<bases>untranslated to<DEL:n>/<INS:n>, and DPYD's HGVS names refused for whitespace. Message halves shipped. S106. - ✅ RM252 — SHIPPED 2026-09-20, released in 0.7.1, owner enricher, severity medium.
effective_declared_usereads the module's own recorded declaration at every gate with a module; the flag still outranks the file. S105. - ✅ RM251 — SHIPPED 2026-09-20, released in 0.7.1, owner enricher, severity medium. An authored pair whose rsID the snapshot knows is recorded from the reference with
ref/alts, so a VRS id mints and the compiler's cross-check compares two independent values. S104. - ✅ RM250 — SHIPPED 2026-09-20, released in 0.7.1, owner enricher + compiler, severity medium.
spec_genome_buildlooks past the scaffold's stubs and nothing else;append_rowsnames the template row and its line. S103. - ✅ RM249 — SHIPPED 2026-09-20, released in 0.7.1, owner enricher, severity medium.
partner_geneson both CPIC clients; the empty-drug explanation gains the pair-keyed arm; the pair count (18 of 103 drugs, six pairs) recorded on RM28. S102. - RM248 — 🔵 open — a RESEARCH item, unsized; asked by the maintainer 2026-09-20. Some kind of report schema (Jinja templates or something) where the contents are static and declarative and the CSS lives downstream. Filed as research because the charter speaks first: the Non-goals say presentation belongs to consumers, so the item's own framing — a report declares CONTENTS, not appearance — is the thing to test rather than assume, and that ruling is the first deliverable. P1 decides the other half: OakVar's reporter modules are Turing-complete and Jinja is a spectrum rather than a safe point on it. Not RM7, which is per-sample evaluation output and therefore a consumer contract. Not a fourth library on today's evidence. Pairs with RM28 — ClawBio's pharmgx-reporter reaches its one AVOID across 59 drugs through
"special": "warfarin", a hardcoded branch, so the report is where RM28's missing multi-subject predicate surfaces — and with RM188, whose ClawBio and genomi surveys already ran. Cheapest first measurement: whatjust-dna-literenders today and which fields a module does not carry. · from the maintainer · also in ROADMAP - RM247 — ✅ FIXED 2026-09-20, shipped in
just-dna-enricher0.7.1 (withjust-dna-compiler0.7.1).uv run just-dna-enricher <anything>raises before Typer:[build-system] requires = ["grpcio-tools>=1.68.0"]is a floor with no ceiling resolved in an isolated build envuv.lockdoes not constrain, so it stampsGRPC_GENERATED_VERSION = '1.84.0'into the generated Atlas bindings while the runtimegrpciois locked at 1.83.1. One number written twice, one pinned and one floating. Blast radius is the whole command surface —cli.pyimportsalphagenome_check→atlas_clientat module scope, soenrich/draft/literaturedie on an Atlas dep they do not use, and 17 test files error during collection (38 importjust_dna_enricher.cli). Reproduced from clean: the generated tree is git-ignored, anduv sync --reinstall-package just-dna-enricherregenerates the same broken stamp — so it arrived with agrpcio-toolsrelease, not a commit here (suite was green at 4658 on 2026-09-13; generated files dated 2026-09-19). Do not bump the runtime floor without re-reading RM192, which measured the Atlas cost at that exact grpcio/protobuf pair. Three candidate repairs argued in the entry: make it one number, import the bindings lazily so a grpcio fault cannot killdraft, and a smoke test that imports the entrypoint the console script does. All three candidate repairs shipped, because the first two are independent defects: the build tool is pinned at the runtime floor (one number, asserted equal, at RM192's measured pair rather than a bump), both module-scopeatlas_clientguards now catchRuntimeErroras well asImportError, and the console entrypoint is imported by a test. A fourth defect surfaced only by installing the wheel:resolverimportsjust_dna_compiler.resolution_findings, a module RM244 added afterv0.7.0, so the wheelModuleNotFoundError'd in a clean venv under its own>=0.7.0floor — the intra-workspace floor guard compares a declaration against the local tree, where every module exists. A new guard reads the dependency's modules off thev<floor>tag;just-dna-compileris cut to 0.7.1 alongside andjust-dna-formatstays at 0.7.0. · from a peer session blocked ondraft --gene· related RM192, RM196 - ✅ RM246 — SHIPPED 2026-09-18 in the uncut 0.7 line. A check whose severity is the compile mode said so three ways:
(errors if strict else warnings_out)for four codes, anif strict:that also suppressed the symbolic-allele drop, andResolutionOutcome.strict_errorspairing a warning with a different, longer refusal for three more. The third is the general case:ladder.LadderFinding(warning, refusal=None)plusroute, withResolutionOutcomederiving bothwarningsandstrict_errorsfrom one list of pairs rather than storing two that could drift. What the compile DOES with a refusal stays caller policy — resolution aborts under astrict resolution:prefix, membership accumulates. The@ladderequality widened from 4 codes to 7, and its walk had to become per-construction rather than per-function: the first cut credited nine plain warnings that shareresolve_from_tablewith two real ladder members. · from RM149's first pass, finding 2 · also in CHANGELOG - ✅ RM245 — SHIPPED 2026-09-18 in the uncut 0.7 line. Every corpus scenario pointed at
<path>:<line>, and 110 of them had no check beyond the line is inside the file. Measured against one ordinary session of code edits (RM244 + RM246): 53 lines ended up outside the function they were written against.# source:now names the file and# anchor:the symbol, and an anchored scenario carries no line at all — the alignment check became the emission site is inside this symbol's range rather than within three lines of this number. 225 of 228 anchored; the three line-only ones are twovocab.pyconstants for@reservedmembers and a module docstring. The recovery is the part worth reading: each line was resolved against the revision it belonged to, since deriving from the current tree would have written the drift in permanently. · from RM149's second pass · also in CHANGELOG - ✅ RM244 — SHIPPED 2026-09-18 in the uncut 0.7 line. Nine
VALID_WARNING_CODESmembers are emitted by bothcompiler/resolution.pyandenricher/resolver.py, and seven pairs were a different sentence —rsid_unresolvedread not found in resolution table, position remains unset in one and not in the injected Ensembl snapshot in the other, so a consumer grepping either found half the emitters.just_dna_compiler.resolution_findingsis the nine builders both tiers now speak through; they returnstrso the literalCodedWarningstays at each emission site, andNoneomits a clause this caller cannot establish — four withholds, all recorded decisions (S61 twice, S33, and which tables a cross-build skip left unjoined). Placement is the compiler because the enricher already importsresolution.genotype_fitsand because the enricher's route dies at 1.0. Three breaks caught by guards rather than by reading: a dedupe that keys on the message, 77 shifted# source:anchors, and a third narrowing of the corpus phrase check. · from the RM149 corpus's second pass · also in CHANGELOG - ✅ RM243 — SHIPPED 2026-09-13 in the uncut 0.7 line. ENRICHER.md's which of these attest paragraph opens by refusing to state a total — a number in prose is a registry nothing iterates — and then attributed a count to each of four commands, summing to 17 of the 24 emitting members.
enrich()said six and emits 8 (gainedpublished_refutationandevidence_status_currency);check-identifierssaid three and emits 5 (gained the two PGS members with RM163); three commands were absent from the sentence entirely.enrich._verification_records' docstring carried the same wrong six. RM218's repair applied a third time: state the rule, not the figure, and assert the property — the attribution moved into the check table, which already carried it per row. Two guards, and the one worth reading is the invariant that was wrong first: theWherecell names the emitting module fails on five correct rows, because that column names the site of the comparison andreference_alleleis compared insequencesand attested byenrich. · from the RM149 Gherkin drafting round · also in ENRICHER, CHANGELOG - ✅ RM242 — SHIPPED 2026-09-13 in the uncut 0.7 line.
alphagenome_check's no-client branch wroteskipped(CHECK, "unchecked"), and"unchecked"is not a member ofVALID_VERIFICATION_SKIPS— one of the per-pass spellings that set replaced, surviving in a single call site — so the branch raisedValidationErrorwhere it was supposed to record nobody asked. Reachable by the defaultalphagenome checkrun against a local AVI snapshot with noALPHAGENOME_API_KEY, while the--offlinebranch three lines up attested correctly. Repaired tooffline, the member that means needs egress, had none, withclient_absence()'s sentence carrying which absence it is indetail. Guarded by an AST walk over every literalskipped()reason in the workspace rather than by pinning the one branch, which would pass the day another pass writesno_snapshot. · from the RM149 Gherkin drafting round · also in CHANGELOG - RM241 — 🟡 open, filed 2026-09-13 from RM188's ClawBio half. RM92 built
module_spec.weightingbecauseweightis the one magnitude with no unit (@weight-has-no-unit); it is advisory and not reconstructed byreverse_module, withpanel/authorship/license. Documented and field-by-field defensible — it is prose, correctly outsidecontent_signature. The survey hit the consequence: translating ClawBio's panel forced an honestweightingblock (their weights are importances within a nutrient domain, normalised by the SNPs found, comparable only inside one run), andreversedrops it — so a consumer holding two reversed modules has twoweightcolumns and no way to learn the scales differ, which is what RM92 exists to prevent. Three dispositions, none picked: FAQ it; carry it through from the manifest; or warn on the drop the way the dropped attestation already warns (likeliest, one line). Not by hashing it — a reworded note must not move the digest. · from probes/CLAWBIO_SURVEY · related RM92, RM240, RM188 - RM240 — 🟡 open, filed 2026-09-13 from RM188's ClawBio half; the translation is run, the landing is not. ClawBio's 28-SNP nutrition panel translated field-for-field:
validategreen,compilegiving 84 weight rows over 28 variants / 24 genes / 12 categories, andcompile → reverse → compilereproducingcontent_signatureexactly. Land it asreference_examples/nutrigenomics_panel/(@probe-becomes-example). Two refusals on the way, both findings:stateis required whiledirectionis not, so a translation written against the modern column is refused for omitting the superseded one (the 1.0-cleanup tracker has it, and the run adds that it is the first error a new author meets); and their 28ref_allelecells carry no coordinate, which the schema correctly refuses. Still needs aresolution.csvfor--strict, asources.csvwith read terms (theirdata_licenseis blank and MIT covers the code —@a-hosts-terms-are-not-its-contents-terms), a closure, a README and a REFERENCE_EXAMPLES section. · from probes/CLAWBIO_SURVEY · related RM188, RM241 - RM239 — 🟡 open, filed 2026-09-13 from RM188's ClawBio half. ClawBio's
gwas-lookupreturns credible sets with a posterior probability and 95%/99% membership per(trait, study). A PIP is the same class of object as an allele frequency or a LOEUF — a number a named dataset publishes — and its key isGwasEffectRow's key plus nothing, so two optional columns (posterior_probability,credible_set) is the shape, minor-legal under P3/P8. Smallest item on the survey's list; do it the next timeenricher/gwas.pyis open, not on its own. Two things a design owes: whethercredible_setis a membership flag or the set's level (95/99 are two answers to one question), and a withhold for a harmonised study carrying none — a nobody-asked third state, never a zero. · from probes/CLAWBIO_SURVEY · related RM90, RM188 - RM238 — 🟡 open and PARKED on a consumer, filed 2026-09-13 from RM188's ClawBio half. ClawBio's
gwas-lookupreturns five cis-eQTLs by named tissue (GTEx + EBI eQTL Catalogue).expression_effects.csvis the wrong place for them: AlphaGenome-shaped, one row per(variant, gene)aggregating 371 tracks, andexpression.pyargues per-track rows are lossless and unreadable. A GTEx row is a measured eQTL in one tissue where the tissue is the fact, so it iseqtl_effects.csvkeyed(variant, gene, tissue, dataset). Parked because USE_CASES § 7.2's rule applies — reopen with a consumer, never with an argument — and a competitor rendering the table is an argument; the first step when one appears is the acquisition measurement that parked the frequency snapshot. · from probes/CLAWBIO_SURVEY · related RM194, RM200, RM188 - RM237 — 🟡 open, filed 2026-09-13 from RM188's ClawBio half.
GeneMetricsRow.haploinsufficiency/.triplosensitivitykey on a gene symbol; ClinGen publishes four dosage lists andenricher/clingen.pyreads one, leaving region curation, recurrent CNVs and ISCA regions — the half a CNV classifier needs — unwritable. ClawBio's dosage map carries anelement_typecolumn for exactly that reason (22q11.2 is two of its four rows). A siblingregion_metrics.csvkeyed(chrom, start, end, name), not anelement_typediscriminator: a 22q11.2 deletion is not a claim about any one gene in the interval (@gene-map-is-another-sources-attribution), and a shared table would have half its key null per row. Two things first: read ClinGen's terms rather than recalling them, and decide whether region curation is a second surface of theclingenlane (@write-the-sourcerow). · from probes/CLAWBIO_SURVEY · related RM188 - RM236 — 🟡 open, filed 2026-09-13 from RM188's ClawBio half.
consequence(SO term) andimpact(HIGH/MODERATE/LOW/MODIFIER) sit in ROADMAP § Reserved namespace as planned axes that get a slot only when a release actually commits; ClawBio's running ACMG engine reads both — PVS1 offconsequence=frameshift_variant, PM1 offimpact=HIGH, BP7 off both — which is the commitment case. Neither name is inRESERVED_NAMES_0_4, so nothing moves out of it; committing means building the column or adding the slot + aRESERVED_NAME_REASONSentry. The blocker is grain, and it is RM23's blocker restated: MANE-only is lossy, most-severe is an interpretation and therefore out, and a derivedconsequences.csvkeyed(variant_key, transcript)is half cost and the shape RM23 also needs — settle both in one pass. · from probes/CLAWBIO_SURVEY · related RM23, RM188 - ✅ RM235 — SHIPPED in the uncut 0.7 line (2026-09-13: a
verdictmodule, both gate properties retyped, two CLI branches; no behaviour in the artifact changed, two in the commands did). Filed on a premise the real code refuted: the claim that an unreachable dbSNP or HGNC is counted stale while an unreachable OLS4 reports clean was measured on hand-builtIdentifierReportobjects carrying states the pipeline does not write —RsidStatus.stateislive|merged|absent|withdrawnwith nounchecked, andcheck_identifiersnever populatesreport.rsidsat all. Against a dead port the ontology leg raisesIdentifierUnavailableand the command exits 1 with anunreachablerecord for all five checks, so an outage was already a hard refusal carrying its reason (@a-disagreement-with-a-document-may-be-in-the-instrument, applied elsewhere in the very pass that filed this). What survived is S100's shape:cleanansweredTrueover ids nobody read when an id-bearing table would not parse, and--strictexited 0 beneath all identifiers current. Bothcleanproperties are now aVerdict— falsy when it carries codes, empty is the pass — so a gate stays binary while the reason rides beside it, which is the one documented exception to the house tri-state. The set holds errors, not non-answers:not_requestedandnothing_to_checkare deliberately not members, andunreachablecould not be. Two behaviour changes:check-identifiers --strictnewly exits 1 on an unreadable id-bearing table, andAcmgReport.cleanonnothing_to_checkgoes fromNoneto a pass, superseding that half of RM234 a day later. A prose filter was the defect underneath —unreadable_tablescounted the row-taking form's reason as a parse failure, found by the existing tests going red. · from the RM234 investigation · related RM234, RM94, S86, S100 - ✅ RM234 — shipped 2026-09-12 in the uncut 0.7 line, owner enricher, severity medium.
AcmgReport.cleanwasnot self.mismatches, andmismatchesselectsnot_listed/denied— so a run that obtained no SF list gave every row the verdictunchecked, leftmismatchesempty, and answeredTrue: a comparison that never happened reporting as one where everything agreed.version=None checked=0 clean=Trueandversion=3.3 checked=13 clean=Trueare the two readings a caller could not tell apart, and@tautology-zerois the rule (a check that cannot fail must not report a pass). The attestation was already right, which is what shaped the repair:verification_recordhas always returned askippedon both arms, so the fix is onenot_consultedproperty both read rather than a second condition beside it, with a test asserting the equality across all five arms.Nonerather thanFalse— negating would claim disagreement with a list nobody read.if report.clean:is unaffected (Noneis falsy) and the CLI's redundantand report.versionguard is gone;--strictgates onmismatches, so no offline run newly refuses. One existing test was asserting the defect and now readsclean is None. · from S100 (just-module-creator) · related RM235, RM72, RM94 - ✅ RM233 — shipped 2026-09-12, test infrastructure only, owner enricher tests + the suite root, severity medium.
mainwas red at2001215on both Python jobs and green on every local run: two tests match a string inside Typer's rich-rendered output, and rich decides colour from the environment, so--usearrives as three ANSI spans (FORCE_COLOR=1reproduces it) — while the second failure, a phrase wrapped across the error box, was never environment-dependent at all, becauseCliRunnerpins its own width. Repaired in two places because there are two causes:TERM=dumbin a rootconftest.pyfor colour (NO_COLORfixes only half;COLUMNSis deliberately absent, measured useless againstCliRunner), and the already-existing_unwrappedhelper promoted out oftest_cache_lanes.pyintocli_textfor wrapping. The transferable half is the private name: the normalizer existed and the second caller could not find it, so it wrote the raw match that went red — and it stripped box drawing but never escapes. 2 of 491 CLI tests were affected; the other 489 pass on the luck of what they match. · from CI run 34703638770 · related RM202 - ✅ RM232 — landed 2026-09-12, after the 0.7.0 cut (
83b1674) and so unreleased; the release class is the maintainer's call and CHANGELOG states both readings, owner compiler + enricher, severity high. RM231 folded each enrichment pass's licence row into its data table's commit and had to name five exemptions to close its roster; two of them are this item.civic_citations.draft_civic_citationsanddrafting.record_draft_provenance— the scaffold's recorder, reached by five drafters — record the licence only after the compiler'sdraft.append_*has renamed the drafted rows into place, so a refused merge leaves drafted rows with no licence record and the compile gate nothing to refuse on. A scaffold's<<REPLACE>>placeholder is enough to trigger it, which is S98's own trigger one layer over. RM231's seam does not reach:before_commitbinds one callback to one rename, andpgx_draftappends three tables in three separate atomic commits. The fix threads the same optional kwarg throughappend_rows/append_partial_rowsand fires it per file that writes — hoisting ahead of the first append is refuted bycoveredbeing unknowable until the append is attempted (differscovers nothing), and binding to first or last alone leaves a table unlicensed either way. Filed at discovery rather than at approval, and that is the transferable half: it had been recorded only as two exemption reasons in a passing test, which no release gate reading no open RMs, all green can see. The guard is now an equality from both ends — nine committing passes, two named callbacks, and every one of the 11append_*calls carrying abefore_commit(all 11 unbound before, all 11 bound after). · from the RM231 handover · related RM231, RM228, RM222, RM142 - ✅ RM231 — shipped 2026-09-12 in the uncut 0.7.0, owner enricher, severity high.
alphagenome expressionwrote 12,003 non-commercial rows, then refused its licence row on a scaffold's placeholder and said FAILED — and the compile gate, keyed on the licence table alone, passed the module as unrestricted. Eight passes had the tail.layout.atomic_writer(before_commit=…)runs the merge inside the table's commit;require_sources_filepre-reads the table before the fetch; a guard asserts the eight plus five named exemptions, two of them RM228's same gap in the drafting scaffold. Licence-row-first refused (a row for a pass that contributed nothing). · from S98 (just-module-creator) · related RM128, RM142, RM228 - ✅ RM230 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity high.
EuropePmcClient.lookupleakedhttpx.HTTPStatusError,httpx.ConnectErrorandjson.JSONDecodeErrorinto a pass whosetry:has only afinally:— hidden because the contract suite's exemption for that class was argued from what one method (fulltext) promises. Removing it also showedcoveredwas keyed on the module and could not express a per-class exemption.check-identifiersgains--use: PGS rows were hardcodedunstated, anacademic_research_onlyscore taints atannotation, and the compile's refusal named a flag that did not exist — measured live, 6 of the first 250 Catalog scores are in that class. And RM228's self-recorded debt is disproved:clinvar_draft/pubmind_draftreturn early before the licence write, so the test kept as a pin on that early return. · from the enricher tail of the 2026-09-11 round · related RM208, RM222, RM228, RM163 - ✅ RM228 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium. Seven
*_draft.pyproviders each carried a copy of the same four decisions and the copies had drifted: two recorded adatasetand never withdrew a stale one, one imported another's private_MATCH_ONacross modules, one parsed pydantic's rendered message as an API, andDRAFT_PROJECTIONSwas a hand-kept copy of the drafters'match_on. The obvious fix was refuted by measurement:authoring_requirements'any_ofgrammar cannot expressref/altsrequire a position, so the one provider that looked correctly derived accepts a partial coordinate the model refuses — constructing the model is the only complete oracle. Adrafting.pyscaffold splits the derived model rule from a declared source precondition carrying its reason as a field; the import cycle it exposed showed the drafted-value axis had been sitting inprovenance.pyall along. Registry + AST guards, both failing on all seven pre-migration. · from the long-tail triage of the 2026-09-11 round · related RM222, RM73, RM4 - 🕓 RM227 — open, owner format, severity medium. RM215 folded allele case into
content_signature;derive_variant_key's coordinate fallback still does not, so1:100:a:g,tand1:100:A:G,Tare two keys for one locus. Fires on a multi-alt row or a non-GRCh38 build, since the VA path normalizes already. Splits joins, not dedup, and moves a stored cell — so RM215's corrected-derivation argument does not reach it. Complicated byref/altsnot being grammar-checked at all. Pinned by a test so the note cannot rot into a silent fix. · from RM215 · related RM215, RM81 - 🕓 RM226 — open, 1.0, owner format + compiler, severity low. Three decisions the code declares in its own comments and no tracker held:
VariantRow.variant_key/authored_identinsidecontent_signaturewhile every positional model's stamps are outside;likely_pathogenic/likely_benignhardcodedFalseinweights.parquetwith no authored field; and_freeze_identityderiving a key with nobuild=. Each reversal moves published identities, so each is major — filed so the 1.0 cleanup has a list instead of a grep. · from the 2026-09-11 round's self-declared candidates · related RM15, RM52 - ✅ RM225 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity medium. Four schema long-tail candidates walked item by item.
actionabilityis closed and three places said otherwise —vocab.py's comment,base.vocabulary's own docstring, and an earlierreference.pyincident — plus the_SEEDname; renamedVALID_ACTIONABILITYwith the old name a working alias.CANONICAL_MT_REFERENCE_SEQUENCESis correctly unenforced but its value was a literal in the refusal beside it. Apgx.pycomment namedStudyRow.chromas validated at two sites; it is not.is_multi_valued_number's docstring promised a tri-state its sole caller does not need — the collapse is the contract. The guard measures closedness against the validator and walks the helper's own docstring. · from the long-tail triage of the 2026-09-11 round · related RM217, RM218 - ✅ RM224 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity medium.
SIDECAR_SPELLINGSis keyed on the table key (sources.csv) and the preferred filename was not a key, sosidecar_write_path(dir, "licensing.csv")on a module carryingsources.csvcreated the second copy the function documents itself as preventing.sidecar_keyreads the map backwards, derived;sidecar_spellingsnormalises through it, so either spelling is a key and every helper is fixed at once. A filename is never refused. · from S96 (just-module-creator) · related RM51, RM49 - ✅ RM223 — shipped 2026-09-11 in the uncut 0.7.0, owner compiler, severity medium.
INTEGRATION_0_7.mdstated four registry sizes and all four were wrong when a consumer measured them (ARTIFACT_PARQUETS22 vs 23,VALID_WARNING_CODES72 and 71 vs 73, the authoring reference 31 vs 32 models); three moved because the AlphaGenome round landed after the numbers were taken. The document's own § 8 forbids counted prose — nothing walked the file, so the guard, not the four words, is the repair. · from a consumer measurement during the 2026-09-11 round · related RM218, RM217, RM194 - ✅ RM222 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium. Three
@write-the-sourcerowfindings at one call site. The "contributed nothing writes none" half was a comment above a gate that only checkeddry_run, so a--genefilter matching nothing wrote aciviclicence row — a claim the module uses a source it does not; both sibling drafters already gate on an outcome.datasetwas computed for every row'sconclusionand dropped, becauserecord_source_termshad no parameter for one, so the row readdataset=''and a CIViC-drafted module sat outside the currency check--verify-datasets/withdraw_stale_datasetrun. And that function's docstring still said "None of these layers can taint", written for the three fact passes and false since this drafter began recording atannotation. · from the 2026-09-11 blind re-derivation round · related RM152, RM85, RM165 - ✅ RM221 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher + format, severity low. Rich reads a bare
[word]as a style tag, so three help texts lost the extra's name —atlas --helpprinted "Needs the extra" andatlas generate --help"which is inand deliberately not in". Escaped. The extra's size disagreed across five places (22 MB vs the measured 19 MB, two of them written earlier the same day). "Vendored" survived RM196 in the group help and ENRICHER.md whileatlas generate --helptwo lines away said the opposite and the directory holds only a README. AndVALID_VERIFICATION_CHECKS' first block said "enrichwrites these six" against eight — membership right, sentence drifted; the number is gone and the enricher now walks both sides. · from the 2026-09-11 blind re-derivation round · related RM192, RM196, RM45 - ✅ RM220 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity high. Two readings of
--offlinecoexisted:pgx/enrich/frequenciesmake it absolute (RM38's licensing reason, asserted by name intest_pgx_licensing.py),gwaslets an injected client win (documented, and the Catalog is ungated).expressionhadgwas's shape againstpgx's situation — the Atlas is licence-gated, so an injected client fetched under a flag documented as making no egress.@flag-means-same. The axis the two readings differ on is the source's licence, now written down in ENRICHER.md;gwaskeeps its behaviour on purpose. The licence gate was masking the hole, so the test declares its use to remove the second gate. · from the 2026-09-11 blind re-derivation round · related RM38, RM194, RM200 - ✅ RM219 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium.
download.pydocuments at length that every fetch stages through.partbecauseHfFileSystem.getcreates the local file before discovering the remote is missing;_provision_root_file_snapshotstaged its payload and fetchedrelease.jsonstraight to the target two lines later, so a repo publishing no description left a 0-byte one. That turns nobody said into the description is corrupt —_json_parsesrejects it andLaneStatusreportsrelease_unreadable, sending an operator to re-pull a lane with nothing to give. The test's fake creates-then-raises, reproducing the documented client behaviour rather than assuming it. · from the 2026-09-11 blind re-derivation round · related RM209, RM187 - ✅ RM218 — shipped 2026-09-11 in the uncut 0.7.0, owner compiler, severity low.
test_counted_prose.pyscopes itself todocs/and the same class was live incompiler.py: "up to twelve in all" against 23 parquets, and_vrs_gap_reason's "six reasons" against 8 arms (RM5 and RM59 each added one without moving the number). Nothing re-counted — both sentences state the rule, and the guard asserts the property each stood in for, for the reasons@answered-is-not-absent's pairwise-distinct arms, which a count never checked. Also:_build_weights' 15-nameissubsetfloor over a 39-column schema promoted to an equality over the walked set, with its two hand-kept halves compared to each other; andvalidate_spec's docstring, in both copies, corrected from "changes severity only" —strictgenuinely adds two aggregate findings.ensembl_reference/ba1_thresholdsurfaced as CLI-unreachable rather than fixed. · from the 2026-09-11 blind re-derivation round · related RM5, RM59, RM93 - ✅ RM217 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity low. Eight of
vocab's 29VALID_*/RECOMMENDED_*frozensets were named nowhere inSCHEMAS.md, andRECOMMENDED_ANCESTRY_GROUPS+VALID_EFFECT_DIRECTIONSin no maintained file at all — the other six only in release-scoped ones. The doc described the mechanism (how a field carries its members) and never the registry, which is the recurring shape. Roster added carrying count, openness and purpose but not members (@fieldnames-from-model); the count and the openness flag are both asserted, the latter becauseactionabilityonce shipped as an open seed against a closed validator. Scoped tovocab's own sets, since a central registry would needvocabto importpgx. · from the 2026-09-11 blind re-derivation round · related RM216, S21 - ✅ RM216 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium. The superset sweep the round owed: every identifier a
*_FROM_CODE.mdnames, grepped against its maintained doc — 341 real surfaces absent across three tiers, most legitimately delegated (@fieldnames-from-model), error types not, because a consumer writes one in anexcept. ENRICHER.md carried a ten-row table against a tier defining 83 classes, 51 of them named nowhere. Complete roster added, grouped by what raises them (pass / client / builder / snapshot reader / drafting provider) because the groups are the contract, with the narrowing column asserted to be a real subclass ladder —exceptorder is load-bearing. Walked as an equality, builtins dropped rather than the pattern narrowed. · from the 2026-09-11 blind re-derivation round · related RM97, RM101, RM208 - ✅ RM215 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity medium.
ALLELE_PATTERNcarriesre.IGNORECASEand the cell is stored verbatim, so one heterozygote spelledA/G/a/G/A/g/a/ghashed four ways.content_signaturenow folds a cell whose grammar is case-insensitive, driven by aCASE_INSENSITIVE_ALLELEmarker over the four columns whose validator is that grammar —ref/altsexcluded because they are not grammar-checked at all. Filed for 1.0 and the filing was wrong: it cited RM81, a parquet retype, for a change that retypes nothing; this is P3's corrected-derivation case and RM36 is the precedent in the same function. 536 corpus cells measured, none lowercase, so no published signature moves. Thevariant_keycoordinate fallback still splits on case and is surfaced, not fixed. · from the 2026-09-11 blind re-derivation round · related RM214, RM36, RM81 - ✅ RM214 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity medium.
ALLELE_PATTERNcarriesre.IGNORECASE, so lowercase alleles are legal; the unphased sort beside it was ASCII, which orders every uppercase letter before every lowercase one — soA/gwas accepted anda/Grefused, the same unordered pair with two answers. Sorted onstr.casefoldwith a stable sort, so every previously-valid value still validates and nothing authored moves: a loosening, minor-legal. It deliberately does not make the pair canonical —A/ganda/Ghash differently undercontent_signaturebecause the cell is stored verbatim (@verbatim-except-ordernormalizes the order only), and normalizing allele case would move an identity key, which is 1.0 work. · from the 2026-09-11 blind re-derivation round · related RM31, RM5 - ✅ RM213 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity low (latent).
merge_key's docstring says a silent()would merge every row into one and it raised for a model declaring no key while returning()for one declaring an empty key —MeasureBinRow's base-class default. Measured: two rows differing in every column returned equal keys. Latent (authored table, and every subclass overrides), fixed because the next kind to inherit the default would find the collapse in a merge pass.hints.table_keykeeps reading the same falsy value asNone, which is the right answer to its different question. · from the 2026-09-11 blind re-derivation round · related S51, S48 - ✅ RM212 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium.
expression._connectreadALPHAGENOME_API_KEYfromos.environwithoutload_env()— in the one function whose docstring cites@credential-where-read— and nothing else onalphagenome expression's path loads a.env, so a key living only there was invisible and the pass refused with is not set. Measured.cli._atlas_client_or_nonehad the same gap, failing quietly into the knot interval. Both refusals now carrymissing_credential_reason, sinceexport VAR=is strictly stronger than never setting it and "not set" sent an operator to the wrong fix. Same incident as the PharmVar lane's, whose comment already says a pre-check answering differently from what it guards is worse than none. · from the 2026-09-11 blind re-derivation round · related RM191, RM194, RM204 - ✅ RM211 — shipped 2026-09-11 in the uncut 0.7.0, owner compiler, severity medium. RM93 moved
_check_frequency_arithmeticinto the pre-flight and left_check_gene_metrics_arithmetic— its exact structural analogue — in a compile-side per-model closure, where a table being loaded in both commands makes a table-by-table audit stop. Four moved: the arithmetic check,_cross_check_gene_metricsand_cross_check_gene_validity(keyed on gene, which is authored and which nothing fills), and_check_declared_license_agrees. Five deliberately did not, recorded rather than left to be re-derived: four are keyed on position orvariant_keyand would report every unresolved authored row as an orphan, and_source_checksneeds aused_sourcesthat is complete only after every sidecar is read. No new dedup — the fact-table extend site already filters on the message. · from the 2026-09-11 blind re-derivation round · related RM93, RM44 - ✅ RM210 — shipped 2026-09-11 in the uncut 0.7.0, owner compiler, severity medium.
_cross_check_literatureruns on both sides and every message embeds a count; the pre-flight was handedloaded_kindsand the compilekind_rows(post_apply_symbolic_drops), so apharm_variants.csvrow that is droppable and citing made the two sentences differ by a number and both survived the message dedup — one manifest carrying "1 citation(s) … ['99999999']" beside "2 citation(s) … ['29165669', '99999999']" withwarnings_summary: {literature_row_uncited: 2}. Reproduced onreference_examples/pgx_slco1b1_simvastatin. Fixed by passingsurvivors, the post-drop view the pre-flight already computed for the positional fill; the post-drop sentence is the right one, since the dropped row is not in the artifact.citation_not_in_pubmedand the quote-counter finding share the input and are fixed with it. · from the 2026-09-11 blind re-derivation round · related RM44, RM79 - ✅ RM209 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity high.
upload.pywalkslocations.SNAPSHOT_ROOT_FILENAMES;download._provision_snapshotiterated a hand-kept(release.json, LICENSE.txt)pair, so RM198'savi_knots.parquetwas published and never pulled — and the AVI lane stores noPHRED, so a pulled lane held scores nobody can rank andalphagenome checkrefuses it. Two docstrings over that code claimed the registry was walked. The test compares the set of root names asked for against the tuple, so a registry that grows by one is covered without anybody remembering. · from the 2026-09-11 blind re-derivation round · related RM191, RM198, RM202 - ✅ RM208 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity high. One root, two opposite symptoms:
CrossrefClient.existscaughthttpx.HTTPError, the superclass of both types its own@retrymatched, so it made one upstream request whereattempt_floor(3)asked for three;GwasCatalogClient._getre-raised the transport leg bare and nothing translated it once the attempts were spent, soassociations_forraised rawhttpx.ConnectErrorat a caller told to expectGwasError. Both measured. Repaired with the_request/_getsplit every other client already had, and guarded bytest_retry_is_reachable.py, which walks the package — both clients sat in the contract suite'sexemptset, and a roster-walking guard inherits the roster's exemptions (the RM101 blind spot). GWAS's exemption is removed; it joinsFOUR_OH_FOUR_IS_AN_ANSWERfor its own reason. · from the 2026-09-11 blind re-derivation round · related RM97, RM101, RM187, RM203 - ✅ RM207 — shipped 2026-09-11 in the uncut 0.7.0, owner compiler, severity high. The
withdrawnrsID refusal — fatal in both modes — walkedpatchedand looked the post-expansionga4gh:VA.…key up in a table keyed by the authored one, so it silently never fired on an expanded row; and it lived only insideresolve_from_table, which onlycompile_modulecalls, so where it did firevalidatewas green in both modes and a plaincompilerefused. Both reproduced onreference_examples/hfe_hemochromatosiswith one column changed.withdrawn_refusals/ambiguous_refusals/ambiguous_warningsare shared predicates both sides call; the sentences are shared (two interpolations, so copying drifts) and only theresolution:/strict resolution:channel prefix is restated, because that text is API. · from the 2026-09-11 blind re-derivation round · related S76, RM93 - ✅ RM206 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium.
LookupClients.ensure(name, factory): one lazy path under a lock, name checked against the derivedCLIENT_FIELDS,close()walking the same tuple. Six legs built a per-request client and closed it, two assigned back; a host filling six of eight fields had unpaced egress on the one that mattered. Alookup_*call given no bundle now closes the one it built. The CPIC half stays consumer-side (draft_gene(client=)). · from S92 (just-dna-registry) · related RM42, S15 - ✅ RM205 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity low.
VariantHint.checkedholds labels only (ensembl,clinvar,ensembl-rest), the unreadable-snapshot finding interpolates the label, and the newVariantHint.snapshots(label → path, every snapshot opened or tried, PubMind and clin_sig legs included) is the one field carrying a path — a host drops it and audits nothing else. Taken as the consumer proposed;_brief(exc)stays upstream's sentence. · from S93 (just-dna-registry) · related RM201 - ✅ RM204 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity medium.
caches.lane_status()→LaneStatusper lane (state∈LANE_STATES= present/absent/occupied,looked_in,path,release,release_unreadable), andcache statusrenders it — the registry's status half beside its provisioning half, so a consumer servingGET /cachesstops re-writing the loop.occupied(non-empty, holds no snapshot, the targetpreparerefuses) used to print asabsent; named by the fact rather than the consumer'spartial, which guesses a cause. · from S91 (just-dna-registry) · related RM176, RM182, RM184 - ✅ RM203 — shipped 2026-09-11 in the uncut 0.7.0, owner enricher, severity low.
PacingGate.spent: admissions so far, bumped under the slot lock, one per upstream attempt (the clients wait inside their retry loop, measured ongnomad._postandeutils._request). A host metering egress reads it instead of charging by request shape. Awaitedtotal was refused: the sleep is outside the lock by design. · from S95 (just-dna-registry) · related RM42 - ✅ RM202 — shipped 2026-09-11, owner enricher, severity medium. RM198 wired
alphagenome_avi'spublish_repoand nothing could reach it:cache rebuild --publishwalks lanes with arebuildadapter, which every publishable lane has except this one. The tests passed because they asserted the registry's data and the publish test calledplan_reference_snapshotdirectly, bypassing the CLI — a field can be set correctly and mean nothing if no path acts on it. The guard already existed on the build side (build_commandis walked against the real Typer tree) and had no publish equivalent. Shipsalphagenome publish, apublish_commandfield, and a biconditional guard: a publishable lane is reachable by a rebuild adapter or its own command, exactly one. · from RM198 · related RM191, RM198, RM199 - ✅ RM201 — shipped 2026-09-11 in the uncut 0.7.0, owner format, severity medium.
DeclaredChange.requires: the dotted manifest paths a module must carry for a declared change to reach it — a necessary condition,()for every module,Nonefor unstated — with the predicate ours (reaches, three-valued,Falsethe only answer acted on) andRecompileAnswer.declared_forthe Kleene filter. RM108's and RM110's corrections carrygene_validity/gene_metrics; RM121'sstats.genespair stays unstated on purpose, and a test asserts that set as an equality. The consumer'sNone-means-every-module was refused on the algebra. · from S90 (just-dna-registry) · related RM126, RM183 - ✅ RM200 — shipped 2026-09-11 in the uncut 0.7.0, narrowed to
RNA_SEQand shipped as the tenth derived-fact sidecar rather than as a column or a finding, owner enricher, severity medium. Corrects § 4.7: "no expression direction anywhere in the model" is true of the AVI aggregate (allMAX_ABS_*) and false of the API — eight scorers reportis_signed=True.RNA_SEQis the only scorer with a gene axis (shape varies with the window, 61 genes at one variant and 48 at another), so AlphaGenome attributes it itself — adopt for drafting.CHIP_TFrefused on measurement though all 1,617 tracks name a real TF: top-3 of 751 TFs carry 1–3% of the mass, it does not track effect size, and every leader is a singleton track.*_ACTIVEis an activity level, not a variant effect — raw assay units barely moved by the ALT — which makes it a locus annotation rather than a variant one, normalisable by thenonzero_meanevery track carries. Assayed 2026-09-11 (probes/ALPHAGENOME_ATLAS § 6.6): consensus fraction is a property of the scorer, not the variant —CAGE/PROCAPare near-unanimous even atPHRED0.007, so it is no confidence measure and the shape this entry first proposed is dead;RNA_SEQnever exceeds 61% and that is structural, since a variant can raise one gene and lower another.*_ACTIVEdoes move with the ALT at ~16× control in Z-DNA formers and ~10× in poly-T runs (20% at individual loci) and ~15× in G-quadruplexes — mostly positional, with a real per-variant component wherever geometry is at stake. The G4 row read background until the probe stopped sampling loop bases instead of G-tracts, the third conclusion here overturned by the instrument rather than the data. Positional scorers stay unusable as named claims on two independent tests. All non-commercial; needs the second source namealphagenome_atlas. · from RM193 · related RM191, RM193, RM194