Explain silent no-op society-wide reports with an informational callout#1117
Merged
Conversation
When a reform only edits programs not in effect in the simulated year (for example a credit that has sunset), every society-wide output reads "No change" with no explanation, leaving users unable to tell a genuine no-op from a start-date or sunset mismatch. Add isSocietyWideReportNoOp, a pure detection util that returns true only for an exact whole-report no-op: budgetary impact, benefit-spending and tax-revenue components all exactly 0, and the winners/losers intra-decile breakdown 100% "No change". Missing or partial fields are treated as NOT a no-op and it never throws; both US and UK shapes are handled. SocietyWideOverview renders an informational (not error) callout with the simulated year above the cards when it returns true, so a single zero panel never triggers it. Fixes #1116 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
What
The society-wide report output now shows an informational callout above the result cards when a reform is a complete no-op — every output is identical to current law. Previously the page rendered "No change" everywhere (budget, deciles, winners/losers at 100% no change, poverty, inequality) with no explanation, so users could not tell a genuine zero-impact reform from one that never touched anything in effect that year.
This is the "exact-zero callout" from #1116 (suggestion 1). Motivating repro: an Oregon Kids' Credit expansion modeled for 2029, after the credit sunsets (HB 3235) — editing its amount for 2029+ changes nothing, and the null result read as user error.
Why
Silent no-ops are indistinguishable from real zero-impact reforms and from plain start-date / simulated-year mismatches. The callout names the likely cause and the year to check.
Detection rule
isSocietyWideReportNoOp(output)returns true only for an exact whole-report no-op — all four must hold:budget.budgetary_impactexactly 0budget.benefit_spending_impactexactly 0budget.tax_revenue_impactexactly 0intra_decile.all['No change']exactly 1 (100% of the population unchanged)Missing or malformed fields are treated as NOT a no-op, and the function never throws. Both US and UK report shapes are handled (the checked fields are identical across them). Because all four conditions are required, a single zero panel — e.g. a revenue-neutral reform that still moves money between households — does not trigger the callout.
Callout
Reuses the repo's
Alertidiom (@/components/ui, informational teal-bordered styling withIconInfoCircle, matchingFloatingAlert's info type). Copy is sentence case, with<year>from the report context viauseReportYear():<year>"<year>, and that the programs you edited are in effect that year — some credits phase in later or expire."Files
app/src/utils/isSocietyWideReportNoOp.ts— pure detection utilapp/src/pages/report-output/NoOpReportCallout.tsx— the callout componentapp/src/pages/report-output/SocietyWideOverview.tsx— renders the callout above the card grid when the util returns true (the large line count is prettier re-indentation from the newStackwrapper; the logical change is ~7 lines — see thegit diff -w)app/src/pages/report-output/SocietyWideOverview.story.tsx— adds aCompleteNoOpstory (plus theCountryProvider/ReportYearProviderdecorators it needs to render)changelog_entry.yaml— user-facingfixedlineTest coverage
app/src/tests/unit/utils/isSocietyWideReportNoOp.test.ts): all-zero US → true; all-zero UK → true; tiny nonzero budgetary / benefit-spending / tax-revenue → false; 99.9% no change → false; revenue-neutral with real winners and losers → false; null / undefined / missing budget / missing intra_decile / missing "No change" / non-numeric → false.SocietyWideOverview.test.tsx): callout renders with the interpolated year on an all-zero fixture; falls back to a generic year phrase when there is no report-year context; absent on the default (nonzero) fixture; absent on a revenue-neutral fixture.Verification
vitest(util + component suites): 36 passedtsc --noEmitclean;eslint . --cache0 warnings;prettier --checkcleanCompleteNoOpStorybook story and confirmed the callout appears above the cards with the informational styling and the 2029 year interpolated.Fixes #1116
🤖 Generated with Claude Code