Skip to content

Delegate a Bounded Change

Use this procedure for supervised implementation in gepa-adk, whatever the model or harness. The supervisor selects work, decides boundaries, verifies behaviour, commits and opens the pull request. The worker implements a scoped change and returns evidence. Apply the bounded execution limits before dispatch. Use one validation path. Do not add another harness to repeat required repository checks. Each role's duties live once, under shared roles.

Required chain for behaviour changes

Production behaviour changes under src/, and the tests that prove them, follow this order. Do not replace a step with ad hoc edits in the main supervisor session.

Step Role Outcome
1 Supervisor Issue labelled (pi-fit or judgment, size-*) and split when needed
2 Specifier, or supervisor Accepted contract as an issue comment
3 Builder Diff in the allowed paths, red and green evidence, no commit
4 Acceptance-reviewer Fresh session; verdict accept, repair, reject or incomplete
5 Supervisor Commit on the branch after review accepts, then the draft pull request, Copilot review and API squash merge under .claude/rules/pull-requests.md

A chat turn that edits behaviour without a builder dispatch breaks this chain. Only the accepted contract can name a supervisor implementation exception, and that exception still needs step 4. Documentation and policy slices follow the same issue and contract rules. Their contract may omit the builder and names whether independent review runs. After a repair verdict, reuse the builder or send a narrow repair brief, then review the integrated repair before commit.

Worker harnesses

gepa-adk has three worker harnesses. The worker run contract records launch evidence for each.

  • pi runs local models through the delegate-to-pi skill.
  • Claude sub agents run through the Agent tool with definitions in .claude/agents/.
  • Cursor CLI runs Cursor-pool models in print mode, guarded by .cursor/cli.json.

The Claude definitions are builder.md, acceptance-reviewer.md and specifier.md.

Job Harness and model
Lookups and file search Agent tool, haiku
Research and documentation reads Agent tool, sonnet
Implementation and gate repairs Agent tool, opus with builder; pi with a local coder model; or Cursor CLI with a Cursor-pool model
Acceptance review Agent tool, opus with acceptance-reviewer
Specification Agent tool, opus with specifier; or pi with a local reasoning model

The delegate-to-pi skill names the local models and their settings. No author accepts their own work. Every change, including supervisor contributions, needs a fresh reviewer who authored none of it. The supervisor never asks a worker to double-check itself. Do not retry an unavailable worker. Continue directly when the contract authorizes it, or record the outage. An acceptance review runs in a fresh agent, separate from the builder.

1. Make the task ready

The GitHub issue is the durable task record. Its accepted specification lives in an issue comment, never on disk. Pass the exact comment URL and its text in the brief. Never substitute the latest comment. The builder and the Cursor worker never run gh, so the brief carries the contract text.

Request a read-only specification pass only when a concrete design question remains. The specifier agent or a pi reasoning model can answer it. Review its answer before implementation. Skip that pass for a known defect with a decided fix and regression.

For behavioural changes, require a regression that fails before the fix. Check that the failure shows missing behaviour, not a broken fixture. Keep the test and implementation in the same deliverable and the same dispatch.

Ownership, dependencies and evidence freshness

The issue contract names the supervisor, sole checkout writer, mechanical validation owner and dependency issue/PR revisions. The supervisor owns release-round integration. Independent work may proceed in separate worktrees. Shared-code rounds wait for their dependency or name an integration boundary before implementation begins.

After repair, merge or conflict resolution, list the assertions affected by the diff. Reuse evidence for unchanged assertions; independently exercise changed behaviour at the integrated revision before acceptance. Prose-only repairs do not mandate a whole new audit. Record finding → repair revision → independent command/result on the same issue/PR. A builder's repair proof alone is not an independent verdict.

A review budget checkpoint returns incomplete under review completion. Never turn an unfinished review into a clean verdict.

Name one mechanical validation owner, normally the supervisor executing installed pre-commit/pre-push hooks. Workers run assigned focused acceptance checks; reviewers run independent probes and mutations. Reuse passing checks for unchanged revisions; do not have every role repeat the gate table. Hook path filters govern applicability, and an unrun required gate stays unverified. Verify both hook stages in each checkout. Claude's PostToolUse hook is harness-specific; other harnesses must not claim it ran.

Cursor keeps its git/gh deny rules. Supply the restricted-worker evidence packet in its brief. Harness limitations do not waive evidence requirements.

Issue-only work uses the issue and PR, with no required story ID or new ledger. Optional story workflows remain available. Promote reusable lessons to shared guidance; keep local memory as pointers to durable issue/PR evidence.

2. Size by behaviour

Start with one behaviour across two to four production files, plus tests and documentation. Treat this range as an initial tuning rule, not a measured worker capability. Split independent behaviours even when they fit in one file. Keep an invariant together when a split would leave an unsafe intermediate state.

Task shape Dispatch
Decided behaviour with a failing acceptance test Implement directly
Several independent behaviours or acceptance commands Split into named slices
Unresolved port, adapter or ADR decision Resolve the decision first
Small mechanical correction with an obvious proof Use a short repair brief
Broad failure after repeated repairs Reassess the contract and split again

One GitHub issue need not equal one worker task. Name the parent issue and slice in every dispatch.

3. Launch with a bounded brief

Use the template below. Replace every placeholder before dispatch. Keep task context short. Link precise files and evidence instead of copying history.

Use one writer per checkout. The supervisor creates the branch before dispatch, named under .claude/rules/pull-requests.md. Record the branch, base revision and existing modifications before launch. Keep temporary files outside the checkout, in the session scratchpad directory.

For pi, inspect the installed harness help before choosing options. For a Claude sub agent, pass model on every Agent call and name the agent definition. For Cursor, paste the full contract into the brief, because gh is denied to the worker. Planning and review stay read-only. Implementation needs local edit and test permissions.

Role: bounded implementation worker. The supervisor owns acceptance, the commit and the pull request.
Supervisor / worker / harness: <actual assignments; requested model or alias>
Issue and slice: <issue number, one behaviour>
Branch, base revision and existing modifications: <exact values>
Accepted specification: <exact issue comment URL and its text>
Decision and reason: <settled shape and why>
Read first: <targeted files and cited source URLs>
Allowed edits: <production, test and documentation paths>
Out of scope: <adjacent work and tempting incorrect fixes>

Acceptance:
- <observable invariant, exact command, expected result>
- <regression that must stay unchanged>
Run the acceptance test before implementation. Preserve its red output.
Do not weaken the acceptance test to obtain green output.
Validation owner: <one named owner; default supervisor through hooks>.
Run assigned focused checks during edits; leave mechanical gates to that owner.
Report required checks you did not run.

Skip session bookkeeping and backlog sweeps.
Do not edit CLAUDE.md, .claude/rules/, .claude/hooks/ or other policy files.
Do not run gh, commit, push, open a pull request, pass --no-verify or add a gate suppression.
Do not run pytest -m api unless this brief authorizes it.
Preserve unrelated changes. Do not reset, clean, stash or restore them.
If required edits exceed the allowed scope, return the missing scope.

Return: changed paths, red/green commands and output, unrun checks,
remaining gaps, then the receipt: actual harness, loaded instructions,
effective permissions, your model identity, duration and usage counters
(`unknown` when unavailable). Leave the diff for review and stop.

Brief checklist

