Behind the data

How the archive behind the rankings was built, how much of each regatta it covers, which consistency checks it fails and where, and the assumptions it rests on. The methodology page explains how ratings are computed from it.

From web pages to results

Results are collected only from original sources: organizers, timing vendors, governing bodies and clubs. 1,615 URLs were found; 607 were catalogued as results pages, of which 589 could be fetched and 14 could not (4 skipped as out of scope). They yielded 539 distinct files (74 were copies of another file), and 477 of those parsed into 18,625 races and 100,595 crew results, 97,707 of them with a finish time.

3 of the results files were downloaded by hand from pages the fetcher cannot reach (live-results sheets, file viewers) and are recorded with the page they came from; they hold 453 crew results and appear as "manual" in the diagram.

Found byCatalogued asFetchedParser familyEdition statuswayback cdx → results: 144 URLswayback cdx → not results: 364 URLswayback cdx → index: 64 URLswayback cdx → review: 147 URLsresults → ok: 589 URLsresults → http 4xx: 14 URLsresults → skipped: 4 URLsdbbc grid → parsed: 103 filesordered list → parsed: 80 filesordered list → partial: 2 filesalkame → parsed: 57 filesok → dbbc grid: 103 filesok → ordered list: 82 filesok → duplicate: 74 filesok → alkame: 57 filesok → gwn pdf: 53 filesok → club pdf heats: 40 filesok → unknown: 37 filesok → placings sheet: 25 filesok → csv blocks: 20 filesok → event blocks: 13 filesok → jy html: 13 filesok → race cards: 12 filesok → racegrid html: 12 filesok → not results: 12 filesok → lane grid: 10 filesok → dbc htm: 9 filesok → titled list: 8 filesok → dbc pdf: 7 filesok → csv cards: 4 filesok → alkame: 4 filesok → two lane: 4 filesok → team place html: 3 filesok → standings: 3 filesok → crash: 3 filesok → ocr low quality: 2 filesok → race rows: 1 filesok → results of racing: 1 filesok → ocr needed: 1 filesgwn pdf → parsed: 50 filesgwn pdf → partial: 3 filesclub pdf heats → parsed: 40 filesseed crawl page → results: 108 URLsseed crawl page → not results: 77 URLsseed crawl page → index: 95 URLsseed crawl page → review: 16 URLsunknown → found: 31 filesunknown → partial: 6 filesplacings sheet → parsed: 25 filescsv blocks → parsed: 20 filesevent blocks → parsed: 13 filesjy html → parsed: 13 filesrace cards → parsed: 12 filesseed crawl → results: 243 URLsseed crawl → not results: 52 URLsracegrid html → parsed: 12 filesnot results → parsed: 12 fileslane grid → parsed: 5 fileslane grid → partial: 5 filesdbc htm → parsed: 9 filestitled list → parsed: 6 filestitled list → partial: 2 filesdbc pdf → parsed: 7 filescsv cards → parsed: 4 filesseed crawl offsite → results: 11 URLsseed crawl offsite → not results: 75 URLsseed crawl offsite → index: 88 URLsalkame → parsed: 4 filestwo lane → parsed: 3 filestwo lane → partial: 1 filesteam place html → parsed: 3 filesstandings → found: 1 filesstandings → partial: 2 filescrash → found: 3 filesocr low quality → ocr low quality: 2 fileswp media → results: 88 URLswp media → not results: 28 URLswp media → review: 1 URLsrace rows → parsed: 1 filesresults of racing → parsed: 1 filesocr needed → found: 1 filesseed known → results: 7 URLscatalog override → results: 3 URLscatalog override → review: 1 URLsmanual → results: 3 URLsFound by: wayback cdx (method:wayback_cdx), 719 URLswayback cdx 719Found by: seed crawl page (method:seed_crawl_page), 296 URLsseed crawl page 296Found by: seed crawl (method:seed_crawl), 295 URLsseed crawl 295Found by: seed crawl offsite (method:seed_crawl_offsite), 174 URLsseed crawl offsite 174Found by: wp media (method:wp_media), 117 URLswp media 117Found by: seed known (method:seed_known), 7 URLsseed known 7Found by: catalog override (method:catalog_override), 4 URLscatalog override 4Found by: manual (method:manual), 3 URLsmanual 3Catalogued as: results (kind:results), 607 URLsresults 607Catalogued as: not results (kind:not_results), 596 URLsnot results 596Catalogued as: index (kind:index), 247 URLsindex 247Catalogued as: review (kind:review), 165 URLsreview 165Fetched: ok (fetch:ok), 613 URLs in, files outok 613Fetched: http 4xx (fetch:http_4xx), 14 URLshttp 4xx 14Fetched: skipped (fetch:skipped), 4 URLsskipped 4Parser family: dbbc grid (family:grid_pdf/dbbc_grid), 103 filesdbbc grid 103Parser family: ordered list (family:ordered_pdf/ordered_list), 82 filesordered list 82Parser family: duplicate (family:duplicate), 74 filesduplicate 74Parser family: alkame (family:alkame/alkame), 57 filesalkame 57Parser family: gwn pdf (family:race_blocks/gwn_pdf), 53 filesgwn pdf 53Parser family: club pdf heats (family:race_blocks/club_pdf_heats), 40 filesclub pdf heats 40Parser family: unknown (family:terminal/unknown), 37 filesunknown 37Parser family: placings sheet (family:placings_sheet/placings_sheet), 25 filesplacings sheet 25Parser family: csv blocks (family:csv_blocks/csv_blocks), 20 filescsv blocks 20Parser family: event blocks (family:event_blocks/event_blocks), 13 filesevent blocks 13Parser family: jy html (family:jy_html/jy_html), 13 filesjy html 13Parser family: race cards (family:race_cards/race_cards), 12 filesrace cards 12Parser family: racegrid html (family:racegrid_html/racegrid_html), 12 filesracegrid html 12Parser family: not results (family:terminal/not_results), 12 filesnot results 12Parser family: lane grid (family:lane_grid/lane_grid), 10 fileslane grid 10Parser family: dbc htm (family:csv_blocks/dbc_htm), 9 filesdbc htm 9Parser family: titled list (family:titled_list/titled_list), 8 filestitled list 8Parser family: dbc pdf (family:race_blocks/dbc_pdf), 7 filesdbc pdf 7Parser family: csv cards (family:csv_cards/csv_cards), 4 filescsv cards 4Parser family: alkame (family:terminal/alkame), 4 filesalkame 4Parser family: two lane (family:two_lane/two_lane), 4 filestwo lane 4Parser family: team place html (family:html_results/team_place_html), 3 filesteam place html 3Parser family: standings (family:standings/standings), 3 filesstandings 3Parser family: crash (family:terminal/crash), 3 filescrash 3Parser family: ocr low quality (family:terminal/ocr_low_quality), 2 filesocr low quality 2Parser family: race rows (family:race_rows/race_rows), 1 filesrace rows 1Parser family: results of racing (family:results_of_racing/results_of_racing), 1 filesresults of racing 1Parser family: ocr needed (family:terminal/ocr_needed), 1 filesocr needed 1Edition status: parsed (status:parsed), 480 filesparsed 480Edition status: found (status:found), 36 filesfound 36Edition status: partial (status:partial), 21 filespartial 21Edition status: ocr low quality (status:ocr_low_quality), 2 filesocr low quality 2
Left to right: how each URL was found, what the catalogue made of it, whether it was fetched, which parser read the file, and the coverage status of the edition it belongs to. A fetched sheet can hold several tabs and a file can be found at two URLs, so 589 fetched URLs became 613 files. Hover a bar or a flow for its count.
Funnel table (85 flows)
Every flow of the diagram, from reports/funnel.json
FromToCount
Parser family: alkameEdition status: parsed57
Parser family: csv blocksEdition status: parsed20
Parser family: dbc htmEdition status: parsed9
Parser family: csv cardsEdition status: parsed4
Parser family: event blocksEdition status: parsed13
Parser family: dbbc gridEdition status: parsed103
Parser family: team place htmlEdition status: parsed3
Parser family: jy htmlEdition status: parsed13
Parser family: lane gridEdition status: parsed5
Parser family: lane gridEdition status: partial5
Parser family: ordered listEdition status: parsed80
Parser family: ordered listEdition status: partial2
Parser family: placings sheetEdition status: parsed25
Parser family: club pdf heatsEdition status: parsed40
Parser family: dbc pdfEdition status: parsed7
Parser family: gwn pdfEdition status: parsed50
Parser family: gwn pdfEdition status: partial3
Parser family: race cardsEdition status: parsed12
Parser family: race rowsEdition status: parsed1
Parser family: racegrid htmlEdition status: parsed12
Parser family: results of racingEdition status: parsed1
Parser family: standingsEdition status: found1
Parser family: standingsEdition status: partial2
Parser family: alkameEdition status: parsed4
Parser family: crashEdition status: found3
Parser family: not resultsEdition status: parsed12
Parser family: ocr low qualityEdition status: ocr low quality2
Parser family: ocr neededEdition status: found1
Parser family: unknownEdition status: found31
Parser family: unknownEdition status: partial6
Parser family: titled listEdition status: parsed6
Parser family: titled listEdition status: partial2
Parser family: two laneEdition status: parsed3
Parser family: two laneEdition status: partial1
Fetched: okParser family: alkame57
Fetched: okParser family: csv blocks20
Fetched: okParser family: dbc htm9
Fetched: okParser family: csv cards4
Fetched: okParser family: duplicate74
Fetched: okParser family: event blocks13
Fetched: okParser family: dbbc grid103
Fetched: okParser family: team place html3
Fetched: okParser family: jy html13
Fetched: okParser family: lane grid10
Fetched: okParser family: ordered list82
Fetched: okParser family: placings sheet25
Fetched: okParser family: club pdf heats40
Fetched: okParser family: dbc pdf7
Fetched: okParser family: gwn pdf53
Fetched: okParser family: race cards12
Fetched: okParser family: race rows1
Fetched: okParser family: racegrid html12
Fetched: okParser family: results of racing1
Fetched: okParser family: standings3
Fetched: okParser family: alkame4
Fetched: okParser family: crash3
Fetched: okParser family: not results12
Fetched: okParser family: ocr low quality2
Fetched: okParser family: ocr needed1
Fetched: okParser family: unknown37
Fetched: okParser family: titled list8
Fetched: okParser family: two lane4
Catalogued as: resultsFetched: http 4xx14
Catalogued as: resultsFetched: ok589
Catalogued as: resultsFetched: skipped4
Found by: catalog overrideCatalogued as: results3
Found by: catalog overrideCatalogued as: review1
Found by: manualCatalogued as: results3
Found by: seed crawlCatalogued as: not results52
Found by: seed crawlCatalogued as: results243
Found by: seed crawl offsiteCatalogued as: index88
Found by: seed crawl offsiteCatalogued as: not results75
Found by: seed crawl offsiteCatalogued as: results11
Found by: seed crawl pageCatalogued as: index95
Found by: seed crawl pageCatalogued as: not results77
Found by: seed crawl pageCatalogued as: results108
Found by: seed crawl pageCatalogued as: review16
Found by: seed knownCatalogued as: results7
Found by: wayback cdxCatalogued as: index64
Found by: wayback cdxCatalogued as: not results364
Found by: wayback cdxCatalogued as: results144
Found by: wayback cdxCatalogued as: review147
Found by: wp mediaCatalogued as: not results28
Found by: wp mediaCatalogued as: results88
Found by: wp mediaCatalogued as: review1

