Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ Functional:
- `patchmill version` prints the installed Patchmill CLI version.
- `patchmill triage` is the intake/sorting station. It classifies open issues
and can apply readiness labels or comments.
- `patchmill run-once` is the one-issue production run. It claims one ready
issue, creates or reuses a plan, runs implementation, reviews or lands the
result, and records the outcome.
- `patchmill run-once` is the one-issue production run. It advances one
actionable issue through spec writing, plan writing, implementation, and any
configured human approval stops.

In progress:

Expand Down
47 changes: 35 additions & 12 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,41 @@ object and are not added to `triage.stateMap`.
}
```

When specification approval is required, automatic `run-once` selection ignores
ready issues that do not have `workflow.specApproval.approvedLabel`. Explicit
`patchmill run-once --issue <number>` fails with an `approval-required` result
for the requested issue instead of silently choosing another issue.

When plan approval is required, Patchmill creates or finds the issue plan,
comments that the plan is ready, applies `workflow.planApproval.reviewLabel`,
restores the ready label, removes `in-progress`, records the run as finished,
and stops. After a human applies `workflow.planApproval.approvedLabel`, a later
`run-once` reuses the existing plan and proceeds to implementation. During the
claim step, Patchmill removes the active plan-review label when the approved
label is present.
`patchmill run-once` treats the configured ready label, spec-approved label, and
plan-approved label as actionable workflow states. Review labels without
matching approved labels are waiting states for human review.

When both spec and plan approval are required:

```text
agent-ready --run-once--> write spec, stop at spec-review
spec-approved --run-once--> write/reuse spec, write plan, stop at plan-review
plan-approved --run-once--> write/reuse spec and plan, implement, stop at agent-done
```

When spec approval is required and plan approval is not required:

```text
agent-ready --run-once--> write spec, stop at spec-review
spec-approved --run-once--> write/reuse spec, write plan, implement, stop at agent-done
```

When spec approval is not required and plan approval is required:

```text
agent-ready --run-once--> write spec, write plan, stop at plan-review
plan-approved --run-once--> write/reuse spec and plan, implement, stop at agent-done
```

When neither approval is required:

```text
agent-ready --run-once--> write spec, write plan, implement, stop at agent-done
```

Humans may either replace review labels with approved labels or add approved
labels while leaving review labels in place. Patchmill tolerates both and
removes stale `spec-*` and `plan-*` workflow labels as it advances.

`projectPolicy.planRequiresApproval` remains as a compatibility alias. If
`workflow.planApproval.required` is omitted, Patchmill derives plan approval
Expand Down
35 changes: 19 additions & 16 deletions docs/issue-agent-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,16 @@ flowchart TD

### Issue selection and safety gates

`patchmill run-once` processes one issue. It prefers a single resumable
`in-progress` run with valid run state. Otherwise it selects an open issue
carrying the configured ready label and no excluded/protection labels. Priority
labels determine ordering, then lower issue number wins.
`patchmill run-once` processes one actionable issue. Actionable labels are the
configured ready label, the configured spec-approved label, and the configured
plan-approved label. Review labels without their approved counterparts are
waiting states and are ignored by automatic selection.

When `workflow.specApproval.required` is true, the automatic candidate set is
filtered before priority ordering so a high-priority unapproved issue does not
starve a lower-priority approved issue. Explicit `--issue` selection validates
the requested issue and returns `approval-required` with the missing spec
approved label if the approval is absent.
It prefers a single resumable `in-progress` run with valid run state. Otherwise
it selects an open actionable issue with no excluded/protection labels. Priority
labels determine ordering, then lower issue number wins. Explicit `--issue`
selection validates the requested issue and returns `approval-required` for a
waiting review state with the missing approved label.

Before mutating, it checks the repository worktree is clean, ignoring configured
local state paths such as the run-state directory and issue todo root. It
Expand Down Expand Up @@ -273,10 +273,11 @@ A blocked plan moves the issue from `in-progress` to `needs-info` and posts the
blocker questions.

Plan approval is a workflow stop. When required and missing, Patchmill comments
that the plan is ready, applies the configured plan-review label, restores the
ready label, removes `in-progress`, records the run as finished, and exits with
`plan-created` or `plan-found`. Once the configured plan-approved label is
present, a later `run-once` reuses the plan and proceeds to implementation.
that the plan is ready, applies the configured plan-review label, removes stale
spec and plan approval labels, removes `in-progress`, records the run as
finished, and exits with `plan-created` or `plan-found`. Once the configured
plan-approved label is present, a later `run-once` reuses the plan and proceeds
to implementation.

### Implementation Pi prompt

Expand Down Expand Up @@ -356,9 +357,11 @@ or missing statuses are errors.

### Logging and progress

`patchmill run-once` writes final JSON to stdout. Progress goes to stderr unless
`--quiet` is used, and every event is appended to a JSONL run log under the
configured run-state directory.
`patchmill run-once` writes final JSON to stdout. In dry-run mode, the summary
includes the selected issue and planned workflow transition, such as
`agent-ready -> spec-review` or `plan-approved -> agent-done`. Progress goes to
stderr unless `--quiet` is used, and every event is appended to a JSONL run log
under the configured run-state directory.

Console progress includes:

Expand Down
123 changes: 123 additions & 0 deletions docs/plans/2026-06-13-run-once-workflow-advancement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Run Once Workflow Advancement Implementation Plan

## Spec reference

- Design: `docs/specs/2026-06-13-run-once-workflow-advancement-design.md`
- Scope: advance `patchmill run-once` through spec, plan, and implementation
workflow states.
- Actionable labels: `agent-ready`, `spec-approved`, `plan-approved`.
- Waiting labels: `spec-review`, `plan-review`.

## Durable decisions

1. `patchmill run-once` remains the single automation entrypoint.
2. Spec creation precedes plan creation when no plan already exists.
3. A pre-existing plan means the issue can skip spec creation and continue with
plan/implementation behavior.
4. Required spec approval gates any current spec unless the issue currently
carries a non-stale `spec-approved` label.
5. Required plan approval gates any current plan unless the issue currently
carries a non-stale `plan-approved` label.
6. Creating a new spec or plan makes any already-present approval label stale
for that artifact.
7. Review labels are waiting states and should not be selected automatically.
8. Stage prompts must stay stage-specific: spec prompts write specs, plan
prompts manage plan task todos, implementation prompts execute plans.
9. Filesystem state checks should only translate `ENOENT` to “missing”; all
other IO failures must fail loudly with path context.

## Implementation structure

### Workflow state

- Add a canonical workflow-state module for:
- resolving actionable vs waiting labels,
- explicit issue approval errors,
- review-label cleanup rules,
- plan approval gate decisions.
- Remove stale duplicate approval helpers so approval ownership is in one
module.

### Workflow artifacts

- Use shared artifact helpers for date prefixes, slugged filenames, issue
artifact lookup, and path construction.
- Keep spec/plan modules as narrow wrappers:
- plan filenames: `<date>-issue-<number>-<slug>.md`
- spec filenames: `<date>-issue-<number>-<slug>-design.md`

### Planning stage orchestration

- Keep `runOneIssue` focused on selection, claim, implementation, and top-level
failure handling.
- Delegate spec/plan advancement to a shared stage orchestrator that performs:
1. resolve saved/found/generated artifact path,
2. create artifact with Pi when needed,
3. persist run-state checkpoints,
4. post ready comments,
5. apply review/approval labels,
6. return either a final spec/plan result or normalized data for
implementation.

### Prompts

- Spec prompt:
- writes and commits the spec only,
- returns `spec-created`,
- does not create/update implementation task todos.
- Plan prompt:
- writes and commits the plan,
- creates/updates plan task todos according to the task contract,
- returns `plan-created`.
- Implementation prompt:
- consumes the approved plan and task todos,
- reports PR/merge/blocker outcomes.

### Selection and summaries

- Automatic selection accepts actionable labels and ignores waiting review
labels.
- Explicit issue selection returns `approval-required` for waiting review
labels.
- Dry-run and CLI summaries report the workflow transition that would be
attempted.

## Test plan

Focused behavior tests:

- workflow-state resolution and cleanup rules,
- spec and plan artifact filename/path/find behavior,
- prompt contracts for spec, plan, and implementation stages,
- automatic and explicit issue selection by workflow state,
- pipeline paths for:
- spec creation then spec review,
- existing spec then spec review,
- stale spec approval after replacement spec creation,
- plan creation then plan review,
- approved plan advancing to implementation,
- saved artifact access failures that are not `ENOENT`.

Verification commands:

```bash
npm run test:run-once
npm test
npm run lint
npm run build
git diff --check
```

## Completion checklist

- [x] Workflow state labels modeled centrally.
- [x] Spec artifact helpers and configuration added.
- [x] Spec creation result contract added.
- [x] Selection recognizes actionable approval labels.
- [x] Pipeline advances through spec, plan, and implementation stages.
- [x] Spec approval gates existing and newly-created specs.
- [x] Spec prompt no longer leaks plan-task todo mechanics.
- [x] Saved artifact access fails fast for non-`ENOENT` errors.
- [x] Shared artifact helpers eliminate spec/plan copy-paste.
- [x] Approval ownership consolidated into workflow-state.
- [x] Oversized implementation plan compressed to durable decisions.
6 changes: 3 additions & 3 deletions docs/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ classification logic and reports proposed labels, comments, closures, canonical
bucket, and rationale without mutating the issue host.

Patchmill still owns the automation intake contract used by
`patchmill run-once`: an issue is eligible only when it is open, has the
configured ready label, and has none of the configured protection or non-ready
triage labels.
`patchmill run-once`: an issue is eligible when it is open, has no
protection/exclusion label, and carries an actionable workflow label:
`agent-ready`, `spec-approved`, or `plan-approved` by default.
Loading
Loading