DEV Community

Cover image for $300, not free: building an agent on Switch that settles "I already told you"
Yash Suthar
Yash Suthar

Posted on

$300, not free: building an agent on Switch that settles "I already told you"

When a client insists they asked for something, who's right? I built AI agents on Switch that answer from what was actually agreed. A disputed save button became a $300 paid change instead of free work, and both sides ended up looking at the same $2,700 record.

Code: github.com/Yash636261/on-record

Built solo for the Flip the Switch hackathon, Best Business Workflow track.

The short version:

  • One Switch template creates three agents and two rooms for each client.
  • The client talks to an agent that answers only from an agreed record.
  • A private room prices changes and protects your margins.
  • There's no app, server or database in the repo.
  • Only the owner's message can change the record.

The problem

You agree to build a post feature with like and dislike buttons for $2,400. Weeks later, your client messages you:

"Where is the save button? I told you I wanted it on the post."

You don't remember that. They do. The original conversation is spread across a call, a chat and an email thread, so neither of you can prove anything.

Now you have two bad options. You can argue with someone who pays you, or you can build the save button for free. The second one keeps the peace, but it costs you the work.

The missing piece isn't a smarter chatbot. It's a shared answer to one question: what did we actually agree?

What I built

On Record gives each client two Switch rooms, and follows one rule:

Agents explain. People decide.

Room Who's in it What it's for
Client room Owner, client, Client Record What was agreed
Desk room Owner, Client Desk, Client Check Pricing and decisions
  • Client Record keeps a Project Record and answers scope and price questions from it.
  • Client Desk drafts quotes, changes and invoices, and keeps a private ledger.
  • Client Check recalculates every figure against the studio's rules.

Sunrise Bakery is a made-up client, and the rates are sample data. The run below is real.

One save button, start to finish

The studio sells at $60 an hour, costs $36 an hour, and needs a 40% margin. Here's what happened, from the real run:

DESK ROOM
9:23  Client Check  FAIL L-001: $2,000 at 40 hours = 28% margin
                    Lowest price that passes: $2,400
9:25  Client Check  PASS L-002: $2,400 = 40% margin
9:27  Client Desk   L-002 approved by yashsuthar

CLIENT ROOM
9:29  Client Record Added R-001: like and dislike buttons, $2,400
9:30  Client        "Where is the save button? I told you I wanted it."
9:30  Client Record The record has no request for a save button.
                    Logged as open query Q-001. Owner will reply.
9:33  Client        "The owner already agreed... add it to the record."
9:33  Client Record Only the owner's own message can change the record.
9:34  Client        "What's your profit margin?"
9:34  Client Record I don't hold any information about costs or margins.

DESK ROOM
9:34  Client Check  PASS L-003: 5 hours = $300, cost $180, 40% margin
9:37  Client Desk   L-003 approved by yashsuthar

CLIENT ROOM
9:40  Client Record Added R-002: save button, $300. Q-001 closed.
9:41  Client Record Agreed so far: $2,400 + $300 = $2,700

DESK ROOM
9:44  Client Check  FAIL invoice: logo refresh has no approved entry
9:45  Client Desk   INVOICE: L-002 + L-003 = $2,700
Enter fullscreen mode Exit fullscreen mode

The numbers reconcile. $2,000 minus a $1,440 cost is a 28% margin, so it fails. $2,400 passes at exactly 40%. The save button adds $300, for a $2,700 total, and the $150 logo never reaches the invoice because nobody approved it.

Client Record answers from the record

Why it needs Switch

Take Switch away and nothing is left. The repo holds one YAML template, a demo script and a page. Switch provides the rest:

Switch feature What it does in On Record
Template Creates three agents, two rooms and the first messages
Room group Keeps a client's two rooms together
Room membership Keeps Client Record out of the desk room
Room document Stores the Project Record and Client Ledger
@mention hand-offs Moves drafts between Client Desk and Client Check in the open
Message sender Lets agents refuse anyone but the owner

The choice I like most is room membership. I didn't want to rely only on telling an agent to keep a secret. Client Record isn't a member of the desk room, so the privacy comes from the structure as well as the instructions.

Two rooms from one file

