Loop protocol / Set it up

From an empty repository to a first loop

Prerequisites, the six steps to a first loop on Claude Code, a first week that builds trust in it, and the habits I keep outside a loop.

Before you start

  • Claude Code with plugin support, git, and Python 3.9 or later for the hooks.
  • The Backlog.md CLI. A loop admits work only from a board.
  • A command that proves a change. I use just check; any command that fails on a broken change works.
  • Optional: the CodeRabbit CLI, dsreview and the GitHub CLI. Without them, delete their lines from the run's LANE.md and the protocol falls back to the Opus reviewer.

A loop pays off on a repository with a real test suite and a queue of tasks that each fit in one worktree. With neither, start with ordinary sessions and the habits at the end of this page.

Six steps to a first loop

  1. Install the plugin from rknightion/agent-workflows:

    /plugin marketplace add rknightion/agent-workflows
    /plugin install agent-workflows@rob-knight

    Start a new session. claude plugin details agent-workflows should list one skill, five agents and the hooks. The hooks arm only in a session launched as a loop root.

  2. Give the repository a board (backlog init) with some ready tasks, each with acceptance criteria a lane can prove. Run files live in codex/, which is never committed:

    mkdir -p codex && echo 'codex/' >> .gitignore

    The board's config is where the gate becomes the definition of done, so every task carries it as an acceptance criterion. From the repository in In practice:

    statuses: ["To Do", "In Progress", "Parked", "Done"]
    definition_of_done:
      - "just check"
      - "For area:frontend tasks: a fresh-context agent given only a screenshot of the deployed screen
         and a one-paragraph persona brief correctly identifies the screen's purpose, what it found and
         the next action; log the result per screen"
    labels: ["seam", "area:backend", "area:frontend", "area:infra", "area:docs", "needs-triage", "later"]
    zero_padded_ids: 4
    auto_commit: false
    remote_operations: false

    Parked is a status of its own, so a task the loop can't finish never looks like work in progress. The second definition of done is a cold read: a screen passes only when an agent that has never seen the product can say what it's for from a screenshot. Setting up Backlog.md for agents explains the other settings.

  3. Write LOOP.md at the repository root. tier is routine or guarded, gate is the command that proves a change, and the other two keys name required CI checks and a telemetry stack, or none.

    # Loop: my-repo
    tier: routine
    gate: just check
    ci-required: none
    grafana-stack: none
    
    ## Lane brief
    
    - Build and test with `just check`; it must pass before a candidate is handed back.

    Check it with loop-lint loopmd LOOP.md --offline.

    A small file is fine to start. The one from In practice grew to about 120 lines over a month of loops. Its head:

    # Loop: <repository>
    tier: guarded
    gate: just check
    ci-required: ci-success, integration-success
    release-on-push: yes
    deploy-on-push: yes
    baseline-red: none. Base `just check` on <sha> passed. Skipped or unexecuted legs are not passes.
    grafana-stack: <stack>
    
    Gate notes: `just check` is the gate (definition_of_done in backlog/config.yml); run `just`
    with stdin from /dev/null. Heavy gates (`just check`, integration packages, the browser suite)
    run on the remote gate runners, paced with gaterun-slot.
    
    ## Red main stops the line
    ## Landing
    ## Standing authority
    ## Credentials
    ## Traps
    ## Mutexes

    Each section holds something a lane got wrong once:

    • Red main stops the line. A red CI check on main means the root lands nothing new until the fix for that check does. A red check on the release pull request doesn't count.
    • Landing. How candidates are composed and gated before a push: continuous landing, one lander at a time, the composed gate's legs run in parallel from a committed tree.
    • Standing authority. Live actions the owner has approved for every loop, quoted, and the ones that still wait for a person, such as a production promotion.
    • Credentials. Where each environment's access comes from and how to prove it live, never the secrets themselves.
    • Traps. One line each: "release-please owns its files", "just lint falls back to go run when the local linter isn't at the pinned version, which auto mode denies", "CodeRabbit reports no review for a diff with no added lines".
    • Mutexes. What can't run twice at once (one container test suite per lane), the lane cap, and the slot count the root meters admission by.
  4. Prepare a run with /agent-workflows:loop. It reads the board, asks every decision the first wave needs in one round, writes the charter, the lane rules and a launch file, and lints them.

  5. Start a fresh session with the command on the launch file's cmd: line and paste the rest of the file as the first message. The root works the queue and writes codex/closeout-<date>-loop<N>.md when nothing ready is left.

  6. Pass that closeout to the next run: /agent-workflows:loop <closeout path>. Its Parked and For ratification sections are where the next charter starts.

A first week

Trust in a loop comes from reading what it did, so make the first runs small enough to read.

  1. Run one loop with tier: routine on five to ten small tasks and stay in the session. Answer its questions as they come and read every lane return in the run directory.
  2. Read the closeout against git log. Anything it calls Landed should be on main and green in CI; anything Parked should say what would unpark it.
  3. Move what you corrected by hand into LOOP.md lane rules, or into the board as tasks, so the next run starts from it.
  4. Only then try a longer run you don't watch, and a guarded tier on code that touches auth, data or deploys.

Habits outside a loop

Most of my sessions aren't loops. The same rules apply to them, and these habits matter most:

  • Decisions come as a prompt with a recommendation. Scope, preference and anything irreversible go to me with options and trade-offs; engineering choices inside agreed scope the agent makes and states. Operating model.
  • Investigate means read-only. "Assess", "diagnose" and "review" change nothing and end with proposed actions.
  • Review is proportionate. CodeRabbit before any commit that changes code; a fresh agent's adversarial review on a plan I asked for; nothing extra on a small change.
  • Out-of-scope findings become tasks on the board, not a line in chat that scrolls away.
  • Prompts are handed back whole, never as a diff to apply by hand. Full prompts, never deltas.
  • Compaction writes down what can't be re-derived first, then compacts. Compaction cycle.

The loop's own rules are in the contract and the Claude Code harness.