package materializer import ( "encoding/json" "testing" "git.agentview.dev/profit/golangLAKEHOUSE/internal/distillation" ) const fixedRecordedAt = "2026-05-02T00:00:00Z" const fixedSigHash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" func ti(row map[string]any, source string, lineOffset int64) TransformInput { return TransformInput{ Row: row, LineOffset: lineOffset, SourceFileRelPath: source, RecordedAt: fixedRecordedAt, SigHash: fixedSigHash, } } func TestExtractorTransform_DistilledFacts(t *testing.T) { in := ti(map[string]any{ "run_id": "run-1", "source_label": "lab-3", "created_at": "2026-04-01T00:00:00Z", "extractor": "qwen3.5:latest", "text": "Hello.", }, "data/_kb/distilled_facts.jsonl", 0) rec := extractorTransform(in) if rec == nil { t.Fatal("nil record") } if rec.RunID != "run-1" || rec.TaskID != "lab-3" { t.Fatalf("ids: %+v", rec) } if rec.ModelRole != distillation.RoleExtractor { t.Errorf("role=%v, want extractor", rec.ModelRole) } if rec.ModelProvider != "ollama" { t.Errorf("provider=%q, want ollama", rec.ModelProvider) } if rec.Provenance.SigHash != fixedSigHash { t.Errorf("provenance.sig_hash mismatch: %q", rec.Provenance.SigHash) } if rec.Text != "Hello." { t.Errorf("text=%q", rec.Text) } } func TestExtractorTransform_FallbackIDs(t *testing.T) { in := ti(map[string]any{ "created_at": "2026-04-01T00:00:00Z", "text": "row without ids", }, "data/_kb/distilled_procedures.jsonl", 7) rec := extractorTransform(in) if rec.RunID != "distilled_procedures:7" || rec.TaskID != "distilled_procedures:7" { t.Fatalf("fallback ids wrong: %+v", rec) } } func TestContractAnalysesTransform_Fields(t *testing.T) { in := ti(map[string]any{ "permit_id": "P-001", "ts": "2026-04-26T12:00:00Z", "matrix_corpora": map[string]any{"workers": 1, "candidates": 1}, "matrix_hits": 3.0, "observer_notes": []any{"good", "spec match"}, "observer_verdict": "accept", "observer_conf": 85.0, "ok": true, "cost": 2_500_000.0, // micro-units "duration_ms": 1234.0, "contractor": "Acme", "analysis": "Looks good.", }, "data/_kb/contract_analyses.jsonl", 0) rec := contractAnalysesTransform(in) if rec.RunID == "" || rec.TaskID != "permit:P-001" { t.Fatalf("ids: %+v", rec) } if rec.ModelRole != distillation.RoleExecutor { t.Errorf("role=%v", rec.ModelRole) } if rec.RetrievedContext == nil || len(rec.RetrievedContext.MatrixCorpora) != 2 || rec.RetrievedContext.MatrixHits != 3 { t.Errorf("retrieved_context wrong: %+v", rec.RetrievedContext) } if len(rec.ObserverNotes) != 2 { t.Errorf("observer_notes=%v", rec.ObserverNotes) } if string(rec.ObserverVerdict) != "accept" || rec.ObserverConfidence != 85 { t.Errorf("observer fields: %+v", rec) } if rec.CostUSD != 2.5 { t.Errorf("cost should convert micro→USD; got %v", rec.CostUSD) } if rec.LatencyMs != 1234 { t.Errorf("latency: %v", rec.LatencyMs) } if rec.Metadata == nil || rec.Metadata["contractor"] != "Acme" { t.Errorf("metadata.contractor missing: %v", rec.Metadata) } if len(rec.SuccessMarkers) != 1 || rec.SuccessMarkers[0] != "matrix_hits_above_threshold" { t.Errorf("success_markers: %v", rec.SuccessMarkers) } if len(rec.FailureMarkers) != 0 { t.Errorf("expected no failure_markers when ok=true and verdict=accept, got %v", rec.FailureMarkers) } } func TestContractAnalysesTransform_FailureMarkers(t *testing.T) { in := ti(map[string]any{ "permit_id": "P-002", "ts": "2026-04-26T12:00:00Z", "observer_verdict": "reject", "ok": false, "analysis": "Issues found.", }, "data/_kb/contract_analyses.jsonl", 1) rec := contractAnalysesTransform(in) if len(rec.FailureMarkers) != 1 || rec.FailureMarkers[0] != "observer_rejected" { t.Errorf("failure_markers: %v", rec.FailureMarkers) } } func TestModeExperimentsTransform_ProviderInference(t *testing.T) { openrouter := ti(map[string]any{ "ts": "2026-04-26T12:00:00Z", "task_class": "scrum_review", "model": "anthropic/claude-opus-4-7", "file_path": "src/foo.rs", "sources": map[string]any{"matrix_corpus": []any{"docs"}, "matrix_chunks_kept": 4.0}, "latency_ms": 200.0, "response": "ok", }, "data/_kb/mode_experiments.jsonl", 0) rec := modeExperimentsTransform(openrouter) if rec.ModelProvider != "openrouter" { t.Errorf("provider=%q, want openrouter", rec.ModelProvider) } cloud := ti(map[string]any{ "ts": "2026-04-26T12:00:00Z", "task_class": "scrum_review", "model": "qwen3-coder:480b", "sources": map[string]any{"matrix_corpus": []any{"docs"}}, "response": "ok", }, "data/_kb/mode_experiments.jsonl", 1) rec2 := modeExperimentsTransform(cloud) if rec2.ModelProvider != "ollama_cloud" { t.Errorf("provider=%q, want ollama_cloud", rec2.ModelProvider) } if len(rec2.SourceFiles) != 0 { t.Errorf("source_files should be empty when file_path missing; got %v", rec2.SourceFiles) } } func TestObserverEscalationsTransform_Tokens(t *testing.T) { in := ti(map[string]any{ "ts": "2026-04-26T12:00:00Z", "sig_hash": "abc", "cluster_endpoint": "/v1/chat", "prompt_tokens": 100.0, "completion_tokens": 50.0, "analysis": "review", }, "data/_kb/observer_escalations.jsonl", 0) rec := observerEscalationsTransform(in) if rec.PromptTokens != 100 || rec.CompletionTokens != 50 { t.Errorf("tokens: prompt=%d completion=%d", rec.PromptTokens, rec.CompletionTokens) } if rec.TaskID != "observer_escalation:/v1/chat" { t.Errorf("task_id=%q", rec.TaskID) } } func TestAuditFactsTransform_TextIsSummary(t *testing.T) { in := ti(map[string]any{ "head_sha": "abc123", "pr_number": 11.0, "extracted_at": "2026-04-26T12:00:00Z", "extractor": "qwen2.5", "facts": []any{"f1", "f2"}, "entities": []any{"e1"}, "relationships": []any{}, }, "data/_kb/audit_facts.jsonl", 0) rec := auditFactsTransform(in) var summary map[string]any if err := json.Unmarshal([]byte(rec.Text), &summary); err != nil { t.Fatalf("text not JSON: %v", err) } if summary["facts"].(float64) != 2 || summary["entities"].(float64) != 1 || summary["relationships"].(float64) != 0 { t.Errorf("counts wrong: %+v", summary) } } func TestAutoApplyTransform_DeterministicTimestampFallback(t *testing.T) { in := ti(map[string]any{ "action": "committed", "file": "src/x.rs", }, "data/_kb/auto_apply.jsonl", 0) rec := autoApplyTransform(in) if rec.Timestamp != fixedRecordedAt { t.Errorf("expected fallback to RecordedAt %q, got %q", fixedRecordedAt, rec.Timestamp) } if len(rec.SuccessMarkers) != 1 || rec.SuccessMarkers[0] != "committed" { t.Errorf("success_markers: %v", rec.SuccessMarkers) } revertedIn := ti(map[string]any{ "ts": "2026-04-26T12:00:00Z", "action": "auto_reverted_after_test_fail", "file": "src/x.rs", }, "data/_kb/auto_apply.jsonl", 1) rec2 := autoApplyTransform(revertedIn) if len(rec2.FailureMarkers) != 1 || rec2.FailureMarkers[0] != "auto_reverted_after_test_fail" { t.Errorf("failure_markers: %v", rec2.FailureMarkers) } } func TestAuditsTransform_SeverityRouting(t *testing.T) { cases := []struct { sev string success bool blocking bool medium bool }{ {"info", true, false, false}, {"low", true, false, false}, {"medium", false, false, true}, {"high", false, true, false}, {"critical", false, true, false}, } for _, c := range cases { t.Run(c.sev, func(t *testing.T) { in := ti(map[string]any{ "finding_id": "F-1", "phase": "G2", "severity": c.sev, "ts": "2026-04-26T12:00:00Z", "evidence": "details", }, "data/_kb/audits.jsonl", 0) rec := auditsTransform(in) hasSuccess := len(rec.SuccessMarkers) > 0 hasFailure := len(rec.FailureMarkers) > 0 if hasSuccess != c.success { t.Errorf("severity=%s success=%v wanted %v", c.sev, hasSuccess, c.success) } if hasFailure != (c.blocking || c.medium) { t.Errorf("severity=%s failure=%v wanted %v", c.sev, hasFailure, c.blocking || c.medium) } }) } } func TestOutcomesTransform_LatencyAndSuccess(t *testing.T) { in := ti(map[string]any{ "run_id": "r-1", "created_at": "2026-04-26T12:00:00Z", "sig_hash": "abc", "elapsed_secs": 1.234, "ok_events": 5.0, "total_events": 5.0, "total_gap_signals": 2.0, "total_citations": 3.0, }, "data/_kb/outcomes.jsonl", 0) rec := outcomesTransform(in) if rec.LatencyMs != 1234 { t.Errorf("latency=%d", rec.LatencyMs) } if len(rec.SuccessMarkers) != 1 || rec.SuccessMarkers[0] != "all_events_ok" { t.Errorf("success: %v", rec.SuccessMarkers) } if g, ok := rec.ValidationResults["gap_signals"].(int64); !ok || g != 2 { t.Errorf("gap_signals: %v", rec.ValidationResults) } if c, ok := rec.ValidationResults["citation_count"].(int64); !ok || c != 3 { t.Errorf("citation_count: %v", rec.ValidationResults) } } func TestTransformByPath_Found(t *testing.T) { td := TransformByPath("data/_kb/distilled_facts.jsonl") if td == nil { t.Fatal("expected to find distilled_facts transform") } if TransformByPath("data/_kb/never_existed.jsonl") != nil { t.Fatal("expected nil for unknown path") } }