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
1.6 KiB
ADR-0003 — The wire contract is the boundary
Status: accepted · Date: 2026-09-04
Context
ADR-0002 puts fluid-core in a separate process from everything it serves. Something has to define how those processes agree.
Decision
The boundary is a set of on-the-wire artifacts, not a Go API:
- the revision descriptor (Blueprint §36);
- the routing policy (Blueprint §17);
- the telemetry envelope;
- the control APIs (Blueprint §44).
These live in schemas/ as JSON Schema. Go types in internal/contract are
generated from those schemas and are never hand-written.
Rationale
Field names and semantics are the interop surface — the schema specification says so directly in its §1. Generating from the schema means the specification cannot drift from the implementation without failing the build.
It also makes the Go choice reversible where it matters. A future high-throughput gateway in another language, a Python Daimon, a TypeScript adapter: none of them need anything from this repository except the schemas.
Enforcement
make check-generatedfails CI wheninternal/contractis stale.conformance/validate_schemas.pyvalidates fixtures transcribed from the spec's own worked examples, so a spec change that the schemas miss fails too.- The Go round-trip test decodes those fixtures with
DisallowUnknownFields, catching any field the generated types have no home for.
Consequence
Any change that would leak a Go type across this boundary is a design failure, not a convenience. If a consumer needs something, it goes in a schema first.