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>
262 lines
5.5 KiB
Markdown
262 lines
5.5 KiB
Markdown
# StemeDB Go SDK
|
|
|
|
Go SDK for StemeDB - A probabilistic knowledge graph database.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
go get github.com/orchard9/stemedb-go/steme
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/orchard9/stemedb-go/steme"
|
|
)
|
|
|
|
func main() {
|
|
// Generate a new keypair (or load from environment)
|
|
signer, err := steme.GenerateSigner()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Create a client
|
|
client := steme.NewClient("http://localhost:3000", signer)
|
|
|
|
// Create an assertion
|
|
assertion := steme.NewAssertion("Tesla_Inc", "has_revenue").
|
|
WithNumber(96.7).
|
|
WithConfidence(0.95).
|
|
WithLifecycle(steme.LifecycleApproved).
|
|
WithSourceClass(steme.SourceClassClinical).
|
|
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
|
|
Build()
|
|
|
|
// Submit to StemeDB (automatically signed)
|
|
hash, err := client.Assert(context.Background(), assertion)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Printf("Created assertion: %s\n", hash)
|
|
|
|
// Query with lens-based conflict resolution
|
|
params := steme.NewQuery().
|
|
WithSubject("Tesla_Inc").
|
|
WithPredicate("has_revenue").
|
|
WithLens(steme.LensConsensus).
|
|
Build()
|
|
|
|
result, err := client.Query(context.Background(), params)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Printf("Found %d assertions\n", result.TotalCount)
|
|
for _, a := range result.Assertions {
|
|
fmt.Printf(" %s: %v (confidence: %.2f)\n", a.Subject, a.Object.Value, a.Confidence)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Features
|
|
|
|
### 1. Automatic Signing
|
|
|
|
The SDK automatically signs all assertions using Ed25519 cryptography. You don't need to think about keys, signatures, or timestamps.
|
|
|
|
```go
|
|
signer, _ := steme.GenerateSigner()
|
|
client := steme.NewClient("http://localhost:3000", signer)
|
|
|
|
// Assertion is automatically signed during Assert()
|
|
hash, _ := client.Assert(ctx, assertion)
|
|
```
|
|
|
|
### 2. Fluent API
|
|
|
|
Build assertions and queries with a clean, chainable API.
|
|
|
|
```go
|
|
assertion := steme.NewAssertion("Semaglutide", "muscle_loss").
|
|
WithText("significant").
|
|
WithConfidence(0.85).
|
|
WithLifecycle(steme.LifecycleApproved).
|
|
WithSourceClass(steme.SourceClassClinical).
|
|
WithSourceHash("...").
|
|
Build()
|
|
|
|
params := steme.NewQuery().
|
|
WithSubject("Semaglutide").
|
|
WithPredicate("muscle_loss").
|
|
WithLens(steme.LensConsensus).
|
|
WithLimit(10).
|
|
Build()
|
|
```
|
|
|
|
### 3. Type-Safe Enums
|
|
|
|
All StemeDB enums are type-safe Go constants.
|
|
|
|
```go
|
|
// Lifecycle stages
|
|
steme.LifecycleProposed
|
|
steme.LifecycleUnderReview
|
|
steme.LifecycleApproved
|
|
steme.LifecycleDeprecated
|
|
steme.LifecycleRejected
|
|
|
|
// Source authority tiers
|
|
steme.SourceClassRegulatory // Tier 0
|
|
steme.SourceClassClinical // Tier 1
|
|
steme.SourceClassExpert // Tier 3
|
|
steme.SourceClassAnecdotal // Tier 5
|
|
|
|
// Lenses
|
|
steme.LensRecency
|
|
steme.LensConsensus
|
|
steme.LensAuthority
|
|
steme.LensVoteAwareConsensus
|
|
steme.LensTrustAwareAuthority
|
|
```
|
|
|
|
### 4. Context Support
|
|
|
|
All API calls support `context.Context` for cancellation and deadlines.
|
|
|
|
```go
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
result, err := client.Query(ctx, params)
|
|
```
|
|
|
|
### 5. Skeptic Queries ("Trust but Verify")
|
|
|
|
See all competing claims instead of just the winner.
|
|
|
|
```go
|
|
result, err := client.Skeptic(ctx, steme.SkepticQueryParams{
|
|
Subject: "Semaglutide",
|
|
Predicate: "muscle_effect",
|
|
})
|
|
|
|
fmt.Printf("Status: %s, Conflict: %.2f\n", result.Status, result.ConflictScore)
|
|
for _, claim := range result.Claims {
|
|
fmt.Printf(" %v (%.1f%% support, %d assertions)\n",
|
|
claim.Value.Value,
|
|
claim.WeightShare*100,
|
|
claim.AssertionCount,
|
|
)
|
|
}
|
|
```
|
|
|
|
## Key Management
|
|
|
|
### Generate New Keypair
|
|
|
|
```go
|
|
signer, err := steme.GenerateSigner()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Save for later
|
|
seed := signer.Seed() // Hex-encoded 32-byte seed
|
|
publicKey := signer.PublicKey() // Your agent_id
|
|
```
|
|
|
|
### Load from Seed
|
|
|
|
```go
|
|
signer, err := steme.NewSignerFromHex("your-hex-seed")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
```
|
|
|
|
### Load from Environment
|
|
|
|
```go
|
|
signer, err := steme.SignerFromEnv("STEME_PRIVATE_KEY")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
```
|
|
|
|
## Object Values
|
|
|
|
StemeDB supports four value types.
|
|
|
|
```go
|
|
// Text
|
|
assertion.WithText("hello world")
|
|
|
|
// Number
|
|
assertion.WithNumber(42.5)
|
|
|
|
// Boolean
|
|
assertion.WithBoolean(true)
|
|
|
|
// Reference (pointer to another entity)
|
|
assertion.WithReference("Other_Entity_Id")
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The SDK uses typed errors for common failure modes.
|
|
|
|
```go
|
|
hash, err := client.Assert(ctx, assertion)
|
|
if err != nil {
|
|
switch e := err.(type) {
|
|
case *steme.APIError:
|
|
fmt.Printf("API error [%d]: %s\n", e.StatusCode, e.Message)
|
|
case *steme.ValidationError:
|
|
fmt.Printf("Validation failed on %s: %s\n", e.Field, e.Message)
|
|
default:
|
|
fmt.Printf("Error: %v\n", err)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
Run unit tests:
|
|
|
|
```bash
|
|
go test -v ./...
|
|
```
|
|
|
|
Run integration tests against a live server:
|
|
|
|
```bash
|
|
# Start the StemeDB API server
|
|
cargo run --bin stemedb-api
|
|
|
|
# Run integration tests
|
|
STEMEDB_URL=http://localhost:3000 go test -tags=integration -v ./...
|
|
```
|
|
|
|
See [INTEGRATION_TESTS.md](./INTEGRATION_TESTS.md) for detailed integration test documentation.
|
|
|
|
## Examples
|
|
|
|
See the `examples/` directory for complete examples:
|
|
|
|
- `examples/basic/` - Simple assertion and query
|
|
- `examples/skeptic/` - Trust-but-verify conflict analysis
|
|
- `examples/batch/` - Batch assertion ingestion
|
|
|
|
## License
|
|
|
|
MIT
|