root b2e45f7f26 playbook_lift: harness expansion + reality test #001 (7/8 lift, 87.5%)
The 5-loop substrate's load-bearing gate is verified — playbook +
matrix indexer give the results we're looking for. Per the report's
rubric, lift ≥ 50% of discoveries means matrix is doing real work;
7/8 = 87.5% blew through that.

Harness was structurally hiding bugs behind a 5-daemon stripped boot.
Expanding to the full 10-daemon prod stack surfaced 7 fixes in cascade:

1. driver→matrixd: {"query": ...} → {"query_text": ...} field name
2. harness temp toml missing [s3] → wrong default bucket → catalogd
   rehydrate 500 on first call
3. harness→queryd SQL probe: {"q": ...} → {"sql": ...} field name
4. expand boot from 5 → 10 daemons in dep-ordered launch
5. add SQL surface probe (3-row CSV ingest → COUNT(*)=3 assertion)
6. candidates corpus was synthetic SWE-tech (Swift/iOS, Scala/Spark) —
   wrong domain for staffing queries; replaced with ethereal_workers
   (10K rows, real staffing schema, "e-" id prefix to avoid collision
   with workers' "w-"). staffing_workers driver gains -index-name +
   -id-prefix flags so the same binary serves both corpora
7. local_judge qwen3.5:latest is a vision-SSM 256K-ctx build running
   ~30s per judge call against the lift loop; reverted to
   qwen2.5:latest (~1s/call, 30× faster, held lift theory)

Each contract drift (1, 3) is now locked into a cmd/<bin>/main_test.go
so future drift fires in `go test`, not in a reality run. R-005 closed:

- cmd/matrixd/main_test.go (new) — playbook record drift detector +
  score bounds + 6 routes mounted
- cmd/queryd/main_test.go — wrong-field-name drift detector
- cmd/pathwayd/main_test.go (new) — 9 routes + add round-trip + retire
- cmd/observerd/main_test.go (new) — 4 routes + invalid-op + unknown-mode

`go test ./cmd/{matrixd,queryd,pathwayd,observerd}` all green.

Reality test results (reports/reality-tests/playbook_lift_001.{json,md}):
  Queries              21 (staffing-domain, 7 categories)
  Discoveries          8 (judge ≠ cosine top-1)
  Lifts                7/8 (87.5%)
  Boosts triggered     9
  Mean Δ distance      -0.053 (warm closer than cold)
  OOD honesty          dental/RN/SWE rated 1, no fake matches
  Cross-corpus boosts  confirmed (e- ↔ w- swaps in lifts)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 06:22:21 -05:00

105 lines
3.2 KiB
Go

package main
import (
"bytes"
"net/http"
"net/http/httptest"
"testing"
"github.com/go-chi/chi/v5"
"git.agentview.dev/profit/golangLAKEHOUSE/internal/pathway"
)
// newTestRouter builds the pathwayd router with an in-memory store
// (nil persistor). Closes R-005 for pathwayd: 9 routes mounted with
// no router-level test prior to this file.
func newTestRouter(t *testing.T) http.Handler {
t.Helper()
h := &handlers{store: pathway.NewStore(nil)}
r := chi.NewRouter()
h.register(r)
return r
}
func TestRoutesMounted(t *testing.T) {
r := newTestRouter(t)
want := map[string]string{
"POST /pathway/add": "",
"POST /pathway/add_idempotent": "",
"POST /pathway/update": "",
"POST /pathway/revise": "",
"POST /pathway/retire": "",
"GET /pathway/get/{uid}": "",
"GET /pathway/history/{uid}": "",
"POST /pathway/search": "",
"GET /pathway/stats": "",
}
got := map[string]bool{}
router := r.(chi.Router)
_ = chi.Walk(router, func(method, route string, _ http.Handler, _ ...func(http.Handler) http.Handler) error {
got[method+" "+route] = true
return nil
})
for k := range want {
if !got[k] {
t.Errorf("route not mounted: %s", k)
}
}
}
// TestAdd_RoundTrip locks the happy-path contract: POST a content blob,
// receive a 201 with a trace, GET it back at /pathway/get/{uid}.
// Catches drift in either the add response shape or the get path.
func TestAdd_RoundTrip(t *testing.T) {
r := newTestRouter(t)
body := []byte(`{"content":{"hello":"world"},"tags":["test"]}`)
req := httptest.NewRequest("POST", "/pathway/add", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusCreated {
t.Fatalf("expected 201 on add, got %d (body=%s)", w.Code, w.Body.String())
}
}
func TestStats_GET(t *testing.T) {
r := newTestRouter(t)
req := httptest.NewRequest("GET", "/pathway/stats", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected 200 on stats, got %d", w.Code)
}
}
// TestAddIdempotent_MissingUID locks the validation: empty UID must
// 4xx rather than silently accepting (which would defeat the
// idempotency contract).
func TestAddIdempotent_MissingUID(t *testing.T) {
r := newTestRouter(t)
body := []byte(`{"content":{"x":1}}`)
req := httptest.NewRequest("POST", "/pathway/add_idempotent", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code/100 != 4 {
t.Errorf("missing uid should 4xx, got %d (body=%s)", w.Code, w.Body.String())
}
}
// TestRetire_NonexistentUID locks the not-found path. The store rejects
// retiring traces that don't exist; the handler must surface that as a
// 4xx, not a 5xx.
func TestRetire_NonexistentUID(t *testing.T) {
r := newTestRouter(t)
body := []byte(`{"uid":"does-not-exist"}`)
req := httptest.NewRequest("POST", "/pathway/retire", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code/100 != 4 {
t.Errorf("retire of nonexistent uid should 4xx, got %d", w.Code)
}
}