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>
2.4 KiB
2.4 KiB
API Documentation Pattern
Last Updated: 2026-01-31 Confidence: High
Summary
Episteme uses a "define once, document everywhere" approach. Rust types are the single source of truth for both runtime behavior and API documentation. The utoipa crate generates OpenAPI 3.1 specs at compile time from derive macros on the same structs used for JSON serialization.
Key Facts:
utoipachosen overaidefor compile-time generation and framework-agnostic designutoipa-axumprovidesOpenApiRouterthat collects handler metadata automaticallyutoipa-swagger-uiserves interactive docs in dev modewiddershinsconverts OpenAPI JSON to Slate-compatible markdown in CI- No separate schema files to maintain; types ARE the schema
The Stack
| Layer | Tool | Purpose |
|---|---|---|
| Type definitions | serde + utoipa::ToSchema |
Single struct defines JSON shape AND OpenAPI schema |
| Handler docs | #[utoipa::path] |
Documents endpoint alongside implementation |
| Router | utoipa_axum::OpenApiRouter |
Collects all handler metadata automatically |
| Spec output | /api-doc/openapi.json |
OpenAPI 3.1 spec, no build step |
| Dev UI | utoipa-swagger-ui |
Interactive API explorer at /swagger-ui |
| Published docs | widdershins + Slate |
CI generates static docs from OpenAPI spec |
Adding a New Endpoint (Quick Reference)
- Define DTO types with
#[derive(Serialize, Deserialize, ToSchema)] - Write handler function
- Annotate with
#[utoipa::path(post, path = "/foo", ...)] - Register on
OpenApiRouter- docs update automatically - No manual schema sync needed
File Pointer: .claude/guides/backend/api-endpoints.md for full procedure.
Why utoipa Over aide
- Compile-time generation fits zero-cost philosophy
- Framework-agnostic (future gRPC won't require rewrite)
- Larger ecosystem (SwaggerUI, Redoc, Scalar, RapiDoc crates)
- Already macro-heavy codebase (rkyv derives) - one more derive is natural
gRPC (Future)
When added, .proto files will be the source for gRPC docs via protoc-gen-doc.
Both HTTP and gRPC will share the same internal types via From<> conversions.
The DTO layer keeps internal rkyv types separate from public API contracts.
Related Topics
- API Service - Endpoints and crate structure
- Error Handling - thiserror + context pattern