Skip to content

ADR-0007 — No AI component may reach the broker

Status: Accepted · Date: 2026-08-03

Context

The system has language-model agents that analyse instruments and a broker adapter that can move real money. The convenient design gives an execution agent a place_order tool and lets the model call it when it concludes a trade is warranted. Most agent frameworks encourage exactly this, and it demos beautifully.

Decision

No AI component holds a broker handle, and no agent's toolset contains an order-placing function. Agents emit structured signals; a deterministic pipeline — Shariah, risk, portfolio, execution engine — converts a signal into an order, and only the adapter talks to IBKR.

The separation is enforced by construction, not convention: the agent runtime is never passed an adapter instance, and the dependency direction (01 §6) forbids packages/agents from importing the broker module. CI fails on violation.

Rationale

The system ingests attacker-controlled text. News articles, press releases, and forum posts flow into the news and social agents (ADR-0005). If any agent could place an order, the distance between "anyone can publish a sentence" and "money moves" would be one successful prompt injection. Removing the capability makes the question moot: there is nothing to invoke.

Non-determinism belongs on the analysis side, not the execution side. A model that is right 70% of the time is a useful analyst and an unacceptable executor. Order construction — quantity, limit price, idempotency key — must be reproducible from inputs. A temperature setting has no business anywhere near a share count.

Auditability requires a deterministic chain. "Why was this order placed?" must resolve to stored signals, a calibrated score, a sizing calculation, and a limit check. If a model could originate an order directly, the honest answer would sometimes be "the model decided to," which is not an answer.

Every guard depends on it. Compliance, risk limits, portfolio checks, and adapter caps only bind if they sit on the single path to the broker. One tool call that bypasses them makes all of them advisory.

Consequences

Positive. A fully successful prompt injection cannot place an order — the worst outcome is one skewed narrative signal with a capped contribution. Order construction is reproducible and testable without mocking a language model. The guard pipeline is genuinely mandatory rather than merely usual.

Negative. The system cannot express execution judgement that only a model could supply — reacting to an unusual intraday condition no rule anticipated, for instance. The Execution Planner agent can recommend timing and order type, but a deterministic engine decides. Some genuine edge is likely given up here, and that is accepted: the downside of being wrong in the other direction is unbounded.

It also costs indirection. An agent that "wants" to trade must emit a signal that flows through four validation stages, and debugging spans that whole chain rather than one call.

Rejected alternative. Giving the Execution Planner a tool with guard rails inside the tool implementation. This concentrates every safety property into code invoked by the model, so the guarantee becomes "the model called the right function with the right arguments." That is exactly the assumption an injection attacks.