chore(routing): pre-merge cleanup — Plan 7 reminders, code_review→review, operator note
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
25
DECISIONS.md
25
DECISIONS.md
@@ -67,6 +67,31 @@ Record *why* things are the way they are. Future-you will thank present-you.
|
||||
|
||||
---
|
||||
|
||||
## Plan 6: routing pod reuses internal/skills/{review,debug,retrospective,trainer}
|
||||
|
||||
Plan 6 (Mode 2 routing pod, 2026-05-04) introduces a second consumer of
|
||||
the four cost-routable skill packages. The routing pod constructs each
|
||||
skill via `<pkg>.New(Config{...})` and hands it `routing.Router.Run` as
|
||||
the `CompleteFunc`. Plan 7 (supervisor retirement) MUST NOT delete the
|
||||
four packages.
|
||||
|
||||
**Plan 7's allowed deletions:**
|
||||
- `internal/skills/{tdd,spec,tier}/` (not consumed by the routing pod)
|
||||
- `cmd/supervisor/` (binary)
|
||||
- `Dockerfile` (supervisor's, at repo root — distinct from `Dockerfile.routing`)
|
||||
- supervisor manifests in the infra repo
|
||||
- NodePort `:30320`
|
||||
|
||||
**Plan 7's preserved code:**
|
||||
- `internal/skills/{review,debug,retrospective,trainer}/`
|
||||
- `internal/registry`
|
||||
- `internal/mcp`
|
||||
- `internal/exec/litellm.go`
|
||||
- `internal/routing/` (entirely new in Plan 6)
|
||||
- `cmd/routing/`
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-08 — Mistral Vibe gets its own adapter
|
||||
|
||||
**Context**: Vibe doesn't read `AGENTS.md` — it uses `~/.vibe/prompts/` and `~/.vibe/agents/` with TOML config.
|
||||
|
||||
@@ -122,6 +122,8 @@ The supervisor probes connectivity at call time:
|
||||
| `HYPERGUILD_ROUTE_LOCAL_CEIL` | `0.70` | Below pass rate, route to Claude. Between CEIL and FLOOR is the sample band. |
|
||||
| `HYPERGUILD_PASS_RATE_TTL_SECONDS` | `60` | Per-skill pass-rate cache TTL |
|
||||
|
||||
> **Operator note:** LiteLLM at `LITELLM_BASE_URL` must register both `HYPERGUILD_LOCAL_MODEL` and `HYPERGUILD_CLAUDE_MODEL` for routing to do useful work. If a model is missing, LiteLLM returns 4xx, the routing pod's local route fails, the fail-open retry on Claude likely also fails (since both are missing), and the only signal is `final_status: "fail"` on `_routing` entries in the brain.
|
||||
|
||||
## Phase 2 (planned)
|
||||
|
||||
- `review` skill — structured code review with iron law enforcement
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package main
|
||||
|
||||
// The internal/skills/{debug,retrospective,review,trainer} packages imported
|
||||
// below are also imported by cmd/supervisor. Plan 7 (supervisor retirement)
|
||||
// MUST NOT delete these four packages — the routing pod is their second
|
||||
// consumer. Plan 7 deletes only internal/skills/{tdd,spec,tier} (the skills
|
||||
// that don't route to local), the supervisor binary, and supervisor manifests.
|
||||
// See docs/superpowers/specs/2026-05-04-mode-2-routing-pod-design.md (Constraints).
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
// LogEntry describes a single routing decision to log via the brain MCP.
|
||||
type LogEntry struct {
|
||||
SessionID string
|
||||
Skill string // the original skill the call routed (e.g., "code_review")
|
||||
Skill string // the original skill the call routed (e.g., "review")
|
||||
Decision string // "local" or "claude" or "claude_fallback"
|
||||
Message string // free-form, e.g. "model=qwen35, pass_rate=0.94"
|
||||
ProjectRoot string
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestLoggerLogDecision(t *testing.T) {
|
||||
l := routing.NewLogger(srv.URL)
|
||||
err := l.LogDecision(context.Background(), routing.LogEntry{
|
||||
SessionID: "sess-1",
|
||||
Skill: "code_review",
|
||||
Skill: "review",
|
||||
Decision: "local",
|
||||
Message: "model=qwen35, pass_rate=0.94",
|
||||
ProjectRoot: "/home/x/proj",
|
||||
@@ -44,7 +44,7 @@ func TestLoggerLogDecision(t *testing.T) {
|
||||
assert.Equal(t, "_routing", args["skill"])
|
||||
assert.Equal(t, "decide", args["phase"])
|
||||
assert.Equal(t, "skip", args["final_status"])
|
||||
assert.Contains(t, args["message"].(string), "code_review: local")
|
||||
assert.Contains(t, args["message"].(string), "review: local")
|
||||
assert.Equal(t, "sess-1", args["session_id"])
|
||||
assert.Equal(t, "/home/x/proj", args["project_root"])
|
||||
assert.Equal(t, float64(1234), args["duration_ms"])
|
||||
|
||||
@@ -64,7 +64,7 @@ func TestRouterRoutesLocalAtHighPassRate(t *testing.T) {
|
||||
r, _, _ := newRouter(t, llm, 0.95)
|
||||
|
||||
out, _, err := r.Run(context.Background(), routing.RunInput{
|
||||
Skill: "code_review", System: "sys", User: "user", SessionID: "s1", ProjectRoot: "/p",
|
||||
Skill: "review", System: "sys", User: "user", SessionID: "s1", ProjectRoot: "/p",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "ok", out)
|
||||
@@ -80,7 +80,7 @@ func TestRouterRoutesClaudeAtLowPassRate(t *testing.T) {
|
||||
r, _, _ := newRouter(t, llm, 0.3)
|
||||
|
||||
_, _, err := r.Run(context.Background(), routing.RunInput{
|
||||
Skill: "code_review", System: "sys", User: "user", SessionID: "s2",
|
||||
Skill: "review", System: "sys", User: "user", SessionID: "s2",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -95,7 +95,7 @@ func TestRouterFailsOpenLocalErrorToClaude(t *testing.T) {
|
||||
r, _, _ := newRouter(t, llm, 0.95) // would route local
|
||||
|
||||
out, _, err := r.Run(context.Background(), routing.RunInput{
|
||||
Skill: "code_review", System: "sys", User: "user", SessionID: "s3",
|
||||
Skill: "review", System: "sys", User: "user", SessionID: "s3",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "ok-after-fallback", out)
|
||||
@@ -125,7 +125,7 @@ func TestRouterDefaultsToLocalWhenBrainUnreachable(t *testing.T) {
|
||||
}
|
||||
|
||||
_, _, err := r.Run(context.Background(), routing.RunInput{
|
||||
Skill: "code_review", System: "sys", User: "user", SessionID: "s4",
|
||||
Skill: "review", System: "sys", User: "user", SessionID: "s4",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user