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
37 lines
1.9 KiB
Markdown
37 lines
1.9 KiB
Markdown
# ADR-0005: Rules delivered via `get_rules`, enforced by session gating
|
|
|
|
**Status:** Accepted (2026-08-08)
|
|
|
|
## Context
|
|
|
|
Bridle's premise is that the canonical ruleset governs every agent session. But an MCP server can
|
|
only *offer* a `get_rules` tool — it cannot make a model call it. Meanwhile Claude Code auto-loads
|
|
`CLAUDE.md` from disk and Codex auto-loads `AGENTS.md` from disk, unprompted, every session. A tool
|
|
the model may skip is strictly weaker than a file the harness injects.
|
|
|
|
Three delivery mechanisms were considered:
|
|
|
|
1. A local sync client (`bridle sync` or a session-start hook) writing rendered files to disk —
|
|
reliable across agents today, but adds a client-side component the design doc does not have.
|
|
2. The `instructions` field of the MCP `initialize` result — no client install, but whether a given
|
|
client injects it into the system prompt varies and would need per-agent empirical testing.
|
|
3. The `get_rules` tool alone — matches the design doc, but leaves delivery best-effort.
|
|
|
|
## Decision
|
|
|
|
Deliver rules through the **`get_rules(project_id, agent_type)` tool**, and make it reliable by
|
|
**gating the session**: any other tool call before `get_rules` has succeeded returns a structured
|
|
error naming the required call. Per-session state tracks whether rules have been fetched.
|
|
|
|
## Consequences
|
|
|
|
- Delivery becomes effectively guaranteed using only the in-band MCP mechanism — no client-side
|
|
component to install or maintain per agent.
|
|
- Costs one extra round-trip at the start of each session.
|
|
- The error message is part of the product surface and must be unambiguous enough that an agent
|
|
recovers on the first try.
|
|
- Populating the `initialize` `instructions` field remains available later as belt-and-braces. It
|
|
reuses the same renderer, requires no client install, and does not change this architecture.
|
|
- Session state now matters: the gate flag must be scoped to the MCP session, and session loss
|
|
means re-fetching.
|