Skip to content
bflo.sh

ADR-0002: Contract-first team boundary with strict tier direction

ADR-0002 — Accepted (template baseline). Part of the platform's decision record.

Adapted from the repo's docs/adr/0002-contract-first-team-boundary.md — Part of Internals: the platform's design set, published as content on the platform it describes.

  • Status: Accepted
  • Date: template baseline
  • Deciders: project lead
  • Tiers affected: contract, backend, frontend, infra, docs
  • Related: ADR-0001, docs/rules-of-engagement.md

Context

The project is built by a roster of autonomous agents working in parallel. Parallel autonomy without a hard interface boundary produces drift: consumers coding against guessed shapes, producers breaking consumers silently, and cross-file edits that bypass ownership. We need a coordination mechanism that is cheap to enforce mechanically and survives roster changes.

Decision

We will use contract/ (OpenAPI 3.1 + AsyncAPI 3.0, linted by a Spectral ruleset) as the only coupling point between backend and frontend, owned exclusively by contract-owner. Dependency direction is fixed (frontend → contract ← backend; within backend Http → Domain → Data ports), and all cross-tier work is routed as tasks/messages through contract-owner rather than direct cross-file edits.

Alternatives considered

  1. Contract-first with single owner (chosen) — pro: one arbiter, mechanical linting, parallel-safe; con: contract-owner can become a bottleneck (mitigated: additive changes are cheap minor bumps).
  2. Shared types package generated from backend code — pro: zero spec drift; con: makes backend internals the de-facto interface, inverts tier direction, couples deploys.
  3. Ad-hoc coordination per feature — pro: no ceremony; con: does not survive parallel autonomous agents; drift guaranteed.

Consequences

  • Every interface change has a published, versioned artifact before implementation starts.
  • Members can work in parallel with worktree isolation and still integrate cleanly.
  • New cost: interface needs travel through contract-owner even when "obvious".
  • Forbidden henceforth: hand-written API shapes in frontend/, controller-level Eloquent, Domain→Http imports, app-code edits to DDEV topology.

Compliance

  • Spectral lint (contract/.spectral.yaml) gates every contract change, locally and in CI.
  • Members verify no forbidden import edges in touched files as part of Definition of Done.
  • docs/rules-of-engagement.md lists canonical violations; reviewers reject on sight.