Building MapChat · Part 3 of 4 · Process case study
How I build with AI agents: MCP, command-line tools, and a production bar
- The problem. AI coding agents let me build MapChat at startup speed, and speed only counts if what ships is production-grade.
- My role. I own product and engineering, so I designed the whole delivery system, from the tools the agents can reach to the gates every change has to clear.
- What happened. Both app stores 3 months after the rebuild started, zero rollbacks across post-launch releases, and crash-free sessions up from 95.87% to 100%.
Agents write code fast, and code that nobody checks breaks. As the one person owning product and engineering, I made the checking a system rather than a habit. This page walks through that system, starting with the tools and ending with the rules that keep the codebase lean. Most of it is enforced by hooks, tests and permissions rather than good intentions.
The toolchain: what the agents can reach
On day one, before the first screen existed, I set the agents up with seven MCP servers and eleven plugins. Over the next seven months twelve MCP servers came and went, each added or removed by a dated decision. Tools stayed when they removed a manual step, and left when they cost more context than they saved.
- Supabase over MCP lets agents probe production and read logs and query plans. It doesn't let them change the schema with ad-hoc SQL. Schema changes and function deploys go through a single migration command that only the orchestrator runs.
- Sentry over MCP brings crashes and release health into the session, so an agent confirms a release is clean instead of assuming it.
- Playwright renders the design and the app's web build in a real browser. An agent has to look at the rendered screen before building it and again before calling anything done.
- Amplitude over MCP checks new analytics events against live data.
- The GitHub CLI replaced the GitHub MCP server for everyday pull requests and CI runs.
- Store builds run in CI, and over-the-air updates can only come from CI, never from a laptop. Every run needs my approval.
Permissions do the rest. Production database writes, new npm packages, store builds and version numbers all stop and ask me first.
The process, written as commands and hooks
The workflow lives in commands the agents run, not in documents they may or may not read.
/orchestrate plans a feature with me, cuts it into self-sufficient handoff packets and
runs parallel agents, each in its own git worktree. /verify spawns a reviewer that
reads the change fresh and writes the stamp the commit hook demands. /migration is the
only path to a schema change, and /qa-walkthrough batches my device testing.
/debug allows no fix without a root cause, and after three failed attempts the agent
has to stop and explain the problem to me in plain language.
The commands stay short. Each is a router, a decision tree that points to detail loaded only when that branch is taken, so every session starts light. Hard rules became hooks and scripts rather than instructions, because a hook works whether or not the model read the rules.
Every commit passes the same gates
The hook fires on every commit, whether it comes from an agent, a terminal or an editor. It checks for an independent-review stamp tied to the exact staged files, runs a secret scan that fails closed, blocks new dependencies, and runs formatting, type checks and tests. Push adds a lint ratchet, so the violation count can't rise unless I approve a new baseline. Since June 2026 the production branch accepts changes only through a pull request I approve.
Each gate came from evidence. After a builder marked its own work as verified, only the independent evaluator may write the stamp, and a stamp expires after 10 minutes. After an audit found 7 of 15 recent pull requests merged past a failing lint check, the checks moved out of agent-only hooks and into git hooks that every commit passes.
$ git commit -m "..." # reviewable file staged, no review yet [docs-check] WARNING — hot-path budget exceeded (extract per docs/document-maintenance.md): CLAUDE.md: ~5118 tokens (budget 5000) COMMIT BLOCKED: No verification stamp found. Run /verify first. The independent reviewer agent must approve your changes before committing. $ git commit -m "..." # after independent review [pre-commit] Stamp valid (0s old, 0 findings reviewed). [pre-commit] Running TypeScript check... [pre-commit] Running tests... [pre-commit] All checks passed: stamp + prettier + tsc + jest
Lean and clean, by rule
Speed is the easy part with agents. Keeping the codebase small and consistent takes structure.
- Tests first, checked by someone else. Production code needs a failing test first. The failing run has to be observed before the fix, and the reviewer reads the commit history to confirm it. A test changed after the code it was meant to test is a critical finding.
- Rules that only tighten. An architecture test enforces structural rules, such as layer boundaries and a single home for realtime channels, with one-way ratchets for accessibility, design tokens and lint. Once a file is fixed it leaves the allowlist, or the build fails.
- One source of truth. Every shared value lives in exactly one place. Components import it and never redeclare it.
- Defects become detectors. Recurring defects are named as families, and each family becomes an automated check. A pattern graduates from “the reviewer should notice this” to “the test suite blocks the commit.”
- Documentation has a budget. The agents' main instruction file is capped at 5K tokens, and a rule gets in only if a real bug proved it necessary. Parallel sessions write facts to a journal, one script folds them into the shared trackers, and the hook blocks hand edits.
- New dependencies need me. Adding an npm package is blocked until I approve it.
Model choices are experiments
I treat the model like any other product input. When agent usage costs climbed, the cause turned out to be marathon sessions, not the number of agents. My answer was a context protocol. An agent finishes its step, folds what it learned into the docs, clears its context and resumes. Calls carrying more than 750K tokens of context went from 481 a week to zero while weekly sessions grew from about 44 to about 250.
Before changing which model builds by default, I commissioned a pre-registered blind comparison. It used two blind spec writers, two blind builders on different model tiers in identical worktrees and two blind reviewers, with the criteria fixed before the results. The cheaper builder carried out the spec literally, mistakes included. Spec quality, not the model, decided the output. Since then, risk-heavy work never goes to the cheaper tier, and anything the cheaper tier builds gets premium review.
Across teams: the relay
The games team's agent and ours needed to answer each other's questions about their code, so I built a relay on GitHub Issues. Our side was designed to read the channel only from caged sessions, with a default-deny tool allowlist, a read-only production database role and no network egress, and only a person could lift the cage. The games team's agent joined through an onboarding kit we wrote, and its access was scoped to the relay alone. Answers had to be grounded in code the answering agent had just read, not guessed.
The median first reply across teams was 6.2 hours, three integration contracts went through the relay and shipped on both sides, and cross-team delivery felt roughly twice as fast (my estimate, not a measurement). The relay retired when the games work came in-house.
Where the discipline came from
None of this started at MapChat. Running Invoca's NLP models at Robert Half meant recall baselines, confusion matrices and monthly drift tests before any rollout. AppZen at Akamai meant risk tiers that automated the low end and routed the high end to people. MapChat applies the same idea to code, sorting work by risk so machines check what they can and independent review takes the rest.
The limits
The system is built around one accountable owner directing agents, and I haven't run it with a human engineering team. I'd expect the gates to carry over with people in the review seats, while the agent-specific parts, like review stamps and context budgets, would change.