← All churts

My Agents Were Waiting on Me to Click Something I Had Already Approved

My Agents Were Waiting on Me to Click Something I Had Already Approved

The wait that isn’t hard

Look at where an agent’s time goes in a swarm and the slow part is rarely a hard problem. It’s the gap between I approved this and something started it. The work was already decided. It sat there until I, or a client I had open, clicked.

v0.6.0-beta.1 closes that gap. It follows the web UI in 0.2 and the console redesign in 0.5, and if you’re new here, start with the introduction.

Keep-going starts the work

Keep-going mode used to wait for a client or for the desk to act. Now the daemon does it. It continues approved items whose lane never ran or whose last run a crash cut off, then starts approved items with no lane, in rank order, until the run slots are full.

The part I care about is what it can’t do. It adds no new authority: everything it starts was already approved by something else. Every start passes the same gate as the desk’s, so the spend cap, run cap, idle time, end of day and starts per lane all still hold, with the reason in the feed. It never answers a decision, approves, merges, pushes for me, tags, releases or deploys.

A new lane takes its scope from the item’s plan document, a line like Scope: internal/x/**, docs/y.md. If the plan names no scope, the item is held and the feed says so. I’d rather it stop and tell me than guess a scope. shepherd keep-going status now ends with a summary of what the mode did: items started, runs finished and failed, merge requests, and why and when it stopped.

A failed round moves to Claude Code

When a round of fixes on a merge request’s failed pipeline or review threads doesn’t close what it was sent to close, the next round runs on Claude Code instead of the agent that took the first one. The first round is never escalated. Repeating the same attempt with the same agent was the pattern I kept watching fail.

Ask Crook why

Crook is the part of Shepherd that answers “may I do this now?” Every answer a call site acts on is now written to the daemon’s store with the rule that decided, its stage, the actor and a redacted reason. shepherd crook why <id>, crook why run <id> and crook why lane <name> explain a past hold or refusal. crook log and crook rules list and count verdicts, and all of them take --json.

Muster tidies what went stale

Muster is a plain-code upkeep pass over artifacts, lanes, runs, next-up items, questions and decisions. It tidies what is safe and can be undone, and raises a finding for the rest. Every fix is a row in a log and can be undone for a number of days. It has no routes, CLI or web screens for its findings yet, so for now it works without much of a face.

Approved checks stay put

Lanes can set approved check files apart. I approve them, they’re left out of a build lane’s scope, and lane ship refuses a branch that changes them. An agent shouldn’t be able to make its own tests pass by editing the tests.

Merge rules, in shadow mode first

A repo can now have a merge rule in .shepherd/rules/<id>.md. In shadow mode Shepherd works out what the rule would have done for each open lane merge request and records it. I still merge. Shadow mode never merges, approves, retries a job or posts. shepherd crook shadow lists the records, so I can see how a rule would have behaved before I trust it with anything. Going live isn’t built yet: there is no forge merge call, revert or switch.

What’s next

Alongside Shepherd we’re working on uBixKelpie. It already reviews merge requests with AI and leaves its findings as review threads, and we’re building toward having it triage those threads and fix them.

Upgrade, and what’s rough

From a running install, press Upgrade in the web UI, run shepherd update upgrade, or use /update upgrade in shepherd chat. Nothing in this release breaks existing use, but store changes are forward-only, so going back a version can mean a fresh store. The git-hook guards for agents (they’re told never to skip hooks, and a run seen doing so is flagged) are cooperative, not a boundary.

It’s a beta and interfaces may still change. Grab it from the v0.6.0-beta.1 release, and tell me where it breaks.

← All churts