Skip to content

Build: state and district populations, and indexing in a pop-up - #1254

Open
PavelMakarchuk wants to merge 16 commits into
mainfrom
feat/build-populations
Open

PavelMakarchuk wants to merge 16 commits into
mainfrom
feat/build-populations

Conversation

@PavelMakarchuk

@PavelMakarchuk PavelMakarchuk commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Reports from Build ran nationwide only. This PR lets a reform run on any US state or congressional district, which are the subnational regions that the API supports. It touches v3 (flagship) code only.

  • Population menu in Build. It offers Nationwide, the 51 states and the 436 congressional districts, and you can search them by name or code ("ca", "calif", "CA-01"). Districts join the list once something is typed, so the list stays short. "A household" stays marked Soon; household runs come in a follow-up PR.
  • The run uses the region. The draft stores it (population.region, for example state/de or congressional_district/CA-12), and runFlagshipReport creates both simulations on it. The report's calculation then runs with that region.
  • Report cover. The line under the title reads the population and the year, for example "Delaware · 2026" or "Nationwide · 2026". It no longer reads "Hand-built". "Edit the reform" brings the region back to Build.
  • Recompute keeps the population. The adjust panel now recomputes on the report's region and year. Before, it ran nationwide and in the current year, even for a state report or a 2027 bill.
  • Bills from the Reforms page. "Run impact report" for a state bill now runs on its state, as the bill's own report does.
  • Headline revenue. The headline leads with state revenue only when a state reform runs on part of the country (leadsWithStateRevenue). A federal reform on one state leads with its full budget effect. A $100 CTC increase run on Delaware now shows "$12.8m annual government cost", where it showed "$0.0 state revenue change".

Build: edit modes, indexing in a pop-up, aligned columns

  • Modes: New value | By year | Custom dates | Indexed. New value is the default; Indexed is last.
    • New value is a single box with current law next to it. An Applies from menu sets the year it starts; the years before it stay at current law. A closed row then reads, for example, "$1,000" and "from 2028".
    • Indexed (money amounts only) shows the value, what it grows to in the later years, and "Edit indexing". Choosing it indexes the amount at once: at current law's rate when current law indexes the amount, otherwise with the first index offered.
    • A new value holds flat until Indexed is chosen, also on an amount that current law indexes. Only a provision that already indexes opens in Indexed.
    • Back in New value, an amount never edited returns to current law, and an edited one holds from its year.
  • Pop-up. Edit indexing opens a pop-up with the index, the start year, the base year, and the rounding mode and step. It shows the live formula and has Cancel / Apply. "None" is not offered, because New value covers it.
  • Indexing changes the values. Indexing applies also to an amount still at current law. A flat $100 indexed to CPI-U shows $102 … $122 by 2035.
  • Aligned grid. The year columns share the width evenly, and each heading starts at its values' "$". The current-law row and the later years lay out values as the input box does (ValueDisplay). A phone scrolls the grid instead of squeezing it.
  • Wording. "No values differ from current law yet. Adjust at least one value to run the report." "Show past values" now reads "Show historic values".
  • The Population menu names a state ("Arkansas") while metadata loads, not "state/ar".

Report side panel

  • Population and year. The panel has the same Population menu, and a recompute runs on the chosen region and year.
  • Rename. The reform's name can change in the panel; a rename alone is a change to recompute.
  • "Baseline: {value}" replaces "was" beside each editor. Booleans edit as a true/false switch.
  • Edit in Build takes the adjusted reform (name, year, region) back to Build to add more provisions.

Saved reforms (Reforms page)

  • The source labels ("Hand-built", "From a question", …) no longer show on the cards or the detail.
  • Dates are kept. The detail read only a reform's first value against today's law ("$500 → 1000" for a value from 2028). Its report ran that value from the current year, and "Save changes" kept only the first period of a schedule. Now:
    • each row says when its value applies ("from 2028", "3 periods from 2026"), against current law in that year
    • a one-period value edits in place and keeps its dates on save; a schedule reads as its summary and saves whole (it changes in Build)
    • "View full impact report" runs every dated value, in the reform's first year of change

Progress bar

  • A society-wide run shows a bar with the elapsed time and a percentage (RunProgress). The API reports no stages for a single-year run, so the bar follows the typical run time (US 6 min, UK 3 min), and stops at 95% until the results arrive.

Test plan

  • tsc, ESLint and Prettier are clean.
  • Full Vitest: 4,220 passed. New tests cover:
    • the picker (choosing a state, searching for a district)
    • the run sending the region to both simulations
    • recompute keeping the region and year
    • the state revenue rule
    • the indexing pop-up: Apply on an unedited amount, and Cancel
    • the mode order, New value as the default, and "Applies from" moving the start year
    • the side panel: population, rename, Edit in Build
    • the report cover: population and year, no "Hand-built"
    • saved reforms: a later start shown, kept on save and in the run; a schedule saved whole
  • On localhost:
    • A flat amount indexed to CPI-U: the later years show the indexed values, and the "$" and the digits line up in every column.
    • A new value with "Applies from" 2028 on a 2026 report: 2026–2027 stay at current law, and the closed row reads "$1,000" and "from 2028".
    • Typing "CA-12" finds California's 12th district, and choosing it sets the draft's region.
    • A Delaware run calls /us/economy/…?region=state/de and finishes. The headline reads "$12.8m Annual government cost".

🤖 Generated with Claude Code

Reports from Build ran nationwide only. The Population menu now offers
the whole country, any of the 51 states, or any of the 436 congressional
districts, searchable by name or code ("ca", "CA-01"); districts join
the list once something is typed. A household stays marked as coming.

- The draft keeps the chosen region; runFlagshipReport creates both
  simulations on it, so the report and its economy run use it.
- A report on part of the country names it on the cover ("Delaware ·
  Hand-built"), and "Edit the reform" brings the region back to Build.
- The adjust panel recomputes on the report's region and year (it ran
  nationwide in this year), and a bill run from the Reforms page runs on
  its state, as the bill's own report does.
- The headline leads with state revenue only for a state reform on part
  of the country; a federal reform on one state leads with its full
  budget effect ($12.8m for a $100 CTC rise in Delaware, not "$0.0
  state revenue change").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policyengine-calculator-next Ready Ready Preview Oct 13, 2026 3:51pm UTC
policyengine-website Ready Ready Preview Oct 13, 2026 3:51pm UTC

Request Review

- Indexing's choices (index, start year, base year, rounding mode and
  step) move from a row of inline menus into a pop-up with the live
  formula and Cancel / Apply; the grid row keeps the formula in force
  and an "Add indexing" / "Edit indexing" button.
- Apply indexes every amount in the draft, also one still at current
  law: indexing a flat $1,750 is itself the change, so the later years
  now show what it grows to ($1,782 … $2,135) instead of $1,750 again.
- The current-law row and the later years' values lay out as the input
  box does (ValueDisplay): the "$" and the digits sit where the box's do,
  and the reform row's values share its height, so the columns line up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PavelMakarchuk PavelMakarchuk changed the title Build: run a reform on a state or congressional district Build: state and district populations, and indexing in a pop-up Oct 13, 2026
The value grid let the input's column take twice the others' width
(215px against 102px) and started each year heading at the cell's edge,
12px left of the "$" and digits beneath it. Year columns now share the
width evenly (a fixed layout, with a minimum so a phone scrolls the grid
instead of crushing it), the input fills its column, and each heading
starts where its values' "$" does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The value modes become One value | Indexed | By year | Custom dates.
  One value is a single box from its year, with current law beside it:
  no grid of later years and no indexing row. Indexed (money amounts
  only) shows the value, what it grows to in later years, and "Edit
  indexing"; choosing it indexes at once, at current law's rate where
  current law indexes the amount, else with the first index offered.
  The pop-up no longer offers "None" — that is One value.
- Back to One value, an amount never edited returns to current law;
  an edited one holds from its year.
- An amount current law indexes still opens indexed, as before.
- "Show past values" reads "Show historic values".
- The Population menu names a state ("Arkansas") while metadata loads,
  not "state/ar"; DC joins the state names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Adjust parameters panel offered only the reform's values. It now
leads with the same Population picker as Build: nationwide, a state, or
a congressional district, starting at the report's own population.
Choosing another one counts as an adjustment, so Recompute runs the
same reform there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Adjust parameters panel starts with the reform's name, editable.
  A new name is a change to recompute: the saved reform and the new
  report take it, in place of "… (adjusted)".
- The panel's population now follows the report's own until one is
  chosen: it could open on Nationwide when the report's simulations
  loaded after the panel.
- Changed values say "Baseline: $100" rather than "was $100", in the
  panel and in Build's grids: current law for a draft, the law a bill
  was scored against for an enacted one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- An "Edit in Build" button loads the reform as the panel has it — its
  values, name, population, and year — as the draft, and opens Build to
  add parameters or change it further.
- A value edited in the panel now replaces the provision's own dates:
  a bill's dated provision kept its intervals, so recompute ran the
  dates and ignored the edit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A computing report showed a spinner and "Calculating report results…";
a bill's full run the same. Both now show one progress card: what is
running ("Calculating the results for Delaware", "Calculating the full
results"), the time so far and a percentage, a bar, any queue position,
and a caption that the estimate follows typical run times. The API
reports no stages for a single-year run, so the bar follows the
calculation strategy's time estimate (6 minutes US, 3 UK), held short of
the end until the results arrive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Nothing is changed yet. Change a value to run the report." now reads
"No values differ from current law yet. Adjust at least one value to run
the report."; the disabled Run button's hint matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The edit modes read New value | By year | Custom dates | Indexed, and a
provision opens in New value unless it already indexes. A new value holds
flat until Indexed is chosen. An "Applies from" menu moves the year the
value starts; the years before it stay at current law.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new value from 2028 on a 2026 report showed a 2026 box at current law.
The closed row now reads the new value and "from 2028", and opens the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tracker's author field is the research post's author on blog rows
(ut-sb60 read "Sponsored by David Trimmer") and empty on 72 of 75 bill
rows, so it never reliably named a sponsor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The line under a Build report's title read how the reform was made
("Delaware · Hand-built"). It now reads who the report ran on and the
year: "Delaware · 2026", "Nationwide · 2026". The source note stays in the
report's record and the adjust panel's runs. Bill reports keep no line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The saved reform cards and the reform detail no longer show how a reform
came about. The label stays in the report's record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e save

The detail read only a reform's first value, against today's law:
"$500 → 1000" for a value from 2028. Its report then ran that value from
the current year, and "Save changes" kept only the first period of a
schedule.

Now each row says when its value applies ("from 2028", "3 periods from
2026") against current law in that year. A one-period value still edits in
place and keeps its dates on save; a schedule reads as its summary and
saves whole (it changes in Build). The report runs every dated value, in
the reform's first year of change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

2 active deployments
Preview – policyengine-calculator-next — 2812008d Deployed Oct 13, 2026 by vercel[bot]
Preview – policyengine-website — 2812008d Deployed Oct 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant