Standpat™ How it works Tour Install

A session with Standpat™

One sitting in a throwaway repository, from the 20-minute walk on the install page. Every reply is Standpat's own, copied from a rehearsal; your times and versions will differ. Lines marked › are what you type in the chat.

  1. Name what must not change

    Each repository gets a handbrake file, .standpat/handbrake. You list the lines the agent may not change, by path or by phrase.

    check, in your own terminal, says whether the file is valid and gives its version.

    .standpat/handbrake
    {
      "standpat_format": 1,
      "project": "Play",
      "must_not_change": [
        {"id": "app", "label": "The app", "matcher": "path", "pattern": "app.py", "class": "other"}
      ],
      "done": "",
      "who_may_widen": ["owner"]
    }
    Your terminal
    python3 ~/standpat/standpat/standpat.py check ~/standpat-play
    Standpat: the handbrake at ~/standpat-play/.standpat/handbrake is valid, version <version>.
    …
  2. brake, and the goal

    Every chat starts free and holds nothing. Type brake, name a goal, accept the handbrake's version. None of these words reaches the agent.

    The status line under the prompt shows the goal, moves today, minutes this sitting and what to type now.

    In the chat
    › brake
    Standpat: the handbrake is on in this chat from the agent's next action; type `free` to turn it off. Type `goal <name>` to say what this chat is for, then `handbrake accept <version>` to accept what must not change, then your message for the agent. Nothing was sent to the agent.
    
    › goal demo
    Standpat: goal demo is open. Type `handbrake accept <version>` to accept the handbrake, then your message for the agent. Nothing was sent to the agent.
    
    › handbrake accept <version>
    Standpat: handbrake version <version> accepted. Type your message for the agent. Nothing was sent to the agent.
    ›
    Standpat · demo · moves 0 of 3 today · 0 of 240 min this sitting · nothing held · load 4 ■□□□□
  3. The agent tries a change, and it is held

    Ask the agent to change app.py. Its edit is not run. The agent's output shows what it tried, the line it crosses, the change itself and what it costs.

    In the chat
    › Change app.py so it prints hello, world.
    
    Standpat: hold 1, held for a stamp: Edit on app.py.
    Lines it crosses: The app.
    - print("hello")
    + print("hello, world")
    Cost: 1 handbrake move. Handbrake moves today so far: 0 of 3.
    Type `stamp` to allow exactly this, once, or `park` to stop.
    ›
    Standpat · demo · moves 0 of 3 today · … · type stamp …
  4. stamp lets exactly that through

    One stamp allows that one action, once, for 30 minutes. Send the agent any message and it runs it.

    In the chat
    › stamp
    Standpat: stamped Edit on app.py, held at <time>, crossing The app. The action is allowed for 30 minutes. Send the agent any message and it will run it.
    
    › Go ahead.
    ›
    Standpat · demo · moves 1 of 3 today · … · nothing held …
  5. park when you walk away

    Type park before you go. Anything held for a stamp is not run.

    In the chat
    › park
    Standpat: parked; anything held for a stamp was not run, and this sitting used 1 handbrake move. When you are back, send your next message as usual and the card comes with it. Nothing was sent to the agent.
    ›
    Standpat · … · parked since <time> …
  6. Coming back

    When you are back, send your next message as usual. It goes through, and the agent is told to show you the return card first: the goal, what it may not change, the budget, and what was done and refused while you were parked.

    The agent shows the card first
    › I'm back.
    
    Goal: demo
    …
    Agent may not: The app
    …
    Done while parked: nothing
    Refused while parked: nothing

Questions

Is it safe to install?

Before it writes, install proves that taking its own lines back out of the new settings file gives your file back byte for byte, so nothing of yours is removed or changed; the one byte it adds to your part is a comma after the item its block follows. If it cannot prove that, it refuses, prints one line saying why and writes nothing. uninstall takes the entries out again under the same proof. Install also refuses when run from inside an agent session, and changes nothing.

Does it slow the agent down?

Standpat runs as a hook: the agent app runs its check before each action the agent takes. A shell command it can prove only reads passes, and in a chat that is free it holds none of your lines. Only an action that would change a line you named waits, until you type stamp.

What does it change on my machine?

Three things, and only these:

  • ~/.claude/settings.json, the agent app's settings file: one block of entries is added after yours (eight hook entries and a status line). If your settings file already has a status line of your own, install keeps yours and adds none.
  • A hook file and a copy of the command line, in /Library/Application Support/Standpat/<version>/. --system asks for your password through sudo once, to copy the hook into a folder owned by root, so the agent, which runs as you, cannot change the gate it has to pass.
  • A folder ~/.standpat, with Standpat's state and your user log.

How do I remove it?

In your own terminal:

python3 ~/standpat/standpat/standpat.py uninstall

It prints settings: restored byte for byte. among its lines; cmp ~/settings.before-standpat.json ~/.claude/settings.json then prints nothing if you changed nothing else in the file. What stays: ~/.standpat with your user log, each repository's .standpat/ with its handbrake and log, and the hook copy in /Library/Application Support/Standpat/, which sudo rm -r "/Library/Application Support/Standpat" removes.

What does it cost?

Version 0.15.0 is a preview, and it is free to download.

Standpat 0.15.0, a preview.

For a Mac with git and Python 3.9 or later. The install takes 5 minutes and the full walk 20.