Talal Khawaja, home

Article · Next.js

Sometimes the best trade is no trade: a fail-closed risk governor for AI agents

ThesisCircuit lets three strategy agents argue, a critic object, and a deterministic risk governor decide. It trades on paper only, and NO TRADE is an audited result rather than an error.

Paper trading only. Everything below describes a system that talks exclusively to Alpaca's paper endpoint. No real money was involved, and nothing here is investment advice.

Most trading-agent demos are built to produce a trade. We built ThesisCircuit, as team teqprotech for the Alpaca AI Trading Agents Hackathon on lablab.ai, to do something harder: defend a decision, including the decision not to trade. Its line is "AI strategies compete. Risk decides. Sometimes the best trade is no trade."

Separate the voices from the vote

Each cycle starts from current Alpaca market, account and options data. Three deterministic strategy agents read the same snapshot:

  • Trend looks for directional continuation.
  • Range looks for mean reversion.
  • Defensive prefers to preserve capital when the evidence is weak.

Each one emits a typed thesis: its rationale, confidence, data timestamps, invalidation conditions and a bounded-loss estimate. A decision council compares the theses, and a critic goes looking for stale evidence, disagreement, liquidity problems and hidden assumptions.

Then comes the part that matters. Agent consensus can create a proposal, but it can't authorise an order. Authority belongs to one component.

The governor

The risk governor is deterministic. It checks paper mode, endpoint safety, data freshness, liquidity, buying power, bounded premium loss, conflicts, idempotency and session budgets. It fails closed: if something can't be confirmed, the answer is no.

A rejection isn't an exception to swallow. It becomes an audited NO TRADE, stored with the reasons like any other outcome. A system that can't record why it refused will, sooner or later, hide a refusal.

The same philosophy runs down to configuration. The only broker host the system accepts is Alpaca's paper endpoint, and live trading was never created. A live configuration doesn't degrade gracefully. It fails closed.

Surviving the boring failures

Trading systems rarely fail on the clever part. They fail on a timeout halfway through a submission, a restart, or two workers picking up the same job. ThesisCircuit treats those as first-class problems:

  • Durable order intents. An approval becomes an order intent in Supabase that exactly one worker can claim.
  • Reconcile before retry. If a submission times out, the system reconciles by client_order_id before it tries again, so a lost response can't turn into a duplicate order.
  • Bounded sessions. Execution sessions expire on their own and carry separate budgets for opening, closing and total orders.
  • Conservative accounting. An order in an UNKNOWN state still consumes budget, and terminal outcomes force the execution flags off.

Shadow records, clearly labelled

Rejected but well-formed proposals are kept as shadow records. They're never shown as broker activity. A documented rule marks each one against later quotes without letting duplicate cycles inflate the sample.

We're explicit about the limits. Historical options paths and exact-horizon quote retrieval aren't implemented, so the shadow analysis is not a backtest, and we don't present it as one.

One paper-account proof, then stop

On 2 September 2026 the full pipeline placed a single, deliberately small order in the dedicated paper account: one SPY call contract, a DAY limit order, filled at the limit or better. No second or closing order was submitted. Production now rests with execution and autonomous trading disabled. Bounded autonomous activation was verified synthetically with zero broker calls.

The final validation suite had 256 backend tests passing, plus Ruff, a frontend typecheck, a production build and a paper-safety audit. The backend is FastAPI on the official alpaca-py SDK, hosted on Railway, and the dashboard is a Next.js app on Vercel.

What generalises

You can swap "order" for "quote", "stock allocation" or "dispatch" and the design still holds:

  1. Let agents argue, and make them argue in typed, timestamped structures.
  2. Give one deterministic component the authority, and make it fail closed.
  3. Treat "no" as a result with reasons, not an error.
  4. Assume the network will lie to you about whether something happened, and reconcile before you retry.

It's the same pattern as the human approval step in QuotePilot AI and the protected reserve in NeighborOps AI. In those two the final authority is a person. Here it's a set of rules people wrote in advance. I wrote more about that pattern in Human approval is an architecture decision. The AI agents and Python skill pages list the related builds, and Teqprotech's AI agents with human approval service is the client-facing side of the same approach. If you're designing an agent of your own, the free human-approval architecture checklist turns these rules into checks you can run.

Work like this runs through Teqprotech · Python, Scraping & Data Automation , AI Agents with Human Approval , API & CRM Integrations

The build

Projects in this post

  • Hackathon · 2026

    NeighborOps AI

    An operations dashboard for community pantries: a Strands agent handles routine coordination through narrow tools, and people decide how scarce resources are used.

  • Hackathon · 2026

    ThesisCircuit

    Paper-only options research agents: three strategies compete, a critic objects, and a fail-closed risk governor has the final say. NO TRADE is a first-class, audited result.

  • Hackathon · 2026

    QuotePilot AI

    An autopilot quoting agent for service businesses: Qwen reads the request, deterministic tools own price and availability, and a human approves before anything is sent.

More writing

Keep reading

  • Article

    Human approval is an architecture decision, not a UX checkbox

    Four agent builds, one lesson: an approval step only protects anything if the system is shaped around it. Where authority lives, what the model can touch, and what happens when someone says no.

  • Article

    Let the model reason, not promise: building QuotePilot AI

    QuotePilot AI splits flexible AI reasoning from business-critical commitments. Qwen structures the request, deterministic tools compute price and availability, and nothing reaches a customer without human approval.

  • Blog

    What LockSmith checks before a migration ships

    A migration can look harmless in a diff and still freeze production. Here's what LockSmith looks for, how it proves the lock in a real Postgres engine, and what it deliberately doesn't claim.