Adapts docs/SCRUM.md framework (originally written for the matrix-agent-validated repo) to the Go rewrite. Five deliverables: golang-lakehouse-scrum-test.md top-line + scoring + verdict risk-register.md 12 findings, R-001..R-012 claim-coverage-table.md claim/test/risk for Sprint 2 sprint-backlog.md 5 sprints, ~2 weeks of work acceptance-gates.md DoD as runnable commands Every claim cites file:line, command output, or "missing evidence." Smoke chain ran clean (33s wall, all 9 PASS) and is captured in reports/scrum/_evidence/smoke_chain.log (gitignored — runtime artifact). Scoring: Reproducibility 7/10 9 smokes deterministic, no just/CI gate Test Coverage 6/10 internal/ packages tested, 6/7 cmd/ aren't Trust Boundary 7/10 escapes ok, zero auth, /sql is RCE-eq off-loopback Memory Correctness 3/10 pathway/playbook/observer not yet ported Deployment Readiness 4/10 no REPLICATION, no env template, no systemd Maintainability 8/10 no god-files, 7 lean binaries, ADRs current Top three risks: R-001 HIGH queryd /sql + DuckDB + non-loopback bind = RCE-equivalent R-002 HIGH internal/shared (server.go + config.go) zero tests R-003 HIGH internal/storeclient zero tests, used by 2 services R-004 MED 9-smoke chain green but not gated (no justfile/hook) The audit is the work; refactors come after. Sprint 0 owns coverage + CI gating; Sprint 1 owns trust-boundary decisions; Sprints 2-3 are mostly design-bar work for unbuilt agent components. .gitignore exception: /reports/* + !/reports/scrum/ keeps reports/ a runtime-artifact directory while exposing reports/scrum/ as tracked documentation. Mirrors the pattern future audit passes will land in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
101 lines
8.8 KiB
Markdown
101 lines
8.8 KiB
Markdown
# golangLAKEHOUSE — Claim-Coverage Table
|
|
|
|
Per SCRUM.md §3, mapping each agent / memory claim from the upstream system to its current status in the Go rewrite. Many rows are "not yet ported" — those become Sprint 2 design bars rather than current-state failures. Risk IDs reference `risk-register.md`.
|
|
|
|
---
|
|
|
|
## Format
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|
|
A claim with status **"not yet ported"** in Code Location means the upstream Rust system implements it but the Go rewrite has not. These rows define design bars for when the port lands.
|
|
|
|
---
|
|
|
|
## Vector retrieval
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| HNSW search returns top-K by cosine similarity | `internal/vectord/index.go` (Add/Search/Lookup with RWMutex per memory `b8c072c`) | `internal/vectord/index_test.go` (13 funcs, including recall search per `g1_smoke.sh:7`) | Concurrent-search-during-add stress test (RWMutex contention behavior); cross-binary search via gateway latency budget | LOW (covered) |
|
|
| Index recall = 1.0 on round-trip with same vectors | `cmd/vectord/main.go` add+search handlers | `g1_smoke.sh` line 7 (recall-search assertion); `g2_smoke.sh` end-to-end at distance 5.96e-8 | None — covered by 2 smokes | LOW (covered) |
|
|
| Cross-corpora retrieval (multi-index search in one query) | **not yet ported** — Rust `vectord` had federated-corpus search, Go vectord is per-index only | — | All — design bar | DESIGN-BAR (Sprint 2) |
|
|
| Dimension mismatch on add → 400 | `internal/vectord/index.go` (Validates per memory) | `g1_smoke.sh:7` (dim-mismatch-400 assertion) | Unit test with explicit dimension assertion | MED (smoke covers, no go-test) |
|
|
| Zero-norm vector under cosine → reject | `internal/vectord/index.go` (Validates per memory `b8c072c`) | `internal/vectord/index_test.go` (13 funcs — likely covers; not verified by reading every test) | Audit which of the 13 funcs covers this; if none, add | LOW |
|
|
|
|
## Vector persistence (G1P)
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Save → kill → restart → search returns dist=0 | `internal/vectord/persistor.go` + `cmd/vectord/main.go` boot path | `g1p_smoke.sh` (kill+restart preserves state, 8/8 PASS per memory `8b92518`); `internal/vectord/persistor_test.go` (5 funcs) | None — covered | LOW (covered) |
|
|
| Single-Put framed format prevents torn-write half-state | `internal/vectord/persistor.go` LHV1 single-Put per memory (3-way convergent scrum fix) | `persistor_test.go` likely covers | Failure-injection test: PUT-fails-mid-stream → Load returns "no state" rather than half-loaded state | MED |
|
|
| Persistence above 256 MiB single-key (≈150K vectors @ d=768) | **NOT IMPLEMENTED** — storaged's MaxBytesReader 256 MiB caps single-file LHV1 (cited in head commit `1f700e7` and memory) | — | Test asserting persistence works at 200K+ vectors | DESIGN-BAR (Sprint 2 / G3) |
|
|
| Save failure logged-not-fatal (in-memory still source of truth) | `cmd/vectord/main.go` boot per memory `8b92518` | not verified by reading test | Unit test injecting storaged-down → Save returns nil error, log line emitted | MED |
|
|
|
|
## Embedding (G2)
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Text → 768-d vector via Ollama nomic-embed-text | `internal/embed/ollama.go` + `cmd/embedd/main.go:59` | `internal/embed/ollama_test.go` (6 funcs); `g2_smoke.sh` end-to-end | None — covered | LOW (covered) |
|
|
| Provider interface allows swap (OpenAI/Voyage/etc.) | `internal/embed/embed.go:20` (`Embed` interface) per memory `9ee7fc5` | Interface-only — provider selection in `cmd/embedd/main.go` not unit-tested | Test that wiring swaps providers based on config | LOW |
|
|
| Bad model → 502 from upstream | `cmd/embedd/main.go` error mapping | `g2_smoke.sh:103-106` (bad-model → 502 assertion) | Unit test on the error-mapping branch | LOW (smoke covers) |
|
|
| Float64 → float32 narrowing at boundary | `internal/embed/ollama.go` per memory `9ee7fc5` | `ollama_test.go` likely covers | Verify test with adversarial near-overflow inputs | LOW |
|
|
|
|
## SQL truth path
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Query catalog list → CREATE OR REPLACE VIEW per manifest | `internal/queryd/registrar.go:139` | `internal/queryd/registrar_test.go` (7 funcs incl. drop-before-create order, idempotency) | None — covered | LOW |
|
|
| Updated_at as implicit etag prevents repeated CREATE | `internal/queryd/registrar.go:114` (`prior.Equal(m.UpdatedAt)`) | `registrar_test.go` covers Skipped count | None — covered | LOW |
|
|
| Schema-drift CSV → 409, view unchanged | `cmd/ingestd/main.go` + `cmd/queryd/main.go` | `d4_smoke.sh` (schema-drift 409); `d5_smoke.sh` (view unchanged through drift) | None — covered | LOW |
|
|
| Arbitrary SQL via /sql is safe (it isn't — by design) | `cmd/queryd/main.go:142` | none | Auth boundary test (R-001) | **HIGH (R-001)** |
|
|
|
|
## Mem0-style memory semantics (ADD / UPDATE / REVISE / RETIRE / HISTORY)
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| ADD a new pathway trace | **not yet ported** — Rust has `pathway_memory` crate, Go does not | — | All | DESIGN-BAR (Sprint 2) |
|
|
| UPDATE replaces existing trace by uid | **not yet ported** | — | All | DESIGN-BAR |
|
|
| REVISE creates a new revision linked via history chain | **not yet ported** | — | All | DESIGN-BAR |
|
|
| RETIRE marks a trace excluded from retrieval | **not yet ported** | — | All — including retrieval-must-not-return-retired test | DESIGN-BAR |
|
|
| HISTORY chain is cycle-safe | **not yet ported** | — | All — explicit cycle injection + detection test | DESIGN-BAR |
|
|
| Replay count increments on duplicate ADD | **not yet ported** | — | All | DESIGN-BAR |
|
|
| Corrupted memory row recovery | **not yet ported** | — | All — fixture with poison row | DESIGN-BAR |
|
|
|
|
**Sprint 2 design bar:** when pathway memory ports to Go, the test fixture must include all 7 rows above on day one. This is the lesson from the Rust system having shipped these features ahead of their tests.
|
|
|
|
## Observer / hand-review
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Observer gates candidates before they reach playbook seal | **not yet ported** — Rust `mcp-server/observer.ts` exists, Go does not | — | All | DESIGN-BAR (Sprint 3) |
|
|
| Observer review failure does NOT auto-accept | **not yet ported** — but R-007 verdict pre-decided: Go observer must default `degraded=true, verdict=cycle` on internal error. ADR-002 design bar. | — | Test injecting observer-side error → response has `degraded: true`, never `verdict: "accept"` | DESIGN-BAR (Sprint 3) |
|
|
| Health endpoint content-type matches consumer expectation (the Rust `r.json()` on text/plain crash-loop bug from memory) | `internal/shared/server.go:61` returns plain string `"<service> ok"` per the existing pattern | none — but the bug it would catch already exists in the Rust system's history (memory `54689d5`) | Regression test: consumer of `/health` accepts text/plain or 502s loudly, never silently nulls | MED (Sprint 3) |
|
|
|
|
## Playbook seal + retrieval
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Successful playbooks are sealed for later retrieval | **not yet ported** | — | All | DESIGN-BAR (Sprint 3) |
|
|
| Second-run retrieval surfaces prior playbook | **not yet ported** | — | All | DESIGN-BAR (Sprint 3) |
|
|
| Negative case: observer rejects hallucinated claim | **not yet ported** | — | All | DESIGN-BAR (Sprint 3) |
|
|
| Agent claims verifiable against SQL truth | partial — `cmd/queryd/main.go` is the SQL truth surface; no agent layer above it yet | none for the agent layer | All | DESIGN-BAR (Sprint 3) |
|
|
|
|
## Cloud-only adaptation
|
|
|
|
| Claim | Code Location | Existing Test | Missing Test | Risk |
|
|
|---|---|---|---|---|
|
|
| Embed works without local Ollama (cloud Provider) | `internal/embed/embed.go:20` interface allows it; no cloud Provider implemented yet | none | All | DESIGN-BAR (Sprint 4 — once cloud Provider lands) |
|
|
| Persistence works without local MinIO (real S3 / R2) | `internal/storaged/bucket.go` uses aws-sdk-go-v2 — should work against real S3 with no code changes | not exercised in smokes | Smoke variant pointing at AWS S3 in addition to MinIO | LOW |
|
|
|
|
---
|
|
|
|
## Summary counts
|
|
|
|
- **Claims covered by existing tests + smokes:** 14
|
|
- **Claims partially covered (smoke only, no go-test):** 5
|
|
- **Claims uncovered but component built:** 2 (concurrent-search stress, large LHV1 persistence)
|
|
- **Claims marked "not yet ported" (design bars):** 14
|
|
- **Claims with HIGH-risk gaps in current code:** 1 (R-001, the queryd /sql boundary)
|
|
|
|
The 14 design-bar rows are the primary Sprint 2-3 backlog. The 5 partially-covered + 2 uncovered rows are Sprint 0 follow-ups. The 1 HIGH-risk gap is Sprint 1's anchor.
|