Skip to content
rochecompaanPublic

About

Patchmill is an agent-driven software factory

Topics

Resources

Stars

15 stars

Watchers

0 watching

Forks

Latest commit

 

History

424 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Patchmill logo

Patchmill advances one issue through planning and implementation with Pi. A small kernel handles process control and host facts. Skills hold the advice for planning, coding, review, and evidence. GitHub uses gh. Forgejo and Gitea use tea.

The five kernel responsibilities

Process supervision starts a fresh Pi session for each phase. It sets the agent directory and enforces pi.timeoutMinutes, which defaults to 90 minutes. On timeout or cancellation, it sends SIGTERM to the process group, then SIGKILL after five seconds if needed.

Claim and release prevent cooperating runs from owning the same issue in one clone. The kernel holds an OS lock on a permanent file and swaps host labels. A narrow race between separate clones remains possible. The lock file and its parent directory must stay in place, even after a crash.

Phase derivation reads git and the issue host. Spec and plan gates are optional and default off. A required gate passes when its planning pull request is merged into base, or its document is on the pushed implementation branch after an interactive approval without a PR. Logs, result files, and approval labels never decide what happens next.

Outcome verification checks facts after Pi finishes. Planning needs the pushed branch and required documents. A gated stage also needs its planning pull request unless the maintainer approved it without a PR in an interactive run. Implementation needs an open, non-draft pull request whose head matches the branch and whose body closes the issue. agent-done means that this pull request exists, not that it merged.

Stable names give humans and agents the same paths. Branches use agent/issue-N-<slug> for implementation. Required gates use agent/issue-N--spec and agent/issue-N--plan. Specs use docs/specs/YYYY-MM-DD-issue-N-<slug>-design.md. Plans use docs/plans/YYYY-MM-DD-issue-N-<slug>-plan.md. The slug comes from the issue title and only describes the file. The issue number and the -design or -plan suffix identify it, so a title edit never changes which file is the spec or the plan. Plans from earlier versions have no -plan suffix. Rename them once, for example 2026-10-01-issue-9-login.md to 2026-10-01-issue-9-login-plan.md. Worktrees live under .worktrees, with branch slashes replaced by hyphens.

Install and start

npm install -g patchmill
patchmill init --provider github-gh
patchmill auth
patchmill labels setup
patchmill doctor
patchmill triage --dry-run
patchmill triage
patchmill run-once

Run these commands in a repository with an origin remote and authenticated host CLI. auth asks for an authentication method, provider, and model. It saves credentials and the default model in the repository's Pi agent directory, runs a real provider smoke prompt, and returns to your shell without opening Pi chat. doctor includes a real model smoke prompt. Triage dry runs also call the model.

By default, planning writes the spec and plan on the implementation branch and continues to implementation. Set either workflow gate to required: true for a separate planning pull request. Review and merge that pull request, then run patchmill run-once --issue N again. Review approval alone does not unlock a gate. The issue stays in-progress while waiting, and no Pi session runs then.

With both gates enabled, merge the spec PR, then the plan PR, before implementation. Each later branch starts from the fetched base with the merged documents. Ungated documents go into the next gated PR or the implementation PR. After a confirmed implementation PR merge, interactive runs remove the issue's implementation, spec, and plan worktrees and local branches when each worktree's git status --porcelain is empty. Dirty worktrees are kept, with the reason shown in chat. Non-interactive runs leave them in place.

Commands

