Skip to content

Commit 5cb8ae5

Browse files
authored
Merge pull request #75 from dmoliveira/my_opencode-e12-routing-verification
Complete Epic 12 routing verification checks
2 parents e5a7f46 + c3a9136 commit 5cb8ae5

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ All notable changes to this project are documented in this file.
7575
- Expanded doctor summary coverage to include context resilience subsystem health checks.
7676
- Expanded selftest coverage for model-routing trace persistence and runtime fallback-chain reporting.
7777
- Expanded README guidance with category-driven routing examples and troubleshooting steps for unexpected model selection.
78+
- Expanded routing verification coverage for deterministic trace stability and explicit fallback/no-fallback explain outcomes, and added `/routing` smoke hints in install output.
7879

7980
## v0.2.0 - 2026-02-12
8081

IMPLEMENTATION_ROADMAP.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Use this map to avoid overlapping implementations.
4848
| E9 | Conditional Rules Injector | done | High | E1 | bd-1q8, bd-3rj, bd-fo8, bd-2ik | Enforce project conventions with scoped rules |
4949
| E10 | Auto Slash Command Detector | paused | Medium | E1, E8 | TBD | Resume only if intent precision stays high in prototypes |
5050
| E11 | Context-Window Resilience Toolkit | done | High | E4 | bd-2tj, bd-n9y, bd-2t0, bd-18e | Improve long-session stability and recovery |
51-
| E12 | Provider/Model Fallback Visibility | in_progress | Medium | E5 | bd-1jq, bd-298, bd-194 | Explain why model routing decisions happen |
51+
| E12 | Provider/Model Fallback Visibility | done | Medium | E5 | bd-1jq, bd-298, bd-194, bd-2gq | Explain why model routing decisions happen |
5252
| E13 | Browser Automation Profile Switching | planned | Medium | E1 | TBD | Toggle Playwright/agent-browser with checks |
5353
| E14 | Plan-to-Execution Bridge Command | planned | Medium | E2, E3 | TBD | Execute validated plans with progress tracking |
5454
| E15 | Todo Enforcer and Plan Compliance | planned | High | E14 | TBD | Keep execution aligned with approved checklists |
@@ -172,7 +172,7 @@ Every command-oriented epic must ship all of the following:
172172

173173
## Epic 1 - Config Layering + JSONC Support
174174

175-
**Status:** `done`
175+
**Status:** `paused`
176176
**Priority:** High
177177
**Goal:** Add user/project layered config and JSONC parsing so behavior can be customized per repo without mutating global defaults.
178178
**Depends on:** None
@@ -439,7 +439,7 @@ Every command-oriented epic must ship all of the following:
439439

440440
## Epic 10 - Auto Slash Command Detector
441441

442-
**Status:** `in_progress`
442+
**Status:** `paused`
443443
**Priority:** Medium
444444
**Goal:** Detect natural-language intent that maps to existing slash commands and optionally execute with guardrails.
445445
**Depends on:** Epic 1, Epic 8
@@ -499,7 +499,7 @@ Every command-oriented epic must ship all of the following:
499499

500500
## Epic 12 - Provider/Model Fallback Visibility
501501

502-
**Status:** `in_progress`
502+
**Status:** `done`
503503
**Priority:** Medium
504504
**Goal:** Make model routing and provider fallback decisions observable and explainable.
505505
**Depends on:** Epic 5
@@ -519,12 +519,13 @@ Every command-oriented epic must ship all of the following:
519519
- [x] Subtask 12.3.2: Add examples for category-driven routing outcomes
520520
- [x] Subtask 12.3.3: Add docs for troubleshooting unexpected model selection
521521
- [x] Notes: Added `scripts/routing_command.py`, routed aliases in `opencode.json`, and README examples/troubleshooting for compact explainability workflows.
522-
- [ ] Task 12.4: Verification
523-
- [ ] Subtask 12.4.1: Add tests for deterministic trace output
524-
- [ ] Subtask 12.4.2: Add tests for fallback and no-fallback scenarios
525-
- [ ] Subtask 12.4.3: Add install-test smoke checks
526-
- [ ] Exit criteria: users can explain model/provider selection for every routed task
527-
- [ ] Exit criteria: trace output remains readable in default mode
522+
- [x] Task 12.4: Verification
523+
- [x] Subtask 12.4.1: Add tests for deterministic trace output
524+
- [x] Subtask 12.4.2: Add tests for fallback and no-fallback scenarios
525+
- [x] Subtask 12.4.3: Add install-test smoke checks
526+
- [x] Notes: Expanded `scripts/selftest.py` with deterministic resolution-trace assertions plus fallback/no-fallback routing explain scenarios and added `/routing` smoke hints in `install.sh`.
527+
- [x] Exit criteria: users can explain model/provider selection for every routed task
528+
- [x] Exit criteria: trace output remains readable in default mode
528529

