Skip to content

feat(control-plane): expose route decision explanations - #1016

Merged
Wibias merged 1 commit into
lidge-jun:devfrom
Wibias:feat/ri-09-route-explainability-api
Aug 5, 2026
Merged

feat(control-plane): expose route decision explanations#1016
Wibias merged 1 commit into
lidge-jun:devfrom
Wibias:feat/ri-09-route-explainability-api

Conversation

@Wibias

@Wibias Wibias commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

RI-09 of the Router Intelligence / Routing Control Plane programme. Exposes
why-this-route explanations from the durable trace + attempt history:

  • GET /api/request-history/:requestId/route-decision - requested model,
    route kind, profile + revision, requirements, candidates with exclusions
    and score components, selected candidate + tie-break, actual attempt
    sequence, and final outcome.
  • GET /api/routing-profiles (RI-04) and POST /api/routing-profiles/dry-run
    remain the profile inspection surfaces; the dry-run endpoint now also
    assembles canonical capability/health/quota/cost evidence when no candidate
    evidence is supplied ("evaluate" mode).
  • CLI: ocx logs explain <request-id> and ocx route policy evaluate <profile> (an alias of dry-run with auto-evidence).

The API returns stable structured codes + display-ready summaries - never
localized prose as the only contract.

Scope

  • src/server/management/request-history-routes.ts - the
    /route-decision subroute (checked before the generic :requestId
    branch): merges the persisted RI-01 trace, the execution attempts[], and
    a summary/outcome block. Pre-trace rows answer with routeDecision: null
    and their attempts/outcome (honest, not fabricated).
  • src/server/management/routing-profile-routes.ts - dry-run auto-evidence:
    candidates omitted -> canonical capability (catalog/registry/native),
    health (index), quota (caches), cost (price model + profile limit)
    evidence per profile candidate.
  • src/cli/observe.ts - ocx logs explain <id> [--json].
  • src/cli/route-policy.ts - ocx route policy evaluate <id> [--json].
  • tests/route-explainability.test.ts - 4 tests.

Privacy / security

  • The explanation surfaces only data already bounded by the trace and the
    usage entry: no prompts, credentials, or raw responses.
  • bun run privacy:scan passes.

Compatibility

  • Additive endpoints and CLI subcommands; /api/logs and /api/request-history
    unchanged.

Dependency

Non-goals

  • No UI (RI-10).
  • No localized prose as the API contract (stable codes + summaries only).

Local verification (exact)

  • bun x tsc --noEmit -> PASSED (0 errors)
  • bun run test tests/route-explainability.test.ts -> 4/4 pass
  • Focused regression suites -> 70/70 pass across 8 files
  • bun run privacy:scan -> passed

Summary by CodeRabbit

  • New Features

    • Added logs explain to inspect routing decisions by request ID, with formatted and JSON output.
    • Added route-decision history through the management API.
    • Added route-policy evaluate support and cost details to routing profile previews.
  • Bug Fixes

    • Improved validation for route-policy profile IDs and request IDs.
    • Corrected capability reporting when a provider is unavailable.
    • Improved final provider and model reporting for completed requests.
  • Tests

    • Added coverage for route explanations, dry-run evidence, validation, and unavailable providers.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Wibias, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 91af24a6-a570-44db-82e7-e4204b91d97b

📥 Commits

Reviewing files that changed from the base of the PR and between 410db97 and ae2c329.

📒 Files selected for processing (7)
  • devlog/_plan/260804_router_intelligence/001_pr_stack_status.md
  • src/cli/observe.ts
  • src/cli/route-policy.ts
  • src/routing/capability.ts
  • src/server/management/request-history-routes.ts
  • src/server/management/routing-profile-routes.ts
  • tests/route-explainability.test.ts
📝 Walkthrough

Walkthrough

The PR adds a route-decision history endpoint and CLI explanation command. It extends routing-profile dry runs with cost and capability evidence. It updates policy CLI dispatch and adds explainability tests and acceptance records.

