mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-08-17 13:03:31 +00:00
The substrate's read and write surfaces are end-to-end-tested internally; this slice answers the harder question — "is the substrate actually usable from the outside?" — by writing the smallest standalone program that consumes it. agent-probe walks the discovery → triage → depth → push flow against a running Pulse instance using only the Go standard library, so it doubles as a reference implementation for anyone building MCP servers, Claude Code integrations, or custom agents on top of Pulse. It resolves every path from the manifest rather than hardcoding them — if discovery moves a path, the probe follows automatically — and branches on the stable error envelope's "error" code field, never on human-readable messages. The focus rule (severity-lex-ordered) is intentionally simple so a reader can predict what the probe will pick; real agents will have richer policies. This is documentation as code: the program is short enough to read top-to-bottom and reads like the agent's own narration of what it's doing. The unit test pins the focus rule's lex ordering so a refactor that swaps it for a weighted score (which allowed many warnings to outrank one critical) cannot regress silently.
83 lines
2 KiB
Go
83 lines
2 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// TestPickFocus_PrefersCriticalThenWarningThenInfo pins the focus
|
|
// rule the probe uses for "where do I look first?". The unit test
|
|
// is here rather than against the substrate because the rule is a
|
|
// probe-side triage convention, not a contract Pulse owns; agents
|
|
// building on the substrate can implement their own ordering.
|
|
func TestPickFocus_PrefersCriticalThenWarningThenInfo(t *testing.T) {
|
|
mk := func(id string, c, w, i, p int) fleetResource {
|
|
r := fleetResource{CanonicalID: id, PendingApprovalCount: p}
|
|
r.Findings.Critical = c
|
|
r.Findings.Warning = w
|
|
r.Findings.Info = i
|
|
r.Findings.Total = c + w + i
|
|
return r
|
|
}
|
|
|
|
cases := []struct {
|
|
name string
|
|
resources []fleetResource
|
|
want string
|
|
}{
|
|
{
|
|
name: "single critical beats many warnings",
|
|
resources: []fleetResource{
|
|
mk("vm:noisy", 0, 50, 0, 0),
|
|
mk("vm:critical", 1, 0, 0, 0),
|
|
mk("vm:quiet", 0, 0, 0, 0),
|
|
},
|
|
want: "vm:critical",
|
|
},
|
|
{
|
|
name: "tie on severity broken by count",
|
|
resources: []fleetResource{
|
|
mk("vm:warm", 0, 1, 0, 0),
|
|
mk("vm:warmer", 0, 3, 0, 0),
|
|
},
|
|
want: "vm:warmer",
|
|
},
|
|
{
|
|
name: "no findings — pending approvals as tiebreaker",
|
|
resources: []fleetResource{
|
|
mk("vm:idle", 0, 0, 0, 0),
|
|
mk("vm:waiting", 0, 0, 0, 2),
|
|
},
|
|
want: "vm:waiting",
|
|
},
|
|
{
|
|
name: "no findings or approvals — first wins so depth step still runs",
|
|
resources: []fleetResource{
|
|
mk("vm:first", 0, 0, 0, 0),
|
|
mk("vm:second", 0, 0, 0, 0),
|
|
},
|
|
want: "vm:first",
|
|
},
|
|
{
|
|
name: "empty fleet returns nil",
|
|
resources: nil,
|
|
want: "",
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := pickFocus(tc.resources)
|
|
if tc.want == "" {
|
|
if got != nil {
|
|
t.Fatalf("expected nil for empty fleet; got %+v", got)
|
|
}
|
|
return
|
|
}
|
|
if got == nil {
|
|
t.Fatalf("expected %q; got nil", tc.want)
|
|
}
|
|
if got.CanonicalID != tc.want {
|
|
t.Errorf("focus = %q; want %q", got.CanonicalID, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|