My AI Builder Said No. It Was Right

My AI Builder Said No. It Was Right

●1 ●6
calendar_today ago • schedule5 min read

On Monday, your team picks Postgres. It takes twenty messages and one good argument about reporting. Everyone agrees. Everyone moves on.

On Wednesday, someone asks your AI agent: "Set up the user store in MongoDB."

The agent says "Sure!" and does it. It never saw Monday's argument. It only sees the latest message, and the latest message asked for MongoDB.

Teams forget decisions because chat buries them. Agents forget because they never saw them. I built Thusfar for a hackathon to fix both problems at once.

Two agents, one room

Thusfar is a Switch room with two agents that have different jobs.

The scribe writes down what the team decides: what they chose, why, and who decided. The builder does the real work, but it reads that log first. If your request breaks an active decision, it stops and asks a human to override the decision.

The name comes from "thus far". The log holds what the team has settled so far, and a human can change it at any time.

What a decision looks like

Every entry in the log has the same shape:

D-001 | ACTIVE
Decision: Use Postgres as the primary database, not MongoDB.
Why: The team knows it, and reporting needs relational joins.
Decided by: David, 2026-11-06
Supersedes: none

A decision is either ACTIVE or SUPERSEDED. When a team changes its mind, the old entry stays in the log and its first line points to the entry that replaced it, such as D-001 | SUPERSEDED by D-005. IDs run in order and nobody reuses them. You can read the log like a history, and it shows how the team's thinking changed.

You talk to the scribe in three commands:

@thusfar-scribe record: <decision>. Why: <reason>
@thusfar-scribe list
@thusfar-scribe supersede D-nnn with: <decision>. Why: <reason>

If you forget the reason, the scribe asks once. A decision with no reason is a rule nobody can argue with later, so it insists.

The builder pushes back

Here is the demo scenario, rebuilt from memory of the flow (the real transcripts are in the repo):

You: @thusfar-builder add a users collection in MongoDB

Builder: Before I start, D-001 is active: "Use Postgres as the primary database, not MongoDB." The reason was that the team knows it and reporting needs joins. David decided this on 2026-11-06. Your request conflicts with it. A human needs to override D-001 before I go ahead.

You: ok sure

Builder: I can't treat that as an override. Do you want to supersede D-001? Say so, give a reason, and the scribe will record it.

The builder turns down a vague "ok sure". Only a clear human override, recorded by the scribe, lets the work go ahead. After that, the builder cites the new decision and builds.

The builder also does not object to everything. If your task matches a decision, it goes ahead and cites it. If no decision covers the task, it says "none relevant" and goes ahead. When it can't tell, it says so and asks.

Why only the scribe writes

The log is a Switch room document, and Switch lets only the agent that created a document change it. I made that a design rule (ADR 0001) instead of working around it.

One writer means one author for the log. The builder cannot edit a decision to make its own task legal, and the scribe never writes code. The two jobs stay apart.

Room documents have a second benefit. Every agent in the room can read one, even right after !reset wipes its context. My sixth test checks this: reset the builder, ask what the team decided about a topic, and it quotes the right entry.

No server, no database, no service code

Thusfar is one YAML template. You import it into Switch Console, select Create all, and both agents and the room appear, with four seed decisions already in the log.

Each part of the project maps to a Switch feature. Rooms give the humans and both agents one shared history. Room documents hold the log. Room instructions give both agents the same rules about the decision format and what counts as an override. The Mattermost bridge lets people join from an ordinary chat app. Without Switch, I would have had to build a chat server, a document store, and an agent runner. With it, I wrote a template and a set of instructions.

Testing an agent room

An agent that "usually" behaves is a bug waiting for a deadline, so I wrote six scenarios and ran each one three times through a real room. The test script posts as a human and checks only the replies a human would see.

# Human says Expected
1 Asks for work that matches a decision Goes ahead and cites it
2 Asks for work that breaks a decision Stops and cites ID, reason, and decider
3 Overrides a decision Scribe supersedes; builder goes ahead
4 Records a decision with no reason Scribe asks once for it
5 Asks for work no decision covers Says "none relevant" and goes ahead
6 Asks what was decided, after !reset Quotes the right decision

All 18 runs passed, but one needed a rerun, and that story is the most useful part of the project.

Scenario 3, run 2 failed on the first full pass. I read the transcript and the agents had done everything right. The scribe recorded the override, and the builder posted its migration file afterward. My test had stopped reading the room while the builder was still working. The bug was in the test, so I fixed the wait and reran that one run. It passed.

If you test agents, expect some failures to belong to your test and not your agents. Read the transcript before you blame the model. Every run's transcript and posted files are in results/runs/.

What it can't do yet

I tested Thusfar on Fedora Linux only. The template uses no platform-specific feature, so macOS and Windows should work, but I haven't checked. The builder is also only as good as the log: a decision nobody recorded does not exist for it. The scribe makes recording cheap, but a human still has to say the words.

Try it

You need Switch Console, Docker, and Claude Code. Then:

  1. Clone the repo.
  2. In Switch Console, import thusfar.template.yaml.
  3. Select Use, keep the defaults, and select Create all.
  4. Open the thusfar-decisions channel and wait for both agents to say hello.

The code is on GitHub under the MIT license, and the 2 min 50 s demo shows the MongoDB challenge from start to finish.

One question for the comments: what is the first decision your team made that someone, or something, later undid by accident? Write it as a decision entry. You may find it has been missing from your log all along.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

AAIF Hits 10 Projects. Its CTO on What to Adopt Now and the Security Gaps Left Open

Tom Smithverified - Oct 23

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelski - Apr 23

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

I Wrote a Script to Fix Audible's Unreadable PDF Filenames

snapsynapseverified - Apr 20
chevron_left
690 Points • 7 Badges
3Posts
1Comments
4Connections
Data Engineer passionate about building scalable data pipelines, uncovering insights from complex datasets, and leveraging AI/ML to solve problems.

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!