fluid-core/docs/adr/0004-evidence-store-sqlite-to-postgres.md
tegwick 76912adef8
Some checks failed
ci / build (push) Failing after 1m6s
Generate contract types, pin fixtures to spec, add build and ADRs
Completes FLUID-WP-0002. The record types in internal/contract are
generated from schemas/ by a dependency-free generator; fixtures
transcribed from the spec's worked examples validate against those
schemas and round-trip through the generated types with
DisallowUnknownFields, so a spec change that misses the schemas fails
CI rather than drifting silently.

Adds identifier prefix helpers, Makefile, GitHub Actions, and five ADRs
recording the Go choice, out-of-process attachment, the wire contract as
boundary, the evidence store, and revision identity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KmVxhJ35tCo7rE7UnLwWu

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1116572@bnt-lap001
Assistant-Session: 8ba9bb93-a72a-4883-b189-2499cce5c400
2026-09-04 02:03:12 +02:00

1.5 KiB

ADR-0004 — Append-only evidence store, SQLite then Postgres

Status: accepted · Date: 2026-09-04

Context

Blueprint §26 requires an evidence store favouring append-only history, with mutable summaries derived from immutable events. §45 suggests a relational starting model and explicitly argues it is simpler than a graph database for a first implementation.

Decision

One relational schema, two backends. SQLite for development, single-node deployments and the CI conformance suite; PostgreSQL for anything shared. The event table is append-only: no UPDATE, no DELETE, enforced by trigger rather than by convention.

Summary tables are derived views, rebuildable from events at any time.

Rationale

The first real workload — publishing hall-of-helix entries to a Telegram channel — produces a handful of events per day. Requiring Postgres to run the framework at that scale would be an operational tax with no return.

Keeping one schema across both means the CI suite exercises the same statements production runs, which is where divergence usually hides.

Consequences

  • Portable SQL only; no backend-specific features in the core path.
  • Blueprint invariant 8 (every promotion is auditable) is a storage property, not an application convention: rewriting history has to be blocked at the database.
  • Evidence-store failure must not stop the data plane (Blueprint §34.6). The gateway serves from cached published configuration and buffers telemetry.