Check each rule before you dispatch a brief.

  • Paste the accepted comment text and its URL. Workers that cannot run gh get the restricted-worker packet.
  • Name one mechanical validation owner, normally the supervisor through the installed hooks.
  • A change to a message or behaviour needs a grep of tests/ for the old text. Name every file that pins it in the allowed paths.
  • A call-site sweep covers src/, tests/, docs/, examples/ and scripts/.
  • Model strings in docs and examples follow docs/reference/model-selection.md.
  • A new documentation page needs a mkdocs.yml nav entry, or the brief names that as out of scope.
  • Write #N only for a GitHub issue or pull request.
  • Every function, class or module the change touches gets its docstring reviewed and updated in the same change. The commit hook runs docvet check --staged and refuses recommended findings (stale-body, stale-import, missing-examples) as well as required ones. stale-signature is line-overlap based: a comment added to a def line or an annotation unquoted counts as a signature change, so the docstring must be touched with it.
  • The brief ends with the staged docvet command exiting 0 through a temporary index, because a worker may not run git reset. The brief defines $SCRATCH as the session scratchpad directory:

    export GIT_INDEX_FILE="$SCRATCH/index"
    git read-tree HEAD && git add -A src tests docs examples scripts && uv run docvet check --staged; echo "docvet exit=$?"
    unset GIT_INDEX_FILE
    

    --staged vets every staged .py file except those under tests/, scripts/ and .claude/ (docvet's default exclude plus extend-exclude). The docvet-scripts-examples hook vets staged scripts/ and examples/ files by name (#521); run uv run docvet check scripts/foo.py to reproduce it.

4. Accept behaviour and finish

Read the diff against the agreed scope. Run an independent probe of the defining behaviour. Test real production behaviour, not a fake's own return values. Confirm that the regression can detect the original defect.

The gate inventory is the gate table in the repository rules and .pre-commit-config.yaml. Never weaken a gate or report an unrun gate as green.

The acceptance-reviewer duties and verdicts live under shared roles.

Isolated failure proof

Keep the reviewed checkout unchanged throughout acceptance. The review brief names a unique scratch directory in the session scratchpad, outside the checkout. Only that copy may receive review mutations. Copy the tested snapshot and record its revision before changing it. Do not share mutable source, tests, configuration or generated files with the reviewed checkout. Confirm that gepa_adk imports from the scratch copy before the probe. Run the unmutated probe, then the mutation, then record the expected failure. Keep mutation evidence separate from validation of the accepted snapshot. Do not run gates against a copy another actor is mutating. Scratch permission never permits edits to the reviewed checkout or unrelated files.

Review dispositions and continuation

Return a failed assertion and a narrow correction brief when review finds a defect. Default to one implementation, one independent review and one repair dispatch per behaviour. Before another dispatch, report the unresolved assertion and why it can resolve it. Reassess the contract when the same repair fails again. Preserve the useful diff and evidence during reassessment. Never treat supervisor confidence or mechanical gates as independent acceptance.

The supervisor commits on the branch and opens a draft pull request per .claude/rules/pull-requests.md. The pull request body follows .github/PULL_REQUEST_TEMPLATE.md and passes through --body-file. The commit carries worker trailers from the worker's reported identity. The authoritative API squash recipe in the PR rules preserves those trailers, because the squash replaces the branch commits. The pre-commit and pre-push hooks and CI are the gate before main. Passing tests do not authorize a real LLM call.

5. Record outcomes and tune

Record proof and remaining work on the issue or the pull request. Keep one record per slice. Link the commit instead of copying its evidence.

Field Evidence
Identity Issue, slice, base revision, supervisor, worker model, harness and session identifier
Input Accepted specification, planning or implementation
Size Behaviour count, production files, tests and documentation
Cost Elapsed time, reported tokens if available, supervisor repair time
Outcome Accepted unchanged, accepted after repair, rejected or externally blocked
Proof Red and green output, independent probe, gate results, accepted commit
Lesson Specification, implementation, test, harness, environment or external failure

Compare accepted behaviour and supervisor repair time, not lines written or worker confidence. Group measurements by model, harness, reasoning setting, task type and size. Treat unavailable measurements as unknown. Do not combine unlike token counters. Separate external blocking from implementation failure. Persist recurring rules here. Keep task facts in the accepted contract.