02 — Case study · Building with agents← Back to work

Agentic Engineering

How I ship production software as a team of one, by engineering the system around the AI agents instead of prompting harder.

The build
solo · 2.5 months

A production SaaS in a privacy-sensitive consumer domain: regulated user data, strict multi-tenant isolation, and real AI spend on every generation call. The interesting part is not that AI wrote code. It’s the operating system around the agents: 13 executable process commands, 3 specialized subagents, 4 lifecycle hooks, a written loop-engineering doctrine, and an audit practice that measures the machine.

480
merged PRs in ~2.5 months · ~500 opened
~6/day
merged PRs per day, average
~$160
per shipped ticket, flat even in bursts
~4×
daily-spend reduction after the July audit
~395
test files · unit / integr. / E2E / pgTAP · 83 migrations
01 The infrastructure · Production-grade, run solo

The agents ship into real production machinery, not a sandbox. Before any process doctrine, the substrate: a typed monorepo, a CI gate no PR can skip, per-branch preview deploys, and tracing on every AI call: the infrastructure a funded team would stand up, operated by one person.

Plan
Linear
Linear
Build
Claude Code
Claude Code
Gate
Actions
GitHub CI
Deploy
Vercel
Vercel
Data
Postgres
RLS everywhere
Observe
Langfuse · Sentry
Langfuse · Sentry
CI/CD pipeline

Every PR runs typecheck, lint, migration checks, and the full suite: ~395 test files across unit, integration, E2E, and pgTAP. Every branch gets its own preview deploy; green CI is a precondition, and the human merge is the only manual step between a ticket and production.

Observability

Error tracking scrubbed of end-user PII by written rule. Every AI generation call is traced with token counts and per-call cost attribution, the ledger the July audit was built on. Alerts are tuned to page a team of one, not a rotation.

Data & environments

Postgres with row-level security enabled on every table, 83 migrations in. Agents build in isolated git worktrees that never touch each other's state; scheduled jobs handle retention and purge unattended.

02 The problem · Headcount: one

One person cannot review every line, remember every decision, or babysit every CI run, and an ungoverned agent fails in predictable ways: it expands scope quietly, lets quality decay behind green-looking output, burns unbounded spend, and forgets everything between sessions.

“Move fast” and “never leak user data” had to hold at the same time, with no second engineer as a safety net.

What does an engineering organization look like when the headcount is one human and the rest is agents?

The same things that make human orgs work (definitions of ready, quality gates, review, incident writeups, retros), written as executable process, enforced by machinery rather than culture.

03 The operating system · Process as code

Every ticket enters through a single gate: /ticket AIP-XXX loads the Linear issue and applies a canonical Definition of Ready before any code is written. Every ticket gets a verdict: only Ready proceeds. The same bar is applied read-only by the autonomous loop, so tightening it once propagates everywhere.

Ready

Goal, testable ACs, out-of-scope, definition of done, no hidden decision

Thin

An AC is vague: "make it work" is not an acceptance criterion

Missing

A required section of the spec is absent

Decision-gated

The ticket hides a product or security choice an agent must never make silently

Track 1 · Custom

Custom TDD implementation: worktree, red to green

Track 2 · Superpowers

A heavier plugin-based rigor track for risky work

Track 3 · Spike

A discovery spike that ships a design doc instead of code

/ticketDefinition of ReadyTrack choiceTDD red→greenpre-PR gateReview fan-outCodex review · 2nd model, adversarialHuman merge

The endpoints are deliberately human: an agent never merges, and never invokes its own reviewer. The loop parks at the merge boundary. A post-deploy validation stage is the next planned gate.

04 Guardrails as code · Enforced, not suggested
Sensitive data

No end-user PII in error tracking or analytics. Collect the coarsest data the feature can work with, by written rule. Every deletion of user-owned data writes an audit_log row in the same request handler.

Row-level security

Every new table enables RLS with explicit policies. no-unscoped-tenant-read statically fails CI on any tenant read not provably scoped to the authenticated tenant, including request-derived values laundered through local variables. Every tenant-owned route ships a two-tenant negative test.

