What this pack is

2 contests, 338 people, 62 poll response rows, 1,959 result rows and 218,699 money edges, built 2026-09-03.

The cycle phase shown on every contest is computed from the election date and how well that date is known. The corpus carries its own status column; it disagrees with the derived phase on 20 of the 61 contests across all twenty-two countries, so it is carried through but never read.

Money rows and result rows are held off the site at their full grain: the staged corpus is 156 MB. What is published here is the aggregate computed once at build time, and every aggregate states the number of rows it stands for.

Everything known to be wrong or limited

licence · grain · method
  • An as-submitted snapshot: only 846 of 1,959 GE45 candidacies appear, because returns publish as filed and audited. Absence is not zero. Party and EDA money is annual-return money whose received date falls in the writ period, so filter on cycle, not election_id. All contributors are individuals - corporate and union gifts are illegal in Canada - so there are no PAC or independent-expenditure labels.
  • vote_share is a FRACTION (0-1), not a percentage. Built from Elections Canada poll-by-poll files summed per district and checked against EC Table 12: zero district mismatches across 1,959 rows.
  • 338 of 343 seats. Five were vacant on 2026-09-03, three of them contested at the 2026-08-31 by-elections with winners not yet seated. Missing MPs were not invented. Senators are omitted: sencanada.ca is JS-rendered with no stable id.
  • Elections Canada's licence and terms pages both returned HTTP 500 on repeated attempts. The licence is recorded only as 'Elections Canada open data (elections.ca)'. Confirm before commercial redistribution.
  • vote_share in this pack is a FRACTION of 1 (largest observed 0.839843), not a percentage. India and Nigeria file percentages; the rest file fractions.

The pack's own record

every URL fetched, every inclusion and exclusion
SOURCES.md
# CAN sources

Everything below was fetched on 2026-09-03. ourcommons.ca blocks this box's IP with a 403, so House of
Commons material was fetched through the user's registered machine (Zee.local) — the URLs are the real
official endpoints and are listed as such. No Wikipedia was used anywhere in this pack, and no figure in
any CSV comes from a search-engine summary.

## Calendar / elections.csv

| URL | What came from it |
|---|---|
| https://www.elections.ca/content.aspx?section=ele&document=index&lang=e | Elections Canada "Elections" landing page. Live content on 2026-09-03: **"August 31, 2026 by-elections in: Chicoutimi–Le Fjord (QC), Beaches–East York (ON), North Vancouver–Capilano (BC)"**. The "a federal general election has been called" line on that page is inside an HTML comment (a 2025 leftover) — no general election is called, which is why `cycle_status=sitting`. |
| https://www.elections.ca/content.aspx?section=ele&dir=pas&document=index&lang=e | Past elections index (confirms the 45th general election as the last national contest) |
| https://laws-lois.justice.gc.ca/eng/acts/e-2.01/section-56.1.html | Canada Elections Act s.56.1: (1) preserves the Governor General's power to dissolve Parliament; (2) "each general election must be held on the third Monday of October in the fourth calendar year following polling day for the last general election" → 2029-10-15 for `can-hoc-next`, `date_confidence=constitutional_due` |
| https://www.elections.ca/content.aspx?section=res&dir=rep/off/45gedata&document=index&lang=e | "45th General Election: Official Voting Results (raw data)" page (date modified 2025-11-12) — download index for the poll-by-poll and summary tables; `source_url` for elections.csv and results.csv |
| https://www.elections.ca/content.aspx?section=abo&document=notices&lang=e , https://www.elections.ca/content.aspx?section=pol&document=index&dir=oda&lang=e | **Attempted and failed** (HTTP 500 both times) — this is why the `license` column says only "Elections Canada open data (elections.ca)" rather than quoting a licence |

## people.csv

| URL | What came from it |
|---|---|
| https://www.ourcommons.ca/members/en/search/csv | Current House of Commons roster, 338 rows: Person ID, honorific, first/last name, constituency, province/territory, political affiliation, start date. This is the `source_url` on every people row. |
| https://www.ourcommons.ca/members/en/search/xml | Same roster in XML (used to confirm the row count and field values; 338 members) |
| https://www.ourcommons.ca/members/en/{PersonId} | One fetch per member (338 requests) to read the official 45th-Parliament photo path off the profile page, and the `official_url` recorded in the file |
| https://www.ourcommons.ca/Content/Parliamentarians/Images/OfficialMPPhotos/45/… | The official photo URLs recorded verbatim in `photo_url` (338/338 found). Deriving these from names + party was tested and rejected: the filename encodes the party at photo time (e.g. `DEntremontChris_CPC.jpg` for a member now sitting as a Liberal), so guessing them would have produced wrong or dead links. |
| https://sencanada.ca/en/senators/ , https://sencanada.ca/en/senators/?v=list | **Attempted; no data used.** The senator list is client-side rendered: the served HTML contains no senator links, no embedded JSON and no API endpoint, and headless Chrome returned an empty DOM. Senate profile URLs are name slugs, not stable ids, so senators were left out rather than keyed on a slug (see HANDOFF). |

## money-edges.csv

| URL | What came from it |
|---|---|
| https://www.elections.ca/content.aspx?section=fin&dir=oda&document=index&lang=e | Elections Canada **Political Financing → Open Data** page; located the contributions bulk downloads |
| https://www.elections.ca/fin/oda/od_cntrbtn_de_e.zip | "Contributions — as submitted" bulk download (206 MB zip → 4.4 GB CSV, 12,655,377 contribution rows across all events and fiscal years). Streamed and filtered on this box; this URL is the `source_url` on every money row. |

Filtering actually applied (all of it reproducible from the file above):

1. First pass kept rows whose fiscal/election date is 2025 or 2026 **or** whose electoral event is the
   45th general election → 1,193,431 rows.
2. `money-edges.csv` then kept: **all** `Candidates` rows for the *45th general election*;
   `Registered parties` rows from the *Registered Party Financial Transactions Return (2019)* for fiscal
   2025 whose contribution-received date falls in the writ period **2025-03-23 … 2025-04-28**; and
   `Registered associations` rows from the *Registered Association's Financial Transactions Return (2019)*
   for fiscal 2025 in the same window.

## results.csv

| URL | What came from it |
|---|---|
| https://www.elections.ca/res/rep/off/ovrGE45/62/data_donnees/pollresults_resultatsbureauCanada.zip | Poll-by-poll official results for all 343 electoral districts (343 CSVs): candidate family/middle/first name, political affiliation (EN/FR), incumbent and elected indicators, per-poll candidate votes, rejected ballots and electors. Aggregated to candidate × district. |
| https://www.elections.ca/res/rep/off/ovrGE45/62/data_donnees/table_tableau12.csv | Elections Canada Table 12 (official candidate votes and published percentages, 1,959 rows) — used **only to validate** the aggregation: district totals match for all 343 districts and the derived percentages match the published ones for all 1,959 rows. |
| https://www.elections.ca/content.aspx?section=res&dir=rep/off/45gedata&document=pollresults&lang=e | Poll-by-poll download page (per province/territory and all-Canada zips) |
| https://www.elections.ca/content.aspx?section=res&dir=rep/off/45gedata&document=index&lang=e | Landing page for all of the above; recorded as `source_url` in results.csv |

## polls.csv

