All Posts

We Shipped 9 Features Before Lunch

An event-driven AI pipeline that goes from GitHub issue to merged PR with zero idle time. Here's what happens when you automate the boring parts of engineering.

4 min read
aideveloper-toolsautomationcase-study

We Shipped 9 Features Before Lunch

What happens when your dev pipeline has zero idle time.


This morning at 5:54 AM, I opened a GitHub issue about a duplicate header in our sidebar. By 11:08 AM, nine tickets were closed, seven PRs were merged, and the pipeline was idle — not because it broke, but because it ran out of work.

No standup. No sprint planning. No context switches. Just an event-driven loop: ticket → code → PR → review → merge → next ticket.

The Loop

The system is simple:

  1. Pick the next ticket from the backlog (sorted by priority, then size — small first)
  2. Start a Claude Code job with the ticket context and repo access
  3. Wake on completion via a system event (JOB_DONE:issue-236)
  4. Review the diff, check CI, merge or fix
  5. Immediately pick the next ticket

No polling. No cron-based batching. Event-driven wake means the moment a job finishes, the orchestrator picks up the result and starts the next one. The gap between "PR merged" and "next job started" is under 30 seconds.

What Actually Shipped

Here's the morning's output, in order:

| # | Ticket | Size | Time | |---|--------|------|------| | 1 | Duplicate header fix | S | ~15 min | | 2 | Account submenu restructure | M | ~40 min | | 3 | Billing cycle display + one-click cancel | M | ~35 min | | 4 | Onboarding checklist + contextual empty states | M | ~45 min | | 5 | Quality gate feedback loop | M | ~30 min | | 6 | Voice profile autocomplete + dynamic prompts | S | ~20 min | | 7 | Teams management with Clerk Organizations | L | ~90 min |

Three of those tickets (#241 legacy billing cleanup, #242 upgrade gate, and the header fix) shipped as parts of larger PRs. No ticket bloat — if two changes naturally go together, they ship together.

Why Small-First Matters

The backlog sort is p1 > p2 > p3, then S > M > L > XL within each priority level. This isn't arbitrary.

Small tickets build momentum. A 15-minute fix that merges clean gives the pipeline a warm codebase, a known-good CI state, and a commit to build on. By the time it hits the large tickets, it's already shipped four clean PRs and the codebase is in better shape than when it started.

It also means the pipeline's throughput looks absurd in the morning — four PRs before most people finish their coffee — and then settles into the bigger work naturally.

The Orchestrator Doesn't Write Code

This is the part people get wrong. The orchestrator is a project manager, not a programmer. It:

  • Reads the ticket
  • Composes a prompt with the right context (file paths, related code, acceptance criteria)
  • Hands it to Claude Code with repo access
  • Reviews the output when it's done

It never touches a file directly. It never git commits. It never writes a function. The separation matters because orchestration logic and coding logic are different skills with different failure modes. Mixing them makes both worse.

What I Actually Did

I triaged. I made product decisions. I reviewed diffs.

The cancel flow on the billing page? I decided it should be "Are you sure?" and done. No survey, no retention flow, no guilt trip. That's a product decision the pipeline can't make.

The onboarding approach? Checklist computed from real data, not click-tracking. Optional tour, not a forced tooltip walkthrough. Another product decision.

The pipeline handles the implementation. I handle the "what should this be?" The split is clean.

The Compound Effect

Here's what makes this work long-term: ticket #7 (quality gate feedback loop) literally made the pipeline's output better. The drafts it generates now learn from rejection history — patterns from the last 30 days of rejected drafts get injected into the generation prompt.

The pipeline built its own feedback loop. Each ticket makes the next one's output slightly better.

Try This

You don't need our specific stack. The pattern is:

  1. Event-driven, not cron-based. Wake on completion, not on a timer.
  2. WIP limit of 1. One job at a time. No parallelism, no merge conflicts, no coordination overhead.
  3. Small-first sort. Build momentum before tackling big work.
  4. Separate orchestration from execution. The thing that picks tickets should not be the thing that writes code.
  5. Review everything. Automation without review is just automated technical debt.

The best part? The pipeline doesn't get tired, doesn't context-switch, and doesn't have opinions about whether a ticket is boring. It just ships.

Nine features before lunch. The pipeline is idle. I'm going to go get coffee.

Want to work this way?

We help companies ship quality software at speeds they didn't think were possible.

Tell us about your project