Two threads landing together — the doc edits interleave so they ship in a single commit. 1. **vectord substrate fix verified at original scale** (closes the 2026-05-01 thread). Re-ran multitier 5min @ conc=50: 132,211 scenarios at 438/sec, 6/6 classes at 0% failure (was 4/6 pre-fix). Throughput dropped 1,115 → 438/sec because previously-broken scenarios now do real HNSW Add work — honest cost of correctness. The fix (i.vectors side-store + safeGraphAdd recover wrappers + smallIndexRebuildThreshold=32 + saveTask coalescing) holds at the footprint that originally surfaced the bug. 2. **Materializer port** — internal/materializer + cmd/materializer + scripts/materializer_smoke.sh. Ports scripts/distillation/transforms.ts (12 transforms) + build_evidence_index.ts (idempotency, day-partition, receipt). On-wire JSON shape matches TS so Bun and Go runs are interchangeable. 14 tests green. 3. **Replay port** — internal/replay + cmd/replay + scripts/replay_smoke.sh. Ports scripts/distillation/replay.ts (retrieve → bundle → /v1/chat → validate → log). Closes audit-FULL phase 7 live invocation on the Go side. Both runtimes append to the same data/_kb/replay_runs.jsonl (schema=replay_run.v1). 14 tests green. Side effect on internal/distillation/types.go: EvidenceRecord gained prompt_tokens, completion_tokens, and metadata fields to mirror the TS shape the materializer transforms produce. STATE_OF_PLAY refreshed to 2026-05-02; ARCHITECTURE_COMPARISON decisions tracker moves the materializer + replay items from _open_ to DONE and adds the substrate-fix scale verification row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 lines
1.2 KiB
Go
46 lines
1.2 KiB
Go
package materializer
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCanonicalSha256_StableAcrossMapOrder(t *testing.T) {
|
|
a := map[string]any{"b": 2, "a": 1, "c": map[string]any{"y": "Y", "x": "X"}}
|
|
b := map[string]any{"a": 1, "c": map[string]any{"x": "X", "y": "Y"}, "b": 2}
|
|
hashA, err := CanonicalSha256(a)
|
|
if err != nil {
|
|
t.Fatalf("hash a: %v", err)
|
|
}
|
|
hashB, err := CanonicalSha256(b)
|
|
if err != nil {
|
|
t.Fatalf("hash b: %v", err)
|
|
}
|
|
if hashA != hashB {
|
|
t.Fatalf("identical objects produced different hashes:\n a=%s\n b=%s", hashA, hashB)
|
|
}
|
|
if len(hashA) != 64 || strings.Trim(hashA, "0123456789abcdef") != "" {
|
|
t.Fatalf("hash isn't a 64-char hex string: %q", hashA)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalSha256_DistinctsDifferentInputs(t *testing.T) {
|
|
a := map[string]any{"k": "v"}
|
|
b := map[string]any{"k": "v2"}
|
|
hashA, _ := CanonicalSha256(a)
|
|
hashB, _ := CanonicalSha256(b)
|
|
if hashA == hashB {
|
|
t.Fatalf("different inputs collided: %s", hashA)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalSha256_ArrayOrderMatters(t *testing.T) {
|
|
a := map[string]any{"k": []any{1, 2, 3}}
|
|
b := map[string]any{"k": []any{3, 2, 1}}
|
|
hashA, _ := CanonicalSha256(a)
|
|
hashB, _ := CanonicalSha256(b)
|
|
if hashA == hashB {
|
|
t.Fatal("array order should change the hash, but did not")
|
|
}
|
|
}
|