Building With Claude Code ยท How it works
7 min readHow it works
What agentic AI-assisted development means here
"Agentic" means the AI is not a chat box that returns text. It is an agent with tools. In this project Claude Code can:
whether a capability already exists.
agent and collect the result.
- Read and write files in the repository.
- Run commands (builds, tests, scripts) and read their output.
- Search the codebase to find where something lives, how a pattern is used, or
- Orchestrate sub-agents โ delegate a focused piece of work to a more specialized
The practical consequence is that a single instruction like "add this endpoint and make sure everything still passes" turns into a multi-step plan: write the code, run the checks, read the failures, fix them, re-run, and report. The agent closes the loop itself instead of handing back a snippet and stopping.
The honest framing matters: AI accelerates implementation, review, and testing. It does not replace judgment. The architecture decisions, the product direction, and the final approval stay human. What the tooling buys you is speed with a safety net, not autonomy without one.
The specialized subagents
Rather than one general agent doing everything, the workflow uses multiple specialized subagents, each with a focused role and its own domain. Narrow scope keeps each agent's context relevant and its output easier to verify.
| Agent | Role | Returns |
|---|---|---|
frontend-dev | React Native / Expo Web UI: components, styling, frontend unit tests | code + tests |
backend-dev | C# API endpoints, EF Core schemas and migrations, backend unit tests | code + tests |
regression-tester | Playwright E2E tests, regression runs, test maintenance | test results |
quality-gate | Runs lint, dead-code (YAGNI) checks, and unit tests | GATE_PASSED / GATE_FAILED |
code-reviewer | Standards-compliance review of the change | REVIEW_PASSED / REVIEW_FAILED |
chief-architect | System design and multi-agent coordination | a plan / decisions |
visual-qa | Visual QA of UI in a real Chrome browser | findings + screenshots |
tilt-ops | Tilt operations: restart services, read logs, diagnose failures | diagnosis / status |
A few things to notice about this table:
don't write features โ they return a clear binary verdict (_PASSED / _FAILED). That makes their output trivial to aggregate and act on programmatically.
UI; quality-gate, code-reviewer, and visual-qa independently check it. Keeping authoring and judging in separate roles reduces the "I wrote it so it's fine" bias.
services and reading logs is a distinct skill from writing code, and you don't want a feature agent improvising infrastructure changes.
- Two of the agents are pure gatekeepers.
quality-gateandcode-reviewer - The implementer and the verifier are different agents.
frontend-devwrites the - Operational concerns are their own agent.
tilt-opsexists because restarting
The full development lifecycle pipeline
After any code change, a mandatory lifecycle runs. It is non-negotiable: a change is not "done" until the pipeline produces a passing report.
Implementation
|
v
+-----------------------------------------+
| PARALLEL (one of each per affected |
| domain โ frontend / backend / E2E) |
| |
| quality-gate code-reviewer |
| (lint + YAGNI (standards |
| + unit tests) compliance) |
+-----------------------------------------+
|
v
UI or API changed? --- no ---> skip the next two
|
yes
v
visual-qa (real Chrome browser)
|
v
regression-tester (Playwright E2E)
|
v
+-----------------------------------------+
| Aggregated report: |
| LIFECYCLE_PASSED / LIFECYCLE_FAILED |
+-----------------------------------------+
|
any check FAILED? -- yes --> route back to the
responsible agent,
fix, re-run ONLY the
failed check
|
no
v
Done
Reading the diagram:
the code.
Lint, dead-code checks, and unit tests on one side; standards-compliance review on the other.
real Chrome browser and looks at them.
Playwright E2E suites.
- Implementation โ a feature agent (e.g.
frontend-devorbackend-dev) writes quality-gate+code-reviewerrun in parallel, one pair per affected domain.visual-qaruns only if UI or API changed โ it loads the affected pages in aregression-testerruns only if UI or API changed โ it runs the relevant- An aggregated report comes back as
LIFECYCLE_PASSEDorLIFECYCLE_FAILED.
The failure rule is what makes this efficient instead of bureaucratic: any failed check routes back to the responsible agent, gets fixed, and only the failed check re-runs. You don't re-run the whole pipeline because the linter found one issue.
There is one more rule that shapes the culture: fix ALL issues found, including pre-existing ones. If the linter, the tests, or the reviewer surface a problem that your change didn't introduce, you still fix it. The standing instruction is to leave the codebase cleaner than you found it. This stops the slow rot where "not my bug" accumulates into an unmaintainable mess.
Parallel delegation by domain
When a task spans multiple domains โ say it touches frontend, backend, and E2E โ the independent work streams are launched in parallel, in a single message, and their results are aggregated into one pass/fail report.
The decision rule is simple: prefer parallel over sequential whenever the streams are independent. A backend migration and a frontend component usually don't depend on each other to start, so there's no reason to do them one after another.
The same logic applies to the gatekeepers: quality-gate and code-reviewer are split by domain. If a change touches both the C# service and the React UI, you run a frontend quality-gate and a backend quality-gate (and likewise two code-reviewer passes) at the same time, rather than one giant serial review.
Why this matters:
not the sum of all three.
context stays relevant and its verdict is easier to trust.
parallel results into one LIFECYCLE_PASSED / LIFECYCLE_FAILED is mechanical.
- Latency. Three agents working at once finish in roughly the time of the slowest,
- Focus. A domain-scoped agent only has to reason about its own area, so its
- Clean aggregation. Because each agent returns a binary verdict, combining N
The one thing parallelism requires is honesty about dependencies. If stream B genuinely needs stream A's output (e.g. the frontend needs the new endpoint's shape), you sequence those two โ but you still parallelize everything that is independent.
The Tilt MCP feedback loop
This is the part that keeps the whole system grounded. All verification โ lint, unit tests, builds, security audits, and E2E โ is run through Tilt MCP tools, never as raw npm run lint or dotnet test invocations.
The loop for any check is:
trigger a Tilt resource -> wait for it to finish -> check the result
^ |
| passed? no
| |
+------------- fix the code <---- read the logs <-----+
(on failure)
Concretely: trigger the resource, wait, check the result; if it failed, read the actual logs, fix the code, and retry until it passes.
Two reasons this discipline exists:
owner can see the same pass/fail state the agent saw, in one place. The AI's "it passed" is backed by a result the human can independently look at.
watchers are Tilt-managed and shared. Agents reuse the running instances instead of spawning their own โ which previously wasted large amounts of memory. Agents never start standalone watch processes.
- Results show up in a shared UI. Running checks through Tilt means the human
- Nobody starts duplicate dev servers. All dev servers, preview servers, and test
The deeper principle: this is how the project refuses to trust AI claims. An agent can say the tests pass, but the gate is the real Tilt resource turning green, and the real logs when it doesn't.
Project memory, skills & slash commands
Three pieces of supporting machinery make the agents effective across sessions, not just within one conversation:
that survive across sessions โ what was built, what was deferred and why, known footguns, the shape of a tricky migration. A fresh agent starting a new session can read this and avoid re-discovering (or re-breaking) things.
when relevant: scaffolding a new service, running the E2E suite against an environment, triaging smoke-test reports, sending a daily report, and so on. Instead of an agent improvising a multi-step procedure, it follows the established one.
naming, accessibility, type-safety rules) live in one place so code-reviewer and every implementer share the same definition of "correct." Non-trivial work gets a task document so the intent and the changes are recorded.
finished until the roadmap reflects it. Status lives in one map rather than scattered across people's heads.
- Persistent, file-based project memory. Facts and decisions are written to files
- Skills / slash commands. These are on-demand playbooks the agent can pull in
- Centralized code standards and task documentation. Standards (size limits,
- A graphical product roadmap kept current as part of "done." A change isn't
Together these give the agents continuity. Without persistent memory and shared standards, each session would start from zero and quality would drift.
Guardrails & what stays human
Agentic does not mean unsupervised. The guardrails are deliberate:
"good enough" are human decisions.
handling credentials, DNS changes, and billing are not things an agent does on its own. These are the actions you can't take back, so a human holds the trigger.
design and the trade-offs behind it are owner decisions (with chief-architect helping structure the work, not unilaterally deciding it).
purpose: the project runs the lint, tests, build, and E2E and reads the actual results. It does not take the model's word for it.
- The human owner sets direction and approves. Product priorities and the bar for
- Irreversible or outward-facing actions are owner-gated. Deploys, sending email,
- Architecture stays human. The agent implements, reviews, and tests; the system
- AI output is always verified with real tooling. This is restated everywhere on
The shape of the boundary is consistent: AI does the reversible, verifiable work fast; humans own the irreversible, judgment-heavy decisions.