Changes

Route intelligence

Layer / File(s) Summary
Request-history route-decision API
src/server/management/request-history-routes.ts:6-7, :24, :34-44, :130-173
Adds GET /api/request-history/:requestId/route-decision. The handler validates IDs, loads persisted history, returns route attempts and outcomes, and resolves the final target with fallback behavior.
Routing candidate evidence
src/server/management/routing-profile-routes.ts:14, :23, :91-133, :167; src/routing/capability.ts:188-193, :202
Adds shared candidate evidence assembly for capability, health, quota, and cost data. Omitted providers no longer receive synthetic encryptedCodexTasks results.
CLI commands and validation
src/cli/observe.ts:17, :85-95, :155-156; src/cli/route-policy.ts:16-17, :45, :57, :86-89; tests/route-explainability.test.ts:1-202; devlog/_plan/260804_router_intelligence/001_pr_stack_status.md:49-51, :261-278
Adds logs explain, documents and dispatches route-policy evaluate, rejects option-like profile IDs, and adds route explainability and evidence tests. The stack status and acceptance log are updated.
Estimated code review effort: 4 (Complex) ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant ObserveCLI as observe.ts
  participant RequestHistoryAPI as request-history-routes.ts
  participant PersistedHistory as Persisted request history
  Operator->>ObserveCLI: logs explain request ID
  ObserveCLI->>RequestHistoryAPI: Request route-decision history
  RequestHistoryAPI->>PersistedHistory: Decode ID and load entry
  PersistedHistory-->>RequestHistoryAPI: Trace and attempt data
  RequestHistoryAPI-->>ObserveCLI: JSON or formatted route explanation
  ObserveCLI-->>Operator: Display route decision
Loading

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the PR's primary change: exposing route-decision explanations in the control plane.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added the enhancement New feature or request label Aug 4, 2026
@Wibias
Wibias marked this pull request as ready for review August 5, 2026 08:21
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

PR quality gates passed

This pull request now targets dev with acceptable ancestry, description, and UI screenshot coverage.

The title was left unchanged. The pull request has been marked ready for review again.

@github-actions
github-actions Bot marked this pull request as draft August 5, 2026 08:21
@Wibias
Wibias marked this pull request as ready for review August 5, 2026 08:22
@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

[GD] Verdict: changes-requested

TLDR

  • PR: #1016 — feat(control-plane): expose route decision explanations
  • Head: 6e69a4a6 on dev (mergeStateStatus: DIRTY / CONFLICTING)
  • Decision: useful and mostly sound, but needs 1 blocking bug fix + the owner to update from latest dev before it can be merge-ready
  • Usefulness: delivers the claimed RI-09 explainability value — a bounded, privacy-safe why-this-route API + CLI, with an honest pre-trace null path. Genuinely useful.
  • Bugs: 1 confirmed blocker — src/routing/capability.ts:122-124 fabricates encryptedCodexTasks: false for an absent/unknown provider instead of leaving it unknown.
  • Security: no confirmed issues; the new endpoints ride the existing management-auth path and only read local bounded sources.
  • Spec / standards: clean against the master-plan ADRs and non-goals; one minor docs gap (evaluate alias not shown in CLI USAGE).
  • Reviews: no unresolved threads; CodeRabbit only posted a rate-limit notice (never reviewed). 0 open bot/human findings.
  • Base / CI: required checks green on 6e69a4a6; owner action: update from latest dev (the PR is behind base and conflicting — foreign PR, so I did not push a base sync).
  • Gate: blocked — ship-gate.mjswake:base_dirty_or_behind:base-state.
  • Owner actions (foreign PR): 1) update from latest dev and resolve the conflict; 2) fix the encryptedCodexTasks fabricated-false bug; 3) apply the 2 simplification candidates below.
  • Bottom line: fix the capability bug, rebase/merge dev, and this is a solid, valuable addition. The simplify candidates are optional but cheap.
