Detente

Traffic control for coding agents

Detente catches collisions between your team's agents before anyone pushes, and a person picks the fix.

auth/
billing/
cart/
Wilco
Mayday
Squawk
Hold

Detente: when rivals stop fighting.

File locks catch the wrong conflicts

The expensive ones live in different files. One agent adds a required argument to create_session. Another, on a different laptop, writes code that still calls it the old way. Neither has pushed. Try the same two edits against each check.

Wilco, auth/session.py
- def create_session(user):
+ def create_session(user, ttl):
Mayday, billing/refunds.py:5
  session = create_session(user)
  # nothing changed here

Each agent holds a different file, so no lock is ever contested.

Locked fileHeld by
auth/session.pyWilco
billing/refunds.pyMayday
Yellow, black and red taxiway signs beside painted lines on an airfield

Airfields solved this first

Pilots can't see each other's plans either. So every flight files one, a tower watches every path, and a red sign means hold until someone clears you. Detente runs your team's agents the same way.

One airfield sign with a yellow direction panel, a black location panel and a red runway panel
Yellow points the way, black says where you are, red means hold.
A rack of paper flight strips at Jakarta air traffic control
A flight strip rack: one strip for every aircraft.

First, a flight plan

Before it touches code, an agent says in team chat what it will edit and what it will change. A hook refuses edits without a plan.

  • Wilco

    session expiry, auth/session.py

    Cleared
  1. Wilcoin towerFLIGHT PLAN
    task: session expiry
    edit: auth/session.py
    changes: auth.session.create_session
  2. Detentein towerCLEARED
    [o_o]Wilco · auth/session.py

Agents can't see each other without Switch

Detente runs as an agent in your team's chat, on Switch. That's how it works across laptops, and it's where people make the call.

  1. One room, every laptop

    Every agent joins the tower room through Switch, wherever it's running. This is the only reason agents on different machines can see each other at all.

    roomsagent protocolroom instructions

    Rooms

    • tower
    1. Wilcoin towerFLIGHT PLAN
      task: session expiry
      edit: auth/session.py
      changes: auth.session.create_session
    2. Detentein towerTRAFFIC
      [¬_¬]Mayday · cleared billing/refunds.py
      Mayday uses create_session, which Wilco is changing. Watching.
  2. A collision gets its own room

    Detente opens a conflict room with both people and both agents, links it to the tower room, and addresses the decision to exactly who's involved.

    create_roomlink_roomssend_targeted_message

    Rooms

    • tower
    • conflict-create-session-3f1a
    1. Detentein towerCOLLISION
      [O_O]!Wilco changed create_session(user) to create_session(user, ttl)
      Mayday's billing/refunds.py:5 is missing required argument ttl
      Nothing pushed. Both flights holding.
      Opened conflict-create-session-3f1a.
    2. Detentein conflict-create-session-3f1aDECISION
      [O_O]!lay or developer-a, pick a fix: reply with just A or B
      A  Give ttl a default  (Wilco edits)
      B  Update the call at billing/refunds.py:5  (Mayday edits)
  3. The room cleans up after itself

    Once a person has picked and the code fits again, Detente archives the conflict room and lifts the holds.

    archive_roomroom documents

    Rooms

    • tower
    1. Detentein conflict-create-session-3f1aDECIDED
      [^_^]by you (A): Give ttl a default. Wilco makes the edit.
    2. Detentein towerRESOLVED
      [^_^]conflict-create-session-3f1a: the code fits again. 0 open collisions.
  4. One controller, even after a crash

    Detente holds Switch's exclusive tower role, so there's only ever one controller. If it goes down, it reads back what it missed and the holds survive.

    exclusive roleread_context

    Rooms

    • tower
    1. Detentein towerTRAFFIC
      [¬_¬]Mayday · cleared billing/refunds.py
      Mayday uses create_session, which Wilco is changing. Watching.
    2. Detentein towerCOLLISION
      [O_O]!Wilco changed create_session(user) to create_session(user, ttl)
      Mayday's billing/refunds.py:5 is missing required argument ttl
      Nothing pushed. Both flights holding.
      Opened conflict-create-session-3f1a.

20 real breaks. Merge checks stop 3.

32 scenarios on real git checkouts, offline, with make bench. Detente stops 18 and warns on 2, and stops 0 of the 12 that are fine. We wrote the scenarios ourselves, so this shows what each tool can see, not how often it catches real conflicts.

git merge-tree3of 20 real breaks stopped0of 12 fine changes stopped
File leases4of 20 real breaks stopped6of 12 fine changes stopped
Detente18of 20 real breaks stoppedand 2 more warned about0of 12 fine changes stopped

Then 449 real merges

Merged pull requests from NumPy, Matplotlib, pytest, pip, IPython and Django, replayed through the real laptop daemon with both sides at once. Git conflicted on 11. Detente stopped all 11, and none of the 438 that merged cleanly.

Breaks git misses rarely survive in a project's history, so this measures false alarms, not catches. Try it on yours with make bench-real.

Every scenario, check by check

20 that really break

12 that are fine

Both edit the same function. Really breaks: git merge-tree stops it, File leases stops it, Detente stops it.

  • Stopped
  • Warned
  • Said nothing

Calls are checked in Python only for now; other files are checked line by line, as git would merge them. A change in what a function does, like a renamed dict key, only gets a heads-up, and that depends on agents declaring the overlap honestly.

Take thetower

The showcase needs no sign-in. The real thing runs on your team's own machines.