Adds @check, @simplify, @test, @make, @pm subagents and the /workflow and /review slash commands from the autonomous multi-agent workflow gist by ppries. @pm is rewritten to manage issues in a local ./TODO.md file instead of Linear (file-only access, documented schema, structured JSON output). /workflow is adapted: TODO.md-based issue context, generic worktree paths (no hardcoded ~/repos/veo/sunstone), generic branch examples, and a Phase 1 guard that verifies origin is on GitHub before any work begins.
10 KiB
| description | agent |
|---|---|
| Fire-and-forget multi-agent workflow: plan, test, implement, PR | 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 at the bare repo root and the environment is ready.
- Confirm
.bare/directory exists in the current working directory. If not, stop: "Not at bare repo root. Run from the directory containing.bare/." - Verify the repo is hosted on GitHub:
git remote get-url origin 2>/dev/null | grep -qE '(github\.com|^git@github\.com:)'. If the command fails (nooriginremote, or origin is not on GitHub), stop: "Workflow requires a GitHub remote atorigin(used bygh pr createin Phase 10)." - Run
gh auth status. If auth is expired or missing, stop: "GitHub CLI auth expired. Rungh auth loginbefore retrying." - Proceed to Phase 2 to get issue context before creating the worktree.
Phase 2: Issue Context
Use @pm to fetch the issue matching $ARGUMENTS from ./TODO.md:
- Issue title, description, acceptance criteria
- Labels and priority
- Any existing branch name / PR link
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 the bare repo root (the directory containing .bare/):
git fetch origin- 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> master - Change working directory to the new worktree.
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 PR)
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 master...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 PR anyway
Phase 10: Commit, PR, and Wrap Up
Commit
- Stage all changes
- Write a conventional commit message summarizing the implementation
- If changes are large/varied, use multiple atomic commits (one per logical unit)
Draft PR
gh pr create --draft --title "<conventional title>" --body "<execution report>"- PR body should include:
- Summary of what was implemented
- Reference to TODO.md issue ID
- Acceptance criteria checklist (from issue)
- Files changed with brief descriptions
- TDD summary: X tasks with tests (RED→GREEN), Y tasks NOT_TESTABLE with justifications
- Any test quality escalations and their resolution
- Unresolved blockers (if any from review loops)
- Review cycle outcomes
TODO Update
- Use
@pmto update the issue in./TODO.md:- Set the PR field to the draft PR URL
- Set Branch to the worktree branch name
- Set Status to
In Review - Add a comment with the PR link and a one-line summary
- If acceptance-criteria checkboxes were addressed by the implementation, ask
@pmto check them off
Local Summary
- Write
.opencode/workflow-summary.mdin the worktree with:- Run timestamp
- Issue reference and title
- Branch and PR link
- 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
Failure Handling
At any phase, if an unrecoverable error occurs:
- Write
.opencode/workflow-summary.mdwith what was completed and what failed - If any code was written, commit it with message
wip: incomplete workflow run for <issue-id> - If a branch exists with commits, create the draft PR noting it is incomplete
- Stop execution
Never hang on interactive prompts. If any command appears to require input, treat it as a failure and follow the above procedure.