Blink Build's Software Factory

We've open-sourced the complete agentic development workflow powering Blink Build Studios. From product requirements to production deployments, this post walks through the architecture, tooling, and lessons learned from building a software factory instead of just another coding assistant.

Share
Blink Build's Software Factory
Our agentic development workflow has 25x'ed our output in the last 4 months

We intentionally keep things lean here at Blink Build Studios. The pressure of having to find ways to be more effective with AI forces us to be better practitioners. That practice turns us into better experts, which means we better serve our clients and our own product ambitions. It’s why we can better serve you than most of our competition.

We’re currently leading engineering efforts across five distinct startups, including our own, as a team of three. We’ve additionally brought a product to market on the inside of four months. This speed is due in no small part to our agentic development workflow (ADW). It’s been a long sequence of bumped heads and hard learnings to get here, and in talking to our industry friends many of them are on different stages of their own version of this journey. Thus we’ve decided to open source our workflow and share our story in the hopes that we can help others go faster.

We make no claim to our approach being the “right” way; we know only that it works quite well for us.

TL;DR

This is a long one, so for the hungriest in the audience, let’s start with the red meat. To illustrate the speed-up, here are the commit additions and deletions across our managed repositories over the last 12 months:

Commits per week over the last 12 months

And here is the same trend reflected in lines of code:

Lines of code changed per week over the last 12 months

Note that these stats are strictly from me, and prior to starting Blink Build on 04/01/2026 I was the CTO of a small A16Z-backed AI matchmaking platform (ie: writing a lot of code for my role). They don’t even include the rest of the team. The net outcome? Engineering is no longer our primary bottleneck. Instead, we’re bottlenecked by the deeper question: “What are we building, and why?”

Our setup costs are straightforward:

  • Mac Mini - ~$800/client (one-time cost)
  • Claude Max subscription - $200/mo/client
  • GitHub Actions minutes - ~$80/mo/client

Total outlay per client: an $800 up-front cost and ~$280/mo recurring. That’s effectively an entire engineering team for an annualized cost of just over $4,000.

Our entire ADW is packaged in this repository, which includes:

To put it all to use, run Claude (or your coding agent of choice) in the repository where you want to adopt the pattern and point it at the implementation guide.

If there are any improvements you make or things you want to see changed, please submit a pull request! We’re pretty opinionated in the repo (Claude, Python, Makefile, GitHub actions, etc) and broadening the use cases and documentation to support other options would be lovely.

We've scaled all of our clients Engineering functions with this framework. If you want help setting this up yourself or want to learn more book a call with us here.

The Journey

A mentor once told me that "engineers are skeptics by default," and that resonates. In an industry where the AI noise floor is deafening, identifying true signal is expensive. I’m sharing the journey that brought us to our current ADW in the hopes that it grounds the outcome in the "whys" that powered it.

Over the course of the last seven months we have gone through a process of:

  1. Observe the limitations of our current approach
  2. Iterate on the ADW to solve the immediate bottleneck
  3. Achieve material productivity gains
  4. Inevitably hit the next limitation

…more times than I would like to admit.

Today, we’ve reached a point where engineering is no longer our primary constraint. Whether for our clients or ourselves, the bottleneck has shifted from "how do we build this?" to the much deeper question: "what should we be building and why?"

What follows is the sequence of steps that have brought us to where we are today in the hopes that I can convert you from a skeptic to a believer.

Step 0 - Resistance

Getting started was the hardest part.

Dan Guido of Trail of Bits fame recently gave a talk at Unprompted detailing the barriers to AI adoption in cyber security. He highlighted a blocker I’ve rarely heard anyone else admit, but one that hit me with total clarity:

A barrier to AI adoption in the security industry, from Dan Guido

He’s right. That ego is exactly what I had to wrestle with.

I have been messing around with software since I was 12 years old (here’s looking at you, Starcraft 1 map editor). I have historically taken deep pride and enjoyment in the craft of writing software that scales, is easy to maintain, and is elegant in its solution. It’s an art, backed by science.

