Summary
ModelPort has a modular-monolith product boundary, but one root router still owns all 68 production route registrations. Give each HTTP domain explicit registration ownership and a deterministic route-contract inventory before Compute, Deployment, and Responses add more surface.
Actual behavior
src/routes.rs is 8,711 lines and its single router function registers health, client inference, internal operations, admin authentication, governance, Providers, settings, evidence, enterprise, identity, keys, and quotas in one chain. Handler modules exist, but they do not own their paths, so adding a domain still requires editing the root composition point and route loss or middleware drift is difficult to detect.
Expected behavior
The root application router merges domain-owned routers and applies global middleware once. A deterministic method/path/domain inventory and contract tests prove that every existing route is owned exactly once and preserves its current behavior, while future Compute, Deployment, and Responses routes can extend their own domain without growing the root registration chain.
Steps to reproduce
Inspect the router function on main and count its production route registrations. Move or omit one registration: existing tests cover many handlers but there is no complete route ownership inventory that detects every missing, duplicated, or mis-owned method/path.
Environment
ModelPort main 14ea1f5; Rust/Axum single-process server; 68 production route registrations observed on 2026-08-24.
Acceptance criteria
Additional context
Scope
Introduce explicit HTTP domain composition inside the existing Rust modular
monolith. Domain modules own method/path registration and expose bounded routers;
the application router merges them and applies global middleware exactly once.
The initial domains are:
- public health and metrics;
- client inference and policy APIs;
- internal Ops Agent APIs;
- admin authentication and self-service;
- admin governance and identity resources;
- admin Provider/model/routing configuration;
- admin evidence, enterprise, retention, backup, and operations.
Add one deterministic route-contract inventory containing every registered
method/path and domain owner. Tests must reject duplicate ownership and prove the
inventory matches the composed router for all current routes, including method-not-
allowed behavior where relevant. Future Compute, Deployment, and Responses routes
must join through their domain router rather than extending one root registration
chain.
Compatibility
- Preserve every public path, HTTP method, authentication requirement, browser-write
origin check, cache header, request-body bound, request-ID behavior, tracing field, concurrency
limit, error representation, and response header.
- Keep global middleware order and application-state construction unchanged.
- Do not add service processes, network calls, dependencies, migrations, feature
flags, Provider behavior, protocol support, or Dashboard behavior.
- Keep the single-process modular-monolith deployment contract.
Non-goals
- Moving every handler implementation in the same change when registration
ownership is sufficient.
- Splitting
AppState, ControlStore, or EnterpriseLedger; those require their
own independently verifiable boundary capabilities after route ownership exists.
- Adding Compute, Deployment, Responses, Realtime, or other product APIs.
- Reducing a file to an arbitrary line target.
Documentation
Update the architecture component map and contribution guidance so new HTTP
capabilities declare a domain owner, register through the domain router, and extend
the route-contract inventory. Document rollback as reverting the composition change;
there is no data or protocol migration.
Summary
ModelPort has a modular-monolith product boundary, but one root router still owns all 68 production route registrations. Give each HTTP domain explicit registration ownership and a deterministic route-contract inventory before Compute, Deployment, and Responses add more surface.
Actual behavior
src/routes.rs is 8,711 lines and its single router function registers health, client inference, internal operations, admin authentication, governance, Providers, settings, evidence, enterprise, identity, keys, and quotas in one chain. Handler modules exist, but they do not own their paths, so adding a domain still requires editing the root composition point and route loss or middleware drift is difficult to detect.
Expected behavior
The root application router merges domain-owned routers and applies global middleware once. A deterministic method/path/domain inventory and contract tests prove that every existing route is owned exactly once and preserves its current behavior, while future Compute, Deployment, and Responses routes can extend their own domain without growing the root registration chain.
Steps to reproduce
Inspect the router function on main and count its production route registrations. Move or omit one registration: existing tests cover many handlers but there is no complete route ownership inventory that detects every missing, duplicated, or mis-owned method/path.
Environment
ModelPort main 14ea1f5; Rust/Axum single-process server; 68 production route registrations observed on 2026-08-24.
Acceptance criteria
Additional context
Scope
Introduce explicit HTTP domain composition inside the existing Rust modular
monolith. Domain modules own method/path registration and expose bounded routers;
the application router merges them and applies global middleware exactly once.
The initial domains are:
Add one deterministic route-contract inventory containing every registered
method/path and domain owner. Tests must reject duplicate ownership and prove the
inventory matches the composed router for all current routes, including method-not-
allowed behavior where relevant. Future Compute, Deployment, and Responses routes
must join through their domain router rather than extending one root registration
chain.
Compatibility
origin check, cache header, request-body bound, request-ID behavior, tracing field, concurrency
limit, error representation, and response header.
flags, Provider behavior, protocol support, or Dashboard behavior.
Non-goals
ownership is sufficient.
AppState,ControlStore, orEnterpriseLedger; those require theirown independently verifiable boundary capabilities after route ownership exists.
Documentation
Update the architecture component map and contribution guidance so new HTTP
capabilities declare a domain owner, register through the domain router, and extend
the route-contract inventory. Document rollback as reverting the composition change;
there is no data or protocol migration.