Project 05 · Statistics Canada import files, 1988 to July 2026
Additive Manufacturing Trade Reconstruction
A join on the code alone would misdescribe 8.49% of 39 years of Canadian import value and lose another 35.24% under codes that no longer exist. Joined on the code and the month against the dictionary’s own validity ranges, every one of 186,229,882 rows lands on exactly one meaning, and on that footing growth in 3D-printer imports is reported three ways, with the spread between them as the finding.
The question
Every one of the nine ten-digit codes for 3D-printing machines and parts begins in January 2022. Before that month the codes did not exist, and one of them, 8485100000, meant ships’ propellers from 1988 to 2006. So any growth figure from 2021 divides by a baseline that was never measured. How much of the reported rise is growth, and how much is the classification change that created the codes?
The data and its scale
39 yearly zips through an idempotent backfill with a thirteen-column run log: 186,229,882 rows by month, ten-digit code, partner country, province of clearance and US state, 15,970 billion nominal dollars.
The HS10 dictionary inside the 2026 zip holds 53,570 code-periods over 42,771 codes; 8,631 codes have more than one period, 5,962 more than one meaning, and 2,288 of the 10,930 open codes previously meant something else. The concordance is 2,507 pairs in two spreadsheets.
What the source did
- C1The dictionary is a fixed-width file, 53,570 lines of exactly 213 characters in Windows-1252, with eight fields rather than the six described. Every delimited reader misparses it, so it is parsed on measured column positions.
- ·The dictionary is a snapshot per zip, not one file: the copy in the 1988 to 2018 zips restates 129 periods of the newest copy with a different description. All eight distinct snapshots are parsed and compared before the newest is used.
- ·The concordance is incomplete without its 2022-1 amendment, which alone covers 108 obsolete and 368 new codes.
- ·The planned mapping rule, pairing a retired code with new codes in its own subheading or heading, finds nothing for heading 8485, which had no live code in December 2021, and would have missed 876 of the 2,083 published pairs where the code changed: 598 cross chapters and 278 cross headings. It was measured and rejected, and the publisher’s own table is used instead.
- ·A publisher can answer a missing file with a web page at HTTP 200, so the fetch checks the content type and the zip signature before a byte is written.
Fourteen assertion rules, C1 to C14, all clean: every row of 186 million matched exactly one dictionary period and none matched zero. Two incidents of the first full build are recorded with their dates: an incremental clause that looked only forward and reworked one year while every test passed, caught by a completeness check, and DuckDB refusing to switch its spill directory after a spill.
Method
Batch engineering with a run log, claimed as exactly that and not as a running system. A dbt Core project on DuckDB: 4 staging views over hive-partitioned Parquet, a validity-range dimension in the shape of a type 2 dimension built from the publisher’s own start and end months, 3 intermediate tables, an incremental fact by year with a per-year natural-key test, 7 marts, 2 seeds and 71 tests, 87 passes in about three minutes.
The fact carries, for every row, whether a join on the code alone would have attached the same description, a different one, or none. Three baskets are defined in a committed CSV with the rule and source per row: the nine recipient codes, the seventeen donor codes the concordance names, and the two combined. Every test runs on log monthly value with a trend and month dummies from January 2019, the first month all seventeen donors exist.
Finding
Share of import value a join on the code alone gets wrong
Data behind this chart
| Year | Misdescribed | Orphaned | Wrong in total |
|---|---|---|---|
| 1988 | 11.11% | 78.02% | 89.13% |
| 1997 | 8.30% | 73.92% | 82.23% |
| 2006 | 11.77% | 62.71% | 74.48% |
| 2011 | 11.55% | 52.61% | 64.16% |
| 2016 | 13.54% | 29.80% | 43.34% |
| 2021 | 9.87% | 8.65% | 18.52% |
| 2022 | 0.12% | 0.64% | 0.75% |
| 2025 | 0.00% | 0.02% | 0.02% |
| All 39 years | 8.49% | 35.24% | 43.73% |
- The older the year, the more a naive join gets wrong.89.13% of 1988's import value, 74.48% of 2006, 43.34% of 2016 and 18.52% of 2021.
- It steps down at each revision.The drops fall at 2007, 2012, 2017 and 2022, the revisions of the Harmonized System.
- Near zero from 2022.0.75% in 2022 and zero in 2026 by construction. Across all 39 years: 8.49% misdescribed and 35.24% orphaned, 43.73% of 15,970 billion dollars.
The series. Imports under the nine printer codes were $49.5M in 2022 and $116.1M in 2025, a rise of 134.8% that a reader of the published series cannot compare with anything earlier. The seventeen donors ran $2,266.0M in 2021 and $3,238.8M in 2025, and show no fall at the break: a Chow test at January 2022 gives F 1.46, p 0.158 for the donor basket and F 1.59, p 0.110 for the combined basket, and the interrupted time series with Newey-West errors finds a donor-basket level shift of +1.6%, p 0.679.
The three donors that do fall are all in the rubber and plastics machinery heading: 8477800000 at minus 25.9%, p 0.026, 8477903000 at minus 58.6%, and 8477909090 at minus 16.3%. A rolling Chow scan, named as a locator and not a test, puts the plastics donor’s largest break at August 2021, five months before the tariff change, with its level 35.4% lower after, which is what a code losing its printers over the last months of 2021 looks like.
Three growth estimates, 2021 to 2025. Published: undefined, there was no 2021 value; inside the published series, 2022 to 2025 is +134.8%. Basket-invariant, the combined basket whose goods do not change: +48.1%. Bridged for the donor basket: undefined, since the shift is positive and 1,266 of 2,000 moving-block bootstrap replicates give no negative shift. Bridged for the plastics pair: a backcast 2021 level of $26.0M against $62.7M in 2025, +141.7%, interval +36.2% to +1,463.0%, with 60 replicates undefined. The honest sentence is that the printers grew somewhere between the basket’s 48% and the published series’ 135%, and the one bridge the data can build says about 142% for plastics printers.
Carbon fibre cannot be read as a series at all: five stretches under four regime labels between 1988 and 2026. Not separately coded 1988 to 1997; one clean code for 43 months, $34.8M; the same code commingled with refractory brick for 158 months, $216.2M; not separately coded again from October 2014 to December 2021; and three codes from 2022 for 55 months, $228.4M. No growth rate is quoted across a boundary.
What this cannot tell you
- Whether reclassified goods are physically the same products. The concordance is the publisher’s inference, published without weights.
- What the donor basket lost, since it rose, or growth before 2019.
- Real growth. Every value is nominal at customs valuation.
- Domestic production or market size, and where goods are used: province is province of clearance.
- Materials. Powders, filaments and resins sit in chemical headings and are not separated.
- Anything after July 2026.
Artifacts
- A 40-cell notebook and a findings memo
- The backfill script and its committed run log
- The dbt project, with its lineage drawn from the manifest
- Three committed crosswalks, of 2,507, 2,507 and 36 rows
- A decision log, D-01 to D-10, a data contract for three sources and a source-to-target map
- A nine-table star exported with a DAX measure layer that puts the temporal and naive joins side by side, and a province row-level-security role specified; the Power BI dashboard itself is not yet built
Reproducibility
This project is excluded from the scheduled CI by policy while its backfill is three gigabytes, and the exclusion and its reason are printed in every CI summary. The notebook was run top to bottom on 2026-09-09, and every figure on this page is from that run.
Sources
- Canadian International Merchandise Trade imports by HS10, eight open.canada.ca packages, 39 zips, with hashes in the committed run log. Open Government Licence, Canada.
- The HS10 dictionary cut for July 2026, and the seven earlier snapshots inside the older zips.
- Statistics Canada’s ten-digit concordance for the January 2022 tariff, with its 2022-1 amendment.
- The findings memo, decision log, data contract and source-to-target map in 05-additive-trade/memo.