test(routing): pin tool-schema parity with supervisor
Captures the four routed skills' (review, debug, retrospective, trainer) tool definitions as a JSON snapshot and asserts the routing pod's registry advertises byte-equal schemas. A deliberate schema change fails this test, requiring an intentional snapshot update in lockstep with consumers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
80
internal/routing/snapshot_test.go
Normal file
80
internal/routing/snapshot_test.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package routing_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mathiasbq/supervisor/internal/registry"
|
||||||
|
"github.com/mathiasbq/supervisor/internal/skills/debug"
|
||||||
|
"github.com/mathiasbq/supervisor/internal/skills/retrospective"
|
||||||
|
"github.com/mathiasbq/supervisor/internal/skills/review"
|
||||||
|
"github.com/mathiasbq/supervisor/internal/skills/trainer"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestToolsListMatchesSupervisorSnapshot pins the four routed skills' tool
|
||||||
|
// definitions to the supervisor's current advertisement. A deliberate schema
|
||||||
|
// change must be reflected here by updating testdata/tools_list.snapshot.json.
|
||||||
|
func TestToolsListMatchesSupervisorSnapshot(t *testing.T) {
|
||||||
|
complete := func(_ context.Context, _, _, _ string) (string, int64, error) {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
reg := registry.New()
|
||||||
|
reg.Register(review.New(review.Config{
|
||||||
|
SkillPrompt: "stub",
|
||||||
|
DefaultModel: "stub",
|
||||||
|
CompleteFunc: complete,
|
||||||
|
}))
|
||||||
|
reg.Register(debug.New(debug.Config{
|
||||||
|
SkillPrompt: "stub",
|
||||||
|
DefaultModel: "stub",
|
||||||
|
CompleteFunc: complete,
|
||||||
|
}))
|
||||||
|
reg.Register(retrospective.New(retrospective.Config{
|
||||||
|
SkillPrompt: "stub",
|
||||||
|
DefaultModel: "stub",
|
||||||
|
CompleteFunc: complete,
|
||||||
|
}))
|
||||||
|
reg.Register(trainer.New(trainer.Config{
|
||||||
|
ReaderPrompt: "stub",
|
||||||
|
WriterPrompt: "stub",
|
||||||
|
DefaultModel: "stub",
|
||||||
|
CompleteFunc: complete,
|
||||||
|
}))
|
||||||
|
|
||||||
|
wanted := map[string]bool{
|
||||||
|
"review": true,
|
||||||
|
"debug": true,
|
||||||
|
"retrospective": true,
|
||||||
|
"trainer": true,
|
||||||
|
}
|
||||||
|
var routed []registry.ToolDef
|
||||||
|
for _, td := range reg.Tools() {
|
||||||
|
if wanted[td.Name] {
|
||||||
|
routed = append(routed, td)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Slice(routed, func(i, j int) bool { return routed[i].Name < routed[j].Name })
|
||||||
|
|
||||||
|
got, err := json.MarshalIndent(routed, "", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
want, err := os.ReadFile("testdata/tools_list.snapshot.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Normalize both via re-encode so whitespace differences don't dominate.
|
||||||
|
var gotV, wantV any
|
||||||
|
require.NoError(t, json.Unmarshal(got, &gotV))
|
||||||
|
require.NoError(t, json.Unmarshal(want, &wantV))
|
||||||
|
|
||||||
|
gotN, _ := json.MarshalIndent(gotV, "", " ")
|
||||||
|
wantN, _ := json.MarshalIndent(wantV, "", " ")
|
||||||
|
|
||||||
|
assert.Equal(t, string(wantN), string(gotN),
|
||||||
|
"tool advertisement drifted from supervisor snapshot — update testdata/tools_list.snapshot.json deliberately if the schema change is intentional")
|
||||||
|
}
|
||||||
97
internal/routing/testdata/tools_list.snapshot.json
vendored
Normal file
97
internal/routing/testdata/tools_list.snapshot.json
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"description": "Consult a local model to analyse an error and return hypotheses ordered by likelihood, each with a concrete verification step.",
|
||||||
|
"inputSchema": {
|
||||||
|
"properties": {
|
||||||
|
"context": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"project_root": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"session_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"project_root",
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "retrospective",
|
||||||
|
"description": "Consult a local model to analyse a completed session and identify what is novel or worth preserving as organizational knowledge.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"session_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"session_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "review",
|
||||||
|
"description": "Consult a local model for a structured code review of the specified files. Returns findings with severity levels.",
|
||||||
|
"inputSchema": {
|
||||||
|
"properties": {
|
||||||
|
"context": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"project_root": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"session_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"project_root",
|
||||||
|
"files"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "trainer",
|
||||||
|
"description": "Consult a local model to identify learning moments from a session log and suggest knowledge to preserve in the brain.",
|
||||||
|
"inputSchema": {
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"session_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"session_id"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user