Skip to content

Add the paired-agent workflow for issues - #152

Open
Oleg-Melnik wants to merge 6 commits into
masterfrom
pair-agents-workflow
Open

Add the paired-agent workflow for issues#152
Oleg-Melnik wants to merge 6 commits into
masterfrom
pair-agents-workflow

Conversation

@Oleg-Melnik

Copy link
Copy Markdown
Collaborator

Summary

Adds a workflow that hands one GitHub issue to two different AI agents. One
plans and implements it; the other reviews the plan before any code is written,
and the resulting diff afterwards. They exchange turns through a single Markdown
document under .agents/work/, which is gitignored.

A GitHub issue is the only accepted input. That is what makes the second opinion
meaningful: the reviewer checks the work against acceptance criteria that
neither agent wrote, and the run stops on the first turn if the issue does not
state what to do and what "done" means.

Neither agent may change Git state. The driver compares HEAD, every ref, and
the staged index after each turn and aborts on any difference. Publishing a pull
request is opt-in and performed by the driver itself once a run has finished, so
the prohibition on the agents holds either way.

Both agent commands keep their CLI's approval and sandbox boundaries by default,
and a command containing a known bypass flag is refused unless the caller
confirms an external isolation boundary.

Changes

  • .agents/workflows/pair.sh — the driver: reads the working document's state,
    invokes whichever agent owns the turn, validates every transition against the
    protocol, and optionally opens a draft pull request afterwards.
  • .agents/workflows/pair-test.sh — a regression suite that exercises the
    driver against a throwaway repository with stub agents.
  • .agents/skills/pair-workflow/ — the protocol both agents read, the working
    document template, and the interface metadata.
  • .claude/commands/pair.md — a /pair <issue> entry point that relays the
    agents' questions and results in the conversation.
  • PAIR_AGENTS_RUN_GUIDE.md — the user guide, including how to change the model
    and effort of each agent.
  • README.md, .agents/skills/README.md — pointers to the above.
  • .gitignore — ignore the per-task working directory.

Oleg-Melnik and others added 2 commits July 31, 2026 19:20
Two agents work one GitHub issue through a shared Markdown document: one
plans and implements, the other reviews the plan before any code is written
and the resulting diff afterwards. The issue is the only accepted input, so
the reviewer checks the work against acceptance criteria that neither agent
wrote.

The driver invokes whichever agent owns the turn, keeps a transcript per
turn, and validates each transition against the protocol. Neither agent may
change Git state; the driver compares refs and the index after every turn and
aborts on any difference. Opening a pull request is opt-in, performed by the
driver after a finished run.

Both agent commands keep their CLI approval and sandbox boundaries by
default, and a command containing a known bypass flag is refused unless the
caller confirms an external isolation boundary.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Oleg-Melnik Oleg-Melnik self-assigned this Jul 31, 2026
Oleg-Melnik and others added 3 commits July 31, 2026 20:51
Codex's `workspace-write` sandbox excludes gitignored paths from its
writable set, and `.agents/work/` is gitignored by design — the working
document is a scratch artifact that is never committed. `agent2` could
therefore read the document but not write its review into it, and every
run aborted with "agent2 did not modify ... plan.md".

Name the work root with `--add-dir` in the default `AGENT2_CMD`. This
widens the sandbox by exactly one directory inside the repository, and
`unsafe_agent_roles()` does not classify it as a bypass flag, so the
approval and sandbox boundaries are otherwise unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`pair.sh` runs `agent1` with `--setting-sources project`, which loads
`.claude/settings.json` only. That file did not exist, so every Gradle and
`java` invocation was refused with "This command requires approval", and
the agent handed off an implementation it had never compiled. `agent2`
then had to spend its review round on that fact instead of on the code.

Allow the verification commands `AGENTS.md` prescribes — module `test`,
`check`, `compileKotlin`, `detekt`, the license-report tasks, the local
publishing tasks, and the JDK checks — plus the read-only `gh` commands
the agents use to inspect issues and pull requests.

Publishing tasks (`publish`, `publishCodegenPlugins`) are deliberately
absent: `AGENTS.md` reserves those for CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four failures showed up in one run of issue #148, none of them in the
protocol itself. Each is addressed where it belongs.

The Git tripwire accused the agent. It compares two snapshots taken around
a turn and cannot see who moved between them, so a user switching branches
mid-run produced "agent2 wrote to Git". Report the movement, name the
innocent cause, and leave attribution to the reader. The skill and the run
guide now say the guard cannot attribute, and the guide asks the user not
to touch Git while a run is live.

A turn that died immediately said only that the agent exited non-zero. The
two things that actually fail first — a CLI on `PATH` but not signed in,
and a model identifier only the API rejects — are now named in that
message, and the run guide separates being on `PATH` from being
authenticated.

Verification could report green from cache. When every compile and test
task is `UP-TO-DATE`, `BUILD SUCCESSFUL` describes an earlier build, not
the change in the worktree. The tester skill now requires reading the task
list and forcing the work with `--rerun-tasks` before calling a result
green.

Finally, record why `--add-dir` and `.claude/settings.json` are
load-bearing, in the protocol and in the guide, so neither is dropped by
someone overriding an agent command.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Oleg-Melnik
Oleg-Melnik force-pushed the pair-agents-workflow branch from 29970fa to 388da74 Compare July 31, 2026 20:58
Both fixes in this branch live in configuration rather than in the driver's
logic, so nothing failed when they were wrong until a turn was already
running — several minutes in, with a message about the symptom. These
assert them directly.

`--add-dir` is read out of the `AGENT2_CMD` assignment rather than from the
usage output, which describes the flag in prose: matching that text passed
even with the flag deleted from the default that actually runs. The
companion check asserts `.agents/work` really is gitignored, which is the
reason the flag is needed at all.

The `.claude/settings.json` checks cover the file agent1 loads under
`--setting-sources project` and the verification tasks it must allow.
Without them agent1 hands off an implementation it never compiled.

Each check was confirmed to fail when the thing it guards is removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Oleg-Melnik
Oleg-Melnik marked this pull request as ready for review July 31, 2026 23:14
@Oleg-Melnik
Oleg-Melnik requested review from armiol and dpikhulya July 31, 2026 23:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant