Skip to content

feat(routing): add validated routing policy profiles - #1011

Draft
Wibias wants to merge 5 commits into
lidge-jun:devfrom
Wibias:feat/ri-04-policy-profile-core
Draft

feat(routing): add validated routing policy profiles#1011
Wibias wants to merge 5 commits into
lidge-jun:devfrom
Wibias:feat/ri-04-policy-profile-core

Conversation

@Wibias

@Wibias Wibias commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

RI-04 of the Router Intelligence / Routing Control Plane programme. Adds the
routing policy profile core: a validated top-level routingProfiles
config schema, deterministic normalization + revision digest, collision
validation, a dry-run evaluator, management API, CLI, and documentation.

Policy routing is inert in this PR: no production request uses a profile
yet (that is RI-05). Everything here is configuration, evaluation-on-demand,
and dry-run.

Scope

  • src/types.ts - OcxRoutingProfileConfig (candidates allowlist, alias,
    require, optimize, limits, unknownEvidence) + routingProfiles on
    OcxConfig.
  • src/routing/profile.ts - validation (routingProfileIssues), alias
    collision rules (providers, combos, codex account namespaces, sibling
    profiles, reserved native families, policy/ + combo/ namespaces),
    normalization (normalizeRoutingProfile), SHA-256 revision digest
    (16-hex), resolvePolicyProfileId / parsePolicyModelId /
    policyPublicModelId.
  • src/routing/evaluator.ts - deterministic dry-run evaluator: hard
    capability requirements (min context window, tools, image input, structured
    output, reasoning effort, service tier, local/remote, encrypted Codex
    tasks) are evaluated against supplied evidence; unknown-capability handling
    follows the profile's unknownEvidence; scoring is deterministic
    configured priority only (capability/health/quota/cost components arrive
    with RI-05..08). Produces a full RI-01 decision trace with
    profile.id/profile.revision.
  • src/config.ts - routingProfiles validated inside
    validateConfigCandidate (broken profiles fail closed like broken combos).
  • Management API: GET /api/routing-profiles,
    POST /api/routing-profiles/dry-run.
  • CLI: ocx route policy list | show <id> | dry-run <id> --model-context <tokens> --tools [--image] [--structured-output].
  • Docs: routing configuration reference gains the routingProfiles schema
    and the combos-vs-profiles distinction (locale sync completes in RI-10).
  • tests/routing-profile.test.ts - 12 tests.

Unknown is not zero

unknownEvidence per profile controls unknown capability evidence:
exclude (default), penalize, or allow. Unknown prices/health/quota stay
unknown; nothing converts unknown to zero or free.

No implicit routing

Existing model ids, combos, account namespaces, and default-provider
resolution are byte-for-byte unchanged. Profiles only activate for an
explicitly requested policy/<id> or alias (RI-05 wires execution).

Compatibility

  • Existing config files without routingProfiles load unchanged.
  • Additive APIs; /api/logs, /api/request-history, /api/routing-analytics
    unchanged.

Privacy / security

  • Dry-run never dispatches upstream requests and never touches credentials.
  • Traces follow RI-01 bounds; no prompts, keys, or raw responses.
  • bun run privacy:scan passes.

Dependency

Non-goals

  • No production policy execution (RI-05).
  • No health/quota/cost scoring (RI-06/07/08).
  • No explainability API or GUI (RI-09/10).
  • No implicit candidate expansion - explicit allowlist only.

Local verification (exact)

  • bun x tsc --noEmit -> PASSED (0 errors)
  • bun run test tests/routing-profile.test.ts -> 12/12 pass
  • Focused regression suites -> 176/176 pass across 8 files
  • bun run privacy:scan -> passed
  • tests/config.test.ts: 109/115 pass; the 6 symlink failures reproduce
    identically on the pristine base (Windows symlink EPERM, environmental)

Notes for reviewers

  • Weight normalization keeps defaults for omitted dimensions (documented in
    tests): optimize: { latency: 1, cost: 3 } merges health 0.25 and quota
    0.1 before normalizing (sum 4.35).
  • The revision digest covers the normalized profile (sorted-key canonical
    JSON), so configs that differ only in formatting share a revision.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f7c6ca4-84a6-455e-88e0-977e8502e624

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant