stemedb/sdk/go/examples/skeptic/main.go
jordan 1ce4004807 feat: Complete Phase 2 (The Cortex) - query, lens, and API layers
This commit adds the read path (Cortex) to complement the write path (Spine):

## Crates
- stemedb-api: HTTP API with axum + utoipa OpenAPI
  - /v1/assert, /v1/query, /v1/epoch, /v1/skeptic, /v1/trace, /v1/audit
  - Metered endpoints with quota enforcement
  - Ed25519 signature verification
- stemedb-lens: Truth resolution lenses
  - RecencyLens, ConsensusLens, ConfidenceLens
  - VoteAwareConsensusLens (Ballot Box pattern)
  - TrustAwareAuthorityLens (The Hive pattern)
  - SkepticLens (conflict analysis)
  - EpochAwareLens (paradigm-safe queries)
- stemedb-query: Query engine with materialized views

## Storage Extensions
- VoteStore: Vote aggregation with cached counts
- TrustRankStore: Agent reputation with decay
- AuditStore: Query audit trail
- IndexStore: SP/P/S index structures
- SupersessionStore: Epoch supersession chains

## SDKs
- sdk/go/steme: Go HTTP client with Ed25519 signing
- sdk/go/adk: ADK-Go tools for AI agents

## Documentation
- Updated CLAUDE.md, architecture.md, roadmap.md
- New ai-lookup entries for all services
- Use case docs for consumer health intelligence
- Arena roadmap for simulation advancement

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:22:44 -07:00

125 lines
4.1 KiB
Go

// Package main demonstrates the Skeptic lens ("Trust but Verify").
//
// Unlike standard lenses that pick a single winner, the Skeptic lens
// shows all competing claims with their relative weights. This is critical
// for domains like medicine where you need to see disagreement.
package main
import (
"context"
"fmt"
"log"
"github.com/orchard9/stemedb-go/steme"
)
func main() {
// Setup client
signer, err := steme.GenerateSigner()
if err != nil {
log.Fatalf("Failed to generate signer: %v", err)
}
client := steme.NewClient("http://localhost:3000", signer)
// Seed some conflicting assertions about Semaglutide's muscle effects
seedConflictingData(client)
// Query with Skeptic lens
result, err := client.Skeptic(context.Background(), steme.SkepticQueryParams{
Subject: "Semaglutide",
Predicate: "muscle_effect",
})
if err != nil {
log.Fatalf("Failed to query: %v", err)
}
// Display the conflict analysis
fmt.Printf("=== Skeptic Analysis: Semaglutide muscle_effect ===\n\n")
fmt.Printf("Status: %s\n", result.Status)
fmt.Printf("Conflict Score: %.2f (0.0=unanimous, 1.0=chaos)\n", result.ConflictScore)
fmt.Printf("Candidates Considered: %d\n", result.CandidatesCount)
fmt.Printf("Computed At: %d\n\n", result.ComputedAt)
fmt.Printf("Competing Claims:\n\n")
for i, claim := range result.Claims {
fmt.Printf("Claim #%d: %v\n", i+1, claim.Value.Value)
fmt.Printf(" Weight Share: %.1f%%\n", claim.WeightShare*100)
fmt.Printf(" Assertions: %d\n", claim.AssertionCount)
fmt.Printf(" Representative: %s\n", claim.RepresentativeHash[:16]+"...")
fmt.Printf(" Source: %s\n", claim.Source.SourceHash[:16]+"...")
if len(claim.SupportingAgents) > 0 {
fmt.Printf(" Supporting Agents:\n")
for _, agent := range claim.SupportingAgents {
fmt.Printf(" - %s (trust: %.2f)\n", agent.AgentID[:16]+"...", agent.TrustScore)
}
}
fmt.Println()
}
// Interpretation guide
fmt.Printf("=== Interpretation ===\n\n")
switch result.Status {
case steme.ResolutionUnanimous:
fmt.Println("✓ Unanimous: All sources agree on the same value.")
fmt.Println(" You can trust this result with high confidence.")
case steme.ResolutionAgreed:
fmt.Println("⚠ Agreed: Strong majority (>75%) agrees, but some dissent exists.")
fmt.Println(" The consensus is likely reliable, but review minority claims.")
case steme.ResolutionContested:
fmt.Println("⚠️ Contested: No clear consensus. Significant disagreement exists.")
fmt.Println(" DO NOT rely on any single answer. Review all claims and sources.")
fmt.Println(" This requires human judgment or additional research.")
}
}
func seedConflictingData(client *steme.Client) {
ctx := context.Background()
// Claim 1: Significant muscle loss (Clinical evidence)
claim1 := steme.NewAssertion("Semaglutide", "muscle_effect").
WithText("significant_loss").
WithConfidence(0.85).
WithLifecycle(steme.LifecycleApproved).
WithSourceClass(steme.SourceClassClinical).
WithSourceHash("1111111111111111111111111111111111111111111111111111111111111111").
Build()
if _, err := client.Assert(ctx, claim1); err != nil {
log.Printf("Warning: Failed to seed claim1: %v", err)
}
// Claim 2: Minimal muscle loss (Observational evidence)
claim2 := steme.NewAssertion("Semaglutide", "muscle_effect").
WithText("minimal_loss").
WithConfidence(0.75).
WithLifecycle(steme.LifecycleApproved).
WithSourceClass(steme.SourceClassObservational).
WithSourceHash("2222222222222222222222222222222222222222222222222222222222222222").
Build()
if _, err := client.Assert(ctx, claim2); err != nil {
log.Printf("Warning: Failed to seed claim2: %v", err)
}
// Claim 3: No effect (Anecdotal evidence)
claim3 := steme.NewAssertion("Semaglutide", "muscle_effect").
WithText("no_effect").
WithConfidence(0.60).
WithLifecycle(steme.LifecycleProposed).
WithSourceClass(steme.SourceClassAnecdotal).
WithSourceHash("3333333333333333333333333333333333333333333333333333333333333333").
Build()
if _, err := client.Assert(ctx, claim3); err != nil {
log.Printf("Warning: Failed to seed claim3: %v", err)
}
fmt.Println("✓ Seeded 3 conflicting claims about Semaglutide muscle_effect")
}