Skip to content

City ADST: compost and recycling share wood and paper by rerouting - #114

Merged
HughRunyan merged 3 commits into
am-waste-flowfrom
adst-diversion-reroutes-shared-material
Oct 28, 2026
Merged

HughRunyan merged 3 commits into
am-waste-flowfrom
adst-diversion-reroutes-shared-material

Conversation

@HughRunyan

Copy link
Copy Markdown
Collaborator

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_splits keeps the proportional split. In a year where it overruns a material (judged on over_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.
    • The solver fills interchangeable materials in arbitrary order (all the wood, little of the paper). Its routing is first spread over each group the same pathways can take, in proportion to the mix. Without that, the blend steps all the way to the solver's routing and the result jumps at the cap.
    • A year no routing fits keeps the proportional split, so over_diversion still fires with its existing message.
  • run_advanced_dst_city_limits applies Hall's condition (15 sets of the four pathways, closed-form): max_diversion is the tightest set, and max_food_waste_prevention bisects on it. component_use is read off the split the model uses.
  • At an exact bound, the solver's 1e-9 grid can leave a pathway up to 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.
  • Full suite: 655 passed.
  • One-off fuzz, outside the suite: 2,580 random cities, combustion on in 30% of them. Each pathway's exact bound was accepted, 1e-4 past it was refused, and no split jumped.

Acceptance criteria

  • A request that only a non-proportional routing fits runs, and each material stays within what the city generates
  • Years where the proportional split fits are bit-identical
  • Requests that no routing fits are still refused with over_diversion
  • run_advanced_dst_city_limits reports the new boundary, and the model accepts exactly that boundary
  • Changelog updated

Definition 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

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>
@HughRunyan HughRunyan added enhancement New feature or request model-output-change Changes model OUTPUT values (expected progress, not breaking); results differ from prior runs labels Oct 28, 2026
Copilot AI lite review requested due to automatic review settings October 28, 2026 20:26
@HughRunyan HughRunyan added enhancement New feature or request model-output-change Changes model OUTPUT values (expected progress, not breaking); results differ from prior runs labels Oct 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 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

Comment thread SWEET_python/advanced_dst_city.py Resolved
Copilot AI lite review requested due to automatic review settings October 28, 2026 20:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 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

Comment thread SWEET_python/advanced_dst_city.py Resolved
@HughRunyan
HughRunyan merged commit ca54ba1 into am-waste-flow Oct 28, 2026
3 checks passed
@HughRunyan
HughRunyan deleted the adst-diversion-reroutes-shared-material branch October 28, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request model-output-change Changes model OUTPUT values (expected progress, not breaking); results differ from prior runs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants