Drops all GitHub-specific tooling (gh CLI, draft PR creation) so the workflow stops at git commit and leaves push/PR/MR to the user. TODO.md is now expected to be a tracked file on the default branch. Phase 1 verifies the repo is bare via `git rev-parse --is-bare-repository`, resolves the default branch from HEAD / init.defaultBranch, and snapshots TODO.md via `git show "$DEFAULT_BRANCH:TODO.md"` to a tempfile that @pm reads in Phase 2. Phase 10 updates the live TODO.md inside the worktree and commits the change separately. The /review command drops its PR mode for the same reason; @pm documents the read-only-snapshot vs. live-worktree path distinction.
11 KiB
| description | agent |
|---|---|
| Fire-and-forget multi-agent workflow: plan, test, implement, commit | build |
You are executing the autonomous multi-agent workflow. Run all phases without waiting for user input. The user has walked away.
Task reference: $ARGUMENTS
If $ARGUMENTS is empty, stop immediately: "Usage: /workflow <ISSUE-ID> (e.g. /workflow ABC-1). The ID must exist in ./TODO.md."
Phase 1: Repo Setup
Verify you are in a bare git repo and that the issue tracker exists.
-
Verify the current repository is bare:
git rev-parse --is-bare-repository 2>/dev/nullmust outputtrue. If not, stop: "Workflow requires a bare git repository (set up withgit clone --bareor the.bare/+.gitfile pattern)." -
Capture the bare repo root for later worktree creation:
BARE_REPO_ROOT="$(pwd)". -
Determine the default branch (source of TODO.md and base for new worktrees). Resolve in order: a.
git symbolic-ref --short HEAD— the bare repo's HEAD b.git config init.defaultBranch— the configured default c. fall back tomainStore as
DEFAULT_BRANCH. -
Verify TODO.md exists on the default branch:
git show "$DEFAULT_BRANCH:TODO.md" > /dev/null 2>&1. If not, stop: "TODO.md not found on$DEFAULT_BRANCH. Commit a TODO.md there first — the workflow expects it to be a tracked file." -
Snapshot TODO.md to a temp file so
@pmcan read it before any worktree exists:TODO_READ_PATH="$(mktemp -t todo.XXXXXX.md)" git show "$DEFAULT_BRANCH:TODO.md" > "$TODO_READ_PATH"Pass
$TODO_READ_PATHto@pmin Phase 2 (read-only context). -
Proceed to Phase 2.
Phase 2: Issue Context
Use @pm to fetch the issue matching $ARGUMENTS from the snapshot at $TODO_READ_PATH:
- Issue title, description, acceptance criteria
- Labels and priority
- Any existing branch name
If the issue does not exist or @pm fails, stop with error.
Derive a branch name: <issue-id-lowercase>-<slugified-title> (e.g. abc-1-add-retry-logic). Validate: only [A-Za-z0-9._/-], no leading -.
Phase 3: Repo Setup (continued)
From $BARE_REPO_ROOT:
- If an
originremote is configured, rungit fetch origin(best-effort; ignore failure if there is no remote). - Compute worktree directory: replace all
/with-in the branch name (e.g.feat/abc-1-foobecomesfeat-abc-1-foo) - Check if worktree directory already exists. If yes, enter it and verify
git status --porcelainis empty. If dirty, stop: "Worktree exists but has uncommitted changes. Clean it up first." - If worktree does not exist:
git worktree add <dir-name> -b <branch-name> "$DEFAULT_BRANCH" - Change working directory to the new worktree. From here on,
./TODO.mdin the worktree is the live, writable copy that Phase 10 will update.
Phase 4: Plan
Analyze the codebase in the worktree context. Create a detailed implementation plan addressing the issue's requirements and acceptance criteria.
The plan should include:
-
Problem summary (from issue context)
-
Proposed approach with rationale
-
Files to modify (with brief description of changes)
-
New files to create
-
Risks and open questions
-
Test Design (conditional — include for non-trivial tasks):
- Key behaviors to verify (what tests should assert)
- Edge cases and error conditions worth testing
- What explicitly should NOT be tested (prevents bloat)
- Testability concerns (heavy external deps, GPU-only paths, etc.)
Include Test Design for: Public API changes, bug fixes with behavioral impact, new features with business logic, multi-module changes. Skip Test Design for: Config-only changes, decorator swaps, import reorganization, documentation. When skipped,
@testderives test cases directly from acceptance criteria.
Phase 5: Review Plan
Dispatch @check and @simplify in parallel to review the plan.
Reviewers should evaluate testability:
@check: Is the design testable? Are the right behaviors identified? (Review Framework §8)@simplify: Is the test scope appropriate? Over-testing proposed?
Merge rules:
@checksafety/correctness findings are hard constraints- If
@simplifyrecommends removing something@checkflags as needed,@checkwins - Note conflicts explicitly
Review loop (max 3 cycles):
- Send plan to both reviewers
- Merge findings
- If verdict is ACCEPTABLE from both (or JUSTIFIED COMPLEXITY from
@simplify): proceed to Phase 6 - If BLOCK or NEEDS WORK: revise the plan addressing findings, then re-review
- Convergence detection: if reviewers return the same findings as the previous cycle, stop the loop early
- If still unresolved after 3 cycles: note unresolved blockers and proceed anyway (they will be documented in the workflow summary and commit message)
Phase 6: Split into Tasks
Break the approved plan into discrete tasks for @make. Each task needs:
| Required | Description |
|---|---|
| Task | Clear description of what to implement |
| Acceptance Criteria | Specific, testable criteria (checkbox format) |
| Code Context | Actual code snippets from the codebase, not just file paths |
| Files to Modify | Explicit list, mark new files with "(create)" |
| Test File | Path for test file (colocated pattern), e.g., <module>/tests/test_<feature>.py (create) |
Include Integration Contracts when a task adds/changes function signatures, APIs, config keys, or has dependencies on other tasks.
Include Test Design from Phase 4 when available, attached to the relevant task(s).
Task size: ~10-30 minutes each, single coherent change, clear boundaries.
Phase 7: Write Tests
For each task from Phase 6, dispatch @test with:
- The task spec (acceptance criteria, code context, files to modify)
- The Test Design section from the plan (if provided)
- The test file path to create (following colocated pattern)
@test writes failing tests and verifies RED with structured failure codes.
Post-step file gate (MANDATORY):
Before dispatching @test, snapshot the current changed files:
git diff --name-only > /tmp/pre_test_baseline.txt
After @test completes, validate only NEW changes:
git diff --name-only | comm -23 - /tmp/pre_test_baseline.txt > /tmp/test_new_files.txt
All new files must match: **/test_*.py, **/*_test.py, **/conftest.py (new only), **/test_data/**, **/test_fixtures/**.
If any non-matching file appears: discard @test output, report violation.
Decision table — handling @test results:
| Condition | Action |
|---|---|
TESTS_READY + escalate_to_check: false |
Proceed to Phase 8 |
TESTS_READY + escalate_to_check: true |
Route tests to @check for light review. @check diagnoses, caller routes fixes to @test. Then proceed. |
NOT_TESTABLE |
Route to @check for sign-off on justification. If approved, task goes to @make without tests. |
BLOCKED |
Investigate. May need to revise task spec or plan. |
| Test passes immediately | Investigate — behavior may already exist. Task spec may be wrong. |
Parallelism: Independent tasks can have tests written in parallel.
Constraint: @test must not modify existing conftest.py files (prevents collision during parallel execution).
Phase 8: Implement
Execute each task by dispatching @make with:
- The task spec (from Phase 6)
- Relevant code context (actual snippets)
- Pre-written failing tests and handoff from
@test(if TESTS_READY)
@make runs in TDD mode when tests are provided:
- Entry validation: run tests, verify RED, check failure codes match handoff
- Implement minimal code to make tests pass (GREEN)
- Regression check on broader area
- Refactor while keeping green
- Report RED→GREEN evidence
Escalation: If @make flags test quality concerns during entry validation:
@makereports the issue to caller- Caller routes to
@checkfor diagnosis @checkreports findings- Caller routes to
@testfor fixes - Fixed tests return to
@make
For NOT_TESTABLE tasks, @make runs in standard mode.
After all tasks complete, verify overall integration:
- Run the project's test suite if available
- Run linting/type checking if configured
- Fix any integration issues between tasks
Phase 9: Final Review
Dispatch @check and @simplify in parallel to review the full implementation (all changes across all files).
Provide reviewers with:
- The original plan
- The full diff (
git diff "$DEFAULT_BRANCH"...HEAD) - Any decisions or deviations from the plan
Review loop (max 3 cycles):
- Send implementation to both reviewers
- Merge findings (same precedence rules as Phase 5)
- If ACCEPTABLE: proceed to Phase 10
- If issues found: fix them directly (no need to re-dispatch
@makefor small fixes), then re-review - Convergence detection: same findings twice = stop loop early
- If unresolved after 3 cycles: document blockers, proceed to commit anyway
Phase 10: Commit and Wrap Up
The workflow is forge-agnostic. It commits locally and stops. Do not push, and do not open a pull/merge request — the user chooses their forge and review workflow manually.
Commit Code Changes
- Stage code changes (everything except
TODO.mdand.opencode/workflow-summary.md, which are committed separately below) - Write a conventional commit message summarizing the implementation. Reference the TODO.md issue ID in the body (e.g.
Refs: ABC-1). - If changes are large/varied, use multiple atomic commits (one per logical unit)
TODO Update
- Use
@pmto update the issue in./TODO.md(worktree-local; this is the live, writable copy):- Set Branch to the worktree branch name
- Set Status to
In Review - Add a comment with the branch name, latest commit SHA, and a one-line summary
- If acceptance-criteria checkboxes were addressed by the implementation, ask
@pmto check them off - Commit the TODO.md change as a separate atomic commit:
chore(todo): update <issue-id> status and progress
Local Summary
- Write
.opencode/workflow-summary.mdin the worktree with:- Run timestamp
- Issue reference and title
- Branch name and final commit SHA(s)
- Summary of implementation
- TDD evidence (RED→GREEN per task, NOT_TESTABLE justifications)
- Review outcomes (plan review + final review verdicts)
- Unresolved items (if any)
- Files changed
- Commit the summary:
chore(workflow): summary for <issue-id>
Cleanup
- Remove the temp snapshot from Phase 1:
rm -f "$TODO_READ_PATH"
Failure Handling
At any phase, if an unrecoverable error occurs:
- Write
.opencode/workflow-summary.md(in the worktree, if one exists) with what was completed and what failed - If any code was written, commit it with message
wip: incomplete workflow run for <issue-id> - Leave the branch and worktree intact for the user to inspect — do not push, do not delete
- If a worktree exists, use
@pmto add a comment on the issue in./TODO.mdsummarising what failed - Remove the temp snapshot if it was created:
rm -f "$TODO_READ_PATH" - Stop execution
Never hang on interactive prompts. If any command appears to require input, treat it as a failure and follow the above procedure.