Portable issue-based Spec-Driven Development for AI coding agents that support Agent Skills.
What It Provides · Workflow Design · Installation · Usage · Track Model · Preference Capture
Butter Workflow keeps the working context in repository files so a task can move between tools, models, and sessions without depending on chat history.
See Workflow Design for the full methodology and handoff model.
- Three shared workflow stages: start, implement, and code-review.
- One shared skill set (
skills/) for agents supporting the Agent Skills format (SKILL.md) — no tool-specific command wrappers. - Track A/B/C routing for small changes, planned changes, and high-risk changes.
- Handoff spec documents under
docs/specs/{TASK-ID}/for every track. - Shared user preference memory under
~/.agents/preferences/preferences.md, captured automatically as you work.
Install directly from this GitHub repository with the skills.sh CLI. No clone required:
npx skills add ypjun100/butter-workflow -gThe -g flag makes the workflow available across projects. Update the global
installation to the latest version later with:
npx skills update -gThe CLI supports Claude Code, Codex, and the other agents in its supported-agent list. Agent-specific skill features may vary. Trade-off to know: unlike a plugin marketplace, this installation path has no version pinning or changelog UI — it installs whatever is on the default branch, so check this repository's commit history before updating if that matters to you. Restart the tool or start a new session after installing so the newly loaded skills are available.
Start a workflow by naming the start skill. This is the only stage that requires it:
/butter-workflow-start <task context> # Claude Code and similar
$butter-workflow-start <task context> # Codex
Use the butter-workflow-start skill with <task context>
The remaining stages run from plain language:
Looks good, start implementing. -> butter-workflow-implement
Review this PR: <PR URL> -> butter-workflow-code-review
Ordinary requests inside a running workflow stay ordinary. "Fix this line in the spec" edits the spec document; "apply this feedback" applies it, commits, and pushes. Neither advances a stage — only asking for the next stage's work does.
| Skill | Role |
|---|---|
butter-workflow-start |
Starts a workflow when explicitly named, from the context the user provides: classifies track type, plans the working branch name, writes spec docs for every track, and summarizes the written files as hyperlinks before pausing for approval. |
butter-workflow-implement |
Creates or switches to the working branch, implements the approved spec for any track, verifies changes, commits, pushes, and creates a PR. |
butter-workflow-code-review |
Reviews a PR or branch diff with issue, plan, task, and risk-target context, then closes out the workflow. |
All three stages also capture preferences while they run. See Preference Capture.
- Track A: small low-risk changes; writes a lightweight spec (
00-META.md+01-SPEC.md) and pauses for approval before implementing. - Track B: planned feature or fix within existing architecture; creates the full
docs/specs/{TASK-ID}/set. - Track C: high-risk Track B work involving auth, security, payment, permissions, shared core, architecture, migration, or broad refactor risk; adds
Risk Review Targets.
Every stage watches for preferences in what you say and records them as it goes, so nothing depends on remembering to run a wrap-up step.
~/.agents/preferences/
preferences.md # everything captured, applied to your work from the next task on
A request that contradicts an entry already in the file replaces it, since your latest word is the current one — the swap is reported so you can put it back. Asking for an entry to be dropped removes it.
The bar is low on purpose. Anything that would help write a better plan, change, or review next time gets captured, and the rule is extracted from whatever you happened to be talking about at the time:
"Write the plan in Korean, not English"
-> plan documents are written in Korean from now on
"This component's logic is too complicated, unpack it"
-> favor simple, direct code over defensive handling for unlikely cases
Neither of those is phrased as a preference, and both name something specific. Both are captured, because the rule is what matters and the rule generalizes.
The judging runs in a separate agent alongside your actual request, so a message carrying thirty pieces of feedback does not turn into thirty pieces of deliberation you have to sit through. Each record, replacement, or removal is reported in a single line at the end of the response, so you can correct a bad capture right away.
- Use available Jira/GitHub MCP tools first for issues, PRs, and review comments.
- Use
ghonly for GitHub PR work when MCP is unavailable. - Use
gitfor repository work: branch, status, diff, commit, and push. - Do not modify issue bodies or comments without user approval.
Every track creates a spec directory. Track A writes a lightweight spec:
docs/specs/{TASK-ID}/
00-META.md
01-SPEC.md
Track B/C add the plan and task files:
docs/specs/{TASK-ID}/
00-META.md
01-SPEC.md
02-PLAN.md
03-TASK-*.md
00-META.md is the current workflow state source of truth. Its Status moves
planned → implemented → reviewed, ending at reviewed. Preference data
never lives in the spec directory; it lives in
~/.agents/preferences/preferences.md.