| URL | What came from it |
|---|---|
| https://abacusdata.ca/liberals-hold-a-six-point-lead-as-carney-government-approval-remains-above-50/ | Abacus Data, field 9–16 Jul 2026, n=4,205, MoE ±1.5 — Lib 43 / Con 37 / NDP 9 / BQ 7 / Grn 3 |
| https://abacusdata.ca/liberals-maintain-six-point-lead-as-trump-tariff-threat-and-wildfires-reshape-the-public-agenda/ | Abacus Data, 23–29 Jul 2026, n=1,910, MoE ±2.24 |
| https://abacusdata.ca/carney-liberals-lead-by-seven-nationally-as-quebec-support-drops/ | Abacus Data, 7–12 Aug 2026, n=1,499, MoE ±2.5 |
| https://abacusdata.ca/liberals-open-10-point-lead-as-trump-returns-to-the-centre-of-the-agenda/ | Abacus Data, 21–26 Aug 2026, n=2,022, MoE ±2.2 |
| https://angusreid.org/federal-politics-canadians-cooling-on-carney-as-gap-narrows-between-liberals-and-cpc/ | Angus Reid Institute, 4–10 Jun 2026, n=4,237 — Lib 41 / CPC 36 / NDP 12 (only these three are printed) |
| https://angusreid.org/climate-vote-liberal-ndp/ | Angus Reid Institute release for the 25–27 Jul 2026 survey (fieldwork, n=1,770, methodology) |
| https://angusreid.org/wp-content/uploads/2026/07/2026.07.28_Fed_Vote_tables.pdf | The same survey's published data tables — full topline (Lib 40 / CPC 36 / NDP 13 / BQ 6 / Grn 3 / Other-Ind 2) on a decided+leaning base of 1,571 |
| https://www.ipsos.com/en-ca/liberal-lead-over-conservatives-grows-8-points | Ipsos for Global News, 25–26 Feb 2026, n=1,001, credibility interval ±3.8 |
| https://www.ipsos.com/en-ca/liberals-open-double-digit-national-lead-over-conservatives-advance-elections | Ipsos for Global News, 2–7 Apr 2026, n=1,000, credibility interval ±3.8 |
| https://leger360.com/in-the-news-federal-polling-june-2026/ | Léger, 19–22 Jun 2026, n=1,528, decided voters |
| https://leger360.com/in-the-news-federal-polling-august-2026/ | Léger, 1–3 Aug 2026, n=1,514, decided voters |
| https://nanos.co/the-economy-tops-minds-liberals-top-polls-liberals-45-6-conservatives-29-1-ndp-12-9-nanos/ | Nanos weekly tracking release (rolling-average methodology, link to the data package) |
| https://nanos.co/wp-content/uploads/2026/08/Political-Package-2026-08-07-ZXbP68974-FOR-RELEASE.pdf | Nanos political package: weekly tracking ending 7 Aug 2026, n=1,038, accurate ±3.1 — LPC 45.6 / CPC 29.1 / NDP 12.9 / BQ 6.8 / Grn 4.0 / PPC 1.3 |
| https://nanos.co/category/political-tracking/ (index) | Nanos release index (link discovery; publication dates only, which are not fieldwork dates) |
| https://researchco.ca/ , https://researchco.ca/category/canada/ | **Attempted; no rows.** Research Co.'s recent releases on the site index were issue polls (health care, policing, Alberta separation, justice); no federal vote-intention table was published there at build time. |
HANDOFF.md
# CAN elections pack handoff

Written 2026-09-03 to `/workspace/elections-ingest/can/`.

## Files / counts

| File | Rows (excl. header) | Path |
|---|---|---|
| elections.csv | 2 | /workspace/elections-ingest/can/elections.csv |
| people.csv | 338 | /workspace/elections-ingest/can/people.csv |
| money-edges.csv | 218699 | /workspace/elections-ingest/can/money-edges.csv |
| polls.csv | 62 | /workspace/elections-ingest/can/polls.csv |
| results.csv | 1959 | /workspace/elections-ingest/can/results.csv |
| SOURCES.md | — | /workspace/elections-ingest/can/SOURCES.md |
| STATS.json | — | /workspace/elections-ingest/can/STATS.json |
| HANDOFF.md | — | /workspace/elections-ingest/can/HANDOFF.md |

## Cycle status (verified against Elections Canada / the statute)

- `can-hoc-2025` **sitting** — 2025-04-28, `confirmed_official`. 45th general election; Elections Canada
  published the official voting results (raw data page last modified 2025-11-12). 45th Parliament sitting.
- `can-hoc-next` **sitting** — 2029-10-15, `date_confidence=constitutional_due`. Not called. The date is
  **computed from the statutory formula**, not announced: Canada Elections Act s.56.1(2) — "the third
  Monday of October in the fourth calendar year following polling day for the last general election" —
  which after 2025-04-28 is Monday 2029-10-15. s.56.1(1) expressly preserves the Governor General's power
  to dissolve Parliament earlier, s.56.2 allows an alternate day, and the 45th Parliament is a **minority**,
  so treat this as a ceiling, not a fixture.
- No officially announced general-election date contradicts the brief. One live-content note: the Elections
  Canada "Elections" landing page still contains the sentence "a federal general election has been called"
  **inside an HTML comment** — a 2025 leftover, not current. The visible content on 2026-09-03 announces
  only the 2026-08-31 by-elections (Chicoutimi–Le Fjord, Beaches–East York, North Vancouver–Capilano).

## Join keys

- `people.csv.person_id` = **House of Commons "Person ID"** — the numeric id in
  `ourcommons.ca/members/en/{id}` (e.g. `89156` = Ziad Aboultaif). Never a name slug.
- `people.csv.election_id` → `can-hoc-2025` for all 338 rows.
- `money-edges.csv.election_id` → `can-hoc-2025` on every row (join anchor only — see money caveats).
- `results.csv.constituency_id` = **Elections Canada electoral-district number** (e.g. `10001` Avalon);
  343 districts. `result_id` = `can-ec-2025-{district}-{CandidateName}`.
- `polls.csv.election_id` → `can-hoc-next`.
- **There is no id-level bridge between people, money and results.** See below; do not build one by name.

## Licences

- Elections Canada material (elections.csv sources, money-edges.csv, results.csv): the `license` column
  says only **"Elections Canada open data (elections.ca)"**. The Elections Canada Important Notices and
  Open Data terms pages both returned **HTTP 500** from this box on 2026-09-03, so no licence text could be
  machine-verified; confirm the exact terms before commercial redistribution.
- people.csv: **"House of Commons of Canada (ourcommons.ca) - see site Important Notices"** — same
  caveat, the House publishes its own terms of use.
- polls.csv: each row carries the pollster's own copyright string; all figures are the pollsters' published
  toplines.

## Bars

- Sitting MPs: **338** of 343 seats (5 vacancies — see caveats). `person_id` = ourcommons Person ID, 338/338 present.
- Polls: **62 option-rows** from **11 surveys** across 5 organisations (Abacus Data, Angus Reid Institute,
  Ipsos, Léger, Nanos Research) — bar was ≥40.
- Money: **218,699** Elections Canada contribution edges, **CAD as filed**, non-empty.
- Results: official Elections Canada poll-by-poll returns, reconciled to EC Table 12 (no CLEA fallback needed).

## People

Incumbents only (`role=incumbent`, `incumbent=true`); there is no next-election candidate list because the
election is not called.

- `bio_text` is **empty for all 338 rows** — ourcommons.ca member pages publish roles, committee
  memberships and contact details, not a biography paragraph. Nothing was authored.
- `photo_url` is the official House of Commons 45th-Parliament MP photo, read off each member's profile
  page (338/338 found). These filenames could **not** be derived from name + party: the filename encodes
  the party *at photo time* (e.g. `DEntremontChris_CPC.jpg` for a member now sitting as a Liberal), so
  guessing them would have produced wrong or dead links.
- `party_code` is **blank on every row** — the House member feed publishes the full caucus name only
  ("Conservative", "Bloc Québécois"), with no official abbreviation column. Not invented.
- Party mix (feed strings): Liberal 173, Conservative 138, Bloc Québécois 21, NDP 5, Green Party 1.
- Provinces: ON 121, QC 75, BC 43, AB 37, MB 14, SK 13, NS 11, NB 10, NL 7, PE 4, NT/YT/NU 1 each.

## Money

Elections Canada **Political Financing → Open Data**, "Contributions — as submitted" bulk download
(206 MB zip → 4.4 GB CSV, **12,655,377** contribution rows across all events and fiscal years). Streamed
and filtered on this box; **CAD exactly as filed** (no conversion, no rounding). Three streams, two `cycle` labels:

- `cycle=2025-ge45` — **6,656** edges, all `Candidates` rows for the *45th general election*
  (`Candidate's Electoral Campaign Return (2019)`). Sum: **CAD 4,853,010.87** across **846** distinct candidate
  recipients.
- `cycle=2025-annual-writ-period` — **212,043** edges: registered **party** annual (fiscal 2025)
  returns, **176,050** edges / CAD 37,847,539.63 across 10 parties, plus registered **electoral district
  association** annual (fiscal 2025) returns, **35,993** edges / CAD 16,957,544.72 across 779 EDAs — in both
  cases restricted to contributions *received* in the writ period **2025-03-23 … 2025-04-28**.
- Whole-file sum: **CAD 59,658,095.22**. 89 edges have an as-filed amount of **0.00** (kept as filed).
- `edge_type` is what the regulator published: **`donation` 218,230** (Monetary amount) and
  **`donation_non_monetary` 469** (Non-Monetary amount). Nothing is labelled PAC or IE — Canada has no
  US-style PACs, and this file contains contributions only, not third-party advertising.
- One filed contribution row that carries **both** a monetary and a non-monetary amount becomes **two**
  edges (one per amount type). That is why 218,682 filed rows produce 218,699 edges. `as_filed_note`
  preserves the source row's `form=` (EC form id), `ret=` (stream), `rid=` (EC recipient id),
  `rparty=`, `dist=`, `ctype=` (contributor type), `loc=` and `recd=` (received date).
- Recipient party mix of the edges: Liberal 102,747 · Conservative 101,429 · Green 4,962 · NDP 4,024 ·
  Bloc Québécois 2,950 · PPC 1,067 · CHP 499 · Independent 397 · others <400 each.
- `contributor type` is **Individuals for 100%** of rows — Canada bans corporate and union political
  contributions, so there is no corporate donor layer to display.

**Every money row has a blank `person_id`.** Elections Canada keys recipients by its own **Recipient ID**
(kept in `as_filed_note` as `rid=`), which is a different registry from the House of Commons Person ID in
`people.csv`. **Do not name-match money to the roster** — "Duchesne, Larry" in a candidate return is not
evidence about any sitting member, and the candidate stream includes the many candidates who lost.

Three more money warnings:

1. **This is a filing snapshot, "as submitted".** Only 846 of the 1,959 GE45 candidacies appear, because
   candidate returns are published as they are filed and audited. Absence of a candidate is **not** evidence
   of zero contributions.
2. The annual party/EDA money is **not** election-period money in any legal sense; it is annual-return
   money whose *received date* happens to fall inside the writ period. Use the `cycle` column, not
   `election_id`, when describing it. Party and EDA returns can also each report the same individual's
   gift at different levels of the organisation — do not sum across streams and call it "total 2025 donations".
3. Deliberately **excluded** (present in the source, not donor→recipient edges for this cycle):
   quarterly party returns (111,725 rows, which would double-count the annual return), leadership-contestant
   returns (78,390 rows), nomination-contestant returns (536), and by-election candidate returns
   (Aug 2025 / Apr 2026, 313 rows). Contributions are also the only financial flow here — expenses and
   transfers were not ingested.

## Polls

`polls.csv` is long format, one row per response option, attached to `can-hoc-next`.

- **Abacus Data** — 4 surveys (9–16 Jul, 23–29 Jul, 7–12 Aug, 21–26 Aug 2026), full toplines with
  printed sample sizes and Abacus's stated comparable-probability MoE.
- **Angus Reid Institute** — 2 surveys. 4–10 Jun 2026 (n=4,237) prints only Lib/CPC/NDP, so only those
  three rows exist; 25–27 Jul 2026 (n=1,770) topline taken from ARI's own published data tables PDF
  (decided+leaning base 1,571).
- **Ipsos** for Global News — 2 surveys (25–26 Feb, 2–7 Apr 2026), n≈1,000, **credibility interval**
  ±3.8 recorded in `moe` with the term named in `notes` (Ipsos does not publish a classical MoE).
- **Léger** — 2 surveys (19–22 Jun, 1–3 Aug 2026), decided voters.
- **Nanos Research** — 1 survey, the weekly tracking wave ending 7 Aug 2026 (n=1,038, accurate ±3.1),
  read from the Nanos political package PDF. Nanos publishes a rolling 4-week average; the release index
  gives publication dates, which are **not** fieldwork dates, so only the wave with a printed field
  window was used.
- **Research Co. produced no rows** — its site index at build time carried issue polls (health care,
  policing, Alberta separation, justice) and no federal vote-intention table. Not invented.
- No Wikipedia anywhere. `moe` and `sample_n` are blank wherever the source did not print them.

## Last-cycle returns

`results.csv` — **1,959** rows, `election_id=can-hoc-2025`, `office=lower_chamber`, all from Elections
Canada's official 45th-general-election **poll-by-poll** files (343 district CSVs, all-Canada zip):

- `votes` = each candidate's votes summed over every polling division in the district.
- **Validated against Elections Canada Table 12** (official candidate votes and published percentages):
  district totals match for **all 343 districts** (0 mismatches) and the derived percentages match the
  published ones for **all 1,959** candidate rows.
- `vote_share` is **derived** (candidate votes ÷ district valid votes) and stored as a fraction, not a
  percentage; `seats` = 1 for the 343 elected candidates, else 0. Total valid votes: **19,641,663**.
- `person_id` is blank on every results row — Elections Canada publishes candidate names, not House
  Person IDs, and joining the two registries would be a guess.

## Known holes

- **338 ≠ 343.** The House feed carries 338 sitting members; five seats were vacant on 2026-09-03, three of
  them contested at the 2026-08-31 by-elections whose winners were not yet in the official roster. Do not
  invent the missing five.
- **Senators are not in this pack.** sencanada.ca renders its senator list client-side (no senator links,
  no embedded JSON, no API in the served HTML; headless Chrome returned an empty DOM) and Senate profile
  URLs are **name slugs**, not stable ids. Senators were omitted rather than keyed on a slug.
- The next-election date is a **statutory latest**, computed from s.56.1(2), and a minority Parliament can
  fall earlier. It is not an announced polling day.
- No riding-level *money* aggregation is provided: EDA and candidate money live in different streams with
  different recipient registries, and stitching them per riding would require assumptions the regulator
  did not publish.
- Rejected/spoiled ballots and elector counts exist in the poll-by-poll source but are **not** in
  `results.csv` (the header has no field for them); re-derive from the source zip if needed.
- Elections Canada licence text could not be fetched (HTTP 500 on both terms pages) — see Licences.

Licences on the rows

  • Elections Canada open data (elections.ca)220,658
  • House of Commons of Canada (ourcommons.ca) - see site Important Notices338
  • (c) Abacus Data; topline as published23
  • (c) Ipsos for Global News; topline as published12
  • (c) Léger; topline as published12
  • (c) Angus Reid Institute; topline as published9
  • (c) Nanos Research; topline as published in the Nanos political package6