Full verdict

Semantic propagation

  • Concepts audited: route-decision trace (RI-01), request-history index (RI-02), analytics (RI-03), routing-profile schema/evaluator (RI-04/05), health/quota/cost evidence+scoring (RI-06/07/08), explainability API+CLI (RI-09), and the encryptedCodexTasks capability.
  • Authoritative sources: devlog/_plan/260804_router_intelligence/000_master_plan.md (ADRs 1–11, bounds, privacy model); src/usage/log.ts canonical ledger; src/routing/trace.ts normalizer; src/usage/cost.ts price model.
  • Producers and consumers checked: trace produced at all routeModel() call sites (responses/core.ts, compact.ts, chat-completions.ts, claude-messages.ts, search.ts, router.ts:604) and consumed by request-log.ts, usage/log.ts, the indexer, and the new /route-decision route. All consistent.
  • Public/derived representations checked: routeDecision persisted on PersistedUsageEntry, projected into routing-history.sqlite (decision_json), re-normalized on read (normalizeRouteDecisionTrace), and merged with attempts[] + outcome in the explain endpoint. Old rows parse; corrupt rows drop defensively.
  • Material variant partitions checked: route kinds (explicit-account/provider, native, combo, policy, default-provider), evidence dimensions (capability/health/quota/cost), unknown-evidence modes (allow/penalize/exclude), and pre-trace vs traced rows.
  • Positive and negative assertions checked: tests cover trace round-trip, corruption handling, truncation bounds, cost-limit exclusion, unknown-policy handling, analytics truncation flag, and the 4 RI-09 endpoint tests. Gap: no negative test for absent-provider capability (the encryptedCodexTasks case).
  • Unmapped surfaces: none.
  • Unproven equivalence assumptions: none.
  • Representation mismatches: one — capability.ts emits a definitive encryptedCodexTasks: false when the provider config is absent, which the evaluator treats as unsatisfied rather than unknown (violates ADR-5 "unknown is not zero").
  • Variant coverage gaps: one — absent-provider capability evidence untested.
  • Axis verdict: blocked (the capability mismatch blocks approve-comment; all else passes).

Usefulness

Delivers the claimed RI-09 value: a stable-code explainability API (/api/request-history/:id/route-decision), dry-run "evaluate" mode that assembles canonical evidence, and ocx logs explain / ocx route policy evaluate CLIs. The honest routeDecision: null for pre-trace rows and the bounded privacy posture match the master plan. Real, useful feature work.

Bugs / correctness

  • Method: bug-review.md — Bugbot: n/a (not Cursor); static: typecheck passed; trio: done; complementary: done (silent_failures, resource_leaks, edge_cases, api_cli_wiring, input_shape, evidence_semantics, hot_path_scale, determinism_metrics, malformed_input, budget).
  • Confirmed (High): src/routing/capability.ts:122-124isCanonicalOpenAiForwardProvider(provider ?? {adapter:"",authMode:undefined,baseUrl:undefined}) returns false for an absent provider, and encryptedCodexTasks is emitted unconditionally. A profile with require: { encryptedCodexTasks: true } then marks an unconfigured/unknown candidate unsatisfied (excluded) instead of unknown — failing closed on a capability that is genuinely unknown. Fix: only emit encryptedCodexTasks when the provider is present/canonical (omit otherwise). Regression test: absent-provider candidate → capability has no encryptedCodexTasks, and the requirement evaluates unknown.
  • Needs verification: evaluator.ts:247 reads Date.now() per candidate in the loop (cooldown check) — the "one decision, one clock" rule; in practice a single evaluation is fast, but the evaluator also receives evidence assembled at a different now, so a cooldown could flip between evidence assembly and evaluation. Not blocking, worth a single-clock refactor.
  • Fixed this session: none (foreign PR — no edits).

