Cleaner CRM
Two prompts. Two UAT passes. Three days. Fable did the rest.
A full cleaning-business CRM: owner back office, cleaner field app, and a public booking funnel with real Stripe payments, live on UAT. I two-shotted it: a 110-word prompt on July 7, one sentence for the customer side a day later. Claude Fable 5 orchestrated 172 subagents through the rest. Measured across the conversation, I typed 3,923 characters; the agent wrote just over a million.
What is Cleaner CRM?
A Phoenix LiveView CRM for residential cleaning businesses, scoped by agent-run research into Jobber, Housecall Pro, and Maidily. Three personas: the owner runs the business, the cleaner works the day from a mobile field app, and the customer quotes, books, and pays without ever creating a password. Every story cites a research finding.
Stripe
Payment Element card capture, card-on-file charges, payment links, signed webhooks with replay protection
Twilio
SMS reminders with per-job failure isolation and email fallback
Resend
Magic links, portal invitations, review requests
Oban
Reminder scans, review scheduling, recurring-visit materialization
Kamal + Hetzner
Health-checked container swaps, SSM-bootstrapped secrets
Wallaby
Five headless-Chrome journey tests codifying the QA runs
Key Features
- Recurring plans with series-wide conflict detection and per-visit overrides
- Weekly dispatch board with reassignment and acknowledged schedule-change alerts
- Quotes and invoicing off an owner-configured rate card, Stripe card-on-file
- Public instant-quote calculator and online booking at /book, no login required
- Magic-link client portal: proof-of-work photos, policy-gated reschedule, pay and tip
- Cleaner field app: day view, room-by-room checklists with photo proof, live earnings
- Timesheets with hourly and piece-rate pay, payroll CSV export
- Photo-proof quality scorecards, review engine, append-only audit trail
- Role-gated routing: cleaners physically cannot reach office data
User Stories
Every story that drove this build, complete and unexcerpted: persona, Three Amigos rules with full given-when-then scenarios, acceptance criteria, and resolved questions, exported straight from the harness database. All 21 passed browser-level QA.
Open Source Repository
The repo is public, full build transcripts included: 194 raw session files under .code_my_spec/conversations, synced by a pre-commit hook. Every failure in this teardown is in there. This case study was mined from those transcripts.
View on GitHubThe Dev Story
The Good, The Bad, and The Ugly
One 110-word prompt to a green BDD suite in 4 hours 12 minutes. Overnight, browser QA filed 35 issues and dispatched its own fixers while I slept. Day two: I spotted the missing customer persona at demo time and commissioned it in one sentence. Day three: live UAT, real Stripe, and a stranger from Reddit stress-testing it. Plenty broke along the way.
- 110-word prompt to a green BDD suite in 4h12m: research, 2 personas, 15 stories, ~100 spex, 146 tests
- Research agents corrected my own brief: the competitor I named does not exist; they identified the real one
- Browser QA ran itself: 35 issues filed, fixed, and re-verified agent to agent; a critical authz hole fixed in 8 minutes
- QA caught what specs could not: a dropdown that no-opped in real browsers, a cleaner who could export the company's payroll, a booking dated 2020
- The missing customer side went from one sentence to a QA'd public booking funnel in 2.5 hours
- The real Stripe sandbox caught a Live-adapter bug on the first charge; cassette tests caught a webhook replay vulnerability
- Guardrails held: agents escalated instead of routing around permission blocks, and confessed their own messes unprompted
- Fable orchestrated 172 subagents; I typed 0.4% of the characters (3,923 vs 1,027,791)
- Specs have bugs too: six defect classes on day one, including a story reading 0/5 against a fully correct implementation
- Parallel agents collided on everything shared: one browser, one dev server (9+ restarts), one Postgres, one migration timeline
- Features shipped without their admin half, twice: rate card and cancellation policy configurable only via psql
- The same past-date bug shipped in two code paths; nothing asks where else a just-fixed bug class lives
- Harness gates cried wolf: stop hooks firing on the wrong sessions, stale-warning demands, wakeups after the mission ended
- The build declared itself done with an entire persona missing. My prompt specified two, so it built two; the demo review is the gate no requirement graph replaces
- The harness's own MCP server went down for 8.5 hours; verified QA work sat unsubmittable while the app stayed green
- False-positive green: three features passed every spec while broken in every real browser. LiveView test helpers drive the server, not the browser
- A stranger from Reddit broke it in ten minutes: a $0.12 cleaning, a Fartmail email, a 4,000-hour booking. Report to deployed fixes in 51 minutes
- The dev environment melted down under multi-agent load; the agent abandoned dev-mode serving and invented an immutable-release QA pattern mid-run
Three days. Two prompts: 110 words to start, one sentence for the customer side. Twenty-one stories across three personas, 143 BDD spex, 331 tests, real Stripe payments, and a live UAT. Two UAT passes, one donated by a stranger on Reddit. I typed 0.4 percent of the characters; Claude Fable 5 orchestrated 172 subagents through the rest. That's the loop that ships.