Building with AI · Part 2

Three Wrappers Become One: the birth of aidd

Posted February 1, 2026

When I wrote the last post at the end of November, the situation was: a proven template, six applications riding it, and a backlog growing faster than I could type. The obvious move was to point AI coding agents at the backlog. The non-obvious part was everything else. How do you keep an unattended agent honest? How do you know when it's stuck? How do you make "done" mean something? December was spent learning those lessons the expensive way, and January 8 is the day the lessons got a name.

The automaker era: 1,182 commits of tuition

I didn't start from scratch at first, I forked an upstream orchestrator - the automaker project - and put an absurd 1,182 commits into the fork in December alone: a Cursor provider, MCP server management, a phase model for multi-step agent workflows, a kanban feature-tracking UI, sandbox mode. This wasn't product work. It was tool work, and the bet was explicit in my notes: automating the development process itself should pay compound returns.

The fork also delivered the first installment of what I suspect will be a long war: Windows process handling. Signal propagation, graceful shutdown, orphaned children. Proper signal handling matters a lot when you're running agents unattended overnight, and Windows makes you earn it. I don't think I've seen the last of this.

Unfortunately that project didn't work out for several reasons, so I had to start over fresh.

Why three wrappers, not one

Mid-December I did something that looks like a detour and was actually the important move: I wrote three separate CLI wrappers - aidd-c for Claude Code, aidd-k for KiloCode, aidd-o for OpenCode - instead of one abstraction.

The reasoning: each AI coding tool has fundamentally different CLI interfaces, output formats, and failure modes. Abstracting too early would have produced a leaky abstraction.

The commit counts tell you where the dragons were. KiloCode, whose VS Code extension API was hardest to drive headlessly, needed 25 commits of session management, transcript capture, and error recovery. Claude Code needed 13, including the first version of idle-timeout detection with configurable thresholds. OpenCode needed 6. Writing the same job three times made the shared 70-80% visible as fact rather than guess, and made the provider-specific remainder visible as exactly the integration layer an abstraction would need to isolate.

On December 29, all three got renamed under one brand and, more importantly, gained a .aidd metadata directory. That directory, holding structured feature definitions, is the core concept everything else now hangs on: the project itself carries the contract for how an agent works on it.

January 8: aidd v0.8.0

Three wrappers became one. aidd - the AI Development Director - unified them behind a single orchestrator, with Claude Code as the primary backend. 87 commits took it to v0.8.0 by month's end:

  • Feature-driven development. Work defined in .aidd/features/*/feature.json, not in chat prompts.
  • An audit framework with 20+ categories - security, performance, architecture, dead code, tech debt, React patterns, schema constraints - whose findings become backlog features instead of a report nobody reads.
  • Two-stage idle timeout with agent nudging, automatic retry, consecutive-failure limits, and stuck detection. The immune system for unattended overnight runs.
  • Full iteration transcripts written into .aidd/, because an orchestrator you can't audit is just a slot machine.

The audit framework came from real pain. This same January, Spernakit absorbed a 348-commit audit campaign across eight categories - the scale of technical debt that piles up even in a well-maintained template. Doing that campaign semi-manually is what convinced me the audit belongs inside the orchestrator. The pattern that emerged (findings become features, features become measurable improvements) already feels like the actual innovation here, more than any single orchestration trick.

Building features overnight and reviewing them in the morning is a genuinely different job. It changes the role quite a bit. I'm not sure how I feel about this yet.

The marathon and the proof

Ten days after v0.8.0, I stress-tested it: three projects running under aidd orchestration at the same time. The result was 441 commits in a single day, the highest of any day since this whole thing started. astrid.chat took 151 commits and reached 143 of 144 features. KeyStrike took 123 commits of security hardening. sitemap (an unreleased ui nav PoC) took 205 commits decomposing a 2,000-line App.tsx monolith into twelve domain modules.

Two details from that day matter more than the headline number. First, the loop was already self-correcting: aidd's audit mode caught issues that the feature-building mode introduced. Second, the one feature astrid.chat couldn't close was the honest kind of failure - it needed a human judgment about requirements, not more implementation. An orchestrator that stops and asks is worth more than one that guesses. I want to make that instinct structural eventually, not just observed.

Then, eleven days later, the result that ended the "is this real?" question for me: GroundTruth went from an empty repository to 106 of 106 features passing in a single day. Fifteen commits, ten domain models, CRUD APIs, a dashboard, dependency-graph visualization.

aidd is no longer a hypothesis - it's a production tool.

What December and January taught

Build the concrete implementations before the abstraction. The three-wrapper "detour" is why the unified orchestrator's backend seam was right the first time. aidd drives Claude Code, KiloCode, and OpenCode through one interface today, and adding a fourth backend should cost a parser, not a rewrite.

The metadata is the product. The .aidd/ directory - features, audits, transcripts - is what separates "an agent ran" from "work happened that I can verify."

Unattended means paranoid. Idle detection, nudging, retry caps, failure limits. None of it is glamorous, but it's the difference between waking up to finished features and waking up to a wedged terminal and a burned API budget.

Volume is a byproduct, not a goal. 441 commits in a day is a fun number, but the number that mattered was 106/106 - a complete, verified application. The gap between output and verified output is the thing I keep staring at.

Which brings me to this morning. All those January projects were built on Spernakit v1, and v1's technology choices were made for familiarity, not fit. So today I started Spernakit v2 from a blank repository. A rewrite based on 523 commits of v1 lessons learned.