refactor(opencode): make workflow forge-agnostic and read TODO.md from bare repo

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.
This commit is contained in:
Harald Hoyer 2026-05-06 15:28:08 +02:00
parent 4ec1561af4
commit 2941faa822
3 changed files with 61 additions and 46 deletions

View file

@ -1,5 +1,5 @@
---
description: "Fire-and-forget multi-agent workflow: plan, test, implement, PR"
description: "Fire-and-forget multi-agent workflow: plan, test, implement, commit"
agent: build
---
@ -13,21 +13,33 @@ If `$ARGUMENTS` is empty, stop immediately: "Usage: `/workflow <ISSUE-ID>` (e.g.
## Phase 1: Repo Setup
Verify you are at the bare repo root and the environment is ready.
Verify you are in a bare git repo and that the issue tracker exists.
1. Confirm `.bare/` directory exists in the current working directory. If not, stop: "Not at bare repo root. Run from the directory containing `.bare/`."
2. 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 (no `origin` remote, or origin is not on GitHub), stop: "Workflow requires a GitHub remote at `origin` (used by `gh pr create` in Phase 10)."
3. Run `gh auth status`. If auth is expired or missing, stop: "GitHub CLI auth expired. Run `gh auth login` before retrying."
4. Proceed to Phase 2 to get issue context before creating the worktree.
1. Verify the current repository is bare: `git rev-parse --is-bare-repository 2>/dev/null` must output `true`. If not, stop: "Workflow requires a bare git repository (set up with `git clone --bare` or the `.bare/` + `.git` file pattern)."
2. Capture the bare repo root for later worktree creation: `BARE_REPO_ROOT="$(pwd)"`.
3. 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 to `main`
Store as `DEFAULT_BRANCH`.
4. 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."
5. Snapshot TODO.md to a temp file so `@pm` can read it before any worktree exists:
```bash
TODO_READ_PATH="$(mktemp -t todo.XXXXXX.md)"
git show "$DEFAULT_BRANCH:TODO.md" > "$TODO_READ_PATH"
```
Pass `$TODO_READ_PATH` to `@pm` in Phase 2 (read-only context).
6. Proceed to Phase 2.
---
## Phase 2: Issue Context
Use `@pm` to fetch the issue matching `$ARGUMENTS` from `./TODO.md`:
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 / PR link
- Any existing branch name
If the issue does not exist or `@pm` fails, stop with error.
@ -37,13 +49,13 @@ Derive a branch name: `<issue-id-lowercase>-<slugified-title>` (e.g. `abc-1-add-
## Phase 3: Repo Setup (continued)
From the bare repo root (the directory containing `.bare/`):
From `$BARE_REPO_ROOT`:
1. `git fetch origin`
1. If an `origin` remote is configured, run `git fetch origin` (best-effort; ignore failure if there is no remote).
2. Compute worktree directory: replace all `/` with `-` in the branch name (e.g. `feat/abc-1-foo` becomes `feat-abc-1-foo`)
3. Check if worktree directory already exists. If yes, enter it and verify `git status --porcelain` is empty. If dirty, stop: "Worktree exists but has uncommitted changes. Clean it up first."
4. If worktree does not exist: `git worktree add <dir-name> -b <branch-name> master`
5. Change working directory to the new worktree.
4. If worktree does not exist: `git worktree add <dir-name> -b <branch-name> "$DEFAULT_BRANCH"`
5. Change working directory to the new worktree. From here on, `./TODO.md` in the worktree is the **live, writable** copy that Phase 10 will update.
---
@ -88,7 +100,7 @@ Reviewers should evaluate testability:
3. If verdict is ACCEPTABLE from both (or JUSTIFIED COMPLEXITY from `@simplify`): proceed to Phase 6
4. If BLOCK or NEEDS WORK: revise the plan addressing findings, then re-review
5. **Convergence detection:** if reviewers return the same findings as the previous cycle, stop the loop early
6. If still unresolved after 3 cycles: note unresolved blockers and proceed anyway (they will be documented in the PR)
6. If still unresolved after 3 cycles: note unresolved blockers and proceed anyway (they will be documented in the workflow summary and commit message)
---
@ -184,7 +196,7 @@ Dispatch `@check` and `@simplify` in parallel to review the full implementation
Provide reviewers with:
- The original plan
- The full diff (`git diff master...HEAD`)
- The full diff (`git diff "$DEFAULT_BRANCH"...HEAD`)
- Any decisions or deviations from the plan
**Review loop (max 3 cycles):**
@ -193,57 +205,53 @@ Provide reviewers with:
3. If ACCEPTABLE: proceed to Phase 10
4. If issues found: fix them directly (no need to re-dispatch `@make` for small fixes), then re-review
5. **Convergence detection:** same findings twice = stop loop early
6. If unresolved after 3 cycles: document blockers, proceed to PR anyway
6. If unresolved after 3 cycles: document blockers, proceed to commit anyway
---
## Phase 10: Commit, PR, and Wrap Up
## Phase 10: Commit and Wrap Up
### Commit
- Stage all changes
- Write a conventional commit message summarizing the implementation
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.md` and `.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)
### 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 `@pm` to update the issue in `./TODO.md`:
- Set the **PR** field to the draft PR URL
- Use `@pm` to 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 PR link and a one-line summary
- 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 `@pm` to 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.md` in the worktree with:
- Run timestamp
- Issue reference and title
- Branch and PR link
- 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:
1. Write `.opencode/workflow-summary.md` with what was completed and what failed
1. Write `.opencode/workflow-summary.md` (in the worktree, if one exists) with what was completed and what failed
2. If any code was written, commit it with message `wip: incomplete workflow run for <issue-id>`
3. If a branch exists with commits, create the draft PR noting it is incomplete
4. Stop execution
3. Leave the branch and worktree intact for the user to inspect — do not push, do not delete
4. If a worktree exists, use `@pm` to add a comment on the issue in `./TODO.md` summarising what failed
5. Remove the temp snapshot if it was created: `rm -f "$TODO_READ_PATH"`
6. Stop execution
**Never hang on interactive prompts.** If any command appears to require input, treat it as a failure and follow the above procedure.