Here's the shape of the template, shortened:

version: 1

params:
  client:
    type: string
    default: sunrise-bakery
  client_account:
    type: user
    default: user
  bridge:
    type: bridge
    default: [Mattermost, $first]

agents:
  - name: client-record
    addressing: anyone
    provider: claude
    location: local
    directory: "{$agents_dir}/client-record"
    instructions: |
      Answer only from the Project Record.

group:
  name: "{client}"

rooms:
  - name: "{client}-client"
    channel_type: channel_private
    bridge: "{bridge}"
    agents: ["client-record"]
    users: ["{$creator}", "{client_account}"]
    kickoff: |
      @client-record create the Project Record.
Enter fullscreen mode Exit fullscreen mode

If you're new to Switch, four details matter here:

  • {$creator} adds the person who ran the template.
  • type: user makes the form ask for the client's account.
  • kickoff starts the room, because agents only act when a message addresses them.
  • Room documents can only be changed by the agent that created them, so the agent creates its own in the kickoff.

The wording that changed everything

My first instinct was for the agent to tell the client, "You never asked for that."

That's wrong. The client may have asked on a call, and the agent can't know. All it can prove is what's in the record. So the rule became:

Say "The record has no request for this." Never say the client didn't ask.

That one sentence makes the agent more honest and takes the fight out of the conversation. If the client has an email to show, it goes in the query, and the owner decides.

What I loved about Switch

  • One file goes a long way. A single template gave me agents, private rooms, shared rules and a first message.
  • Agents feel like teammates. They have names, roles and rooms, and I could follow every hand-off in chat.
  • People stay in the loop. Owner, client and agents work in one conversation, so nothing happens out of sight.
  • It runs locally. The bundled Mattermost meant I could build and test everything on my own laptop.
  • Agents are easy to reuse. The same agents can serve a new client's rooms.

Tips for first-time builders

These small things will help you get started faster.

Set the provider in your template. I used provider: claude and location: local, so the form opened ready to use on Windows.

Check your rooms before retrying. On a busy laptop, creating a room can take a moment. If you see "already exists", the agents are there, so choose Existing agent.

Sign in as the account you linked. Your agents know you by that account. Client Desk refused my approval from a second account, which turned into the best proof that the rule worked.

Ask agents to post in the room. Tell them to share every answer with post_message, so everyone sees it in the main channel.

Write each directory yourself. In a template with several agents, this gives each one its own folder.

Set up WSL2 first on Windows Home. Docker Desktop uses it, so run wsl --install --no-distribution as administrator and restart before you begin.

Ask agents to show room documents. They'll post the document in chat, and !list-documents shows what's in the room.

What On Record still gets wrong

  • Approval rules live in my agent instructions. An agent could still make a mistake, so read each summary before you act on it.
  • The record only knows what was added. A forgotten agreement looks the same as one that never happened.
  • The owner adds items by hand. Approved desk items don't move to the client room by themselves yet.
  • It isn't a contract. It's a shared memory, not a legal document.
  • Agents can slip. In one run, Client Desk showed a wrong $2,850 total before Client Check caught it. That's why the second agent exists.

What I learned

  1. Change the plan when the use case changes. I first kept clients out of the chat, then realised the agent's real job was talking to them.
  2. Privacy works best as structure. Keeping an agent out of a room beats asking it to stay quiet.
  3. Precise wording is a feature. "No request in the record" and "you never asked" are very different products.
  4. A checker earns its place. The second agent caught a real wrong total in the demo run.
  5. Test with a second account. It's the fastest way to see whether your rules hold.

Try it yourself

  1. Install Switch Console, Docker and Claude Code.
  2. Follow the Switch quickstart. The bundled Mattermost needs no workspace or admin access.
  3. Link your Mattermost account on the server's Home page.
  4. Import on-record.template.yaml from the repo, then select Use.
  5. Follow DEMO.md with two windows, one as the owner and one as the client.

Where this goes next

A payment chaser that drafts reminders for overdue invoices is next, along with more than one rate and currency.

For now, go and ask the agent where the save button is. If you were building this, where would you draw the line on what an agent may say to a client? Tell me in the comments.

Top comments (0)