ADR-003: Conversation Middleware Pipeline
Status
Accepted (inferred). Evident in code; rationale deferred to the Architect.
Context
The agent loop must enforce several orthogonal turn-level policies: a
turn limit, a price ceiling, auto-compaction near the context limit, a
context warning, and read-only behaviour for the plan and chat
agents. The code expresses each as a ConversationMiddleware with a
before_turn method; a MiddlewarePipeline runs them ahead of every
LLM turn and returns an action — CONTINUE, STOP, COMPACT or
INJECT_MESSAGE [vibe/core/middleware.py:43-247]. The loop assembles
the pipeline from constructor flags [vibe/core/agent_loop.py:722-757].
Decision
Enforce all turn-level policies through a composable before_turn
middleware pipeline, rather than inline conditionals in the loop or
provider-SDK callbacks.
Consequences
-
Positive: each policy is one small, independently testable class; the loop body stays focused on the LLM-call/tool-call cycle.
-
Positive: directly realises the Reliability and Security mechanisms in Chapter 8 (limits, compaction, read-only modes).
-
Negative: control flow is indirect — a
COMPACTresult is handled far from the middleware that raised it. -
Risk: the price ceiling depends on
session_cost, which is a rough estimate — this is technical debt TD-001 in Chapter 11; the--max-priceguarantee is therefore approximate.
Pugh Matrix
Baseline (score 0): Inline policy checks in the agent loop.
| Criterion | Inline checks (baseline) | Middleware pipeline (chosen) | Provider-SDK callbacks |
|---|---|---|---|
Maintainability |
0 |
+1 |
0 |
Testability |
0 |
+1 |
-1 |
Reliability |
0 |
+1 |
? |
Compatibility (provider-agnostic) |
0 |
+1 |
-1 |
Usability (code readability) |
0 |
0 |
0 |
Sum |
0 |
+4 |
? |
The ? cell needs the team’s judgment — whether provider-SDK callbacks
would be reliable enough depends on each SDK’s guarantees.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.