Command Behaviour
patchmill init Write config when missing, install skills, provision the agent directory. Idempotent.
patchmill auth Choose a subscription or API key, provider, and default model. Save them in the configured Pi agent directory, verify the provider, then return to the shell.
patchmill doctor Read-only checks: host CLI logged in, labels exist, worktree directory ignored, skills present, Pi answers a smoke prompt.
patchmill labels setup Create missing labels.
patchmill triage [--dry-run] Run the triage skill per candidate issue. Dry run runs Pi and prints the labels and comment instead of applying them.
patchmill run-once [--issue N] [--dry-run] [--plan-only] Advance one issue. Dry run prints the selected issue and derived phase without claiming or running Pi.
patchmill release --issue N Clear a stale claim after a hard crash.
patchmill skills update Update the managed skill pack to the installed Patchmill version. Refuses edited managed files and removes files dropped from the pack.
patchmill version Print the version.
patchmill setup-test-repo Development tool for the end-to-end CI (#320). Outside the kernel.

Interactive Issue runs

patchmill run-once --issue 225 --interactive

This opens a Pi console for planning with you and running implementation in a background worker, using the same Run-once workflow. --issue N (a positive integer) is optional: without it, the CLI selects the next eligible issue before opening the console. If none is eligible, it exits successfully without opening the console. --interactive cannot be combined with --dry-run or --plan-only. The console agent calls four tools:

  • patchmill_submit_planning_result: submit a planning outcome after your review in one dialog; requesting changes or Escape keeps planning open.
  • patchmill_continue_issue_run: recheck a waiting merge and continue the run.
  • patchmill_run_status: show the current run, worker, wait, and estimated cost.
  • patchmill_confirm_block_guidance: send guidance to a blocked worker after your confirmation.

The planning dialog names the issue and document, shows the files and branch with a short commit, and lists 2–5 key decisions rather than the agent's full summary. A required gate offers Approve and open a planning PR, Approve without a PR (continue now), or Request changes in one dialog. Choosing PR waits for its merge; choosing no PR lets Patchmill push the approved planning head to the implementation branch and continue at once. Later documents stay on that branch. A later required gate offers Approve (continue now) or Request changes and explains which earlier document prevents a planning PR. Ungated planning asks whether you have reviewed the spec, plan, or both, with Reviewed, continue and Request changes. Requesting changes or Escape keeps planning open and pushes nothing through Patchmill. A restart derives approvals from the pushed documents, never saved workflow state.

Type /patchmill-issue <N> to start another issue once the current run ends. It switches to that issue's conversation without a confirmation dialog. Sessions live under <runsDir>/issue-<N>/console/; reopening an issue resumes its newest session, while a new issue gets a fresh conversation.

Quitting the console stops the worker. At startup, Patchmill checks for stray workers and stops them before starting an Issue run; if cleanup fails, it will not start the run. Do not launch this command inside a pi-subagents child process: PI_SUBAGENT_CHILD=1 disables pi-subagents.

Configuration

patchmill.config.json accepts only these keys. Each key has a default. Unknown keys fail by name. git.baseBranch: null uses the remote default branch.

{
  "host": { "provider": "github-gh", "login": "", "trustedAuthors": [] },
  "labels": {
    "ready": "agent-ready",
    "inProgress": "in-progress",
    "needsInfo": "needs-info",
    "done": "agent-done",
    "unsuitable": "agent-unsuitable"
  },
  "paths": {
    "specsDir": "docs/specs",
    "plansDir": "docs/plans",
    "worktreeDir": ".worktrees",
    "runsDir": ".patchmill/runs"
  },
  "git": { "baseBranch": null },
  "skills": {
    "triage": ".patchmill/skills/patchmill-issue-triage",
    "planning": ".patchmill/skills/patchmill-planning",
    "implementation": ".patchmill/skills/patchmill-implementation"
  },
  "pi": { "agentDir": ".patchmill/pi-agent", "timeoutMinutes": 90 },
  "workflow": {
    "specApproval": { "required": false },
    "planApproval": { "required": false }
  }
}

init leaves valid existing configuration unchanged and rejects invalid configuration. Retired spec/plan review-label settings and string-valued labels.blocked are accepted but ignored. New configuration omits them. Other removed keys remain invalid. GitHub init can seed host.login from the detected user. For Forgejo, an empty login selects Tea's default profile. Only an explicit profile alias selects another profile. The detected username is not that alias. The authenticated username and host.trustedAuthors identify trusted comment authors. GitHub also trusts its configured host.login. A Tea profile alias does not grant author trust.

Label lifecycle

Label Meaning Set by Removed by
agent-ready Suitable for automation; dependencies must close. Human or triage Kernel on claim
in-progress Work is active or waiting for a planning PR merge. Kernel on claim Kernel on final release
needs-info The agent asked questions, or the Run attempt failed. Kernel Kernel on next claim
agent-done A ready pull request that closes the issue exists. Kernel after verification Human

Triage returns one of agent-ready, agent-unsuitable, or needs-info by default, plus a comment and structured blockedBy issue numbers. The kernel adds missing native dependency links before it applies labels and comments. Agents own git and the pull request, not issue mutations.

GitHub Blocked by and Forgejo/Gitea Depends on links control when work can start. Automatic runs skip issues with open or unreadable dependencies. Explicit runs refuse them, including interactive, dry-run, and resumed attempts. Closing the last blocker makes an issue eligible on the next selection without another triage run, label change, or comment. Reopening a blocker reverses that. Triage dry run previews links, labels, and comments without host writes.

Manual upgrade from blocked labels

After upgrading, run patchmill skills update to refresh the managed triage skill. Custom triage skills must also return the required blockedBy array.

There is no automatic migration. Before running the upgraded Patchmill, update each affected issue manually:

  1. Add its dependencies through GitHub Blocked by or Forgejo/Gitea Depends on.
  2. Remove the old blocked label or its configured replacement.
  3. If the work suits automation, apply the configured ready label.
  4. Remove labels.blocked from patchmill.config.json.

Old blocked labels no longer prevent work, and old comments do not create native links. If a dependency write fails, triage warns and skips the label and comment. Added links remain intact. Explicit re-triage of ready or in-progress issues can leave them runnable with missing links after an error. Resolve the warning before starting another run on that issue.

Releasing a stale claim

After a hard crash, patchmill release --issue N acquires the same OS lock and resets a stale in-progress label to agent-ready. Contention prevents label changes. Do not delete the permanent lock or its parent directory.

Branch protection

Direct landing is a host control, not a Patchmill feature. The skills forbid pushing the base branch and force-pushing. Shell access cannot enforce that advice. Use branch protection on the host to prevent direct pushes.

Documentation and roadmap

Read patchmill.dev for the quickstart and Run-once guide. The roadmap describes future work, not current capabilities. Patchmill installs pinned Superpowers and SimpleEnglish skills alongside its own skills.

Frontend design and review

For meaningful browser-visible changes, planning adds a linked, offline, full-page HTML mockup to the spec. After validation, implementation reviews the frontend against pinned local rules, fixes every valid finding, and records the review in the pull request. Backend, documentation, and minor copy work skip both steps. No configuration change is needed. See Skills configuration.

License

Apache-2.0. See LICENSE.

About

Patchmill is an agent-driven software factory

Topics

Resources

Stars

15 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages