Source TRANS for 2023 from AIES, and move TOP's residual onto a purchaser-price base (#611, #580) - #733
Merged
Merged
Conversation
SAS stops at data year 2022. AIES carries 2023 for every mode that needed it, so TRANSPORT_MARGIN_YEARS becomes range(2017, 2024) and the 2023 supply bridge is complete for the first time - T016 = 51,543,283 $M with all four subtotals resolving. Truck (67.8%) comes from a new Census_AIES_MiscSector extract on timeseries/aies/miscsector. Its RCPT_MOTR_<group>_DVAL items carry the same eleven group names as SAS Table 8, verified against variables.json, so Crosswalk_SAS_Group_to_BEA_2017.csv joins them unchanged; the parse emits Table 8's own FlowName strings, which keeps load_truck_group_revenue one implementation across the seam rather than two. Hazardous materials is not requested - it is a cross-cut, not a twelfth group. Pipeline (11.9%) and water/air freight revenue (3.8%) come from timeseries/aies/basic, which Census_AIES already calls; _TYPE_OF_OPERATION gains NAICS 48 at TYPOP 00. Those rows are inert for the trade margin, which filters to FlowName 'Gross margins' and reads NAICS 42/44-45 by name. The four pipeline items still partition NAICS 486 to the dollar in 2023. The truck shares step 4x their normal volatility at the seam (mean |dpp| 1.39 vs 0.34). Carried as observed, on the same evidence that settled the retail rate step: taxonomy unchanged, groups still partition, and the movers - used household goods 6.69->9.94%, coal and petroleum 6.99->9.56% - fit the 2023 freight recession. Only shares are spent; the level is anchored on 2017. 2024 stays unsourced. Both AIES datasets return 204, and truck plus pipeline are 79.7% of the column, so a partial fill would break the identity quietly.⚠️ Air's 2023 control total is left defective and flagged: 481212 breaks 2.2x across the seam against a smooth 2019-2022 series while 481112 moves -3.6%, so 2023 air is ~1.6x too large. Bounded at 1.5% of the column. It fails the artifact test truck passes and is documented in the module docstring and the plan rather than silently patched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#580) 70% of TOP is general sales tax with no named NIPA line, and it sat on frozen 2017 shares. The module said the real fix was "a purchaser-price base by commodity, which is Step 5's output" - but the supply bridge reaches it first: once TRADE and TRANS were sourced (#611), T013 + T014 *is* that base, supply at basic value plus the margins carrying it to the purchaser. Two T007 movers were built and rejected in #580. This base clears both: S00402 used and secondhand goods carries 15,699 $M of 2017 TOP, eighth largest of any commodity, and T007 is zero for it by definition - so the T007 mover could not move a top-ten position. Its purchaser base is 174,312 $M, because secondhand goods are almost entirely trade margin. The margin layer reaches exactly what domestic output cannot. The one-sided mover drifted to 1.86x its 2017 level against a control growing 1.53x. This base tracks the control instead: the implied rescale stays within 0.939-1.008 across 2017-2023, because purchaser value is what sales tax is levied on. The pandemic years are the check. 2020 accommodation 721000 falls 7,045 $M against the frozen vector, air transport roughly halves, restaurants fall - the sectors #580 worried the frozen vector would get wrong. The rejected T007 service-side mover put accommodation at -7,511 $M, so two independent bases agree on the size of the effect and only this one reaches it without breaking the control. The base is assembled from the bridge's components, not from derive_initial_supply_bridge, which would be circular - the bridge calls top_column. Taxes are excluded from the base: T015 carries TOP itself, so including it would make the tax its own allocator. 2024 holds 2023's shares rather than reverting to frozen 2017, which would undo six years of movement in one step. It is a hold, not a measurement. 2017 is unchanged, as it must be, and every year still hits its NIPA control exactly and stays non-negative. The divergence from the naive scale-2017-by-the-control default grows from 3.7% to 6.3% of the 2020 column and 5.8% to 7.7% of 2024 - that is the other 70% starting to move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AIES 2023 publishes 481212 nonscheduled chartered freight air at 13,271 $M against 4,846/4,857/4,987/6,045 over 2019-2022 in SAS, unsuppressed. With 481112 that puts air freight revenue at 2.32x its 2017 level. FAF settles it. Air ton-miles for the same mode are 1.06x 2017 in 2023, having fallen back from 1.32x in 2022, so the published revenue implies unit revenue doubling in one year - in the year air cargo rates collapsed from their pandemic peak. Wrong size and wrong sign. From 2023 air's control moves on volume, holding unit revenue at its last observed value: revenue(2022) x ton_miles(year) / ton_miles(2022). FAF is already air's commodity allocator, so this uses what the mode is built on rather than importing a fourth series to arbitrate. Holding unit revenue flat is conservative - rates fell, so this still overstates slightly, and correcting for that would need a rate series the build does not carry. 2023 air revenue becomes 14,386 $M rather than 24,734, unit revenue stays flat at 1.27, and air lands at 1.6% of TRANS - the share the mode table states. Uncorrected it would have taken 2.7%. Water is deliberately not treated this way: its unit revenue moves -4% across the same seam (1.65 -> 1.58), so only air breaks. A test pins that water keeps its published revenue. The 2022->2023 step alone is a misleading cut - from the 2017 anchor the two air codes grow 2.17x and 2.47x, which looks benign. It took an independent series to show the break. Also records that the frozen 2017 coverage ratio is a weak choice kept for now: for water and air it stands in for a domestic/international split that moves, and this defect is a symptom of the same gap - a frozen ratio passes any revenue error straight through to the margin. T016 is unchanged; TRANS nets to zero, so the mode level does not move it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
WesIngwersen
added a commit
that referenced
this pull request
Aug 27, 2026
Docs only. The plan and progress report predated #733/#734 and were describing a Supply bridge that no longer exists. Supply column table, corrected against a live coverage run rather than from memory: eight of the twelve columns now run 2017-2024, and only TRADE, TRANS and therefore T014/T016 stop at 2023. MCIF, MADJ and MDTY were still listed as "2017 candidate" and have been annual since #730. TRANS was "2017-2022" and now reaches 2023 from AIES. TOP's residual is no longer frozen, which the plan asserted in two places. The purchaser-price base did not have to wait for Step 5 as the plan predicted - it is assembled from the bridge's own components, and is not circular because TOP sits in T015 and is excluded from its own base. Recorded with what it buys (S00402's 174,312 base, the 0.939-1.008 rescale) and what it costs: TOP now depends on margin coverage, so 2024 holds 2023's shares. Step 1: F04000 was described as all-zero for 2018-2024 and has been annual since #730 (2,211bn to 3,139bn). F03000 really is still 2017-only, so the two are now stated separately instead of together. Numbers re-measured rather than edited by hand. Steps 1 and 4 re-run, and the embedded images regenerated with them: supply bridge coverage 99.0% to 99.2%, accuracy 61.8% to 62.1%, grand total error 0.092% to 0.048%. That improvement is not Step 4a - it is the Trade FBSs rebuilt on the NAICS-2022 goods Crosswalk, which moved MCIF (misses 27 to 22) and carried through T013 and T016. Per-column table updated with it. Step 3 is unchanged and was not re-run.⚠️ The 2017 trade scorecard moved in two directions at once and the README now says so rather than reporting the half that flatters it: the export national error roughly halved, +12.20% to +6.16%, while Pearson fell 0.96 to 0.92, top-20 Jaccard 0.67 to 0.60 and n_miss rose 39 to 43. The extra mass lands closer to the published total but spread over more Detail codes. The prior row is kept for comparison.⚠️ The stored per-commodity trade baseline was deliberately NOT refreshed. score_2017_trade_detail flags a handful of expected status changes against it; --update-baseline is a judgement call and has not been made. Step 2's plan entries are not touched here - they belong to #735. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
WesIngwersen
added a commit
that referenced
this pull request
Aug 27, 2026
…#737) Two tests in test_nowcast_product_taxes.py have been red on nowcast since #691 merged, but #691 did not cause them: a dispatched CI run on 7827a9e, nowcast immediately before #691, fails with the same two tests and a bit-identical -26278.087320966762. The cause is #734 x #733. #733's last green run (26acafc) did not contain #734 -- `git merge-base --is-ancestor a57b0ca 26acafc` is false -- so the -26,153 band was fit on pre-#734 data. #734 then remapped the Census NAICS 2022 activities onto the goods Crosswalk, which moves the Trade FBS, purchaser_base and so the residual's annual shares. Each PR was green alone; neither was ever built with the other. Re-fit tobacco to -26,278, 0.48% off the old centre against a 0.38% band. The 2017 anchors -- the control totals, NAMED_TOTAL_2017, RESIDUAL_TOTAL_2017 and the 391,162 trade-level split -- all still pass, so the level is intact and it is the shares that moved. The divergence also grew rather than fell, which the test's own docstring names as the safe direction. test_the_two_levels_add_back_to_the_column was a separate, latent bug. producer_level is defined as TOP - trade_level, so .equals asserted that (a - b) + b == a bit-exactly, which floating point does not guarantee; it had been passing on luck. Compared with rel=1e-12 instead. Grouped the four fitted bands into two dict comparisons so a future source change reports every band that moved in one run rather than only the first. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes: #611 (transport phase 2, 2023 leg)
Related: #580, #612
What changed? Why?
The supply bridge is now complete and evaluable for 2017–2023 — seven years, up from one.
TRANSwas the last column blocking it, and sourcing it unblocked a second thing the tax layer had been waiting on.Three commits, in dependency order:
TRANSfor 2023 from AIESTOP's sales-tax residual onto a purchaser-price baseThey are in one PR because each depends on the one before: #2 cannot be built until the margin columns exist, and #3 is a defect in what #1 introduced.
1 — TRANS for 2023 from AIES (#611)
SAS stops at data year 2022, so
TRANSstopped there too and 2023 had no bridge. The plan listed truck as "source found; concordance to build" and 2023 as unsourced. It turned out better: three of the four modes needing a source came across, and the concordance needed no work at all.Truck — 67.8%
New
Census_AIES_MiscSectorextract ontimeseries/aies/miscsector. Its elevenRCPT_MOTR_<group>_DVALitems carry the same eleven group names as SAS Table 8 — verified againstvariables.json, all ten identified groups matchingCrosswalk_SAS_Group_to_BEA_2017.csvexactly — so the crosswalk joins unchanged.The parse emits Table 8's own
FlowNamestrings, so everything below the source dispatch inload_truck_group_revenuestays one implementation across the seam.RCPT_MOTR_HAZRD_DVALis deliberately not requested: hazardous materials is a cross-cut of the same revenue, not a twelfth group.Pipeline (11.9%) and water/air freight revenue (3.8%)
Already inside the
aies/basiccallCensus_AIESmakes — only_TYPE_OF_OPERATIONneeded NAICS48atTYPOP 00. Those rows are inert for the trade margin, which filters toFlowName == 'Gross margins'and reads NAICS42/44-45by name. The four pipeline items still partition NAICS 486 to the dollar in 2023.mode_freight_revenuewas a third SAS dependency not in the plan's mode table — the per-mode control total, which water and air also read. It is routed too; without it the column raised rather than built.The truck splice — carried as observed
Shares step 4× their normal volatility at the seam (mean |Δpp| 1.39 vs 0.34 within SAS). Carried as observed on the same evidence that settled the retail rate step: taxonomy unchanged, the eleven still partition the published total (−65 on 341bn, $1,000 rounding), and the movers — used household goods 6.69→9.94%, coal and petroleum 6.99→9.56% — fit the 2023 freight recession. Only shares are spent; the level is anchored on 2017.
2024 stays unsourced
Both AIES datasets return 204 for 2024. Rail reaches it on STB and water/air on FAF, but truck plus pipeline are 79.7% of the column, so a partial fill would break the identity quietly. Same shape as the
TRADE2024 gap.2 — TOP's residual moves onto a purchaser-price base (#580)
70% of
TOPis general sales tax with no named NIPA line, and it sat on frozen 2017 shares.nowcast_product_taxessaid the fix was "a purchaser-price base by commodity, which is Step 5's output" — but the supply bridge reaches it first. OnceTRADEandTRANSare sourced,T013 + T014is that base: supply at basic value plus the margins carrying it to the purchaser.It clears both objections that killed the T007 movers
T007S00402used/secondhand goods carries 15,699 $M of 2017TOP— eighth largest — andT007is zero for it by definition, so a top-ten position could not moveThe pandemic years are the check
2020 accommodation
721000falls 7,045 $M against the frozen vector, air transport roughly halves, restaurants fall — the sectors #580 worried the frozen vector would get wrong. The rejectedT007service-side mover put accommodation at −7,511 $M, so two independent bases agree on the size of the effect and only this one reaches it without breaking the control.Construction notes
derive_initial_supply_bridge— the bridge callstop_column, soTOPcannot read the finished bridge back.T015carriesTOPitself; including it would make the tax its own allocator.TOPon margin coverage, which resolves when AIES publishes 2024.2017 is unchanged, as it must be. Every year still hits its NIPA control exactly and stays non-negative.
3 — Air's 2023 seam defect, closed on FAF volume (#611)
AIES 2023 publishes
481212nonscheduled chartered freight air at 13,271 $M against 4,846 / 4,857 / 4,987 / 6,045 over 2019–2022 in SAS, unsuppressed. With481112that puts air freight revenue at 2.32× its 2017 level.FAF settles it — and FAF is already air's commodity allocator, so no fourth series was imported to arbitrate:
Volume fell back to 1.06× while revenue claimed 2.32× — unit revenue doubling in the year air cargo rates collapsed from their pandemic peak. Wrong size and wrong sign.
From 2023 air's control moves on volume, holding unit revenue at its last observed value:
revenue(2022) × ton_miles(year) / ton_miles(2022). 2023 air revenue becomes 14,386 $M rather than 24,734, and air lands at 1.6% of TRANS — the share the mode table states. Uncorrected it took 2.7%.481212stays at the new level it is a re-based series, and the fix becomes re-anchoring rather than indexing off 2022.The frozen coverage ratio is now recorded as a weak choice
Kept for now, but no longer reading as settled. For water and air
mode_coverage_ratiois not a coverage correction — it stands in for a domestic/international split that genuinely moves, and it survives on bounded blast radius (3.8% ofTRANS) rather than evidence. This defect was a symptom of the same gap: a frozen ratio passes any revenue error straight through to the margin. Replacing it needs an observed domestic leg, not a different frozen number.SUB needs nothing
Checked rather than assumed: it reconciles to NIPA T31300 exactly in all eight years, is computed live so cannot go stale, and its only commodity-output dependency (the 2020–21 PPP split) does not overlap the years Step 4a changed.
Resulting bridge coverage
2024 blocks on
TRADEandTRANSonly, both on the same cause: AIES has not published data year 2024. That is a release date, not an engineering gap.Testing
Four gates repo-wide: black ✅, ruff ✅, mypy ✅ (4 pre-existing Windows-only
resourceerrors insettings.py, untouched here, green on ubuntu), pytest ✅ 753 passed, 2 skipped, 1 xfailed — up from 745 onnowcast.Two tests were rewritten because their contract changed by design (
TRANSis no longer NaN at 2023; theTOPdivergence from the naive default grows from 3.7%→6.3% of the 2020 column and 5.8%→7.7% of 2024, because the other 70% now moves — a fall there would be the bug).Eight added:
test_aies_continues_the_sas_taxonomy_across_the_2023_seam— fails if Census renames a truck group, which would otherwise silently drop that group's revenue on a missed crosswalk jointest_pipeline_items_still_partition_naics_486_under_aies— the partition check either side of the seamtest_air_revenue_does_not_break_against_its_own_volume_at_the_seamtest_water_keeps_its_published_revenue_across_the_seamtest_air_volume_index_refuses_years_with_a_published_revenuetest_purchaser_base_reaches_what_domestic_output_cannot— theS00402casetest_residual_does_not_drift_against_its_control— 2017–2023test_2024_holds_2023_shares_rather_than_reverting_to_2017GCS extract input — staged ✅
Census_AIES_MiscSector_2023.csvis uploaded togs://cornerstone-default/extract/input-data/Census_AIES_MiscSector/2023/and verified byte-identical on round-trip, so CI's keyless path resolves. AIES requires an API key and CI has none.Census_AIESFBA must be regenerated for the widened_TYPE_OF_OPERATION— editing the parse does not invalidate the parquet.🤖 Generated with Claude Code