Phase 4 operator platform
Per-org allow/deny model policies (Postgres + LRU+TTL cache + Redis pub/sub), OrgAwareRegistry gate in ProviderRoutingMiddleware, agent default_model fill, and management CRUD.
Milestone 4.C.2 — Per-Org Model Routing Configuration
Status: Completed
Goal: Track C — Multi-Provider Adapters & Resilience
Phase: 4 — Operator Platform & Multi-Provider
Estimated effort: 2 days
Track: Track C — Multi-Provider Adapters & Resilience
Why This Milestone Exists
Exit criteria requires model-based routing configuration per org — allowlists/denylists and default-model overrides (e.g. enterprise restricted to Anthropic for compliance). Platform registry remains the source of which models exist; org policy is a veto gate before Registry.For.
Non-Goals
- Generic rules engine / DSL
- Per-user model routing
- Azure OpenAI or Bedrock adapters
- Auth service changes
fallback_chain(4.C.4)- Strict provider allowlist (#790)
Shipped surface
| Layer | What landed |
|---|---|
| ADR | ADR-0075 |
| Schema | Migration 000029_org_model_policies (RLS; no fallback_chain) |
| Domain | packages/modelpolicy — store, evaluate, LRU+TTL, publisher/subscriber, OrgAwareRegistry |
| Proxy | Chat parse allows empty model; ProviderRoutingMiddleware + bootstrap subscriber |
| Errors | 403 MODEL_NOT_ALLOWED; unknown after allow still 501 PROVIDER_NOT_CONFIGURED |
| API | Org-scoped model-policies CRUD + model_policy_updates:{org_id} publish-on-write |
Precedence
- Request
model(trimmed) if non-empty - Else agent
default_modelfrom proxy Postgres - Else
400model required - Org policy first-match (priority ASC,
filepath.Match); no match → allow Registry.For(candidate)→ attach provider or501
Channels
model_policy_updates:{org_id}/model_policy_updates:*- Payload:
{"v":1,"org_id":"<uuid>"}
Success signals
- Deny →
ErrModelNotAllowedForOrg→403 MODEL_NOT_ALLOWED(middleware unit + registry tests) - Cache hit avoids second loader call; TTL expiry + pub/sub invalidate ≤1s (miniredis)
-
TestRouting_OrgPolicy_*against real Postgres (//go:build integration) - Unit foreign-org path checks → 404 on all verbs (
test_unit_model_policies_*_foreign_org_404; live API+RLS ISO is a follow-up) - Minimal middleware + constructor wiring (not “zero middleware changes”)
Prerequisites
- M4.C.1 Anthropic adapter merged (two providers useful for routing demos)
- M4.A.3 agents
default_modelcolumn available for empty-model fill
Edit on GitHub
Last updated on