Skip to content

BPML ↔ library reconciliation

Level: reference · deep dive

Generated by reconcile_bpml.py from committed snapshots of the two Drive sheets taken 2026-08-16, joined against the live registry. The snapshots are point-in-time copies, not a live feed — re-snapshot before trusting a number that matters.

The headline

BPML process rows 111
…citing a test id 11
…recording a gap (missing…) 6
…with no test reference at all 93 (84%)
Distinct test ids cited by BPML 11
…that exist as a runnable case in this repo 1
…that exist only in the Drive test sheet 1
…that exist in neither 9
Case rows in the library registry 276
…distinct BV elections behind them 163
…referenced by any BPML row 1
…referenced by nothing in the sheet 162 (99%)

(The registry holds 276 rows but 163 distinct ids: a multirace election backs several cases that all carry its one test id.)

What the numbers mean

The sheet's coverage column is 84% empty — which is honest, not a failure: it was built as a backlog. The problem is the other direction. The library holds 276 runnable BV-backed case rows (163 distinct elections) and the sheet references 1 of them, so 99% of the testing work this project has already done is invisible to the document that is supposed to track testing coverage.

The two inventories also barely overlap by construction:

  • Drive test-sheet ids not in the library: 68
  • Library cases not in the Drive test sheet: 152

The Drive sheet is the older manual-QA range and stops in the low hundreds; the library's ids run to BV2284. They are not two views of one inventory — they are two inventories.

Why the join returns almost nothing

Not neglect — disjoint subject matter. Split the sheet's rows by what they are actually about:

rows
BPML rows about the application 102 92%
BPML rows about counting votes 9 8%
Library elections, every one about counting votes 163 100%

The sheet is overwhelmingly an application inventory — create an election, change a race, upload voters, download a CSV, log in, archive. The library is entirely a tabulation inventory — given these ballots, is this the right winner. Those are two different testing activities, and no single test-id column can be the coverage map for both.

The nine rows where they genuinely meet:

L1 Process Currently cites
Election Verify Preference Matrix BV705
Voting Methods Ranked Robin - Single Winner BV1550
Voting Methods Single-Winner - Approval —
Voting Methods Single-winner STAR - scoring/runoff divergence BV90
Voting Methods Plurality (chose one) - Single-winner —
Voting Methods Multi-winner - Bloc STAR —
Voting Methods Multi-winner Plurality Multi-winner Plurality
Establish Election Procedures Handling ties —
Tabulation Distribution of Equal Support report —

The three cross-cutting rows, curated

Six of the nine seam rows map onto a single method family. These three do not — their evidence is scattered across methods, so the list is curated by hand and every entry is re-validated against the registry on each run.

Handling ties — 10 cases

Test id Case Method Why it's on the list
BV126 bv126_ties_every_step_8fvd2x STAR every tiebreak rung fires in one election
BV2276 bv2276_qhjyr2_second_finalist_tie STAR tie for the second runoff slot
BV830 bv830_vb3xv2_no_condorcet_tie_score STAR tied with no Condorcet winner
BV129 bv129_score_tiebreak_bloc Bloc STAR score tiebreak, multi-winner
BV130-r2 bv130r2_dead_rung_bloc Bloc STAR a rung that cannot decide
BV750 bv750_tie_breaking_bloc Bloc STAR bloc tie-breaking end to end
BV2141 bv2141_3r3yf7_four_degree_tie RankedRobin four-way tie on the Copeland record
BV2261 bv2261_y2fbpc_tiebreak_recorded_draws RankedRobin BV's seeded shuffle is recorded and replayable
BV2262 bv2262_2gvwr9_nine_way_dead_heat RankedRobin nine-way dead heat, all positions recorded
BV2257 lunch_choose_one_dead_tie Plurality Choose-One dead tie

Distribution of Equal Support — 5 cases

Test id Case Method Why it's on the list
BV11 bv11_6xhfp8_full_equal_support STAR every ballot scores both candidates equally
BV2283 bv2283_hb4qvv_all_equal_recheck STAR all-equal ballots, re-checked against BV
BV655 bv655_jfrk9t_equal_opposition STAR equal support on opposed blocs
BV2219 bv2219_36f4v2_equal_opposite_base STAR the base of the equal/opposite pair
BV2220 bv2220_q8q9m7_equal_opposite_plus_cancel STAR same election plus cancelling ballots

Preference Matrix — 8 cases

Test id Case Method Why it's on the list
BV2270 bv2270_8h4bvh_head_to_head_vs_margin RankedRobin head-to-head result vs margin -- the matrix's two readings
BV2140 bv2140_48hjkv_most_pairwise_wins RankedRobin most pairwise wins across the grid
BV2260 bgg9qh9_most_wins_is_not_condorcet RankedRobin most wins is NOT the Condorcet winner
BV2157 bv2157_mmcmpy_condorcet_cycle_rps STAR a cycle -- the hardest thing the grid has to render
BV2156 bv2156_3grpbb_star_misses_condorcet STAR STAR's winner differs from the grid's
BV2131 bv2131_tennessee_condorcet_center_vqyqkr RankedRobin the Tennessee grid, centre candidate
BV2250 condorcet_1788_star STAR one historical election, three methods on one grid
BV1525 bv1525_condorcet_loser_bloc Bloc STAR Condorcet loser seated under bloc

The consequence for the sheet: it should not gain 162 rows. It should gain nine links. A counting row's verification is a whole family of elections in the library, not one id — so it points at the by-method index, and the library's own count is the coverage number. See SCOPE.md for the re-scope and the resulting column spec.

BPML rows that DO have a runnable case

Test id BPML process Library case
BV15 Create - Single-Winner - Plurality bv15_4h89vj_plurality_abstain

BPML rows citing a test id with no runnable case

These are the sheet's real coverage gaps — a process it believes is tested, where nothing in the library reproduces it.

Test id BPML process Where it exists
BV90 Single-winner STAR - scoring/runoff divergence Drive test sheet only
BV485 Election Admin - Ballot View nowhere
BV486 Preserve Ballot Secrecy nowhere
BV600 Download CVR nowhere
BV610 CSV Download - min 2 races nowhere
BV615 CSV Download - 1 race nowhere
BV630 (unnamed - placeholder) nowhere
BV705 Verify Preference Matrix nowhere
BV1380 Confirmation code - Regular Ballot nowhere
BV1550 Ranked Robin - Single Winner nowhere

Rows the sheet already flags as gaps

The sheet doing its job — these cells are the most useful thing in it.

BPML process Marker
Delete - entire election missing
Mark ballot Abstain - Election Level missing functionality
Mark ballot Abstain - Race Level missing functionality
Confirmation code - Editable Ballot missing document
Void Ballot - Regular missing document
Void Ballot - Editable Ballot missing document

Process rows by area

L1 area rows
Election 34
Ballot 11
Reports 10
Voter 6
Voting Methods 6
Candidates 5
Browse 4
Electors (Voters) 4
Authentication System 3
Poll 3
Security 3
Upload Election 3
Abstain 2
Graphical User Interface 2
Login 2
Registration 2
Audit 1
Certification 1
Communications 1
Establish Election Procedures 1
Precincts 1
Proxy Vote 1
Support Voter 1
Tabulation 1
Training 1
Translation 1
Vote Type 1

Related: the docs information architecture · BV registry · all cases by method