Security

  • Scope reviewed: authn/authz (management origin gate + session), injection (all params parameterized SQL; no string-built SQL), SSRF (evaluate mode reads only local canonical sources — catalog/registry/index/quota caches/price model; no network), secrets/logging (trace builder never receives config objects with keys; privacy:scan green), data storage (derived SQLite index in config dir, same file-mode posture as usage.jsonl), AI/agent/MCP (new endpoints are read-only management surfaces; no new tool/MCP surface).
  • Findings: none confirmed. The encryptedCodexTasks false is a correctness/availability issue (fails-closed exclusion), not a security hole.
  • Fixed this session: none.

Spec / standards

  • Spec source: devlog/_plan/260804_router_intelligence/000_master_plan.md (RI-09 acceptance criteria + non-goals) and the PR body.
  • Standards sources: root AGENTS.md, .github/AGENTS.md, docs-site routing reference, src/routing/ ADR comments, tests/ conventions.
  • Gaps: one minor — src/cli/route-policy.ts USAGE lists ocx route policy evaluate <id> [--json] but the shared handler also accepts --model-context/--tools/--image/--structured-output (same as dry-run); the USAGE for evaluate doesn't show them. Docs/help drift, not a functional bug.
  • Standards: no hard violations. The stack mirrors the existing combos discipline, keeps the canonical ledger authoritative, bounds all serialized data, and stays additive.

Reviews

  • Humans: none (0 open threads).
  • Bots: CodeRabbit posted only a rate-limit notice ("Review limit reached… couldn't start this review") — no findings to address. The CodeRabbit: pass status is the notice, not a review.

Base / CI

Simplification (for the PR owner — not applied, foreign PR)

  1. src/routing/evaluator.ts:315 + :318 — duplicate ...(evidence.health ? { health: evidence.health } : {}) spread. Delete the second (line 318). Behavior identical; reduces noise.
  2. src/server/management/routing-profile-routes.ts:105-126 — the if (candidateEvidence === null) 400 branch is dead: both assignments produce a non-null PolicyCandidateEvidence[] (?? [] in the else). Collapse to const candidateEvidence = body.candidates === undefined ? profileConfig.candidates.map(...) : (parseCandidateEvidence(body.candidates) ?? []); and drop the unreachable check.

Neither is a correctness issue; both are low-risk cleanups.

Gate

  • ship-gate.mjs (full-review, --mutation-mode review): blocked — single blocker wake:base_dirty_or_behind:base-state. No draft/WIP/do-not-merge. Verdict is changes-requested (foreign-PR owner actions + 1 blocking bug), not gated (the conflict is a concrete required owner action, not a soft stop).

Bottom line

This is genuinely useful, well-tested, privacy-conscious work. Before merge-ready: (1) fix capability.ts so absent-provider capability stays unknown (and add the negative test), and (2) update from latest dev and resolve the conflict. The two simplification candidates are optional. After those, this is an approve-comment-worthy contribution.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e69a4a680

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/router.ts
Comment thread src/server/management/routing-profile-routes.ts Outdated
Comment thread src/server/management/request-history-routes.ts Outdated
Comment thread src/routing/evaluator.ts Outdated
Comment thread src/router.ts
@Wibias
Wibias force-pushed the feat/ri-09-route-explainability-api branch from 6e69a4a to d887c12 Compare August 5, 2026 08:59
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Deterministic PR hygiene checks passed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@devlog/_plan/260804_router_intelligence/001_pr_stack_status.md`:
- Around line 263-276: Finalize the RI-09 acceptance record in the findings and
verification section: replace the Base SHA with
410db97e4cd9e9b4f8aba60682d20946e211d6dd, set the Final commit to
d887c120282c8d381f92cd11c1eebe2373a27281, record PR `#1016`, rerun and record the
checks against this head, and update the route-explainability test result from
4/4 to 7/7; do not add a conflict-resolution rebase.