Heavy AI adoption effectively kills that art. In order to really put this wave of technology to use you must graduate from engineer to engineering manager (if not head of product) which is a completely different skillset that scratches a completely different (or, for many, nonexistent) itch.

A good amount of my identity and self-worth is derived from how good I am as an engineer, and the commoditization of my technological skills has been a tough pill to swallow. On the one hand, if I measure my success as an engineer by how many problems I solve, I am many times better as an engineer today than I was 12 months ago. On the other hand, if my measuring stick is how competitive I can be based on my technology knowledge then I am far less distinguished compared to my past self.

I still feel conflicted. I miss the days where I could bury myself in a code problem for a day, come up with a solution that most other engineers could not, and be compensated accordingly. I have started doing ceramics again to take up some of the creative slack that this new AI world has left in my life. At the same time, I look at how much I have enabled my company and my company’s clients in the four months since our inception and feel a different kind of satisfaction.

Whether I like it or not, the world has changed. I can either adapt to it, or I can choose to find a new profession. I love what I do and the process of building too much to do anything else, and so I embrace.

If you’re currently stuck in this stage, you have the same decision to make. My vote is that you embrace too. The good news is that once you get past this stage, things speed up quickly.

Step 1 - Building Locally, Regularly Interrupted

The first step was simple: open a terminal, run Claude Code, and start dictating. (I use Wispr Flow, and if you’re not using it or a competitor, you really should.) Claude would work for a while, but any meaningful tool use or OS interaction required me to manually approve it.

It was impressive - code was actually getting written. I even added a notification sound so that whenever Claude needed approval, a chime would play. I’d be off doing other things until that chime beckoned me back like a trained dog. I’d glance at the terminal, ramp back up on context, approve the action, and then return to my other work.

Productivity Gains - Minimal. While Claude was writing the code, the constant context-switching to catch up on what I was approving ate most of the speed-up. I was technically producing more, but not by much. Plus, I’d lost the part of engineering I actually enjoyed: the act of writing the code.

Bottleneck - I had to maintain constant contextual awareness and stay tethered to my laptop for Claude to make progress.

I needed to find a way to put Claude to use without requiring so much of my attention!

Step 2 - Building Dangerously

The real unlock came when I started running Claude with --dangerously-skip-permissions. This effectively lets Claude operate on the OS level without asking for permission. Those chimes that beckoned me to the terminal every few minutes suddenly dropped to once every 20 or 30.

I’d tell Claude what to do with a few pointers here and there, it might ask me a question or two, and then it would be off to the races for implementation.

Productivity Gains - Substantial. I was managing a team of engineers at the time, and this allowed me to be an effective manager while remaining one of the primary technical contributors. Previously, doing both would have been impossible.

Bottleneck - Quality control. Most PRs required multiple rounds of review because Claude would drift outside the intended bounds. Small errors in direction or reasoning at the start of a session would compound rapidly, forcing me to redo large chunks of work or throw it out wholesale.

I needed to find a way to keep Claude on track and within a bounded scope.

Step 3 - Up Front Instruction

Next, I started having Claude interview me instead of me just dictating. I created a Claude skill to handle the interview process. I’d kick it off, dictate my responses, let Claude enter a planning session, and then set it to work. I did this several times a day. It required more effort upfront, but it drastically reduced the rework and repetition downstream.

Productivity Gains - PRs went from requiring multiple rounds of review - or outright scrapping - to needing just one or two, and sometimes zero. I could finally treat Claude like a junior-to-mid-level engineer.

Bottleneck - The 'Goldilocks' problem of task sizing. If the scope was too large, Claude would lose the thread, hallucinate, or choke on the requirements. If it was too small, the management overhead of the interview and planning loop erased any productivity gains. I needed a reliable way to chunk work into tasks that hit that sweet spot.

I needed a way to reliably chunk work into individual tasks that fell into this Goldilocks zone.

Step 4 - PRDs, Tech Specs, Designs, and Ticket Sequencing

To hit that 'Goldilocks' sweet spot, I turned to the standard synchronization artifacts used in tech product development. By preparing these artifacts beforehand, I could use AI to slice tickets into the ‘Goldilocks’ size and map dependencies, all while ensuring near-zero ambiguity in implementation.

