Register weighted-microdata rules: weights aren't values
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 30/100
Research direction
Start with rules/registry.toml to see how existing rules and their AST guards and proofs are declared, then read simulation_output_common.py, where raw values are read from weighted frames. The output-builder tests that currently use plain pd.DataFrames are the other place to look. Done means the four named rules are registered with guards and proofs, the confined-read exception list is in place, and the builder tests use one shared weighted factory.
Written by the indexing model from the issue text.
Description
Problem
The executor's entity frames are microdf MicroDataFrames weighted by <entity>_weight, so .sum(), .mean() and .count() on any column are already weighted.
In #766 (fixed by #767), build_budgetary_impact passed "household_weight" to _sum_output_variable, the helper it uses for ordinary values. That weighted the weight column by itself, giving the sum of squared weights.
- Effect:
budget.householdswas about 10^4 times too high on every run (New York 2026: 135.6 billion, against about 7.5 million households). Clients divide by it, so the average change per household was about 10^4 times too small. - Why it escaped: the builder test used plain
pd.DataFrames, which carry no weights.
Nothing stops the same class of mistake from coming back.
Proposal
Phase 1 step 1.9. Register the rule that weights aren't values in rules/registry.toml, with AST guards and proofs:
sim.microdata.weights-not-values(doc-only): weights, values, labels and counts each allow different operations.sim.microdata.weights-not-aggregated-as-values: a weight is never the variable of a weighted aggregator, and neverframe[<weight>]followed by a weighted reduction.sim.microdata.weight-stripping-confined: raw values are read from a weighted frame only insimulation_output_common.py.- Counting entities is always allowed there.
- Any other read there is a recorded exception, in a list that may only shrink.
sim.microdata.builder-tests-use-weighted-frames: output-builder tests build entity frames through one shared weighted factory, never as plainpd.DataFrames.
Alongside, two cheap runtime checks that the AST guards can't replace:
- change totals (reform minus baseline) log a warning when the two sides carry different weights;
- an implausible published household count fails the run.
Decisions
- UK local-authority handoff. The breakdown hands policyengine's longwise geography impact a plain household frame, and that function weights by
household_weightitself. The handoff moves intosimulation_output_common.pyas the stripping rule's one recorded exception. Removing it is tracked separately. - Weight mismatch: warn first. It logs a warning and still publishes the total. It becomes an error once logs show that no legitimate run produces a mismatch.
- Household count: fail the run. A failed run is better than a headline that's 10^4 times wrong.
- Dominant language
- Python
- Stars
- 1
- Forks
- 1
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 40
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from PolicyEngine/policyengine-sim-api
-
Integration tests fail due to missing UV virtual environment setupPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
PolicyEngine/policyengine-sim-api#314 ·
Maintainers usually reply within 1 day
-
Update policyengine to 6.4.3Possibly taken @policyengine claimed this today. Open
Difficulty 1/5 1-3 hours Newbie friendliness 35/100
PolicyEngine/policyengine-sim-api#812 ·
Maintainers usually reply within 1 day
-
Update policyengine to 6.4.2Possibly taken @policyengine claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 40/100
PolicyEngine/policyengine-sim-api#810 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 25/100
PolicyEngine/policyengine-sim-api#805 ·
Maintainers usually reply within 1 day
-
Refactor within ruff's complexity limits, then select every ruff rule (ALL)Possibly taken @anth-volk claimed this 1 day ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 15/100
PolicyEngine/policyengine-sim-api#803 ·
Maintainers usually reply within 1 day
All issues in PolicyEngine/policyengine-sim-api
Similar issues
-
Path subtraction removes repeated suffix characters instead of one suffixPossibly taken @Gwerdonatus claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
joke2k/django-environ#671 ·
-
good first issue help wanted windows
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
-
test_pgbouncer deploys the server under test from Charmhub instead of the local build (track/1.31)Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
canonical/temporal-k8s-operator#195 · 1 comment ·
Maintainers usually reply within 4 days
-
`burr` fails to start when the Python path has a space in itPossibly taken @enekoreto claimed this today. Openstatus/needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 5 days
-
device support request
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
zigpy/zha-device-handlers#5461 ·
Maintainers usually reply within 4 days