In `@src/cli/observe.ts`:
- Around line 85-94: Add focused regression coverage in
tests/route-explainability.test.ts:90-202 for the CLI behavior. Exercise
src/cli/observe.ts:85-94 through handleObserveCommand to verify request-ID URL
encoding, --json output, and invalid-argument rejection; exercise
src/cli/route-policy.ts:83-90 through handleRoutePolicyCommand to verify
evaluate sends the dry-run request and rejects option-like profile IDs. Keep the
tests near the existing route explainability tests.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: be2b9d61-429b-417e-8d36-1184df61887b

📥 Commits

Reviewing files that changed from the base of the PR and between 410db97 and d887c12.

📒 Files selected for processing (7)
  • devlog/_plan/260804_router_intelligence/001_pr_stack_status.md
  • src/cli/observe.ts
  • src/cli/route-policy.ts
  • src/routing/capability.ts
  • src/server/management/request-history-routes.ts
  • src/server/management/routing-profile-routes.ts
  • tests/route-explainability.test.ts

Comment thread devlog/_plan/260804_router_intelligence/001_pr_stack_status.md Outdated
Comment thread src/cli/observe.ts
@Wibias
Wibias force-pushed the feat/ri-09-route-explainability-api branch from d887c12 to ae2c329 Compare August 5, 2026 09:05
@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

[GD] Verdict: approve-comment

TLDR

  • PR: feat(control-plane): expose route decision explanations #1016 — feat(control-plane): expose route decision explanations
  • Head: ae2c3297 on dev (mergeStateStatus: CLEAN)
  • Decision: useful and ready for maintainer merge on current head
  • Usefulness: delivers RI-09 why-this-route explainability via management API + CLI
  • Bugs: none blocking on ae2c3297
  • Security: none confirmed; residual is existing management-session boundary only
  • Spec / standards: clean for RI-09 non-goals (no UI; stable codes + summaries)
  • Semantic propagation: pass
  • Reviews / threads: all prior bot threads resolved with fix or verified decline
  • Base / CI: up to date with 410db97e4; required CI green including macos, ci, gates, test 1/4-4/4
  • Gate: ready (ship-gate blockers none)
  • Simplify: nothing worth simplifying beyond already-landed review cleanups
  • Owner actions (foreign PR): none (ours)
  • Bottom line: RI-09 is rebased, reviewed, simplified-as-needed, and ship-gate ready on ae2c3297. Merge when you want; do not merge from this run.
Full verdict

Semantic propagation

  • Concepts audited: route-decision explanation surface; dry-run/evaluate auto-evidence; encryptedCodexTasks unknown-vs-false semantics; selected vs final provider/model for combo rows
  • Authoritative sources: durable entry.routeDecision + entry.attempts for explain; live router candidate evidence assembly in src/router.ts for dry-run parity; isCanonicalOpenAiForwardProvider for encrypted capability
  • Producers and consumers checked: handleRequestHistoryRoutes /route-decision; assembleCandidateEvidence + dry-run; candidateCapabilityEvidence; CLI ocx logs explain / ocx route policy evaluate via src/cli/index.ts wiring
  • Public/derived representations checked: management JSON response shape (routeDecision, attemptSequence, outcome, summary); CLI path encoding; dry-run candidate capability/health/quota/cost
  • Material variant partitions checked: traced policy rows; pre-trace legacy rows (routeDecision: null); combo/fallback physical final attempt; omitted vs malformed dry-run candidates; present vs absent providers for encryptedCodexTasks
  • Positive and negative assertions checked: 404 unknown ids; invalid_candidates 400; absent provider omits encrypted flag; option-like profile id rejected; request-id encoding for spaces
  • Unmapped surfaces: none material for RI-09 (UI intentionally deferred to RI-10)
  • Unproven equivalence assumptions: none blocking; dry-run auto-evidence intentionally mirrors router account/cost wiring
  • Representation mismatches: none remaining after combo final + invalid-candidates fixes
  • Coverage gaps: PR body still says 4 tests while suite is 10/10 (doc drift only; ledger records 10/10)
  • Axis verdict: pass

