# 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: 1. the revision descriptor (Blueprint §36); 2. the routing policy (Blueprint §17); 3. the telemetry envelope; 4. 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-generated` fails CI when `internal/contract` is stale. - `conformance/validate_schemas.py` validates 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.