settings.json — Stop hookinvoluntary
"Stop": [
  { "hooks": [
    { "command":
      "$CLAUDE_PROJECT_DIR/.claude/hooks/
       typecheck-lint-stop.sh" },
    { "command":
      "$CLAUDE_PROJECT_DIR/.claude/hooks/
       codex-review-reminder-stop.sh" }
  ]}
]
Runs the full typecheck + lint + test gate before any turn may end with uncommitted changes. Failures surface before the response finalizes, not in the PR.
Fig. 1 — a Stop-hook gate failure caught and fixed in the same turn
05 Loop engineering · Find work → act → verify → remember → stop

“Run it in a loop” hides several different tools. The repo’s loop-engineering doctrine names them and matches each to a job: a recursive goal plus a find-work → act → verify → remember → stop cycle.

Loop type
What it is
Real instance in this repo
Hook
Fires on an event; involuntary
Stop-time typecheck/lint/test gate; ticket-start reminder
Heartbeat
Re-checks external state on interval
CI wake-loops (ScheduleWakeup) watching checks
Goal
Iterates until a success condition
TDD red-green; /babysit-prs (keep one PR green); /epic
Cron
Unattended schedule
Nightly data-purge job; scheduled cloud routines (opt-in, billed)
The flagship: /epic, the backlog goal-loop

Hand it a Linear parent issue: it enumerates the work, topo-sorts by dependency, pressure-tests every AC, flags duplicate or fragmented tickets, and presents one checkpoint for human approval, then executes ticket-by-ticket in background worktree agents, waking only on external state, under a hard budget: maxCostUsd, wall-clock hours, 3 attempts per obstacle, then escalate. Written boundaries: never merge, never self-invoke review, never wake-poll work the harness already tracks.

Checkpoint approvedDispatch worktree agentWake on external stateci-triage verdict
All-green

Park at merge boundary, human merges

Actionable

Dispatch fixer agent, attempt n of 3

Wait

Sleep until the next external signal

Stuck

Known failure signature, escalate to human

06 Working in parallel · Five fan-out dimensions
Independence is the gate.

Loops decide when to repeat; a second axis decides when to run concurrently: read, implement, review, multi-ticket, batch. Work fans out only when the slices share no mutable state. Plans tag each slice with its file footprint at planning time, writers get isolated git worktrees, and every fan-out ends in a verify/merge stage. N agent outputs never ship unreconciled.

Build learning — earned the hard way
Logged within a day

An early 4-way implement fan-out collided on one shared file. The lesson: test independence at the file level, not the ticket level. The /epic sequencer now checks this automatically, serializing overlapping tickets through merge.

07 Measuring the machine · 54 transcripts · 46 PRs · cost ledger

In July I audited my own agent usage: a retro where the subject is the workflow itself. Parallelism was already the norm (124 of 145 dispatches, 85%, in parallel clusters) and worktree hygiene held: 42 enters, 52 exits, no leaks. But three gaps were invisible until measured:

0/145

agent calls overrode the default (most expensive) model

Fix: cheap-model pins on every read-only agent
~30%

of PRs got the guardrails review fan-out, because it was optional

Fix: made a required pre-PR step
290

inline Linear API calls bloating the main session's context with ticket bodies it never needed again

Fix: linear-scribe (IDs, not bodies) + ci-triage (verdicts, not logs)
$1,900/day $300–500/day
~4× cost reduction · flat per-ticket cost (~$150)
The audit ends with re-measure targets and a date
08 Compounding memory · Agents forget; the system doesn't
M-01
Build learnings

Tooling gotchas and bug postmortems: symptom, root cause, and the rule to apply next time

40+ numbered entries
M-02
Incident RCAs

Dated root-cause writeups for anything prod-impacting, with a template and an index

Templated · indexed
M-03
Architecture decision log

Resolved decisions (don't relitigate) and open questions (surface, don't pick silently)

Checked every ticket
M-04
Session memory

Corrections, conventions, and traps the agent maintains across sessions, one retrievable fact each

Persistent per-project

The effect is compound interest: the same mistake is structurally hard to make twice, and every new session starts smarter than the last one ended.

09 What generalized · Five rules
01Specs are the bottleneck, not code.

Once agents write the code, ambiguous acceptance criteria become the most expensive artifact in the pipeline: "make it work" tickets fail in ways that cost hours.

02Verification is the product.

Investment order that worked: tests → static enforcement → involuntary hooks → independent review agents → a second-model adversarial reviewer.

03Treat agent spend like a budget line.

Per-session ledger, per-run budgets, model tiers matched to task risk. The single cheapest fix of the project was invisible until measured.

04Process-as-code beats process-as-culture.

A checklist in a wiki decays; a Stop hook cannot be skipped, especially at headcount 1. Everything important is enforced by machinery or scheduled to be.

05Keep humans at the irreversible edges.

Agents plan, build, review, babysit CI. Merging, product decisions, and hidden trade-offs stay human, by written rule, not by vibe.

Scale context: the product is pre-launch, with a small production cohort. Every number here measures the delivery system; market traction is a different chapter, deliberately not this one.
10 Artifact library · Deep dives from the working system
The command libraryLoop engineering, in fullThe agentic-workflow auditArtifacts & snippetsSpend, tokens & throughputThe stack — systems behind the machineThe evolution — a git archaeology
Next study — 03
AI-Forward Product Delivery
Agentic Engineering | Phillip Tularak