"End to end" gets used loosely, so let me be specific. For the systems I describe below, I go from a problem statement to running software that other processes depend on: the design, the code, the data model, the cloud resources, the tests, the deploy, the dashboards, and the incident review when it misbehaves. A coding agent does most of the typing. I do the deciding.
That split is the whole skill. Generative AI made writing code cheap. It did not make it cheap to know whether the code is right, whether it should exist, or what it is allowed to touch. Those are the parts I have had to get good at.
The short version
- Research before code. Before the agent changes anything that matters, it explains why the current behaviour exists and proposes a prioritised plan. I approve the plan, not the diff.
- Specs and repo instructions do the steering. Every project carries written instructions for agents: file maps, commands, conventions, and hard rules. Better context beats a cleverer prompt.
- Verify against reality. Tests for the code, and replays against real historical data for anything with consequences. Most ideas die there, which is the point.
- A human gate before production. The agent builds in an isolated copy; I review and I push. Restarts, deploys, and anything touching money or credentials stay with me.
What I have built this way
The largest project is my own algorithmic trading platform, built and run almost entirely with AI coding agents. It is a good test bed precisely because it is unforgiving: it runs against live market data, real broker APIs, and real money, so "it looked right in the demo" is not a standard anyone can hide behind. It includes:
- Market-data and signal services in Node.js that stream quotes, compute signals, and publish them to the strategies and dashboards that consume them.
- Broker integrations across several brokerage APIs, with authentication, order routing, and a normalised interface so strategies do not care which broker they are on.
- A serverless trading bot on AWS Lambda, with its state in MongoDB and DynamoDB, scheduled runs, and a dashboard for the person (me) who has to trust it.
- Operator dashboards for positions, performance tear sheets, and process health — read-only, kept off the trading processes so a dashboard can never move money.
- Research tooling: replays and backtests that run a proposed rule against historical data before it goes anywhere near a live account, plus written post-mortems after anything goes wrong.
Smaller, but just as end to end: this site (plain HTML, CSS, and JavaScript, deployed by GitHub Actions on every push), and a role-based access control lab built on Microsoft Entra ID — a sign-in page, an Express API that validates access tokens and enforces per-route permissions from app roles, a DynamoDB table behind it, and API tests that exercise each role.
The loop
Every change, from a one-line fix to a new service, goes through the same six steps. Small changes go through them in minutes. The steps are what let me move fast without the agent's speed turning into my risk.
- Research before code. The first request is never "change X." It is "explain why X behaves the way it does today, what depends on it, and what you would change, in priority order." Half the time the existing behaviour has a reason nobody wrote down, and the agent finds it in the code or the history. I approve or redirect the plan before a line changes.
- Specify. I write the task so an agent can take it end to end: the outcome, the constraints, what not to touch, and how we will know it worked. The scarce skill in AI-assisted engineering is writing a task precisely — I made that point about the labs in the September note, and it holds at the scale of one engineer too.
- Give the agent the right context. Each repository carries instruction files for agents: a map of where things live, the commands that build and test it, configuration conventions, deployment notes, and the rules that must not be broken. I also keep short, dated notes on decisions and incidents so the next session starts from what we learned, not from zero. This is context engineering applied to my own codebase.
- Build in isolation. The agent works in a separate git worktree or branch, never in the checkout that live processes run from. If the work is wrong, I throw the copy away and nothing running notices.
- Verify against reality. Syntax checks and unit tests are the floor. For anything with consequences, the change is replayed against real historical data and compared with the current behaviour. I have shelved far more strategy ideas than I have shipped because the replay said no — and a replay that says no is the system working.
- Ship through a human gate, then operate. I read the diff, I push, and I restart processes. After it is live I watch the first real runs, and when something breaks the agent helps me write a post-mortem: what happened, the evidence, the fix, and the rule we are adding so it does not happen again.
The guardrails
Speed without limits is how an agent turns a small mistake into a large one. These are the rules I have written into my projects, most of them learned the hard way.
- Hard caps on autonomous loops. Any recurring agent job has a maximum number of runs, a stop time, a pause switch, quiet hours, and an explicit trigger. No open-ended "keep going until done."
- Authority is written down. Which actions the agent may take freely (read, search, run tests), which need my approval (deploys, restarts, schema changes), and which are off-limits (moving money, sharing credentials). This is the human-in-the-loop design I write about, applied to my own work.
- Secrets never enter a repository. Credentials live in an encrypted vault or a locked-down file outside every repo. The agent can use them to do a job; it never copies them into code, notes, or chat.
- Production timing is a rule, not a judgement call. Early on, a database index build I approved during market hours exhausted the memory of a small database host and took it offline until it was restored. The rule since then: no heavy database work on production hosts while the market is open. One incident, one written rule, never repeated.
What it changes about the job
The honest summary is that I write less code than I used to and make more decisions per day. Three things moved to the centre of the work:
- Specification. A vague task produces confident, plausible, wrong code. A precise one produces something I can review in minutes.
- Review. Reading a diff for intent — does this do what we agreed, and nothing else — is now the highest-leverage hour of my day.
- Evidence. When building is cheap, the expensive question is "does it actually work." Tests, replays, and evals are how I answer it without trusting my own enthusiasm.
What did not change: the systems still have to be understandable by the next person who opens them. Every repo I build this way has a README and instruction files written for both humans and agents, because in practice they need the same things.
The stack
- Agents: Claude Code as the primary coding agent, with MCP servers for connected tools and data.
- Languages and runtime: JavaScript and Node.js for services, process management with pm2, plain HTML/CSS/JS for front ends.
- Cloud and data: AWS Lambda and DynamoDB, MongoDB, a VPS behind a tunnel for long-running services.
- Delivery: git worktrees, GitHub, GitHub Actions deploys.
- Identity: Microsoft Entra ID app roles and token validation for access control.
If your team is figuring out how to use coding agents without losing control of what ships, that is the conversation I most enjoy having. Email me — I am happy to walk through any of this in detail.