Files
Agentic-Bridle/docs/adr/0001-single-binary-with-routed-services.md
wtclaude 06917d43e2 docs: add phased implementation plan and architecture decision records
Turns the design doc into an ordered, dependency-correct build plan (phases
0-9) with an exit criterion per phase, and records the twelve architectural
decisions it rests on as ADRs.

Decisions: single Rust binary with routed compose services; Streamable HTTP
only; per-agent bearer tokens with clientInfo as a display hint only; SQLite;
get_rules delivered via session gating; full-document rule delivery; project_id
from day one; enforcement tier scoped to Bridle-mediated actions; stable tool
list on upstream failure; OpenAI-compatible embeddings with model/dim guarding;
pattern RAG gated behind a spike; CLAUDE.md + AGENTS.md as v1 renderer targets.

Deviates from the design doc's original 1-8 ordering by moving the audit log
and multi-project schema into phase 1, building the admin API incrementally
rather than all at the Web Panel phase, downgrading vendor guardrail sourcing
to manual-first, and gating the pattern-example RAG behind a validation spike.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RZerbsHGF9Ka3bKhCjJ9m
2026-08-08 14:33:27 -05:00

33 lines
1.5 KiB
Markdown

# ADR-0001: Single Rust binary with routed compose services
**Status:** Accepted (2026-08-08)
## Context
The design doc's architecture diagram shows Rules, Memory, the Kanboard wrapper, and the Web Panel
as separate boxes, which reads as four independent deployables communicating over HTTP. Bridle
targets single-host, single-user deployment. Splitting hand-written components across processes at
that scale buys nothing: it costs four ports, four health checks, four failure modes, and turns
what would be function calls into network hops.
## Decision
All hand-written components compile into **one Rust binary** with internal modules: `mcp` (server
and session handling), `rules`, `memory`, `proxy`, `admin`, and the Web Panel's served assets.
Module boundaries stay clean enough that any module could be split into its own service later
without redesign.
Third-party and off-the-shelf services remain **separate Docker Compose containers** — Qdrant,
Kanboard, the embedding server, and the existing Gitea MCP server — with all agent traffic to them
routed through the binary.
## Consequences
- One deployable, one health check, one log stream, one thing to restart.
- No Python sidecar: the memory module is Rust talking to Qdrant and to an OpenAI-compatible
embeddings endpoint over HTTP.
- Compose profiles for bundled-versus-external services are unaffected — see the deployment section
of the design doc.
- If Bridle ever outgrows single-host, the module boundaries are the seams to split along. This is
a deliberate deferral, not an oversight.