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
|
## 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.
|
**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_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 |
|
| `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)
|
## Phase 2 (planned)
|
||||||
|
|
||||||
- `review` skill — structured code review with iron law enforcement
|
- `review` skill — structured code review with iron law enforcement
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
package main
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
// LogEntry describes a single routing decision to log via the brain MCP.
|
// LogEntry describes a single routing decision to log via the brain MCP.
|
||||||
type LogEntry struct {
|
type LogEntry struct {
|
||||||
SessionID string
|
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"
|
Decision string // "local" or "claude" or "claude_fallback"
|
||||||
Message string // free-form, e.g. "model=qwen35, pass_rate=0.94"
|
Message string // free-form, e.g. "model=qwen35, pass_rate=0.94"
|
||||||
ProjectRoot string
|
ProjectRoot string
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func TestLoggerLogDecision(t *testing.T) {
|
|||||||
l := routing.NewLogger(srv.URL)
|
l := routing.NewLogger(srv.URL)
|
||||||
err := l.LogDecision(context.Background(), routing.LogEntry{
|
err := l.LogDecision(context.Background(), routing.LogEntry{
|
||||||
SessionID: "sess-1",
|
SessionID: "sess-1",
|
||||||
Skill: "code_review",
|
Skill: "review",
|
||||||
Decision: "local",
|
Decision: "local",
|
||||||
Message: "model=qwen35, pass_rate=0.94",
|
Message: "model=qwen35, pass_rate=0.94",
|
||||||
ProjectRoot: "/home/x/proj",
|
ProjectRoot: "/home/x/proj",
|
||||||
@@ -44,7 +44,7 @@ func TestLoggerLogDecision(t *testing.T) {
|
|||||||
assert.Equal(t, "_routing", args["skill"])
|
assert.Equal(t, "_routing", args["skill"])
|
||||||
assert.Equal(t, "decide", args["phase"])
|
assert.Equal(t, "decide", args["phase"])
|
||||||
assert.Equal(t, "skip", args["final_status"])
|
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, "sess-1", args["session_id"])
|
||||||
assert.Equal(t, "/home/x/proj", args["project_root"])
|
assert.Equal(t, "/home/x/proj", args["project_root"])
|
||||||
assert.Equal(t, float64(1234), args["duration_ms"])
|
assert.Equal(t, float64(1234), args["duration_ms"])
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func TestRouterRoutesLocalAtHighPassRate(t *testing.T) {
|
|||||||
r, _, _ := newRouter(t, llm, 0.95)
|
r, _, _ := newRouter(t, llm, 0.95)
|
||||||
|
|
||||||
out, _, err := r.Run(context.Background(), routing.RunInput{
|
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)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "ok", out)
|
assert.Equal(t, "ok", out)
|
||||||
@@ -80,7 +80,7 @@ func TestRouterRoutesClaudeAtLowPassRate(t *testing.T) {
|
|||||||
r, _, _ := newRouter(t, llm, 0.3)
|
r, _, _ := newRouter(t, llm, 0.3)
|
||||||
|
|
||||||
_, _, err := r.Run(context.Background(), routing.RunInput{
|
_, _, 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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ func TestRouterFailsOpenLocalErrorToClaude(t *testing.T) {
|
|||||||
r, _, _ := newRouter(t, llm, 0.95) // would route local
|
r, _, _ := newRouter(t, llm, 0.95) // would route local
|
||||||
|
|
||||||
out, _, err := r.Run(context.Background(), routing.RunInput{
|
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)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "ok-after-fallback", out)
|
assert.Equal(t, "ok-after-fallback", out)
|
||||||
@@ -125,7 +125,7 @@ func TestRouterDefaultsToLocalWhenBrainUnreachable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, _, err := r.Run(context.Background(), routing.RunInput{
|
_, _, 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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user