Design to production via agentic workflows
A complex, custom Claude workflow to build production software from design and documentation
Project Date: September 2026
Team
Self
Role
Founder
Platform
Web
Outcome
Cross-platform web platform
Setup
Ontrack is tool I've wanted developed for a long time, you can read about my thought process here. The goal was to let an AI agent do most of the end-to-end production without giving it authority over anything that matters. Three ideas carry the whole workflow.
AI is a tool for output. AI should work off human decisions and thought processes. It mustn't come up with it's own ideas about how to handle something and run off explicit instructions.
The repo is the memory. Chat sessions are disposable, so new sessions are always driven off briefs, decision records, specs and review reports in
docs/to carry the context between them.The thing that writes code holds nothing worth stealing. The agent works in an isolated machine with no GitHub login and no production secrets.
Workloop
Every unit of work follows the same loop, defined in docs/workflow.md. Figma is the source of truth for design, so the loop starts there. Claude never writes to Figma, so if design looks wrong, Claude proposes a note and the owner changes Figma.

Orange steps are agent work, blue are human driven work, green is the one step that changes
main.
What a proposal contains
A plan is a briefing, not a step list, stating what is proposed and why, the relevant context, how it works in plain terms, the options considered and what the owner (me) needs to answer. The same rule covers docs changes, new dependencies and system changes - Approval is always first, then the action.
Piece by piece
The agent builds one component, screen or flow per approved unit and is told not to scaffold the whole app in one pass. Where Figma is silent, Claude has permission to interpret its own UI/UX and logs it in an interpretation register, each marked Figma-sourced or interpreted and to be replaced when design catches up.
Context & Design
Sessions get cut off and restarted, so a session must be able to start cold from a few small reads. The docs are layered so the agent loads only what it needs. This helps keep context low per session to prevent hallucinations and excess token spend. Although auto-compact is a feature in Claude, I preferred to keep things systematic.

Artifact | Holds | Scale in this project (as of writing) |
|---|---|---|
Task brief | Goal, acceptance, state, one handoff note (overwritten, never appended) | 40+ briefs, finished ones moved to |
Decision log | Dated decisions that override the product doc | 67 entries |
ADRs | Stack, persistence, boundaries, sync protocol, hosting, Go layout, secretless dev | 7 records |
Figma specs | Each frame distilled once, so later sessions do not refetch Figma | 8 spec files |
Review reports | Blind-review findings and how each ended | 18 reports |
Release notes | Commit, image digest, migrations, checks per release | 2 so far |
Docs are version-controlled and “living”: any task may amend them as part of its work, with the owner’s review. The source product doc and the archive are never rewritten. Changes go in the decision log instead.
Design to code
Figma holds the design and the agent reads it through the Figma MCP server. The rule is that code is never written from memory of a design.

How it worked in practice
Tokens are generated. A snapshot of Figma’s colour variables and text styles is turned into CSS custom properties named after the Figma variable.
Specs record the drift. The task-row spec splits “Figma-sourced” from “Interpreted” and ends with a table of drifts between Figma and the code. Each row says what the code does, what Figma says and the action: follow Figma, keep (user instruction) or propose a Figma note.
Deliberate deviations are named. Live testing found the Figma type scale “too cramped and zoomed in”. Rather than editing generated tokens, we added a separate density layer that overrides them, with the Figma values kept as fallbacks. A proposed Figma note exists now to adopt it or replace it with another system.
Worktrees
Branch policy
main only ever holds approved work. Each task gets one short-lived branch named <type>/<T-NNN>-<slug> and there is no long-lived dev branch because the team is one person. A tracked pre-commit hook blocks direct commits to main except for docs.
Parallel work with worktrees
A worktree is a second working copy of the repo on its own branch. It let several agent sessions work at once without touching each other’s files. Each brief declares which files it owns, and no two open briefs may own the same file. Shared interfaces (domain types, tokens, store API) get their own brief and merge first. Docs are edited in the main checkout only, so worktrees carry code.
Blind Opinion
An author reviewing its own work shares its own blind spots. I added a second check before I'm briefed on anything significant like new modules, shared interfaces, the domain, any sync or backend code, and any sensitive path.
Examples of what it caught
The Account page (password sign-in, JSON import and export) took three blind rounds.
Round 1 found that “Replace” could destroy data account-wide if the backup download was dismissed, and that the sign-in form revealed whether an email had an account.
Round 2 found an IndexedDB upgrade that hung while an older tab was open, and a restore copy that was not tied to an account.
Round 3 approved with only low findings, each written down.
Known limit. Same-model reviewers share blind spots. The workflow allows a different model for risky work on request, and /code-review ultra exists as a separate cloud review the owner triggers.
Model use is also a decision - stronger models for backend, sync, auth, deployment and review, lighter models for UI, specs and mechanical work.

Security
An agent runs shell commands, installs packages and edits any file. If something it reads tricks it, it can do whatever it is allowed to do.
The design limits what it is allowed to do. Agent-accessible identities and environments cannot read production credentials, change who can read them, or deploy code into a workload that holds them.
Safety nets, each with a stated limit
Net | Catches | Does not catch |
|---|---|---|
Agent permission rules in user settings (not the repo) | Reads of | Anything not blocked by name. A fence, not a wall |
gitleaks on commit, in CI and on the Mac | Keys, passwords, connection strings in new commits | Secrets that don’t look like secrets |
Bundle check |
| Secrets in the server image |
Environment rule (Go) | Settings read outside the one reviewed config package | Misconfigured values that pass the checks |
| Keys, dumps, | Files outside the ignore list |
Sensitive-path list + CODEOWNERS | Forces human review of CI, Dockerfiles, | Not enforced by GitHub on this plan; the owner is the enforcement |
Dependency scripts blocked ( | Install-time code from packages | Malicious code that runs at build or test time |
Proving it works
Accepted limits, stated plainly. The machine has open outbound internet, so a tricked agent could send source code out (no secrets are inside). All OrbStack machines share one Linux kernel. Page JavaScript from the machine’s app runs in the Mac’s browser, reduced by using a separate browser profile. One early test showed that connecting the desktop app to the machine brought the owner’s login, connectors and browser tools with it, so that route was rejected and the CLI inside the machine is used instead.
Result
The current build is open at https://ontrack.gestaltapps.com. Although currently a closed-off build, local use does work but account creation is blocked until UI flows are implemented and security tests are finalised with regards to general practices including input validation or rate limiting.
Dilan Omer © 2026. I had no idea what to include in the footer


