Batteries-included agent-harness base, extracted from mort's agent layer. This first cut establishes the module + the zero-coupling core primitives: - lane, dispatchguard, pendingattach, run/progress.go: moved verbatim from mort - config: host config Source seam + env-var default (nil-safe helpers) - deliver: output-egress seam + Discard/Stdout defaults - identity: AdminPolicy + MemberResolver seams (nil-safe) - fanout: programmatic N×M swarm (bounded global + per-key concurrency) - README/CLAUDE.md with the vibe-coded banner; CI with Go gates + the "core stays majordomo+stdlib only" invariant Core builds with stdlib only today; majordomo enters at P1 (model/structured). go build/vet/test -race all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package lane
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestRegistry_PreCreateMakesLanesVisible is the lane-level anchor for
|
||||
// hotfix-5 Bug 4. The mort.go boot path now pre-creates the well-known
|
||||
// lanes (skill-default, webhook-default, etc.) so they appear on
|
||||
// `/skills/admin/queues` and pass set-lane validation BEFORE any run
|
||||
// has ever hit them.
|
||||
//
|
||||
// Why this test (vs the existing GetOrCreate idempotency test): the
|
||||
// production bug was specifically about the registry's lazy-creation
|
||||
// behaviour combined with the queues page only listing materialised
|
||||
// lanes. This test asserts the missing piece: after pre-creation, both
|
||||
// Get and List return the lane immediately, regardless of whether a
|
||||
// job ever touched it.
|
||||
func TestRegistry_PreCreateMakesLanesVisible(t *testing.T) {
|
||||
r := NewRegistry(nil)
|
||||
wellKnown := []string{
|
||||
"ollama", "anthropic-thinking", "anthropic-default", "llm-default",
|
||||
"skill-default", "skill-heavy", "webhook-default",
|
||||
}
|
||||
ctx := context.Background()
|
||||
for _, name := range wellKnown {
|
||||
_ = r.GetOrCreate(ctx, name)
|
||||
}
|
||||
// Get must return non-nil for every lane WITHOUT going through
|
||||
// GetOrCreate again — that's the pre-creation guarantee.
|
||||
for _, name := range wellKnown {
|
||||
if l := r.Get(name); l == nil {
|
||||
t.Errorf("lane %q not registered after pre-create; admin "+
|
||||
"queues page would be missing it (Bug 4 regression)", name)
|
||||
}
|
||||
}
|
||||
// List must enumerate every pre-created lane.
|
||||
got := make([]string, 0)
|
||||
for _, l := range r.List() {
|
||||
got = append(got, l.Name())
|
||||
}
|
||||
sort.Strings(got)
|
||||
want := append([]string{}, wellKnown...)
|
||||
sort.Strings(want)
|
||||
if len(got) != len(want) {
|
||||
t.Fatalf("List length: got %d, want %d (got=%v, want=%v)", len(got), len(want), got, want)
|
||||
}
|
||||
for i := range want {
|
||||
if got[i] != want[i] {
|
||||
t.Errorf("List[%d]: got %q, want %q", i, got[i], want[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user