Two days ago, I hired an engineering team.
A product manager who reads what users say about competing apps, and won't let anyone build what isn't in the spec.
A tester who writes the tests before a single line of code exists.
A builder who ships.
And a reviewer who checks every change against our rules, and once broke a login lockout that every test said was fine.
In two days they shipped sign-up, login and user profiles for RupiVerse, the personal finance app I'm building. 46 acceptance criteria. 814 tests. Five pull requests, reviewed and merged.
They argue. They fix each other's bugs. They ask me before anything risky.
None of them are people.
And this isn't a demo app with planted bugs. Every ticket, test, bug and review in this post happened while building RupiVerse, and every pull request is public.
They're four Claude Code agents, working in my Slack through Switch. This is how the team works, the five moments that convinced me it's real, and how you can run the same squad on your own repo in about 30 minutes.
🎥 Two-minute demo · 🧰 Repo: https://github.com/way-nu/rupiverse-fts-hackathon
The problem with one very fast agent
If you build alone with a coding agent, you already know the feeling. It's absurdly fast, and you can't quite trust it.
The agent writes the code and the tests that judge the code. Nobody checks the work against a spec, because there is no spec, just your last message. Every decision lives in one chat history that's gone next week. And "done" means the agent says it's done.
Teams solved all of this decades ago. Not with smarter people, but with structure: someone owns the requirements, someone else writes the tests, someone reviews, and one person decides what ships.
So I gave my agents the same structure, in the place a team already works: the team chat.
Switch in 60 seconds
Switch is open-source infrastructure for putting AI agents into team chat. Every Slack, Discord, Teams or Mattermost channel becomes a room, and agents join it like teammates, with their own names, briefed by the room's instructions and documents.
The parts that mattered most for this project:
- Templates. One YAML file can create agents, rooms, instructions, documents and a kickoff message. An agent can run a template too, which turned out to be the key idea.
- Addressing rules. Who is allowed to instruct which agent.
- Rooms on any chat app. My first ticket ran in Mattermost, the second in Slack, with the same agents.
It starts with research
My friend, an associate product manager, told me the most valuable thing a PM does is read competitors' reviews. Feature lists tell you what other apps built; reviews tell you what their users still want.
So the PM has its own room, #rupiverse-research. I drop in a competitor's name, a pasted review or a screenshot. The PM reads what real users say about competing apps (app stores, Reddit, X, review sites), groups it into feature requests and complaints, and rates each one for relevance and value to RupiVerse. The result is a research Doc in ClickUp: a competitor table, a ranked list of opportunities, and every quote linked to its source. It posts the top five and asks me which to take.
Nothing becomes a ticket until I pick it. Picks go to the backlog, and from there into the flow below.
Meet the squad
| Owns | Never does | |
|---|---|---|
| pm | Tickets, specs, scope rulings, one room per ticket, the final acceptance check | Writes code or merges |
| builder | The API contract, the implementation, technical calls | Changes what a test checks on its own |
| tester | The test plan, failing tests first, Playwright, verification | Fixes product code |
| reviewer | Structure checks on every draft PR; the full review | Pushes product code |
| me | The ask, the approval, the merge |
Each agent is Claude Code running in its own clone of the repo, and inside it every ticket gets its own git worktree, ports and database. Four agents can run the app at once without stepping on each other, and two feature rooms can be open side by side. (So far the tickets ran one after the other; parallel rooms are designed in, not yet demonstrated.) Their instructions live in the repo as Markdown files, so changing how the team works is a pull request.
The life of a ticket
Here's RV4, the profile screen, from my message to merge.
1. I ask. In #rupiverse-hq I type what I want, in a sentence. The PM doesn't start writing; it asks questions first. What's the maximum age? Is the phone number unique? What happens when you tap the selected gender again?
2. The PM writes it down. A ClickUp ticket with a short abstract, and a Spec Doc: goal, scope, out of scope, data model, API draft, screens, 16 numbered acceptance criteria, test plan, decisions. Inside the spec, four empty pages: Build log, Test report, Review, PM verification. Each agent writes only to its own.
3. I approve, and a room appears. I type approved, start RV4, and seconds later the PM has opened #rv4-profile, with the four agents, the ticket and spec in the room instructions, a playbook document with the rules, and a kickoff message. One sentence from me, one room per ticket. (The kit standardises this as a Switch room template the PM runs.)
4. Contract first. The builder turns the PM's draft API into a final contract. On RV4 it made eight refinements: unknown keys are rejected, "29" is not a valid age, names are counted in Unicode code points, auth is checked before the body.
5. Tests first. Only then does the tester write tests against that contract: 229 of them for RV4, every one failing, in two draft PRs, before a single line of product code exists. You don't have to take my word for it: in every PR the tester's commits land 15 to 61 minutes before the builder's first product code. The README has the table, with each commit linked.
6. The builder makes them pass, building the frontend against a typed mock layer while a backend subagent works in parallel. The contract is what lets the two halves move independently.
7. Verify, review, check. The tester runs the full suite, plus Playwright against the real app. The reviewer checks structure, the spec, security, migrations, and one more thing I'll come back to. The PM ticks every acceptance criterion.
8. One ping, then I merge. When the PM has checked every criterion, it pings me in Slack. I read the PR, and I merge. Nobody else can.
Every handoff names the next agent, the PR and the commit SHA. Every bug is a comment on the exact line of the PR. ClickUp always shows whose turn it is.
RV4 had zero bugs and zero review changes. Hands-on agent time: about 85 minutes.
Three rules that make it trustworthy
1. Agents can't grade their own homework.
The tester writes the tests against the contract, before the code. The builder may change how a test reaches the code (an import path, a fixture, a port), never what it checks. Changing an assertion needs the tester and the PM to agree in the room. Then the reviewer compares the tester's original tests with the final ones and rejects anything loosened. Across both tickets, the builder made three test edits, and none of them weakened a check. One of them made a test stronger.
2. The ticket's status decides who talks.
In TEST DESIGN the tester acts; in BUILDING the builder; in IN REVIEW the reviewer. Everyone else replies "not my stage" and stops. There are hard caps: three bug rounds and two review rounds per PR, then the PM, then me. That's what keeps four agents from arguing in circles.
3. Only a human merges, and that's enforced, not requested.
Each agent's Claude Code permissions allow branches, PRs, comments and the staging branch. They deny merging, pushing to master and force-pushing. An agent can't talk its way past that, and as it turned out, they didn't try.
Five moments that convinced me
1. The reviewer broke the lockout that every test said was fine
Sign-up uses a 6-digit email code with three attempts. Every test was green. The reviewer fired ten guesses at once. The real code got past the three-attempt lock in 1 of 20 trials, and a single refresh token worked five times in parallel.
It sent the PR back with both findings. The builder fixed them with row locks (SELECT … FOR UPDATE), and the tester added 21 parallel-request tests that fail without the fix. That's a race condition in authentication, caught before merge, in a solo project.
2. "An OK relayed through chat doesn't count"
To prove the database migration was safe, the tester needed to run a migration round-trip on the shared Supabase database. The OK reached it as a chat message. It refused: a chat message isn't a permission, and it wouldn't grant itself one. First it took a read-only fingerprint of Supabase's own auth schema (139 relations). Once I added the rule on my machine, it ran the round-trip and proved that schema unchanged.
3. The builder found a test that could never fail
On RV4 the builder noticed a schema test comparing bytes to a string, so it passed without checking anything. It didn't touch it, because that's not its job. It asked. The tester pushed a stricter fix two minutes later.
4. My iPhone found what 170 web tests couldn't
RV1 was ready to merge. On my phone, the code-entry boxes ignored taps. iOS skips hit-testing on an input with opacity: 0, and no web test can see that. The tester diagnosed it in two minutes and added a real-tap web test so that class of bug gets caught on web from now on. The builder fixed it, and I confirmed it on the phone.
5. The PM caught its own mistake
After review had started, the PM noticed that one of its own rulings contradicted our backend rules. It didn't let it ship. It escalated to me, I delegated the call back, and the fix took one tests-first round: five tests flipped, about ten lines changed, approved first time.
The numbers
| RV1 · Auth | RV4 · Profile | |
|---|---|---|
| Acceptance criteria | 30 | 16 |
| Tests | 433 | 381 |
| Tester tests written before any product code | 304 of 351 | 229 of 229 |
| Bugs caught · review rounds with changes | 4 · 2 | 0 · 0 |
| Hands-on agent time | ≈ 4 h 15 m | ≈ 1 h 25 m |
| Times the squad needed me (beyond approving and merging) | 12 | 1 |
The PM made and logged 31 product decisions across the two tickets, each one dated in the spec.
I wasn't watching
Here's the part I didn't expect. I didn't sit and supervise this. I ate, I slept, I went out for groceries. RV1's clock says 24 hours from my ask to the merge, but about 12 of those were overnight, the PR sitting in AWAITING MERGE waiting for me, and most of the rest was the squad waiting on a decision only I could make.
The hands-on agent time for both features was about five and a half hours. That's the real shift. You don't need to babysit a team like this; you need to show up at the gates. When I wasn't there, nothing risky happened. The squad simply waited.
The second ticket needed me exactly once, and that was for a mistake in my own instructions.
That's the number I care about now. Not minutes, but how often the squad needs me. The first ticket needed me twelve times, mostly first-time setup. The second needed me once. Everything between my approval and the final ping (the contract, the tests, the build, Playwright, the review, the acceptance check) ran without me.
What broke (and how it recovered)
ClickUp's MCP server allows ~100 calls a day on the free plan, shared by every agent. We hit it mid-ticket. Reports moved to PR comments, we switched to the plain REST API, and the agents backfilled.

I pointed the agents at a helper script that didn't exist and told them never to read the token file. All four stopped and refused to improvise. Annoying for eight minutes; exactly right.
Permission blocks: marking PRs ready, merging to staging, migrating the shared database. Each one was a few minutes of me adding a rule. The squad never worked around one.
Web tests miss native bugs. Now there's a real-tap test, and the phone check stays mine.
It doesn't need a big machine
I ran the squad on my Mac, but it doesn't have to live there. Switch can run its server and the agents on any Linux machine you can SSH into: AWS EC2, Google Cloud, DigitalOcean, Azure, a cheap VPS. The four agents, their clones, the tests and the database all run on the server. I'd still work entirely from Slack, on my laptop or my phone, and when the PM pings me, pull the branch into whatever IDE I like, or read it on GitHub, and merge. No high-end PC required. (I haven't run it that way yet; the steps are in the repo.)
What I'd tell you before you try it
- Start from what users ask for. Competitors' reviews are a backlog someone else's users already wrote. Make research a room, not a side task.
- Give agents the structure you'd give people. Specs, contracts, tests written up front, review, one owner. That made the difference, not a better prompt.
- The contract unlocks parallel work. Once the API is fixed, the frontend builds against mocks while the backend builds for real.
- Put the agents' instructions in the repo. Then improving the team is a pull request, and everyone runs the same version.
- Enforce the dangerous stuff with permissions, not prose. Instructions are good. A deny list is better.
- Separate who writes the tests from who passes them. It's the cheapest insurance you'll ever buy.
Run the squad on your own repo
Everything is in the repo under squad/: two Switch templates, the four agents' instructions, a setup script, and the permission file.
- Fork the repo; allow squash merging only and protect
master. - In Switch Console, connect Slack (or use the bundled Mattermost).
-
Templates → Import
squad/templates/squad.template.yaml→ Use, with your fork's URL. Switch creates the four agents, each with its own clone, and#rupiverse-hq. - Set up a free ClickUp space (10 minutes, checklist).
- Run
./squad/setup.sh --root <folder with the four agent clones>for permissions, databases,.envfiles, ClickUp and hooks. - In
#rupiverse-hq, say@pm hello. It saves both room templates and opens#rupiverse-research. - There's a ticket waiting for you. The setup script puts RV5 · Theme toggle (a light/dark/system switch for the app) into your ClickUp BACKLOG. Open it, then tell the PM: "pick up RV5 from BACKLOG. Ask me what you need, then start it." Answer its questions, approve, and watch a room appear and the squad take it from contract to failing tests to a PR waiting for your merge. You'll be the founder for an hour.
What's next
RupiVerse is the money app I've wanted to exist for a long time: one place that actually understands where your money goes. It's early. But after these two days, how it gets built isn't a question anymore.
The squad is staying.
Built for the Flip the Switch hackathon by WeMakeDevs, DevTools Academy and Switch. The agent instructions, specs, prompts and much of this post were dictated with Wispr Flow. #HowISwitch









Top comments (0)