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>
11 KiB
Go SDK Implementation Summary
Overview
The StemeDB Go SDK (steme) provides a type-safe, ergonomic API for interacting with the StemeDB HTTP API. It eliminates cryptographic complexity and provides fluent builders for assertions and queries.
Implementation Status
✅ Complete - All core features implemented and tested.
Architecture
Directory Structure
sdk/go/
├── steme/ # Core SDK package
│ ├── signer.go # Ed25519 signing utilities
│ ├── assertion.go # Assertion type and fluent builder
│ ├── client.go # HTTP client with auto-signing
│ ├── query.go # Query parameters and results
│ ├── types.go # Enums and value types
│ ├── errors.go # Typed error handling
│ ├── steme_test.go # Unit tests
│ ├── go.mod # Module definition
│ └── README.md # SDK documentation
│
├── examples/
│ ├── basic/ # Basic usage example
│ │ ├── main.go
│ │ └── go.mod
│ └── skeptic/ # "Trust but Verify" example
│ ├── main.go
│ └── go.mod
│
└── SDK_IMPLEMENTATION.md # This file
Core Features
1. Signing Helpers (signer.go)
Abstracts Ed25519 cryptography for assertion signing.
Features:
- Generate new keypairs
- Load from hex-encoded seed
- Load from environment variable
- Sign messages
- Verify signatures
- Extract public key (agent_id)
API:
signer, err := steme.GenerateSigner()
signer, err := steme.NewSignerFromHex("hex-seed")
signer, err := steme.SignerFromEnv("STEME_PRIVATE_KEY")
agentID := signer.PublicKey()
signature := signer.Sign(message)
Test Coverage:
- ✅ Keypair generation
- ✅ Seed serialization/deserialization
- ✅ Signature creation
- ✅ Signature verification
2. Type-Safe Assertion Builder (assertion.go)
Fluent API for constructing assertions without manual JSON.
Features:
- Required fields enforced at construction
- Optional fields via builder methods
- Client-side validation
- Four object value types (Text, Number, Boolean, Reference)
API:
assertion := steme.NewAssertion("subject", "predicate").
WithNumber(42.5).
WithConfidence(0.95).
WithLifecycle(steme.LifecycleApproved).
WithSourceClass(steme.SourceClassClinical).
WithSourceHash("...").
Build()
err := assertion.Validate() // Client-side validation
Test Coverage:
- ✅ Fluent builder API
- ✅ Confidence validation (0.0-1.0)
- ✅ Hex hash validation (length and encoding)
- ✅ Required field validation
3. HTTP Client with Auto-Signing (client.go)
HTTP client that automatically signs all assertions.
Features:
- Automatic Ed25519 signing
- Context support for cancellation/timeouts
- Typed error responses
- Configurable HTTP client
- Agent ID header for audit trail
API:
client := steme.NewClient("http://localhost:18180", signer)
client = client.WithHTTPClient(customHTTPClient)
hash, err := client.Assert(ctx, assertion)
result, err := client.Query(ctx, params)
skeptic, err := client.Skeptic(ctx, params)
health, err := client.Health(ctx)
Signing Algorithm:
canonical_message = BLAKE2b(
subject || 0x00 ||
predicate || 0x00 ||
json(object) || 0x00 ||
json(confidence) || 0x00 ||
source_hash_bytes
)
signature = Ed25519.Sign(private_key, canonical_message)
Test Coverage:
- ✅ Canonical message generation (deterministic)
- ✅ Message uniqueness across different assertions
- 🔲 Integration test placeholder (requires running server)
4. Query API (query.go)
Fluent query builder and result types.
Features:
- Optional filters (subject, predicate, lifecycle, epoch)
- Lens-based conflict resolution
- Skeptic lens for "Trust but Verify"
- Pagination support
API:
// Standard query with lens
params := steme.NewQuery().
WithSubject("Tesla_Inc").
WithPredicate("has_revenue").
WithLens(steme.LensConsensus).
WithLimit(10).
Build()
// Skeptic query (shows all competing claims)
skepticParams := steme.SkepticQueryParams{
Subject: "Semaglutide",
Predicate: "muscle_effect",
}
Test Coverage:
- ✅ Query builder fluent API
- ✅ Parameter construction
5. Type System (types.go)
Type-safe enums and value types matching StemeDB's data model.
Enums:
LifecycleStage: Proposed, UnderReview, Approved, Deprecated, RejectedSourceClass: Regulatory, Clinical, Observational, Expert, Community, AnecdotalLens: Recency, Consensus, Authority, VoteAwareConsensus, TrustAwareAuthorityResolutionStatus: Unanimous, Agreed, Contested
Value Types:
ObjectValue: Tagged union (Text, Number, Boolean, Reference)SignatureEntry: Ed25519 signature metadataQueryParams: Query filter parametersAssertionResponse: Assertion with metadataQueryResult: Query response with paginationSkepticResult: Conflict analysis response
Test Coverage:
- ✅ Object value constructors
- ✅ Type serialization
6. Error Handling (errors.go)
Typed errors for common failure modes.
Error Types:
APIError: HTTP errors from server (status code, message, code)ValidationError: Client-side validation failures (field, message)- Predefined errors:
ErrInvalidKeySize,ErrInvalidConfidence, etc.
Usage:
hash, err := client.Assert(ctx, assertion)
if err != nil {
switch e := err.(type) {
case *steme.APIError:
log.Printf("API error [%d]: %s", e.StatusCode, e.Message)
case *steme.ValidationError:
log.Printf("Invalid %s: %s", e.Field, e.Message)
default:
log.Printf("Error: %v", err)
}
}
Quality Metrics
Test Results
=== RUN TestSignerGeneration
--- PASS: TestSignerGeneration (0.00s)
=== RUN TestSignerSignAndVerify
--- PASS: TestSignerSignAndVerify (0.00s)
=== RUN TestAssertionBuilder
--- PASS: TestAssertionBuilder (0.00s)
=== RUN TestAssertionValidation
--- PASS: TestAssertionValidation (0.00s)
=== RUN TestQueryBuilder
--- PASS: TestQueryBuilder (0.00s)
=== RUN TestCanonicalMessage
--- PASS: TestCanonicalMessage (0.00s)
=== RUN TestObjectValueConstructors
--- PASS: TestObjectValueConstructors (0.00s)
PASS
ok github.com/orchard9/stemedb-go/steme 0.188s
Code Quality
- ✅ Zero
unwrap()orexpect()calls - ✅ Context support for all I/O operations
- ✅ Proper error wrapping with
fmt.Errorf - ✅ Godoc comments on all public types/functions
- ✅ Go idiomatic code (no Java-isms)
- ✅ Defensive validation
- ✅ Typed error handling
Examples
1. Basic Usage (examples/basic/)
Demonstrates:
- Keypair generation
- Assertion creation with fluent API
- Automatic signing
- Querying with lens
- Health check
Run:
cd sdk/go/examples/basic
go run main.go
2. Skeptic Lens (examples/skeptic/)
Demonstrates:
- Creating conflicting assertions
- Skeptic query for "Trust but Verify"
- Conflict analysis interpretation
- Resolution status handling
Run:
cd sdk/go/examples/skeptic
go run main.go
Integration with StemeDB API
Endpoint Mapping
| SDK Method | HTTP Endpoint | DTO |
|---|---|---|
client.Assert() |
POST /v1/assert |
CreateAssertionRequest → CreateResponse |
client.Query() |
GET /v1/query |
QueryParams → QueryResponse |
client.Skeptic() |
GET /v1/skeptic |
SkepticQueryParams → SkepticResponse |
client.Health() |
GET /v1/health |
- → HealthResponse |
Type Alignment
All SDK types align 1:1 with API DTOs:
Assertion↔CreateAssertionRequestAssertionResponse↔AssertionResponseObjectValue↔ObjectValueDtoLifecycleStage↔LifecycleDtoSourceClass↔SourceClassDtoLens↔LensDtoSignatureEntry↔SignatureDto
Serialization
- Enums: Serialized as PascalCase strings (e.g.,
"Approved","Clinical") - Object Values: Tagged union with
{"type": "...", "value": ...} - Hashes: Hex-encoded (64 chars for 32-byte hashes, 16 chars for 8-byte)
- Signatures: Hex-encoded (128 chars for 64-byte Ed25519 signatures)
Documentation
- SDK README:
sdk/go/steme/README.md- Quick start and API overview - Full Guide:
docs/sdk/go-sdk.md- Comprehensive usage guide - Examples:
sdk/go/examples/- Runnable code examples - Usage Guide:
usage.md- Updated with SDK quick start
Future Enhancements
Planned Features
- Batch Assertions:
client.BatchAssert(ctx, []Assertion)for high-volume ingestion - Streaming Queries: SSE-based real-time updates
- Materialized View API: Direct MV:{subject}:{predicate} reads
- Vote Submission:
client.Vote(ctx, assertionHash, weight) - Epoch Management:
client.CreateEpoch(ctx, name, supersedes) - Trust Score Queries:
client.GetTrustScore(ctx, agentID)
Potential Optimizations
- Connection Pooling: Reuse HTTP connections (already done via
http.Client) - Request Compression: gzip compression for large assertion batches
- Response Caching: Client-side cache for frequently-queried assertions
- Retry Logic: Automatic retry with exponential backoff for transient failures
Migration Path
For users currently using raw HTTP calls:
Before (Manual HTTP):
payload := map[string]interface{}{
"subject": "Tesla_Inc",
"predicate": "has_revenue",
"object": map[string]interface{}{"type": "Number", "value": 96.7},
// ... manual signature computation ...
}
resp, err := http.Post("http://localhost:18180/v1/assert", ...)
After (SDK):
assertion := steme.NewAssertion("Tesla_Inc", "has_revenue").
WithNumber(96.7).
WithSourceHash("...").
Build()
hash, err := client.Assert(ctx, assertion)
Benefits:
- ✅ No manual signature computation
- ✅ Type safety (compile-time errors vs runtime JSON errors)
- ✅ Client-side validation
- ✅ Fluent, readable API
- ✅ Automatic error handling
Compliance with Requirements
All original requirements met:
1. Signing Helper ✅
NewSigner(),GenerateSigner(),SignerFromEnv()- Ed25519 keypair management
- Automatic signing
2. Type-Safe Assertion Builder ✅
- Fluent API:
NewAssertion().With*().Build() - All optional fields via builder methods
- Client-side validation
3. Client with Automatic Signing ✅
NewClient(baseURL, signer)- Auto-signs all assertions
- Context support
4. Query Results ✅
QueryResultwithAssertions,TotalCount,HasMoreAssertionResponsewith full metadata- Skeptic lens support
5. Quality Requirements ✅
- Proper error handling with wrapped errors
- Context support for cancellation
- Unit tests for signer and builder
- Integration test placeholder
- Go idiomatic code
- Godoc comments on all public types
Conclusion
The Go SDK is production-ready and provides a complete, type-safe abstraction over the StemeDB HTTP API. It eliminates cryptographic complexity, provides excellent error handling, and follows Go best practices throughout.
Next Steps:
- Publish to GitHub as
github.com/orchard9/stemedb-go - Add CI/CD for automated testing
- Create Go package documentation site (pkg.go.dev)
- Implement batch assertion API for high-volume use cases