Resolve Follow-ups
Turn a bounded set of recorded follow-ups into independently verified pull
requests. Preserve every item that cannot pass the reproduction and authority
gates.
Choose the execution mode
- Treat an invocation without a specific follow-up path as a sweep. Select
workers from the repository backlog and return one combined report.
- Treat an invocation carrying one follow-up path, base SHA, attempt identity,
owner token, branch, and worktree as a worker. Resolve only that item and
return one terminal outcome.
- Keep Schedule or Routine frequency outside this skill. One invocation is one
sweep, never one recurring schedule per follow-up.
Sweep the backlog
Resolve this skill's directory, then use
scripts/resolve-follow-ups.sh from that directory. The script is the
deterministic boundary for ordering, fresh-base identity, worktree creation,
attempt suppression, and cleanup.
- Run
list --repo <root> to fetch the remote default branch and obtain every
valid candidate in discovery order plus every invalid-follow-up. Report
invalid files without filling in their missing evidence. Do not enumerate a
possibly stale coordinator checkout.
- For each candidate in order, run
identity --repo <root> --follow-up <path>. Continue until three eligible
workers have been started or the ordered backlog is exhausted.
eligible is only a snapshot, not a reservation. The platform adapter must
win the attempt's atomic claim or prepare result before launching a
worker; skipped-unchanged ... claimed <owner> [<worktree> <branch>] means
another sweep already owns the unchanged follow-up content. That active
ownership and a recorded pull request survive unrelated default-branch
advancement; terminal non-PR results become retryable after that advance.
- For
skipped-unchanged:
- When the result carries
claimed and an owner, do not dispatch it again;
another worker already owns the exact content and base identity. If the
adapter proves that owning process has ended without a terminal result,
clean up its exact bound worktree when one is reported, then run recover --repo <root> --attempt-key <key> --owner <owner>. Never recover an active
or uncertain worker merely because its claim is old.
- Preserve a prior
not-reproduced, needs-shaping, or blocked result
until the follow-up content or remote default-branch SHA changes. Terminal
identity output retains owner <owner> [<worktree> <branch>]; if that
worktree still exists after its worker ended, use those exact coordinates
for cleanup before starting the base-change retry. A base advance does not
hide an outstanding terminal worktree.
- When the result carries
pull-request and a URL, check that pull request.
Keep it skipped while open. After an unmerged close, run clear for that
exact base identity before retrying. A merged pull request should remove
the follow-up on the updated default branch; report a mismatch instead of
opening a duplicate. If the path was deleted and later re-created, treat it
as a fresh follow-up lifetime even when its Markdown matches the old item.
- Establish whether candidate scopes are independent before running workers
concurrently. Process uncertain or overlapping scopes separately while
retaining a distinct worktree and pull request for each item.
- A failed worker does not cancel other independent workers. Never exceed
three actual workers in one sweep.
Launch one isolated worker per item
Give every worker only its follow-up path, verified base SHA, attempt identity,
owner token, branch, worktree, and the worker contract below. The owner token is
required when binding the checkout, recording the outcome, and cleaning up, so
one worker cannot overwrite or remove another worker's attempt. The dispatcher
also reserves each canonical worktree path repository-wide; never bypass a
reservation failure by reusing another attempt's checkout.
Claude Routine
Use a subagent with isolation: worktree when the active installation has a
creation-time WorktreeCreate policy or equivalent check that stops on fetch
failure and guarantees the identity base SHA. Require the subagent to compare
its HEAD with that SHA before editing.
Before dispatch, run claim --repo <root> --follow-up <path> --base-sha <sha>.
Dispatch only a claimed <attempt-key> <owner> result. As the worker's first
action, run bind --repo <root> --attempt-key <attempt-key> --owner <owner> --worktree <worktree> --branch <branch> from the native checkout. A bind
failure stops the worker before editing. Claude owns removal of a native
worktree after the coordinator records the terminal outcome.
When native creation cannot make that guarantee, run prepare to create and
verify the worktree, then start a top-level headless Claude worker from that
directory. Do not nest a Claude CLI process merely to duplicate isolation the
native subagent already guarantees.
Codex Scheduled task
Treat the scheduled task as coordinator only; its background worktree does not
isolate item workers. For each eligible item:
- Choose a unique worktree path and branch whose name includes the follow-up
slug and a short attempt-identity suffix.
- Run
prepare --repo <root> --follow-up <path> --worktree <path> --branch <branch>. Continue only for prepared <worktree> <branch> <base-sha> <attempt-key> <owner>; a concurrent sweep can instead return
skipped-unchanged without creating a checkout. The dispatcher persists the
canonical worktree target before creation, so an interrupted prepare is
reported with the same claim owner, worktree, and planned branch for exact
cleanup rather than becoming an anonymous checkout.
- Start a top-level non-interactive Codex worker with
codex exec -C <worktree> --sandbox workspace-write <prompt>. Configure only the network
and approval capabilities needed to verify, push, and open the pull request.
Do not use a writing subagent that inherits the coordinator's working
directory as a substitute for per-item isolation.
Apply the worker contract
Verify the boundary
- Confirm that the worker
HEAD equals the supplied base SHA before any edit.
- Read the one follow-up file and verify all five fields: symptom, observed
evidence, suspected cause, what was tried, and proposed next step.
- Keep the worker diff limited to the selected item. Stop as
blocked when the
base, checkout, permissions, or environment cannot be verified.
Pass the reproduction gate
- Reproduce the symptom through the recorded command, route, test, or
environment before modifying product source.
- Retain concrete baseline evidence such as a failing assertion, exit status,
observable output, or runtime state.
- Return
not-reproduced with the attempts and next useful evidence when the
symptom does not reproduce within the bounded run. Make no speculative source
change or resolution pull request.
When reproduction reveals a different out-of-scope defect, preserve the
selected item and return the new symptom, observed evidence, suspected cause,
what was tried, and proposed next step to the coordinator. Do not leave the only
record in the disposable worker. The coordinator serializes these records in
its own checkout through project-knowledge when available, or writes the same
five fields to docs/follow-ups/<symptom>.md. Before cleaning up the worker,
commit that record and publish a dedicated ready-for-review follow-up-record PR;
do not mix it into the selected item's resolution PR. A local coordinator change
or closing-message copy is not a durable handoff.
Confirm authority to fix
- Derive intended behavior from current tests, specifications, decision
contracts, supported runtime behavior, or an unambiguous compatibility
contract.
- Continue only when the intended result is already settled and can be checked
deterministically.
- Return
needs-shaping without a patch when the item requires a product
decision, public-contract change, or material trade-off. Name the unresolved
choice so a later shape-idea session can settle it.
Repair through evidence
- Make the smallest coherent fix and add or retain a regression check through a
stable public seam when available.
- Re-run the reproduction after each meaningful candidate change. Continue only
while new evidence supports another attempt; repeated failure without new
evidence ends as
blocked.
- Run focused deterministic checks and the affected repository-supported
runtime verification. Static checks do not close a runtime symptom.
- Treat the item as resolved only when the original failure passes and relevant
regression checks remain green.
Publish the result
- Delete the resolved follow-up in the same commit series as the verified fix.
Git history is its archive.
- Push only the worker branch and open one ready-for-review pull request. Include
before-and-after reproduction evidence, checks run, and remaining uncertainty.
- Do not combine another follow-up and do not merge the pull request.
- Return
pull-request with its URL. If publication or verification fails,
retain the follow-up and return blocked rather than claiming resolution.
Finish the worker response with a compact block containing outcome,
follow-up, base-sha, attempt-key, owner, pull-request when present,
the decisive reproduction or blocker evidence, and any newly discovered
follow-up record for the coordinator. The coordinator uses this block to record
the exact attempt; prose alone is not a terminal result.
Record and clean up each outcome
After the worker returns:
- For a pull request, run
mark --repo <root> --follow-up <path> --base-sha <sha> --owner <owner> --outcome pull-request --detail <URL> so later sweeps
do not duplicate it.
- For a non-PR result, run the same
mark command with --outcome not-reproduced, --outcome needs-shaping, or --outcome blocked and use
--detail for compact decisive evidence or the next useful condition. A
different worker cannot replace the first terminal result. The recorded
identity is disposable local automation state, not a status field in the
tracked follow-up.
- For a clean non-PR worker that never moved beyond its base, run
cleanup with
cleanup --repo <root> --worktree <worktree> --attempt-key <attempt-key> --owner <owner>. For a PR worker, run the same cleanup only after its exact
HEAD is visible on the remote branch. The script removes only the worktree
bound to that exact claim and preserves the local branch so cleanup cannot
race a new checkout and delete its ref. It revalidates the repository-wide
coordinate reservation before removal, safely deinitializes clean submodules
through isolated Git metadata without changing shared repository settings, and
leaves Git's final dirty-worktree refusal enabled. It refuses dirty,
unpublished changed, mismatched, foreign, or repository-root targets.
- When an owning process ended before
mark, first inspect its bound branch for
publication and an existing pull request. Record a found pull request with
mark; if a branch was published without one, finish or explicitly block that
publication rather than discarding its identity. Only when no publication
occurred, use cleanup first when its recorded bound or preparing worktree
exists, then recover with the exact attempt key and owner. If preparation
stopped after persisting the target but before creating its path, skip cleanup
and recover the missing target directly; recovery removes an exact stale Git
worktree registration before releasing ownership. Recovery refuses live
worktrees, published branches, and terminal outcomes. A preparing target is
removed only when its checkout is clean and still detached at the base or its
exact prepare-owned branch can be deleted with a head compare-and-swap.
Return one compact sweep report using only pull-request, not-reproduced,
needs-shaping, blocked, invalid-follow-up, and skipped-unchanged. Link
each pull request and state the evidence or next condition for every other
outcome. Never label a retained follow-up as fixed.
1---2name: resolve-follow-ups3description: Resolve evidence-backed `docs/follow-ups/*.md` through a bounded manual, Codex Scheduled task, or Claude Routine sweep. Use when project follow-ups should be reproduced before editing, handled by one isolated worker and branch per item, and published as independent ready-for-review pull requests without automatic merge. Do not use to invent intended behavior or merely record a newly discovered follow-up.4---56# Resolve Follow-ups78Turn a bounded set of recorded follow-ups into independently verified pull9requests. Preserve every item that cannot pass the reproduction and authority10gates.1112## Choose the execution mode1314- Treat an invocation without a specific follow-up path as a **sweep**. Select15 workers from the repository backlog and return one combined report.16- Treat an invocation carrying one follow-up path, base SHA, attempt identity,17 owner token, branch, and worktree as a **worker**. Resolve only that item and18 return one terminal outcome.19- Keep Schedule or Routine frequency outside this skill. One invocation is one20 sweep, never one recurring schedule per follow-up.2122## Sweep the backlog2324Resolve this skill's directory, then use25`scripts/resolve-follow-ups.sh` from that directory. The script is the26deterministic boundary for ordering, fresh-base identity, worktree creation,27attempt suppression, and cleanup.28291. Run `list --repo <root>` to fetch the remote default branch and obtain every30 valid candidate in discovery order plus every `invalid-follow-up`. Report31 invalid files without filling in their missing evidence. Do not enumerate a32 possibly stale coordinator checkout.332. For each candidate in order, run34 `identity --repo <root> --follow-up <path>`. Continue until three eligible35 workers have been started or the ordered backlog is exhausted.36 `eligible` is only a snapshot, not a reservation. The platform adapter must37 win the attempt's atomic `claim` or `prepare` result before launching a38 worker; `skipped-unchanged ... claimed <owner> [<worktree> <branch>]` means39 another sweep already owns the unchanged follow-up content. That active40 ownership and a recorded pull request survive unrelated default-branch41 advancement; terminal non-PR results become retryable after that advance.423. For `skipped-unchanged`:43 - When the result carries `claimed` and an owner, do not dispatch it again;44 another worker already owns the exact content and base identity. If the45 adapter proves that owning process has ended without a terminal result,46 clean up its exact bound worktree when one is reported, then run `recover47 --repo <root> --attempt-key <key> --owner <owner>`. Never recover an active48 or uncertain worker merely because its claim is old.49 - Preserve a prior `not-reproduced`, `needs-shaping`, or `blocked` result50 until the follow-up content or remote default-branch SHA changes. Terminal51 identity output retains `owner <owner> [<worktree> <branch>]`; if that52 worktree still exists after its worker ended, use those exact coordinates53 for `cleanup` before starting the base-change retry. A base advance does not54 hide an outstanding terminal worktree.55 - When the result carries `pull-request` and a URL, check that pull request.56 Keep it skipped while open. After an unmerged close, run `clear` for that57 exact base identity before retrying. A merged pull request should remove58 the follow-up on the updated default branch; report a mismatch instead of59 opening a duplicate. If the path was deleted and later re-created, treat it60 as a fresh follow-up lifetime even when its Markdown matches the old item.614. Establish whether candidate scopes are independent before running workers62 concurrently. Process uncertain or overlapping scopes separately while63 retaining a distinct worktree and pull request for each item.645. A failed worker does not cancel other independent workers. Never exceed65 three actual workers in one sweep.6667## Launch one isolated worker per item6869Give every worker only its follow-up path, verified base SHA, attempt identity,70owner token, branch, worktree, and the worker contract below. The owner token is71required when binding the checkout, recording the outcome, and cleaning up, so72one worker cannot overwrite or remove another worker's attempt. The dispatcher73also reserves each canonical worktree path repository-wide; never bypass a74reservation failure by reusing another attempt's checkout.7576### Claude Routine7778Use a subagent with `isolation: worktree` when the active installation has a79creation-time `WorktreeCreate` policy or equivalent check that stops on fetch80failure and guarantees the identity base SHA. Require the subagent to compare81its `HEAD` with that SHA before editing.8283Before dispatch, run `claim --repo <root> --follow-up <path> --base-sha <sha>`.84Dispatch only a `claimed <attempt-key> <owner>` result. As the worker's first85action, run `bind --repo <root> --attempt-key <attempt-key> --owner <owner>86--worktree <worktree> --branch <branch>` from the native checkout. A bind87failure stops the worker before editing. Claude owns removal of a native88worktree after the coordinator records the terminal outcome.8990When native creation cannot make that guarantee, run `prepare` to create and91verify the worktree, then start a top-level headless Claude worker from that92directory. Do not nest a Claude CLI process merely to duplicate isolation the93native subagent already guarantees.9495### Codex Scheduled task9697Treat the scheduled task as coordinator only; its background worktree does not98isolate item workers. For each eligible item:991001. Choose a unique worktree path and branch whose name includes the follow-up101 slug and a short attempt-identity suffix.1022. Run `prepare --repo <root> --follow-up <path> --worktree <path> --branch103 <branch>`. Continue only for `prepared <worktree> <branch> <base-sha>104 <attempt-key> <owner>`; a concurrent sweep can instead return105 `skipped-unchanged` without creating a checkout. The dispatcher persists the106 canonical worktree target before creation, so an interrupted prepare is107 reported with the same claim owner, worktree, and planned branch for exact108 cleanup rather than becoming an anonymous checkout.1093. Start a top-level non-interactive Codex worker with `codex exec -C110 <worktree> --sandbox workspace-write <prompt>`. Configure only the network111 and approval capabilities needed to verify, push, and open the pull request.112113Do not use a writing subagent that inherits the coordinator's working114directory as a substitute for per-item isolation.115116## Apply the worker contract117118### Verify the boundary119120- Confirm that the worker `HEAD` equals the supplied base SHA before any edit.121- Read the one follow-up file and verify all five fields: symptom, observed122 evidence, suspected cause, what was tried, and proposed next step.123- Keep the worker diff limited to the selected item. Stop as `blocked` when the124 base, checkout, permissions, or environment cannot be verified.125126### Pass the reproduction gate127128- Reproduce the symptom through the recorded command, route, test, or129 environment before modifying product source.130- Retain concrete baseline evidence such as a failing assertion, exit status,131 observable output, or runtime state.132- Return `not-reproduced` with the attempts and next useful evidence when the133 symptom does not reproduce within the bounded run. Make no speculative source134 change or resolution pull request.135136When reproduction reveals a different out-of-scope defect, preserve the137selected item and return the new symptom, observed evidence, suspected cause,138what was tried, and proposed next step to the coordinator. Do not leave the only139record in the disposable worker. The coordinator serializes these records in140its own checkout through `project-knowledge` when available, or writes the same141five fields to `docs/follow-ups/<symptom>.md`. Before cleaning up the worker,142commit that record and publish a dedicated ready-for-review follow-up-record PR;143do not mix it into the selected item's resolution PR. A local coordinator change144or closing-message copy is not a durable handoff.145146### Confirm authority to fix147148- Derive intended behavior from current tests, specifications, decision149 contracts, supported runtime behavior, or an unambiguous compatibility150 contract.151- Continue only when the intended result is already settled and can be checked152 deterministically.153- Return `needs-shaping` without a patch when the item requires a product154 decision, public-contract change, or material trade-off. Name the unresolved155 choice so a later `shape-idea` session can settle it.156157### Repair through evidence158159- Make the smallest coherent fix and add or retain a regression check through a160 stable public seam when available.161- Re-run the reproduction after each meaningful candidate change. Continue only162 while new evidence supports another attempt; repeated failure without new163 evidence ends as `blocked`.164- Run focused deterministic checks and the affected repository-supported165 runtime verification. Static checks do not close a runtime symptom.166- Treat the item as resolved only when the original failure passes and relevant167 regression checks remain green.168169### Publish the result170171- Delete the resolved follow-up in the same commit series as the verified fix.172 Git history is its archive.173- Push only the worker branch and open one ready-for-review pull request. Include174 before-and-after reproduction evidence, checks run, and remaining uncertainty.175- Do not combine another follow-up and do not merge the pull request.176- Return `pull-request` with its URL. If publication or verification fails,177 retain the follow-up and return `blocked` rather than claiming resolution.178179Finish the worker response with a compact block containing `outcome`,180`follow-up`, `base-sha`, `attempt-key`, `owner`, `pull-request` when present,181the decisive reproduction or blocker evidence, and any newly discovered182follow-up record for the coordinator. The coordinator uses this block to record183the exact attempt; prose alone is not a terminal result.184185## Record and clean up each outcome186187After the worker returns:188189- For a pull request, run `mark --repo <root> --follow-up <path> --base-sha190 <sha> --owner <owner> --outcome pull-request --detail <URL>` so later sweeps191 do not duplicate it.192- For a non-PR result, run the same `mark` command with `--outcome193 not-reproduced`, `--outcome needs-shaping`, or `--outcome blocked` and use194 `--detail` for compact decisive evidence or the next useful condition. A195 different worker cannot replace the first terminal result. The recorded196 identity is disposable local automation state, not a status field in the197 tracked follow-up.198- For a clean non-PR worker that never moved beyond its base, run `cleanup` with199 `cleanup --repo <root> --worktree <worktree> --attempt-key <attempt-key>200 --owner <owner>`. For a PR worker, run the same cleanup only after its exact201 `HEAD` is visible on the remote branch. The script removes only the worktree202 bound to that exact claim and preserves the local branch so cleanup cannot203 race a new checkout and delete its ref. It revalidates the repository-wide204 coordinate reservation before removal, safely deinitializes clean submodules205 through isolated Git metadata without changing shared repository settings, and206 leaves Git's final dirty-worktree refusal enabled. It refuses dirty,207 unpublished changed, mismatched, foreign, or repository-root targets.208- When an owning process ended before `mark`, first inspect its bound branch for209 publication and an existing pull request. Record a found pull request with210 `mark`; if a branch was published without one, finish or explicitly block that211 publication rather than discarding its identity. Only when no publication212 occurred, use `cleanup` first when its recorded bound or preparing worktree213 exists, then `recover` with the exact attempt key and owner. If preparation214 stopped after persisting the target but before creating its path, skip cleanup215 and recover the missing target directly; recovery removes an exact stale Git216 worktree registration before releasing ownership. Recovery refuses live217 worktrees, published branches, and terminal outcomes. A preparing target is218 removed only when its checkout is clean and still detached at the base or its219 exact prepare-owned branch can be deleted with a head compare-and-swap.220221Return one compact sweep report using only `pull-request`, `not-reproduced`,222`needs-shaping`, `blocked`, `invalid-follow-up`, and `skipped-unchanged`. Link223each pull request and state the evidence or next condition for every other224outcome. Never label a retained follow-up as fixed.