A quick primer on these documents:

  • Product Requirements Documents (PRDs) - A PRD defines what should be built. They vary in format but typically include problem statements, user stories, goals, and success metrics. A good PRD distills complex ideas into a shared source of truth for product, design, and engineering teams, answering: what are we building, why, and for whom?
  • Tech Specifications - If the PRD answers the ‘what’, ‘why,’ and ‘for who,’ the tech spec answers the ‘how.’ It bridges the user-facing goal with the current state of the codebase. It’s where engineers hash out algorithms, infrastructure, patterns, and security concerns.
  • Designs - A PRD paired with a tech spec is great, but they still don’t show what the feature looks like. Designs - whether in Figma or another platform - clarify the minutiae of the UI/UX. They define the screens, dialogs, and copy that an end-user will interact with.

I adapted the interview Claude skill to still interview me but with the express purpose of filling out the contents of a PRD template. I even updated the skill to pull relevant context from Granola meeting minutes to seed the PRD before jumping into the interview with me. The result was that I could jump on a call with my cofounders, hash out the details of what we wanted to build, and then use the skill to quickly draft a PRD for everyone’s review and approval.

I then drafted another skill for doing effectively the same thing but for a tech spec; it would look at the PRD, review the current state of the code, interview me to address any potential judgment calls around implementation and then draft a complete tech spec documenting all of our joint decision making.

Lastly I would go to Claude Design and instruct it to do a first pass on the implementation using our existing design system as the north star. Claude Design would ask a few questions and then come back with a design. A round or two of revisions later, I’d be happy with the designs.

At that point I had an unambiguous and detailed description of exactly what needed to be built across the PRD, the tech spec, and the design. The only thing left was to chunk up the work into right-sized tickets. And so, of course, I assembled another Claude skill that drafted up all the tickets and placed them in Linear. The end result was a wall of tickets, perfectly sized, ready for one-shotting by Claude Code.

Productivity Gains - Massive. I was spec'ing full product iterations ahead of time, letting Claude run in the background, and reviewing PRs that often required no revisions. Claude had the context to hit the mark reliably. When one PR was done, I’d just tell Claude to take the next ticket.

Bottleneck - Backlog management. We had more work than I had implementation bandwidth, despite Claude running constantly.

I needed more AI development capacity to take on more tickets more of the time.

Step 5 - Multiple Claude Windows on my Laptop

I did what any reasonable engineer might do - more terminal windows! More instances of Claude! Let my laptop overheat and let the tokens burnnnn baby!

Parallelizing took a bit of setup. For instance:

  1. Every worker needed to connect to the same Postgres database but use a distinct test database.
  2. Every worker needed a distinct namespace for shared Redis instances.
  3. I used Git worktrees to run Claude in separate directories.

It was surprisingly painless. Claude would chug along in three terminal windows, implementing three tickets at once. I’d wait for all three to finish, review the PRs, and request changes where needed. Once merged, I’d clean up the instances and pull new worktrees. Rinse. Repeat.

Productivity Gains - I was shipping three times as many PRs. By sticking to the planning phase in step 4, I could implement huge initiatives end-to-end very quickly. The result was ~95% correct, leaving just a quick clean-up pass to handle the rough edges.

Bottleneck - I had to keep track of which Claude window was implementing which ticket. I was also limited by my laptop's hardware - three windows felt like the ceiling.

I needed to find a way to replicate what I was doing on someone else’s computer.

Step 6 - Multiple Claude Windows in the Cloud

I did what any reasonable engineer would: I threw my local stack onto a virtual private server (VPS). I spun up a $20/month DigitalOcean droplet and ported over the essentials - code, tokens, credentials, and infrastructure.

Then I would SSH into the DigitalOcean machine and… have six Claude Code windows in my terminal(s)! I had initially intended to run only on DigitalOcean but after getting everything spun up I found myself juggling local development loops as well as the remote ones. This was at least a repeatable way that I could ramp up the horsepower of the software engineering side of the engine. Another DigitalOcean droplet would net us another three Claude Codes, ad infinitum.