529530
---
530531

install.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ printf " /hooks enable\n"
148148
printf " /hooks doctor --json\n"
149149
printf " /model-routing status\n"
150150
printf " /model-profile status\n"
151+
printf " /routing status\n"
152+
printf " /routing explain --category deep --json\n"
151153
printf " /keyword-mode status\n"
152154
printf " /keyword-mode detect --prompt 'safe-apply deep-analyze investigate this refactor'\n"
153155
printf " /keyword-mode disable-keyword ulw\n"

scripts/selftest.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,70 @@ def run_bg(*args: str) -> subprocess.CompletedProcess[str]:
14591459
isinstance(routing_explain_report.get("resolution_trace"), dict),
14601460
"routing explain should include structured resolution trace",
14611461
)
1462+
expect(
1463+
routing_explain_report.get("fallback_reason")
1464+
== "fallback_unavailable_model_to_category",
1465+
"routing explain should report fallback reason for unavailable model scenario",
1466+
)
1467+
1468+
routing_explain_no_fallback = subprocess.run(
1469+
[
1470+
sys.executable,
1471+
str(ROUTING_SCRIPT),
1472+
"explain",
1473+
"--category",
1474+
"quick",
1475+
"--available-models",
1476+
"openai/gpt-5-mini,openai/gpt-5.3-codex",
1477+
"--json",
1478+
],
1479+
capture_output=True,
1480+
text=True,
1481+
env=refactor_env,
1482+
check=False,
1483+
cwd=REPO_ROOT,
1484+
)
1485+
expect(
1486+
routing_explain_no_fallback.returncode == 0,
1487+
"routing explain should succeed for no-fallback scenario",
1488+
)
1489+
routing_explain_no_fallback_report = parse_json_output(
1490+
routing_explain_no_fallback.stdout
1491+
)
1492+
expect(
1493+
routing_explain_no_fallback_report.get("fallback_reason") == "none",
1494+
"routing explain should report explicit no-fallback reason when first candidate is accepted",
1495+
)
1496+
1497+
deterministic_trace_a = resolve_model_settings(
1498+
schema=routing_schema,
1499+
requested_category="deep",
1500+
user_overrides={"model": "openai/nonexistent"},
1501+
system_defaults={
1502+
"model": "openai/gpt-5.3-codex",
1503+
"temperature": 0.2,
1504+
"reasoning": "medium",
1505+
"verbosity": "medium",
1506+
},
1507+
available_models={"openai/gpt-5-mini", "openai/gpt-5.3-codex"},
1508+
)
1509+
deterministic_trace_b = resolve_model_settings(
1510+
schema=routing_schema,
1511+
requested_category="deep",
1512+
user_overrides={"model": "openai/nonexistent"},
1513+
system_defaults={
1514+
"model": "openai/gpt-5.3-codex",
1515+
"temperature": 0.2,
1516+
"reasoning": "medium",
1517+
"verbosity": "medium",
1518+
},
1519+
available_models={"openai/gpt-5-mini", "openai/gpt-5.3-codex"},
1520+
)
1521+
expect(
1522+
deterministic_trace_a.get("resolution_trace")
1523+
== deterministic_trace_b.get("resolution_trace"),
1524+
"model routing resolution trace should remain deterministic for identical inputs",
1525+
)
14621526

14631527
keyword_report = resolve_prompt_modes(
14641528
"Please safe-apply and deep-analyze this migration; ulw can wait.",

0 commit comments

Comments
 (0)