Coverage by event and year

The coverage register lists every edition of every event the project knows of, with how far its results got: 331 of 566 editions across 62 events are parsed. Events are sorted by parsed editions. A blank cell is a year with no known edition; hover or focus a cell for its detail.

566 editions of 62 events, 1989–2026
Event19891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026no year
concord-pacificNFNFNFNFNFNFNFNFNFNFNFNFNFNFPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPANSPAPAPAPAPAPA
ottawa-dbfPAPAPTPAPAPAPANSPAPAPAPAPAPAPAPANSNSPAPAPAPAPA
tidbrfNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSPANFPAPAPAPANFPAPAPAPAPAPANFPAPANSNSPAPAPAPAPA
halifax-manulifePAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPA
pentictonNSNSNSNSNSNSNSNFPAPAPAPAPAPAPAPAPAPAPAPANSNSPAPAPAPAPA
dbc-nationalsPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPA
pickeringPANFPAPAPAPAPAPANFPAPAPAPAPAPAPAPAPA
lachinePAPAPAPAPAPAPAPAPAPAPAPAPA
coupe-du-quebecPAPAPAPAPAPAPAPAPAPAPAPA
pickering-youthPAPAPAPAPANFPAPAPAPAPAPA
dz-500PAPAPAPAPAPAPAPAPAPA
dz-youth-regattaPAPAPAPAPAPAPAPAPAPA
richmond-stevestonPAPAPAPAPAPAPAPAPAPA
calgaryFDNSFDFDPANFNFNFNFNFNFNFNFNFNFPAPAPANSNSPAPAPAPAPA
montreal-challengePAPAPAPAPAPAPAPAPA
gwn-challengeNSNSNSNSNSNSNSNSNSNSNSNFNFPAPANFNFNFNFNFNFPAPANFNSNSPAPANFPAPA
gwn-chicagoPAPAPAPAPAPAPAPA
gwn-mercerPAFDFDFDPAPAPAPAPAPAPA
dz-spring-sprintPAPAPAPAFDPAPAPA
christie-lakePAPAPAPAPAPA
gwn-sarasotaPAPAPAPAFDPAPA
gwn-sport-regattaPAPAPAPAPAPA
hamilton-waterfestFDPAPAPAPAPAPA
miltonNSPAPAPAPAPAPA
port-perryPAPAPAPAPAPA
dz-fall-classicPAPAPAPAPA
gwn-orlandoPTPAPAPAPAPA
edmontonNSPANFNFNFNFNFNFNFNFSUNFNFNFNFNFPAPAPA
gwn-ridbfPAPAPAPA
hope-floatsPAPAPAPA
reginaPAPTPAFDPAPTPAOCFD
h2o-openPAPAPA
pan-am-cccPAPAPANS
victoriaPAPAPANFNSNFNFNFNFNFNFNFNFNFNFNFNFNFNFNFNFNFNF
can-am-cccPAPA
gwn-kcdbfPAPA
gwn-nycPAPA
lethbridgeNFPAPA
okanagan-super-sprintsFDNSFDFDNSFDFDFDFDFDFDNSNSNSNSNSFDPAPA
vernonNSPAPAFDNSFDNFNFFDNSNSFDFDNFNSNS
dz-oddball-2kPA
harrisonNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNFNFNFPA
kamloopsPA
kelownaPAOCPT
osoyoos-flag-racePA
ottawa-ice-dragonPA
winnipeg-septemberPTPANS
alberta-long-tailNS
atlantic-long-tailNS
barrieNS
dbc-race-seriesNS
gwn-otherNS
idbf-champsNS
manitoba-schoolNS
montreal-festival-historicNS
ontario-long-tailNS
shuswapFDNFFDFDFDNHNHNFNFNFNFNFNFNFNF
sudburyNSNSNSNSNSNSNS
sydenham-challengeNSNSNS
triple-crown-qcNS
winnipegNSNS
woodstockNS

Consistency checks

Every build counts the rows that break one of these invariants. Each count has a ceiling it may not rise above without a logged decision, so the archive can only get cleaner. Races that fail I3, I6 or I12 are kept on their event page but left out of the ratings (see which races count).

16 invariants, from reports/quality.md
IDViolationRowsEditionsTop editions
I1_time_in_nameteam_name holds a finish time anywhere (H:MM:SS / M:SS.ff / M:SS.fff)00-
I2_rule_as_crewteam_key is progression or heading text (fastest, from race, advances, ...) or a bare division word255gwn-sarasota-2023 (8), dbc-nationals-2007 (7), pickering-2013 (5)
I3_empty_resultrace_level entry with no time, no place and nothing printed in the time column (status NULL, or NO_RESULT from a blank time_raw)1,40966concord-pacific-2023 (254), concord-pacific-2025 (214), coupe-du-quebec-2024 (167)
I4_edition_idedition_id is not <event_id>-<4-digit year>, or event_id itself contains a 4-digit year00-
I5_time_rangetime_ms outside the plausible band for the race distance (200 m 0:30-4:00, 250 m 0:35-5:00, 500 m 1:20-7:00, 1000 m 3:00-12:00, 2000 m 7:00-25:00)10627gwn-challenge-2026 (16), dz-oddball-2k-2022 (11), montreal-challenge-2024 (11)
I6_place_orderwithin a race, a place repeated more than twice, or a place greater than the number of entries1,41258ottawa-dbf-2006 (157), ottawa-dbf-2005 (140), ottawa-dbf-2018 (120)
I7_blank_nameteam_key blank or NULL219montreal-challenge-2013 (7), dbc-nationals-2015 (4), gwn-orlando-2019 (3)
I8_footnote_in_nameteam_raw holds penalty/bonus footnote text (penalty, bonus for, impeded, interference, second credit, ...)21ottawa-dbf-2014 (2)
I9_doubled_glyphsteam_name holds fake-bold doubled glyphs (three doubled letters in a row, '::', or a time with 4+ decimals)00-
I10_glued_textteam_name over 70 characters or holding instruction text (determines N, start first, minute gap, +N sec, Race N:, turn left/right, merge onto, Rang Équipe, ...)11halifax-manulife-2009 (1)
I11_club_wrapclub cell is a bare continuation word (Club, Centre, ...), or the team name ends with the first words of a club printed in the same edition (a two-line club read into the crew name)52tidbrf-2004 (3), dbc-nationals-2018 (2)
I12_split_placesrace not marked combined in which a printed place is shared by finishers whose times differ by more than 0.5 s (divisions ranked separately inside one race)32065can-am-ccc-2024 (50), dbc-nationals-2014 (32), gwn-mercer-2017 (29)
I13_short_key_spanshort crew key (digits, or 1-2 letters and at most one digit) whose team_id spans more than one province (or, for events without a single province, more than one edition)00-
I14_bib_prefix_splitin a bib-printing file, team_name '<token> <rest>' whose <rest> is printed with the same bib in the same edition under another team_id (a division/progression code or seed read into the name)132can-am-ccc-2026 (8), gwn-challenge-2010 (5)
I15_place_time_ordertimed, placed race (3+ entries, not combined) in which more than n // 2 pairs of crews have their place order reversed against their time order (places read from another column)15558dbc-nationals-2014 (21), can-am-ccc-2024 (17), gwn-mercer-2017 (9)
I16_team_twice_in_raceentry whose team_id holds more than one entry in its race, any status (two crews merged into one team, a heading or same-name crew keyed alike, or a row the parser duplicated); C57, D804115lachine-2014 (6), ottawa-dbf-2024 (4), richmond-steveston-2023 (4)

Assumptions

Values the data relies on that no source prints, each with its basis, where it applies, how confident the project is and what would make it revisit the assumption. Process decisions are logged separately and are not listed here.

23 assumptions, from ASSUMPTIONS.md
IDAssumptionBasisApplies toConfidenceRevisit ifStatusSource
A1The Ottawa live Google Sheets with no printed year are 2026 results.The Ottawa page already announces the 2027 dates; the raw snapshot is dated 2026-11-07.ottawa 2026 published-sheet tabs (catalog year 2026).highThe sheets are overwritten in 2027 (keep the 2026-11-07 snapshot).activeowner 2026-11-07
A2Regina crews printed only as entry codes (AMR 1, S101, W3) are kept as event-scoped identities: they race within their own edition, never merge with a team in another edition, and a code is never guessed to be a team name.No code-to-name key exists on reginadragonboat.com or in Wayback copies. Safe; loses cross-event linkage for those crews.regina 2013, 2014 (sprint and heats), 2017 (lane_grid, D15). Implemented in T6.highTeam lists are obtained from the organizer (keep on the outreach list).activeowner 2026-11-07
A3The Lachine course is 200 m.Winning times of 0:48–0:58 match 200 m standard-boat times. No file prints the distance.All lachine races 2008–2024 with no printed distance: default_distance_m: 200 in sources.yaml, distance_inferred = TRUE.mediumMission Dragon Boat or another source states a different course length.activeowner 2026-11-07
A4Halifax times printed as SS:FF with SS ≥ 30 are seconds and hundredths ("55:27" = 55.27 s), and plain seconds ≥ 60 are m:ss ("65.38" = 1:05.38). Rewritten in time_raw with a warning.Read as minutes, SS:FF ≥ 30 would be implausibly slow for a 200–500 m race; plain seconds ≥ 60 can't be parsed as printed. Both styles appear in the same files (D12).halifax event_blocks / team_place_html files.highA Halifax file states its time format differently.activeD12
A5The Ottawa 2013 alumni sheet's SS:FF times are seconds and hundredths ("26:24" = 26.24 s). Rewritten with a warning.Same reasoning as A4: read as minutes the times would be implausible for a sprint.ottawa 2013 alumni sheet (titled_list).highA source prints a different reading.activeD19
A6When no place is printed, or printed ranks are ambiguous (repeat within one race), place is the rank by finish time (confidence = inferred).Finish order by time is what places mean when crews race the same distance together.lane_grid (Regina, D15); race_cards cards with repeated ranks (D16); titled_list (D19); race_rows (D19); csv_cards ambiguous lane splits (D20).highA file shows places that disagree with time order (penalties, adjustments).activeD15, D16, D19, D20
A7When a list has no place column, the printed row order is the finish order (confidence = inferred).Parsed as finish-order lists in D5, D14 and D19; the sources print no place, so the order is the only signal.ordered_list (D14) rows without a printed place; csv_blocks tables with no rank column; titled_list lists with neither lane header nor rank; standings pseudo-races (D5).mediumA source lists crews in lane or draw order instead.activeD5, D14, D19
A8Ottawa 2016 charity places are re-derived from the on-water time, not the printed "adjusted time including fundraising incentive".The adjusted ranking is not a race result; the on-water time is.ottawa 2016 charity finals (titled_list).highThe project decides fundraising-adjusted standings should be kept.activeD19
A909:99.99 and 09:95.95 are timing placeholders meaning no time (NT), not real times.No crew takes ~10 min over a sprint course; the values recur as fillers.Ottawa 2025–26 Saturday sheets (ordered_list), 2026 charity challenge cup (race_rows), csv_blocks.highA sheet uses these values as real times.activeD14, D19
A10"DNC" (did not compete) is the same as DNS.The Can-Am sheet's own note defines DNC as did not compete.csv_cards (Can-Am 2026).highA source distinguishes DNC from DNS in a way that matters for ratings.activeD20
A11Printed Can-Am times already include penalties (footnote stars are stripped).D20 reading of the sheet: the stars are penalty footnotes and the printed times are taken as final. Not confirmed by the organizer.csv_cards (Can-Am 2026).mediumThe organizer publishes raw times plus penalties separately.activeD20
A12When neither the file name, link text nor URL path has a year, the year comes from the page the link was found on.Ottawa posts year-less files (/media/342461/sunday-race-results.pdf) from per-year pages (/teams/race-results/2019.aspx)._year() fallback in ingest/catalog.py.mediumA source page links files from other years.activeD7
A13A race with no printed distance gets its event's default_distance_m (distance_inferred = TRUE).Events that run a single course length.dz-500 (500 m), dz-oddball-2k (2000 m), lachine (200 m, A3). Applied in build_db.race_distance; a race_overrides.yaml entry beats both the printed value and the default (D82).mediumA race in those events is printed at another distance (the printed value always wins).activeD6, D82
A14A club acronym (PDBC, FCRCC, 22D …) names the club whose full name is printed beside it, and only that club; trailing age, gender, tier and boat-size words (Snr B Mixed, Premier, SM, _10, PM2) name a crew of the club, not a different club. Used for teams.club_id only, never to merge teams.ingest/normalize/club_aliases.yaml: each acronym is expanded only when a source prints it in the team name with the full name in the club column (or in the same club column); 32 rows, cited by edition. Acronyms with conflicting evidence (CSBD, MDBC, SNS) stay unexpanded. Suffix words: Pan Am CCC names (Pickering DBC Snr B Mixed), DBC Nationals 2025 SM crews in boat_size = small races.ingest/identity.py club_match_keys (C5); all teams with a club.mediumA source shows one acronym used by two clubs, or a suffix word that is part of a club's name.activeD40
A15A trailing class suffix of a crew name (Snr B Mixed, U21 Open, Masters C Women, 60+ women) is the crew's age and gender class: Snr/Senior/Sr/Masters + letter A-D = senior_a-d, 40+/50+/60+/70+ = senior_a-d, bare Masters = senior_a, Junior/Jr = u18, U<nn> = u<nn>, Men = open; a bare Senior gives no age. Used only where the race prints no class for that field.pan-am-ccc-2019 pages print the class beside each crew and in the race's left margin (U16, Snr C, U21 for race 1) while the title reads only "Mixed"; crews keep the same suffix across rounds. The letter and + mappings follow AGE_RULES for race titles.normalize.rounds.class_suffix / entry_class in build_db (entries.age_group, gender_class, class_suffix); teams.age_group. 2,059 entries take their age class from a suffix.mediumA source shows Masters C or a bare Senior meaning another age band, or a suffix that is part of a club's name.activeD55
A16A race with no printed or default distance is in the sprint bucket (≤ 500 m) when its winning time is under 4:00, else in the long bucket (≥ 1000 m); a race with neither distance nor time takes its edition's majority bucket.DB winning times: 99th percentile 2:38 for 200 m and 3:09 for 500 m races, 1st percentile 4:12 for 1000 m. Null-distance winners cluster at 0:30–3:30 and 8:00–12:30, with 24 races between 3:30 and 8:00.Rating pools in ratings/data.py (R1, D67): 7,972 rating races bucketed by winning time, 8 by edition majority (reports/ratings/events.md).mediumA source prints a distance that contradicts the bucket, or 1000 m races under 4:00 appear (fast small-boat 1000 m).superseded by A19 (D78)D67
A17A race with no printed boat size is a standard (20-seat) boat race.Small-boat races are labelled (Small, Petit, SB, 10s) wherever the DB marks them (487 races since C71, D102: the bare word in a race title counts, 316 before); standard is the festival default in every series the DB covers. A title naming both sizes is mixed (22 races) and not rated, so the assumption no longer covers it. Known gaps: a small crew entered in a standard division is rated there (hamilton-waterfest-2023, 8 races; C73), and 6 dbc-nationals-2023 races under a stray "Small" section line have no size word of their own.Rating pools in ratings/data.py (R1, D67): races with boat_size NULL go to the standard_* pools (17,234 races).mediumAn event runs only small boats without printing it (a small-boat regatta or festival).activeD67, D102
A18An edition with no start_date is dated 1 July of its year for rating order (the year's midpoint, phase_2_SPEC §2).No edition in the DB has a start_date (0 of 314).Rating event timestamps in ratings/data.py (R1, D67): every rating race today. Editions sharing a date interleave by race order.lowEdition dates are filled (MP task R1b): the within-year order of events then comes from the dates.activeD67
A19A race with no printed or event-default distance is rated at the distance its winning time points to: 35 s to under 62 s → 200 m; 1:40 to under 4:00 → 500 m; 7:00 or more → 2000 m. Any other winning time, or none, leaves the race unrated (distance_unknown). An event default (A13) is a distance and always comes first.Validated (D79) on Canadian races that print their distance, defaults excluded (data.band_validation, generated in reports/ratings/events.md): 200 m band 96.2 % raw / 98.4 % clean (1,715 races; misses: 26 races at 250 m, 1 at 175 m); 500 m band 94.0 % raw / 100 % clean (2,609); 2000 m band 97.7 % raw / 99.7 % clean (296). 'Clean' left out 214 printed distances the winning time rules out (200 m in 1:40+, 500 m under 1:15 or 7:00+): TIDBRF 2019/2023-2026 and GWN 2018 '200 m' at about 2:15, Nationals 2023 '500 m' at 43-57 s, Pan Am 2015 '500 m' at 10 min. C59 (D82) traced them to the parser (section headings swallowed into the block above), to labels naming two distances ("500m + 2000m": such a label now gives no distance, so A19 decides) and to one misprint; after it, raw accuracy is 98.45 / 100 / 99.3 % and the one race left (gwn-challenge-2026 race 37, placeholder times) is kept as printed with its reason in race_overrides.yaml. The first band (under 1:15, D78) was 84.5 % / 93.0 %: 100 m super sprints (Ottawa, winners 20-34 s) and 250 m races (59-74 s) fell in it, so D79 narrowed it to 35-62 s, the widest range at ≥ 98 % clean. Owner chose winning-time inference over excluding null-distance races (D78).ratings/data.py rated_distance (DATA_VERSION 3): 7,699 of 13,006 rating races take their distance from the winning time (D82); 393 null-distance races are distance_unknown.mediumA clean accuracy drops below 98 % in the generated validation; a series with unlabelled 100 m, 250 m or 1000 m races is added; a keep_printed reason in race_overrides.yaml turns out wrong.activeD78, D79, D82
A20The leaderboard floor is the 10th percentile (rounded down) of the Nationals crews' rated regattas and rated races in the season at any rated distance (D79: all-distances activity), with an absolute minimum of 2 regattas and 6 races; seasons without Nationals inherit the last earlier floor. It applies to every view, judged on the crew's all-distances activity; a view also needs 3 rated races in it.Owner decisions D78 §7 and D79 §1: a crew is ranked when it raced at least as much as the least-active crews at that season's Canadian National Championships. In the data every season's computed floor is at or below the minimum (most Nationals crews appear at one regatta a season), so 2 regattas / 6 races applies throughout (reports/ratings/eligibility.md, 2026-11-09).ratings/ranking.py season_floors, eligible, MIN_VIEW_RACES; meta.json eligibility; ranked standard_all 264, standard_500 262, standard_200 235, standard_2000 4, small-boat views 0 (D79).mediumIt ranks too few crews in a view (today: every small-boat view), or coverage per season grows so the computed floor rises above the minimum (C58 may link Nationals crews to their other regattas).activeD78, D79
A21dragonboat.net/media/675699/sunday-race-results.pdf is the 2024 Ottawa Sunday results (the file prints no year).PDF created 2024-06-28 (the festival ran June 21-23, 2024); a crew named "2024: A Space ODC"; linked as "SUNDAY RACE RESULTS" from raceresults.aspx in the Wayback captures of 2024-08-11 and 2024-11-03; its divisions and crews match the 2024 Saturday file.ottawa-dbf 2024 Sunday races (catalog_overrides.yaml, 48 races).highThe festival re-links or re-labels the file, or a different 2024 Sunday file appears at media/675696.activeD100
A22Every race on a Manitoba Paddling Association "Upstream / Down Stream" sheet is a pursuit-format race, including the 2023 finals sheet, which does not print the word.The 2024 September sheet is headed "Sunday September 8th, 2024 - PURSUIT" over its rounds and finals; the 2023 totals sheet (Sept DB Results 2.pdf) names the two rounds "Pursuit 1" and "Pursuit 2"; the 2023 finals sheet has the same two-boat Upstream / Down Stream columns and "Nth fastest in ..." seeding from those rounds.winnipeg-september 2023-2024: section "Pursuit ..." on 72 races (two_lane), so relay_or_pursuit leaves them unrated.mediumMPA describes the September format (side-by-side lanes would make them ordinary two-boat races), or G10 parses the 2026 sheet and finds a different heading.activeD104
A23A club's home province is the one club_provinces.yaml gives it, or, for a club not listed there, the province where all of its crews race mostly, when there are enough of them: two for a club a sheet prints in a club column, three for a club that is only a shared beginning of crew names, and crews at two or more US regattas for a US club (D131). Any other club has no province.No results sheet prints a club's province. Register entries (59) rest on a place in the club's own name (Pickering, Edmonton, Calgary, Fort Langley, Toronto, Vermont, NYC), on what the sheets print beside the name ("Dragnum - Dragon Boat Calgary", "Dasa/Lethbridge", "Catch22 Racing Ltd (New York)"), or on a clear majority of crews for a name that is one club (22Dragons 223 of 232 in QC). The all-crews-agree case holds for 618 clubs (845 before D131: two crews sharing a first word, or one visit to a US regatta, proved thin: "Dragonflies", "Toba").The province shown for 4,561 crews (home_province_basis club), the Canadian-home rule (D78) and the province floor.mediumA club moves, a listed name turns out to cover two clubs, or a source that prints club addresses is found (a governing body's club list).activeD121, D131

This build

Built from commit 512abfd, data as of : 100,595 crew results in 18,625 races across 337 editions; 15,104 races and 81,429 results feed the ratings of 11,697 crews.