Building Juno solo, in a month, with AI coding agents
The spec-driven workflow that let one person ship a production agent product: what worked, where it broke down, and why CI turned out to be the real game changer.
Juno is an AI wedding-planning studio with a full workspace, an email ingestion pipeline, and an agent with her own inbox. I built it solo in about a month, alongside planning the actual wedding it's used for. That was only possible because the build itself was AI-native: most of the code was written by AI coding agents, and my job looked a lot more like product management than typing. I spent it writing specs, defining invariants, reviewing diffs, and maintaining the context that keeps agent work coherent.
The workflow
Every feature runs through the same pipeline, using both Claude Code and Codex. I encoded it as a set of skills, one per phase, so the steps and their gates stay identical from one feature to the next:
A roadmap item becomes three separate artifacts before any code gets written. spec.md owns the decisions: user-facing behavior, scope boundary, data model, dependencies, and testable success criteria. plan.md owns sequencing: components, their order, and the risks. tasks.md owns implementation: a checklist a coding session can execute one thin slice at a time. Each artifact is a gate. The workflow does not advance to the next until I've approved the current one, and a repair pass blocks the handoff while any open decision is still unanswered. Only then does implementation run, and it stops at an open PR rather than merging itself.
The shape of the spec owes a lot to Addy Osmani's How to write a good spec for AI agents, which is where I picked up most of what I know here: start from a high-level vision and let the agent expand it, structure the spec like a PRD, break the work into modular tasks, and write explicit "always / ask first / never" boundaries into the spec so the agent has constraints to check itself against.
The connective tissue is an agents-facing architecture document (the repo's AGENTS.md and CLAUDE.md): a living file that records the repo's conventions, invariants, and design decisions. Which mutations exist, what the agent is and isn't allowed to touch, how timezones are stored, what the review-queue state machine allows. Every coding session starts grounded in it, which is what keeps session #40 consistent with session #3. Maintaining that document is the highest-leverage writing I did on the project: it's the difference between an agent that extends your architecture and one that reinvents it slightly wrong each time.
Where the workflow broke down
The pipeline's failure mode wasn't quality. It was ceremony. My initial definition of a "roadmap item" was too loose, so the workflow would take a small change and dutifully inflate it into a full spec, plan, and task list. The output quality was genuinely good; the token bill was not. A one-hour tweak would burn the process overhead of a one-week feature.
The fix was tuning the entry criteria: deciding what deserves the full spec-driven treatment and what should just be a direct, lightweight edit. I set a rough floor of three to eight implementation tasks for anything that goes through the full pipeline; smaller work gets grouped with adjacent changes or done as a direct edit. That judgment, matching process weight to change size, turns out to be the same skill as running a human team, where making everyone write a PRD for a copy change kills velocity. Agent teams don't push back on ceremony the way humans do; they'll happily generate all of it. The discipline has to come from you.
CI was the game changer
The single highest-impact investment was boring: continuous integration. Every PR runs four quality gates (lint, typecheck, unit tests, production build) plus a 36-test Playwright e2e suite across 6 spec files, running against real auth and row-level security with deterministic mock model responses. Once that wall existed, bugs largely stopped reaching main.
This matters more with agent-written code, not less. Agents produce plausible code fast, and review attention is the scarce resource, so the machine has to catch the mechanical failures before a human ever looks. CI is what converts "an agent wrote a lot of code quickly" from a liability into velocity. (Model-quality regressions are a different failure class with a different harness. That's the evals article.)
Invariants as code, not vigilance
With agents doing most of the writing, anything you're not willing to re-review on every diff has to be enforced mechanically:
- One mutation surface. The workspace has 70 server actions (Zod-validated, audit-logged); 57 of them are also registered as agent tools with schemas derived from the same Zod definitions. There's no separate "agent API" to drift out of sync, and the gap of 13 is deliberate: sends, uploads, invites, and review-queue approvals are user-only.
- The allowlist is pinned by a unit test. June must never gain send-email or payment authority, so that boundary isn't a convention in a doc. It's a test that fails if a refactor (human or agent) ever changes the tool registry. Guardrails you'd normally enforce through code review become code themselves.
What this taught me
A month of this settled a question I had about what happens to product work when agents write the code: the PM skillset doesn't get automated away. It becomes the bottleneck skill. Everything that made the agents effective was product work: a crisp spec, an explicit invariant, a well-maintained architecture doc, a decision about how much process a change deserves. Everything that went wrong traced back to a place where I'd been vague. Building with agent teams is a compressed, high-feedback version of the job I already had. You find out within hours, not quarters, whether your spec was actually clear.