stemedb/sdk/go/adk/constraint_trace_test.go
jordan b3e8a9a058 feat: Multi-application expansion with chaos testing and community UI
Major additions:
- Community Next.js app (port 18187) for browsing claims with API docs
- stemedb-chaos crate: Fault injection, chaos testing, CRDT properties
- Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents
- Disputed claims handling: Manual review workflows and validation
- Aphoria security scanner: New extractors (SQL injection, command
  injection, weak crypto, TLS version), policy-based ignores, UAT reports
- Docker infrastructure: Dockerfile, docker-compose.yml for full stack
- VulnBank demo: Intentionally vulnerable multi-language test corpus

SDK & API enhancements:
- Source registry handlers for tracking data provenance
- Metrics endpoint
- Skeptic filtering improvements

Code quality:
- Split 14 large files (>500 lines) into focused modules
- All files now under 500-line limit per project guidelines

Documentation:
- Chaos testing guide, circuit breakers, observability docs
- Phase 7 UAT documentation updates
- Martin Kleppmann technical writer agent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:24:14 -07:00

187 lines
4.5 KiB
Go

package adk
import (
"context"
"encoding/json"
"testing"
"github.com/orchard9/stemedb-go/steme"
)
func TestConstraintCheckTool(t *testing.T) {
// Mock client that returns constraint assertions
client := &mockClient{
queryFunc: func(ctx context.Context, params steme.QueryParams) (*steme.QueryResult, error) {
lifecycle := steme.LifecycleApproved
return &steme.QueryResult{
Assertions: []steme.AssertionResponse{
{
Hash: "constraint1",
Subject: "auth_jwt",
Predicate: "must_use",
Object: steme.NewTextValue("Ed25519"),
Confidence: 1.0,
SourceHash: "source",
Lifecycle: lifecycle,
},
{
Hash: "constraint2",
Subject: "auth_jwt",
Predicate: "forbidden",
Object: steme.NewTextValue("MD5"),
Confidence: 1.0,
SourceHash: "source",
Lifecycle: lifecycle,
},
},
TotalCount: 2,
}, nil
},
}
tool := NewConstraintCheckTool(client)
input := ConstraintCheckInput{
Context: "auth_jwt",
}
inputBytes, _ := json.Marshal(input)
outputBytes, err := tool.Execute(context.Background(), inputBytes)
if err != nil {
t.Fatalf("constraint check failed: %v", err)
}
var output ConstraintCheckOutput
if err := json.Unmarshal(outputBytes, &output); err != nil {
t.Fatalf("failed to unmarshal output: %v", err)
}
// Verify constraints were returned
if len(output.Constraints) != 2 {
t.Errorf("expected 2 constraints, got %d", len(output.Constraints))
}
// Check for must-use constraint
foundMustUse := false
for _, c := range output.Constraints {
if c.MustUse == "Ed25519" {
foundMustUse = true
}
}
if !foundMustUse {
t.Error("expected to find Ed25519 must-use constraint")
}
// Check for forbidden constraint
foundForbidden := false
for _, c := range output.Constraints {
if c.Forbidden == "MD5" {
foundForbidden = true
}
}
if !foundForbidden {
t.Error("expected to find MD5 forbidden constraint")
}
}
func TestTraceTool(t *testing.T) {
// Mock client that returns audit records
agentID := "deadbeef00000000000000000000000000000000000000000000000000000000"
subject := "Tesla_Inc"
predicate := "has_revenue"
resultHash := "result_hash_123"
lens := steme.LensConsensus
client := &mockClient{
traceFunc: func(ctx context.Context, params steme.TraceParams) (*steme.TraceResult, error) {
return &steme.TraceResult{
Audits: []steme.QueryAuditRecord{
{
QueryID: "query_123",
AgentID: &agentID,
Timestamp: 1704067200,
Params: steme.QueryParamsAudit{
Subject: &subject,
Predicate: &predicate,
Lens: &lens,
},
ResultHash: &resultHash,
ResultConfidence: 0.95,
ContributingAssertions: []steme.ContributingAssertion{
{
AssertionHash: "assertion_1",
Weight: 1.0,
SourceHash: "source_1",
Lifecycle: steme.LifecycleApproved,
},
{
AssertionHash: "assertion_2",
Weight: 0.5,
SourceHash: "source_2",
Lifecycle: steme.LifecycleProposed,
},
},
},
},
TotalCount: 1,
AgentID: agentID,
FromTimestamp: 1704067200,
ToTimestamp: 1704153600,
}, nil
},
}
tool := NewTraceTool(client)
input := TraceInput{
AgentID: agentID,
From: "1704067200",
To: "1704153600",
Subject: "Tesla*",
}
inputBytes, _ := json.Marshal(input)
outputBytes, err := tool.Execute(context.Background(), inputBytes)
if err != nil {
t.Fatalf("trace failed: %v", err)
}
var output TraceOutput
if err := json.Unmarshal(outputBytes, &output); err != nil {
t.Fatalf("failed to unmarshal output: %v", err)
}
// Verify output
if len(output.Queries) != 1 {
t.Errorf("expected 1 query, got %d", len(output.Queries))
}
if len(output.Queries) > 0 {
query := output.Queries[0]
if query.QueryID != "query_123" {
t.Errorf("expected query_id query_123, got %s", query.QueryID)
}
if query.Subject != "Tesla_Inc" {
t.Errorf("expected subject Tesla_Inc, got %s", query.Subject)
}
if query.Predicate != "has_revenue" {
t.Errorf("expected predicate has_revenue, got %s", query.Predicate)
}
if query.Lens != "consensus" {
t.Errorf("expected lens consensus, got %s", query.Lens)
}
if query.Confidence != 0.95 {
t.Errorf("expected confidence 0.95, got %f", query.Confidence)
}
if len(query.Contributing) != 2 {
t.Errorf("expected 2 contributing assertions, got %d", len(query.Contributing))
}
}
}