PRD 0031: Provisioned-wins merge + EgressRoute inherits Route #121
Reference in New Issue
Block a user
Delete Branch "prd-0031"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #120.
PRD:
ae33d1abfb/docs/prds/0031-split-merge-provider-route.mdSummary
_merge_provider_route’s five-case nested conditional with a flat provisioned-wins merge: provider routes own their hosts, manifest routes fill the gaps, token slot assignment is a single final pass._route_to_yaml_fieldsas the single authoritativeEgressRoute→YAML field mapping to prevent silent type drift betweenEgressRouteandegress_addon_core.Route.Changes (2 commits)
docs(prd): add PRD 0031 — split _merge_provider_route into named case helpersdocs(prd): revise PRD 0031 — provisioned-wins merge + Route type consolidationLet's fold the other egress issue in the unchecked task item from #117 into this PRD and the issue here #120 ... I think we can probably create a cleaner clean up by first determining how to consolidate our route declarations.
I think the flow should be mostly additive. Hierarchy should be like this:
provisioned_routes -> user_routes
A user can't redeclare a route that's provisioned/provisioning wins (for now at least). Have it match on host.
I also think the
requestspecific logic with the mitmproxy specific logic should probably just live in a pure function, but I'm not sure. Revise the plan with this in mind.RE #121 (comment)
Got it — expanding scope and revising the merge design. Here's my read before I update the PRD:
Provisioned-wins merge — this lets us delete almost all of
_merge_provider_route. The new flow is: start with provider routes (they own their hosts outright), then append any manifest routes for hosts not already claimed by a provider. No upgrade logic, no conflict detection. Token slot assignment becomes a single pass over the merged list in order. I'll refactoregress_manifest_routesso it doesn't assign slots itself; slot assignment becomes a final step after the merge.Route type consolidation —
egress_addon_core.Routecan't go away (it's stdlib-only, runs inside the container wherebot_bottleisn't installed). The risk is thatEgressRouteandRoutedrift silently. My plan: add a_to_route_fields(route: EgressRoute) -> dictpure function inegress.pythat produces exactly the fields_parse_oneexpects.egress_render_routesuses it exclusively — one place where the mapping between the two types is spelled out. The existing round-trip test (test_round_trip_through_addon_core) stays as the formal contract.Mitmproxy pure function —
decide()andis_git_push_request()inegress_addon_corealready cover all the decision logic as pure functions.request()inegress_addon.pyis already minimal mitmproxy glue: read host/path/headers from the flow, call the pure functions, apply the result. The split is clean. I'd leaverequest()as-is and not restructure further — the main thing missing is the explicit_to_route_fieldsmapping above.Updating the PRD now.
@@ -0,0 +42,4 @@### 2. Three-way Route type fragmentation`EgressRoute` (in `egress.py`) and `egress_addon_core.Route` areseparate dataclasses with overlapping but not identical field sets:Couldn't we just solve this by having
EgressRouteinheritRoute?RE #121 (comment)
With
EgressRouteinheritingRoute(not the other way), the import direction is fine —egress.pyimports fromegress_addon_core, the addon never imports fromegress.py. So the stdlib-only constraint isn't the blocker here.The real issue is serialization. If
EgressRouteextendsRoute,egress_render_routescan’t justdataclasses.asdictthe whole thing — host-only fields (token_ref,roles,tls_passthrough) must not appear in the YAML the addon reads. You’d still need something that says “only serialize theRoutebase fields” — e.g. iteratingdataclasses.fields(Route)explicitly.That implicit boundary (iterate base class fields to exclude host-only ones) versus the explicit
_route_to_yaml_fieldsfunction is a real tradeoff. Inheritance gives you a formal subtype relationship and auto-propagates newRoutefields toEgressRoute;_route_to_yaml_fieldsmakes the wire boundary a named, documented thing without adding an import coupling between the two modules.Either works. I went with
_route_to_yaml_fieldsas the minimal change that doesn’t restructure the type hierarchy, but if you prefer the inheritance approach I can revise.RE #121 (comment)
We want that coupling, that's the whole point of the change. Do the refactor.
RE #121 (comment)
On it.
PRD 0031: Split _merge_provider_route into named case helpersto PRD 0031: Provisioned-wins merge + EgressRoute inherits Routedidericis-claude referenced this pull request2026-06-02 02:06:53 -04:00