Usefulness

RI-09 closes the control-plane explainability gap: operators can inspect why a request routed where it did and evaluate a profile with assembled evidence without inventing a UI. Value is concrete and scoped.

Bugs / correctness

  • Bugbot: n/a on Codex (complementary lenses only)
  • Confirmed High/Critical: none on current head
  • Fixed earlier in this head lineage: invalid candidates no longer coerced to empty; combo final physical attempt; absent-provider encrypted capability stays unknown; CLI guards + focused tests
  • Declined with evidence: RI-08 cost-estimate hard-cap residual in src/router.ts is outside this PR diff

Security

  • Decision: Pass (low residual)
  • Surfaces: management explain/dry-run + CLI management client; additive read/explain; no prompts/credentials/raw responses
  • Authz remains existing management session / origin boundary (handleManagementAPI)
  • encryptedCodexTasks change is fail-open-to-unknown for missing config, not a capability grant
  • Removed-control lead on dummy provider object is intentional; no SSRF path introduced
  • privacy:scan green; requireAiAgentSecurity reviewed defensively (no new agent/tool execution surface)

Spec / Standards

  • Spec: matches RI-09 + non-goals (no UI; stable codes/summaries, not localized prose as contract)
  • Standards: focused tests present (tests/route-explainability.test.ts 10/10), typecheck green, privacy scan green
  • Docs: no new docs-site page; acceptable for additive control-plane CLI/API pending broader routing docs if maintainers want later

Reviews

  • Unresolved review threads: none
  • Prior Codex/CodeRabbit items fixed or declined on-thread with evidence

Base / CI

  • Base: dev @ 410db97e4 (post feat(routing): add cost-aware policy scoring and limits #1015)
  • Head: ae2c3297da26447001dc8626987df27982954db3
  • Behind base: 0; mergeable: MERGEABLE; mergeStateStatus: CLEAN
  • Local: bun test tests/route-explainability.test.ts 10/10; bun x tsc --noEmit 0; bun run privacy:scan pass
  • Required CI green on head, including macos, aggregate ci, gates, shard tests, npm-global matrix

Simplify

  • Explicit simplify pass run after review fixes
  • Residual candidates: none worth simplifying; earlier cleanup already extracted assembleCandidateEvidence, preserved null invalid-candidates, and tightened CLI guards
  • Result: nothing worth simplifying

Gate

  • ship-gate.mjs decision: ready (mutation-mode maintainer, workflow references/full-review-pr.md)
  • Adaptive settle: head/base unchanged across rechecks; threads remain empty; final gate ready

Bottom line

Approve-comment on ae2c3297. Ready for maintainer merge when desired. This run does not merge.

@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

[GD] Merge ready

  • Head: ae2c3297da26447001dc8626987df27982954db3 on dev
  • Full-review verdict: approve-comment (fr-1016-ae2c3297-20260805T0915Z)
  • Ship-gate: ready (maintainer / full-review-pr)
  • CI: required checks green (macos, aggregate ci, gates, test shards, npm-global)
  • Threads: none unresolved
  • Simplify: nothing worth simplifying
  • Not merged by this run

@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

[GD] Merge

Merging RI-09 route-decision explainability on ae2c3297.

Why it helps: operators can inspect why a request routed where it did via GET /api/request-history/:requestId/route-decision and ocx logs explain, and can dry-run/evaluate a profile with auto-assembled capability/health/quota/cost evidence without inventing a UI. Stable codes + summaries only; no prompts or credentials on the explain surface.

Ship it.

@Wibias
Wibias merged commit 68d3aa0 into lidge-jun:dev Aug 5, 2026
21 checks passed
@Wibias
Wibias deleted the feat/ri-09-route-explainability-api branch August 5, 2026 09:21
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