← Selected work
Case study · AI product

A data-governed agent platform for trading analysis — built solo.

Seven classes of market and research data, a governed ingestion pipeline, and AI agents that run under hard workspace isolation — not prompt hope. Here is the architecture and the decisions behind it.

Architecture

FastAPI + isolated agent runtime + multi-source data plane

The hard part

Data governance + agent memory/isolation that actually hold

Proof

76 isolation tests · internal load audit · owned upstream patches

What & Why

Not a chatbot bolted onto charts — a governed research system.

Most “AI trading tools” fail in the same two places: the data layer is a mess of ad-hoc scrapes, and the agent layer is a prompt with tools and no hard boundary.

This workstation was built to prove a different claim: one AI-native engineer can ship a production-shaped system where data is governed and agents are controlled — long-running research, tool use, persistent memory, multi-provider routing — with isolation enforced before tools run, not after the model “tries to be careful.”

Constraint that shaped everything: financial-session data must not leave the system for third-party “memory clouds,” and multi-user agent workspaces cannot trust prompts as a security boundary.

System design

One host, two runtimes, seven data classes.

The public path is a React SPA behind a reverse proxy. The application plane is a FastAPI backend (50+ route modules, 380+ endpoints). The agent plane is an open-source Craft agent runtime, containerized and bound to localhost only, reverse-proxied for the product UI. Redis is a degradable cache. Market and research data live in a multi-database local plane — not one giant table for everything.

Architecture topology
User browser
↓ HTTPS
Edge — CDN / tunnel / TLS
Nginx — static SPA + API reverse proxy + agent reverse proxy
↓ splits to app plane + agent plane
FastAPI app plane
50+ routers · 380+ endpoints · auth · jobs · insight APIs
Craft agent runtime
localhost-only · tools · long-running research · PreToolUse intercepts
Redis — degradable cache
Local data plane
domain-separated SQLite · scheduled + on-demand pipelines · FTS-first RAG index
Data sources (category layer): historical pipeline · realtime primary/backup · broker/desktop upload · secondary feed · research/news proxies · webhook news · agent callbacks

Application plane and agent plane are deliberately split. Agents do not get ambient access to the whole machine or every user’s files.

Front-end and agents read through read-only aggregated insight APIs — not raw table dumps.
One domain, one store — separation over convenience.
Jobs are config-driven, with persisted run records and retry.
Fallback data is labeled; historical dates are never silently backfilled as live.
Trade-offs

Four decisions, with the reasoning and the cost made explicit.

Decision 1

Build an owned agent-memory gateway after surveying open source

Problem

Agents need durable memory across sessions. Hosted memory products optimize for cloud APIs and cross-app profiles. In a financial research context, shipping user sessions to an external memory cloud is the wrong default.

Options

Hosted memory API · Embed a full stateful-agent platform · Local gateway first, storage swappable later

Choice

Surveyed leading open-source memory systems (Mem0, Letta, Graphiti, and peers), then built an owned Agent Memory Gateway on local SQLite + FTS5 — workspace isolation, owner re-check, actor audit, needs_review for model-inferred conclusions.

Cost

Memory accumulates more slowly than “store everything the model said.” Auditability beats volume.

Evidence: owned memory research notes · agent memory storage module
Decision 2

Workspace isolation: shared → per-user → PreToolUse hard intercept

Problem

Once agents can read files and run tools, multi-user isolation is not a UI concern. A model that “usually respects” another user’s path is still a breach waiting to happen.

Options

Front-end filtering · Prompt the model · Framework permission modes · Hard intercept before tool execution

Choice

Evolve isolation in stages, ending in a PreToolUse hard intercept in the agent core. Prompts are not a security boundary.

Cost

We maintain an upstream agent-runtime fork. Every upgrade has to re-prove the hard boundary still exists.

Result

76 isolation tests passing, plus dual-account acceptance checks covering path traversal and cross-user session reads.

Evidence: isolation design notes · PreToolUse intercept · isolation test suite
Decision 3

Treat the open-source agent runtime as a disciplined fork

Problem

The product needs agent capabilities that move faster than waiting for every isolation fix upstream. A naïve vendor drop-in either blocks the product or silently loses local security patches on upgrade.

Options

Stock upstream only · Soft fork with undocumented edits · Soft fork with patch registry + merge discipline

Choice

Base the agent plane on the open-source Craft framework, with owned patches for multi-user isolation, credential refresh, and product defaults. Upgrade path v0.9.2 → v0.10.3 via three-way merge — not copy-overwrite.

Cost

Upgrade tax. Every upstream bump is an audit, not a git pull. Ten tracked local patches in the current register.

Evidence: patch registry · three-way merge upgrade notes
Decision 4

Govern the data plane before “smarter prompts”

Problem

Agents and dashboards are only as trustworthy as the data underneath. Without pipeline discipline, the UI silently mixes live, delayed, and backfilled history — and the agent narrates it confidently.

System rules

Seven source classes · 25-stage historical enrichment pipeline · aggregated insight APIs · persisted job runs + retry · explicit stale/fallback labels

Choice

Multi-provider LLM routing with staged fallback; long-running task state re-derived from messages + watchdog; deep research degrades to “data gap” instead of fabricating.

Cost

More moving parts than a single ETL script and a chat box. The payoff: agents reason over a system you can audit.

Evidence: data pipeline guide · deployment topology · agent / monitoring design docs
Code & proof

Breadth with controls — not demo theater.

Artifact A — Isolation as an engineering object

Isolation is not a paragraph in a system prompt. It is a PreToolUse intercept in the agent core, a dedicated isolation test suite (76 pass), and dual-account acceptance for cross-workspace reads.

If a tool can read a path, the boundary must run before the tool runs.

Artifact B — Performance as a product surface

Internal measured page-load audit on the default AI entry path (same methodology, before / after):

PathBeforeAfter
Home redirect into the AI workspace10.36s0.55s
AI workspace route~9.4s~0.59s
Login~2.6s~0.55–0.57s

Lab audit on product routes — not a third-party benchmark, not a claim about market alpha.

By the numbers
  • · 50+ API route modules · 380+ endpoints
  • · 10 owned patches on the agent runtime fork · upgrade v0.9.2 → v0.10.3
  • · 76 isolation tests
  • · 25-stage historical data pipeline · 7 data source classes
  • · First-screen path 10.36s → 0.55s (internal measured)

Stack: React + TypeScript + Vite · Python + FastAPI · Redis · multi-provider LLM routing · open-source Craft agent runtime + owned patches · FTS/RAG

The takeaway

Production AI is a data + control problem.

The interesting work was not “call an LLM.” It was governing multi-source data so agents have something true to stand on — then forcing memory, tools, and workspaces into boundaries that still hold when the model is wrong.

If you need AI agents inside a real product — long-running work, tool use, persistent memory, multi-provider routing, realtime and batch data under one roof — this is that class of system, built end to end by one AI-native engineer.