Repository navigation
City ADST: compost and recycling share wood and paper by rerouting - #114
Merged
HughRunyan merged 3 commits intoOct 28, 2026
Merged
Conversation
Compost and recycling both draw on wood and paper. Split in proportion to the mix, a recycling share held a fixed claim on the paper, so over_diversion refused compost shares that a different routing fits. Where the proportional split overruns a material, _pathway_splits now moves it by the smallest step toward dst_allocation's routing. Years that fit are unchanged to the bit. The limits apply Hall's condition, the same boundary the model now enforces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
An active moderate-severity issue remains because the bisection can return an incorrect prevention value for non-monotonic feasibility intervals.
1 open issue
What changed in this PR
This PR updates the city-level advanced DST so composting and recycling can reroute shared materials instead of being rejected by a proportional split, while keeping proportional behavior unchanged when it already fits.
Changes:
- Added solver-backed rerouting for over-diverted materials, with tolerance handling and continuous blending from proportional to feasible allocations.
- Reworked diversion limits and component usage reporting around Hall’s condition.
- Added extensive routing tests and documented the behavior change in the October changelog.
| File | Description |
|---|---|
| tests/test_adst_city_diversion_routing.py | Updated as part of this pull request. |
| SWEET_python/advanced_dst_city.py | Updated as part of this pull request. |
| changelog/2026-10.md | Updated as part of this pull request. |
Review effort: Lite
… while others overreach
There was a problem hiding this comment.
🟡 Changes recommended
A critical bisection bug treats both infeasible endpoints as a valid search bracket, causing the bounded feasible interval case to return 0 instead of the expected upper boundary and failing the advertised bounds test.
1 open issue
1 resolved since last review
Review effort: Lite
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
In the city-level advanced DST, compost and recycling now share wood and paper by rerouting instead of refusing. Each pathway still takes its materials in proportion to the mix. But in a year where that would claim more of a material than the city generates, and some other routing fits, the split moves toward one that does.
User story. As an ADST user, I want to raise composting past what a proportional split allows, so that recycling's share comes more from plastic, metal and glass instead of the request being capped.
With recycling at 18.9%, a mix of 59% organics and 55% recyclables (14% wood + paper, the case in the screenshot that prompted this) used to cap compost at 39%. Compost can now reach 59%.
How
advanced_dst_city._pathway_splitskeeps the proportional split. In a year where it overruns a material (judged onover_diversion's own 1e-6 t tolerance), it blends toward the city DST's routing,dst_allocation.solve_allocation, using the least blend weight that brings every material back within what exists. That weight is closed-form, since each material's total is linear in it.over_diversionstill fires with its existing message.run_advanced_dst_city_limitsapplies Hall's condition (15 sets of the four pathways, closed-form):max_diversionis the tightest set, andmax_food_waste_preventionbisects on it.component_useis read off the split the model uses.ROUTING_GRID_TOLERANCE(1e-8 of generated waste) short. The worst seen was 2.4 kg in a million tonnes.Model-output change
Only past the old proportional cap. Every request that ran before returns identical numbers, because a year that fits is left untouched to the bit.
Testing
tests/test_adst_city_diversion_routing.py(new): the screenshot's case runs; recycling shifts off paper onto plastic; a fitting split is exactly proportional; no jump at the cap; infeasible requests are still refused; the bounds agree with the model on random cities.Acceptance criteria
over_diversionrun_advanced_dst_city_limitsreports the new boundary, and the model accepts exactly that boundaryDefinition of done
Acceptance criteria met · tests pass · changelog updated · reviewed and merged. The WasteMAP half (frontend caps + incinerator clamp) is a paired PR into WasteMAP
am-waste-flow, which builds SWEET from this branch's base.🤖 Generated with Claude Code