Skip to content

Port three robustness analyses onto referee-revised paper#16

Merged
vahid-ahmadi merged 2 commits into
mainfrom
port-robustness-analyses
Jun 28, 2026
Merged

Port three robustness analyses onto referee-revised paper#16
vahid-ahmadi merged 2 commits into
mainfrom
port-robustness-analyses

Conversation

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Builds on the merged referee revisions (#13). Adds three analyses that the referee pass did not include, with all numbers recomputed on this repo's regenerated population so they are consistent with the paper's base, and written in elasticity-free wording (does not re-introduce the "shrinks" / "model-free" / £100-bin / cubic framings #13 corrected).

Added analyses

  1. Value-added robustness of the dominated region (model.tex). Real VAT taxes value added, so a firm remitting net rate τ₀ faces a_i = T*·τ₀/(1−τ₀). On near-threshold firms: ~42% are net input creditors / near-zero remitters (effectively no notch — consistent with the ~43% voluntary-registration share); for the rest the value-added dominated region has a weighted median ~£18,650 (≈£44k for high-net-rate consumer-facing firms), the same order as the £21,250 full-rate width. So the correction scopes out the voluntary registrants rather than collapsing the region. Script: results/task1_value_added_dominated_region.py.
  2. Estimator recovery / power test (a_inference.tex, tab:recovery; pointer in bunching.tex). Injecting a known bunching signal into the step-free Placebo-A population, the same estimator recovers ~90% (89.6%) at E_true = 2k/5k/8k. So it is both specific (placebo: no false positive) and sensitive (recovery: has power) — the null on the real data is a property of the data, not the method. Script: analysis/recovery_bunching.py.
  3. Fiscal-drag projection (conclusion.tex). A frozen £90k threshold draws ~14% more firms into the dominated region by 2028–29 (~130k→148k); the just-below, bunching-exposed band grows ~9.5% (~41k→45k) — consistent with the OBR fiscal-drag narrative. Script: results/task2_fiscal_drag_projection.py.

Notes

  • Numbers were re-run on the regenerated original-model population in this clone (not the other clone's bespoke file, which gave an inconsistent 133k figure and — when mis-based — an OBR-contradicting result). Fiscal drag is correctly based on the 2023-24 turnover distribution aged forward.
  • Build: clean (latexmk -lualatex), 36 pp, all refs/citations resolve.
  • The deeper v_i / negative-VA model issue remains tracked separately in Fix per-firm VAT liability scaling (value-added → net VAT) + repair bunching reproduction #15 and is not addressed here.

🤖 Generated with Claude Code

vahid-ahmadi and others added 2 commits June 28, 2026 19:19
Adds three analyses (absent from PR #13) on top of the merged referee revisions,
with numbers recomputed on this repo's regenerated population so they are
consistent with the paper's base, and in elasticity-free wording:

- Value-added robustness of the dominated region (model.tex): ~42% of
  near-threshold firms are net input creditors / near-zero remitters (no notch),
  consistent with the ~43% voluntary-registration share; for the rest the
  value-added dominated region has a weighted median ~£18,650 (rising to ~£44k
  for high-net-rate consumer-facing firms), the same order as the £21,250 width.
  Script: results/task1_value_added_dominated_region.py.
- Estimator recovery / power test (a_inference.tex + pointer in bunching.tex):
  injecting a known signal into the step-free population, the same estimator
  recovers ~90% (89.6% at E_true = 2k/5k/8k), so the null is a property of the
  data, not the method. Script: analysis/recovery_bunching.py.
- Fiscal-drag projection (conclusion.tex): a frozen £90k threshold draws ~14%
  more firms into the dominated region by 2028-29 (~130k->148k), just-below band
  +9.5% (~41k->45k). Script: results/task2_fiscal_drag_projection.py.

Rebuild main.pdf (36pp). Uses elasticity-free wording; does not re-introduce the
"shrinks" / "model-free" / £100-bin / cubic framings the referee pass corrected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve the CI ruff failures introduced with the three ported scripts:
- task1: split semicolon statements (E702), drop placeholder-free f-string (F541)
- recovery_bunching: remove unused has_power variable (F841)
No behavioural change; scripts produce identical output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — looks good, mergeable ✅

Checked the diff against the regenerated population, the scripts, and CI.

Verified

  • CI green (ruff / pytest / compile + Quarto), no base conflicts.
  • Numbers match their scripts and are reproducible from this repo (with appropriate rounding):
    • value-added: script 41.5% → "~42%"; median £18,650 (exact); top-quartile £43,822 → "~£44k";
    • fiscal drag: 130,481 → 148,403 (+13.7% → "~14%"); just-below +9.5% (41k → 45k);
    • recovery: 89.6% at E_true = 2k/5k/8k.
  • No framing regressions: none of the corrected "shrinks" / "model-free" / £100-bin / cubic phrasings reappear; the additions are elasticity-free throughout.
  • Fiscal drag is correctly based on the 2023-24 turnover distribution aged forward — not the already-aged £90k vintage (which double-counts and produced an OBR-contradicting result where the just-below band shrank).

One substantive note (non-blocking). In model.tex, the dominated-region subsection now states both that ~137,000 firms are "exposed" to the band and that ~42% of near-threshold firms face no notch (net input creditors). These are measured over different ranges (£85k–£106.25k vs £80k–£90k), so they don't contradict — but a reader could perceive tension. Consider one clause tying them together: the 137k is the exposed population over the band, of which the ~42% net-creditors face no binding notch, so the genuinely-distorted count is smaller. Sharpens the honesty without touching the headline.

Minor

  • results/task2_fiscal_drag_projection.py hardcodes the FISCAL_YEARS growth factors that also live in static/model.py — fine for now, but could drift; consider importing them.
  • The recovery test's E_recovered is the deficit-differenced signed-excess measure (defined in the appendix); since that's non-standard, keeping the one-line definition prominent is worth it.

Caveat (already documented). This sits on the original model; the deeper v_i / negative-VA issue is tracked in #15 (now draft PR #17). The value-added robustness paragraph here is, in effect, an honest in-paper acknowledgment of part of that same issue — which is a strength, not a problem.

Recommendation: mergeable as-is. The note above is a nice-to-have, not a blocker.

@vahid-ahmadi vahid-ahmadi merged commit fbc9a86 into main Jun 28, 2026
2 checks passed
vahid-ahmadi added a commit that referenced this pull request Jun 28, 2026
Remove the three blocks sourced from the unmerged PR #16 (not in the published
paper): value-added robustness, the bunching recovery test, and the fiscal-drag
projection. The bunching block now ends with the paper's own framing (bunching
non-identified; Liu et al. 2021 remains the behavioural fact). Drop the
taper_reform_distribution figure (not used in main.pdf); use firms_impact_2025_26
in the reform-menu block and enlarge column-4 figures to rebalance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vahid-ahmadi added a commit that referenced this pull request Jun 29, 2026
* Add conference poster for the VAT microsimulation paper

A0 portrait poster built on the Gemini beamerposter theme with a custom
PolicyEngine colour theme. Three-column narrative: the VAT notch and
dominated region, validation against HMRC, the reform menu (level/shape/
rate on a common static base), the mechanical-bunching placebo, and the
behavioural sensitivity range.

Self-contained build: Raleway/Lato fonts vendored under fonts/, figures
copied from paper/figures/. Compiles with `xelatex poster.tex`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Rebuild poster: landscape A0, comprehensive, official PolicyEngine teal logo

- Landscape A0, 4 balanced columns covering every paper section
  (notch/motivation, contribution, synthetic data, static costing + HMRC
  validation, threshold sweep, dominated region + secondary-notch, value-added
  robustness, mechanical bunching + placebo + recovery, reform-menu table,
  conditional behavioural layer, fiscal drag, conclusions, future work).
- Repalette blue -> official PolicyEngine teal (#2C7A7B); teal wordmark + square
  mark in header (from policyengine-app-v2 brand assets); QR to repo.
- Pull main into the branch so figures/numbers match the referee-revised paper.
- 9 figures; builds cleanly with xelatex (single A0 landscape page).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: show only results that are in main.pdf

Remove the three blocks sourced from the unmerged PR #16 (not in the published
paper): value-added robustness, the bunching recovery test, and the fiscal-drag
projection. The bunching block now ends with the paper's own framing (bunching
non-identified; Liu et al. 2021 remains the behavioural fact). Drop the
taper_reform_distribution figure (not used in main.pdf); use firms_impact_2025_26
in the reform-menu block and enlarge column-4 figures to rebalance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: white block bodies to remove low-zoom rasterisation artifact

The teal-tinted alert/example block bodies produced faint horizontal lines
through the text when the A0 page is rasterised at low zoom (dark text
antialiased against the tint). Switch all alert/example block bodies to white
(keeping teal title bars for hierarchy) so previews are clean at any zoom; the
underlying PDF was always crisp at full resolution.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: section titles as teal text on white (drop filled title bars)

The alert/example block titles ('Contribution', 'The problem', 'Conclusions',
'Static costing', 'Method...') used white text on a filled teal bar, which
showed the same low-zoom rasterisation lines through the title letters. Make
those titles teal/dark-teal bold text on white with a teal underline rule
(matching the standard-block titles) so every section title is artifact-free
and the poster reads uniformly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster header/footer polish

- Header: two-line subtitle — line 1 name + envelope icon + email; line 2
  PolicyEngine + globe icon + www.policyengine.org + 'free, open-source policy
  analysis' tagline (fontawesome5 icons).
- Smaller PolicyEngine wordmark (4.2cm -> 2.9cm); remove the redundant square PE
  mark from the top-right.
- Footer: drop 'branch poster'; use www.policyengine.org.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: tighten narrative flow and section connections

Make the four columns read as one Problem -> Method -> Distortion -> Reforms
arc: add short italic teal lead-in cues and column-start arrows linking each
block to the next; move Contribution up under the problem with a one-line
Headline ('only the graduated taper removes the distortion; the level move is
the dearest and least efficient'); reorder within columns for logic. No content
or numbers changed -- still exactly the main.pdf results; titles stay
teal-on-white, header/footer/logo unchanged. Figure widths trimmed slightly to
keep columns balanced.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: use main's exact figures (drop regenerated/stale versions)

Several poster figures (notably dynamic_notch_fit_e017.png, which showed a
step-UP density that is not the published version) were stale/regenerated copies
that did not match main.pdf. Wipe paper/poster/figures and re-copy every figure
verbatim from origin/main:paper/figures so the poster uses ONLY the figures that
appear in the published paper. Also drop the two unused extras
(obr_vat_bunching, taper_reform_distribution). All 9 figures now md5-match main;
all numeric claims already verified present in main's text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: reorder blocks to follow the paper's section order; fix cut-off

Read column-by-column the blocks now follow main's section order: notch/intro ->
reform families -> contribution -> method -> synthetic data -> static costing
(+HMRC validation) -> threshold sweep -> reform menu -> bunching (placebo) ->
dominated region -> how reforms change it -> behavioural -> conclusions ->
future work. Key fix: bunching (sec 5) now precedes the dominated region (sec 6),
and the reform menu (sec 4) precedes bunching. Rebalanced columns and resized
figures so every column clears the footer (no clipping). No content, numbers, or
figures changed; figures still match main exactly; teal-on-white titles and
header/footer/logo unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: pounds-not-dollars, header QR->vercel, Beamm.conf26 footer, layout polish

- Fix currency: every monetary value now renders with the pound sign; \pounds
  was inside math mode (rendered as $) -> moved to text mode / \text{\pounds}.
- Header: uniform-size two-line subtitle; 'PolicyEngine | (globe) www.policyengine.org
  | Free, open-source tax and benefit analysis'; big QR in the top-right corner
  encoding https://firm-microsim-paper.vercel.app/.
- Footer: 'Beamm.conf26 | Conference on Public Finance & Public Policy Evaluation'.
- Show one figure in the intro (firm-size distribution) and one in the threshold
  sweep; reform menu is the table only; remove the 'Future work & contact' block.
- Enlarge key figures and distribute blocks so all four columns fill the page with
  no cut-off into the footer. Content unchanged and still matches main.pdf.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Poster: unify section-title colour, shorten behavioural block, larger titles

- All block titles render in peteal (example blocks no longer darker)
- LARGE block titles + scale 1.05 to use whitespace
- Trim behavioural-layer text by ~3 lines (keep all numbers + caveat)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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