# Pair

> Pair persistently with another coding agent. Use for live peer work, inbound `[agent ...]` or `[herdr-pair control ...]` messages, and resuming a pair after context compaction.

- Skill: `hcaiano/pair` (Agent Skill, multi-file: 23 files)
- Install (CLI): `npx skillmds@latest add hcaiano/pair`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hcaiano/pair/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: hcaiano (https://skillmd.com/u/hcaiano)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hcaiano/pair

---


# Pair

Pair two agents on one task: you are the **lead**, and the partner is one of
`claude`, `codex`, `cursor`, `grok`, or `opencode`. The transports require a
different CLI, except headless Codex can use a different account home selected
with `--identity <name>`. The helper proves home separation; separate accounts
do not themselves guarantee independent reasoning. Two different harnesses may use the
same underlying model or provider and still form a valid pair. Keep the
pair and its `sid` alive across tasks, accepted work cycles, and context
compaction, naming its `sid` in every command — one lead can run several
pairs at once. Keep protocol headers and identifiers literal.

Two backends carry the same protocol. Inside Herdr the partner is a visible
pane the user can read and interject in; outside it the partner is a persistent
headless session of the partner CLI.

## Choose the pair

Look for an existing pair before proposing one: a session recorded for this
Herdr tab, or a headless one in this repository (the backend reference names
the exact command). Before a new work cycle, read the measured pool state as
defined in [`references/models.md`](references/models.md). Resume an existing
pair when its pool is available. When its pool is protected, state its use,
pace, and reset, then ask whether to spend it or end the session and choose
another partner. When its partner, model, or effort differs from what the user
just asked for, say so and keep going — respawning discards the pair's whole
history, and a model is changed by ending the pair, not by restarting its pane.

With no pair to resume, take every choice the user or an orchestrate unit has
already made — partner, model, effort, identity, role — as final and do not
ask for it again. Ask the user in plain chat text — no structured-question
tool needed — only for a material choice that is still missing, and start
nothing until they answer. Read pool
state first and do not recommend a protected or unavailable pool. The user may
explicitly choose a protected pool after you state its use, pace, and reset:

- **Partner**: a CLI allowed by the transport rule above. A Codex partner may
  also name an **identity**, the account it runs as; `default` is `~/.codex`
  and a named one is `~/.codex-profiles/<name>`.
- **Model and effort**: `CLI default`, an exact model, or `latest:<family>`,
  with effort supported by that model and backend. Read
  [`references/models.md`](references/models.md) for family selection, live
  catalog lookup, effort controls, and account capacity.

The **role** is the last choice, asked only when nothing has set it; it
decides who holds the write leases by default:

- `peer` (default): equals. Split scopes, one lease per scope, review each
  other's `ready`.
- `executor`: the partner holds the write leases and implements; you plan and
  review. Any individual `task` still redistributes leases.

The backend records partner, model, effort, identity, and role in the session,
so a resumed pair keeps them without asking again. The headless backend also
records the exact model the request resolved to; a session keeps that model,
and a different one means a new pair.

## Choose the backend

Read one backend reference in full and follow it:

- Resume through the recorded backend. An explicit headless request, or an
  orchestrate unit recorded as headless, uses the [Headless backend](references/headless.md)
  even inside Herdr. For a new pair needing `latest:<family>` or a named Codex
  identity inside Herdr, offer that explicit headless route.
- `HERDR_ENV=1` → [Herdr backend](references/herdr.md). Its preconditions
  own the `herdr` CLI check: a Herdr environment missing the CLI stops there
  instead of falling through to a hidden headless session.
- Otherwise → [Headless backend](references/headless.md).

A `[herdr-pair control ...]` line identifies Herdr. An `[agent ...]` header is
shared by both transports: use the recorded session to choose its backend.
Done when the selected session and its backend agree; report ambiguous state
before sending a message.

## Protocol

Messages start with a header:

```text
[agent <from> -> <to> kind=<kind> sid=<sid>]

<body>
```

The Herdr backend adds a `[herdr-pair control seq=<n>: ...]` line under it.

Use these kinds:

- `task`: propose or update the work split and its write leases. Begin a
  mid-flight stop with `STOP — <reason>`.
- `review`: request review with file paths and a short change summary.
- `question`: ask for clarification before proceeding.
- `ready`: report changed files, validation, and residual risk.
- `accepted`: accept the partner's `ready` and advance the work cycle.
- `blocked`: name the user decision required to continue.
- `stalemate`: report the same disagreement repeated twice without movement.
- `handoff`: return control to the user in normal local output.

Send every partner message through the backend's helper. Reserve normal
assistant output for a header-free user handoff.

## Write leases

Give one agent the write lease for each file scope: owner, target files,
forbidden changes, validation, and stop point. The partner stays read-only on
that scope until handoff.

The role sets the opening distribution, and each `task` may redistribute from
there. Under `executor` the partner holds every lease until a task says
otherwise, and you review rather than edit.

Under `peer` the partners are equals: propose a scope split — one write lease per scope,
each partner implementing its own scopes and reviewing the other's `ready` —
and include enough context for independent work; the partner accepts or
counters before implementing. A task with no independent scopes takes one
lease: the holder drives while the partner reviews, and the lease alternates
across tasks.

## Broken-checkout windows

Announce every deliberate broken-checkout window. Before mutation testing,
bisect, or a deliberate revert, send a `task` naming the affected paths and
stop condition; send `ready` after the tree is restored and verified. Do not
wait for `accepted`: the notices are the protection. A partner that has seen
an open window treats that checkout's test results as unusable until the
close notice arrives, and asks rather than reports. Run an experiment that
cannot be announced, or that lasts more than a few minutes, in a separate
worktree.

## Work cycles and persistence

Continue while producing useful artifacts. Five consecutive turns with no new
code, test result, decision, or narrowed option require a `handoff`. Reset the
count on real progress. Settle a factual disagreement with one direct proof or
focused test before it can become a stalemate. Send `stalemate` after the same
judgment call repeats twice without movement.

Two `accepted` statuses complete one work cycle. The initiator gives the user a
local handoff naming the result, verification evidence, unresolved issues, and
every pair pane, worktree, or watcher still active. Both agents may idle; the
next task resumes the same pair and `sid`. The session remains active.

Session renewal is a user decision. If a fresh pair is chosen, carry continuity
in a written checkpoint in its first task.

`blocked` and `stalemate` also hand off without deleting the session. End the
session only when the user explicitly asks to end the pair; the backend
reference owns that command.