Productivity Gains - I doubled the number of PRs I could cut again, so between the previous step and this one I was netting 6x as many PRs as I had been authoring a short time before. Once I had cut all the tickets for a given product feature, there would be a flurry of landing PRs where I needed to spend a good amount of mental energy juggling Claude Code windows but then a feature that would otherwise have taken an engineering team weeks to implement would be completed in days.

Bottleneck - Cognitive overload. I was now managing remote infrastructure, keeping track of six Claude Code terminal windows, and performing mental gymnastics to keep it all straight. While I could technically spin up another DigitalOcean droplet, I had hit my mental capacity in keeping everything straight.

I needed a way to scale up my Claude Code worker count without incurring more managerial mental overhead.

Step 7 - GitHub Action Workers to the Rescue

GitHub Action workers let you run bounded compute jobs in the cloud without managing the underlying infrastructure.

The ergonomics were perfect. It was a straightforward trade-off: money for sanity.

  • Kick off new work in reaction to something else happening (ex: a ticket being labeled as ready for development)
  • Run a full stack of our infrastructure in isolation inside of a worker so that we don’t have to worry about different instances of Claude stepping on each others’ toes
  • Pay per minute of usage
  • Spin new workers up / down based on new work coming in rather than having a worker idle when not in use

I updated our workflow to use labels like adw-ready. Applying the label triggered a GitHub worker to tackle the ticket. (At the time, we were using GitHub Issues; we’ve since moved to Linear, as you’ll see in the repo). I added some new GitHub worker YAML files to define all the workflows and even wired one up so that whenever I requested review Claude would spin up, address all my comments, and then re-request review.

The net effect was that I could simply apply labels to tickets and they would automatically be picked up for development in the cloud. No managing of worker infrastructure. No juggling of terminal windows. Just Claude cutting PRs that I would review and oftentimes merge without making any changes. It was the workflow that I was used to in working with teams of human engineers.

Productivity Gains - Significant. Claude was able to spin up in parallel to handle as many tickets as I could possibly feed it. I didn’t have to spin up another droplet or juggle another terminal window. I just had to pay attention to a budget, and otherwise my infrastructure problems were solved.

Bottleneck - Managing ticket dependency. With the capacity side of engineering implementation more or less solved at this point, the bottleneck shifted back to managing the dependency between tickets and figuring out how to parallelize work.

I needed a way to automatically parallelize work and enqueue unblocked work as PRs were merged.

Step 8 - Embedding Dependency in Tickets

I already had a Claude skill that sequenced ticket creation: database models, business logic, API, then UI. I just needed to embed that sequencing directly into the tickets.

I updated the skill to use GitHub’s project functionality and “blocked by” relationships to create a dependency graph of the entire implementation. I also added a GitHub Action that fired whenever a PR merged to main: checking for newly unblocked tickets and automatically labeling them for implementation.

Simple. A machine that automatically enqueued unblocked work and a project management system that identified the sequencing ahead of time. A small change that made a world of difference.

Productivity Gains - The implementation of PRDs, end-to-end, required near-zero project management process. So long as Claude was able to get the sequencing right ahead of time (which it did reliably), my only interaction after that point was reviewing PRs, requesting changes, and merging them. When first implemented a job would fail here or there due to some bugginess in the infrastructure set up, but after those initial hiccups the pipeline would hum along. We built a Golang version of litellm on the inside of a week (which we use ourselves and offer to our clients given the scary nature of litellm’s security track record).

Bottleneck - Our bank account. We blew through $80.00 in GitHub worker minutes in three days. Radically cheaper than a human engineering team. Expensive for us as our costs would scale linearly with our workload.

I needed a way to decouple costs from workload.

Step 9 - Dusting Off the Mac Mini

A few months ago I purchased a Mac Mini with the intent of installing OpenClaw on it. I got it all set up, installed OpenClaw, and then realized that for OpenClaw to be useful at all I had to give it credentialed access to everything I cared about. Horrifying! Side note: this observation was the initial inspiration for building our MCP proxy.

The Mac Mini sat gathering dust, a solution in search of a problem. It turned out to be the perfect candidate for our long-running GitHub worker jobs.

A standard task in a GitHub worker might take a minute or two, but our Claude implementation workers would churn for 30–60 minutes per PR. Looking at our bill, those implementation workers accounted for the lion's share of the cost.

GitHub allows for "self-hosted runners," where GitHub handles the orchestration while delegating execution to your own infrastructure. You simply run a script to connect your device, and you’ll have a containerized runner ready to go. (Note: the script provisions a single runner, so you must run it multiple times to host multiple workers on one device.)

I provisioned five runners on the Mac Mini and configured all Claude implementation workflows to run exclusively on it. This limited us to five simultaneous workers - more than enough, since our PR review and merge process typically takes longer than the implementation itself.

Productivity Gains - This iteration wasn’t so much about productivity improvements but rather cost reduction, as we had finally gotten to a point where our costs started to scale. Cost reduction for us here was substantial, as our monthly GitHub actions bill hovered around $80/month and our implementation worker was a one-time fixed cost of $600.00 for the Mac Mini.

Bottleneck - Limited context. There were still some cases where we needed the implementation worker to run locally; most often when the worker needed to look at Sentry or Datadog or some other debugging source in order to correctly implement a ticket (especially important for bug-fixing).

I needed a way to let Claude have access to more contextual information about the business and our software environments while running somewhere other than my laptop.

Step 10 - The Birth of Stitchwork

When connecting Claude Code to MCP providers that support OAuth - like Linear, Sentry, Cloudflare, or Granola - you must open a browser to complete the authorization flow. This is an obnoxious problem when running Claude Code anywhere other than your laptop, because you can’t really kick off an OAuth flow when Claude is running headlessly on a server somewhere.

Because of this and the security concerns around OpenClaw I mentioned earlier, we built an MCP proxy within our Stitchwork platform. It allows you to:

  1. Connect any of your MCP providers to Stitchwork in a browser.
  2. Generate an auth token that you can give to an agent running anywhere.

The agent connects to Stitchwork using the token which proxies the MCP connection to the upstream data provider. Beyond portability, Stitchwork provides several key capabilities:

  • Granular Access: Surgically define which MCP providers and tools a Stitchwork client can see.
  • Audit Logging: Keep full logs of which agents are calling which MCP tools and where.
  • Instant Kill-Switch: Revoke access immediately.

Once I got this up and running, I connected Linear, Sentry, Datadog, and Heroku to Stitchwork, generated a limited, read-only token, and provided it to our implementation workers. This allowed the workers to debug and review production state from anywhere, closing the final justification for running Claude Code on my laptop.

Productivity Gains - The implementation portion of building software products is no longer a bottleneck for our business. Instead we concern ourselves with questions around what we should be building and for who. Once we agree that an idea has legs, the implementation is completed within a few days, for a few dollars.

Bottleneck - None on the engineering side.

Where We Are Today

A team of three runs engineering for five startups and shipped a product of our own in four months. Our costs scale with the number of clients we take on, not the amount of code we ship - a full engineering org for a little over $4,000 a year, per client (and we're looking for more clients if you're interested).

But the headline isn't the cost. It's what the cost bought us: engineering capacity stopped being our bottleneck. For my part alone, monthly output grew ~25× over the year - from ~19K to ~490K lines a month, peaking north of 650K - and every jump lines up with a step in this journey coming online. When implementation gets that cheap and that fast, the hard problem stops being can we build it and becomes should we, and why? That's a better problem to have, and it's the one we spend our days on now.

I started this journey mourning the craft I'd spent twenty years loving. I'm ending it building more than I ever could by hand - and, honestly, back at the ceramics wheel for the part of me that missed making things slowly. The trade felt like a loss at first. It doesn't anymore.

The whole engine is open source and in this repo. Take it, break it, make it better, and send us the pull requests - we're opinionated but not precious. The more people this frees to go from a good idea to a shipped product, the better.