--- name: llm-project-workflow description: >- Portable, safe operating workflow for LLMs working on any Git/forge project: issue-first, isolated branch worktrees, no self-review/self-merge, distinct author/reviewer profiles, cleanup after merge, and fail-closed behavior. Use at the start of any implementation, review, or merge task on a repo. --- # LLM Project Workflow A reusable workflow any LLM can follow to work on any repository safely. Copy this `skills/llm-project-workflow/` directory into another project unchanged; adapt only the forge-specific names in [Adapting to a project](#adapting-to-a-project). The core promise: **an LLM never does unsafe or untracked work.** Every change is tracked by an issue, isolated in its own worktree, reviewed by a different identity, and cleaned up only after a real merge. --- ## A. Issue-first rule **No repository change without a tracking issue.** This includes creating, editing, deleting, or `chmod`-ing files; docs; scripts; commits; pushes; and PRs. 1. Before any change, confirm a tracking issue exists. 2. If none exists, create one first (title + problem + scope + acceptance). 3. Claim it (assign yourself or apply the `status:in-progress` label) and comment that work is starting, including the planned branch name. 4. **If the issue cannot be created or claimed, stop.** Do not touch files. Reading the repo, running read-only status/`git log`, and creating/claiming the issue itself are allowed from the orchestration checkout without a prior issue. ## B. Isolated worktree rule **Never implement or review in the main checkout.** The main checkout is for orchestration and status only (issue creation, `git status`, creating worktrees). - Each issue gets its own branch worktree under an ignored `branches/` directory. - Review work uses a **separate** review worktree, never the author's folder. - Dirty work in one branch folder must not block starting another issue. - No LLM may edit another issue's worktree unless explicitly assigned to it. - Branch folders are removed only after the PR is merged/closed **and** cleanup is explicitly part of the task. Preferred helpers (if present in the project): ```bash scripts/worktree-start fix/issue-123-example # → branches/fix-issue-123-example scripts/worktree-review fix/issue-123-example # → branches/review-fix-issue-123-example (detached) scripts/worktree-clean --delete-branch fix/issue-123-example ``` Manual equivalent: ```bash git fetch --prune git worktree add -b fix/issue-123-example branches/fix-issue-123-example /master cd branches/fix-issue-123-example ``` `venv/` and similar are not copied into new worktrees — run checks with a known interpreter path, or create a venv inside the branch folder. ## C. Identity and profile safety - Use canonical execution profiles where available; the profile is the role, not the LLM. A task selects a profile; a profile is not permanently assigned. - **Author and reviewer identities must be distinct.** - Never place raw tokens/passwords in an LLM/MCP client config. Reference secrets by keychain id or environment variable name only. Prefer a single canonical config file selected by two env vars, e.g.: - `GITEA_MCP_CONFIG` — path to the canonical profiles file - `GITEA_MCP_PROFILE` — the profile to activate - **If the authenticated user equals the PR author, stop** — no self-review, no self-merge. ## D. Branch naming ```text fix/issue-123-short-description feat/issue-123-short-description docs/issue-123-short-description review/pr-456-scope-check ``` Worktree folder = branch with `/` replaced by `-` (`branches/fix-issue-123-short-description`). ## E. Start-work workflow 1. Verify the orchestration checkout (right repo, clean tree). 2. Fetch/prune: `git fetch --prune`. 3. Confirm local `master` equals remote `master` (`git rev-list --left-right --count /master...master` → `0 0`). 4. Create/claim the issue (§A). 5. Create the isolated worktree (§B) from latest remote `master`. 6. Implement the narrow scope only — no unrelated refactors or formatting churn. 7. Add/update focused tests when behavior changes. 8. Run the checks (tests, compile/lint, `git diff --check`, secret scan). 9. Commit with an issue-linked message. 10. Push the branch. 11. Open a PR to `master`. 12. **If you are the author, stop before review/merge.** ## F. Review workflow 1. Use a separate review worktree (`scripts/worktree-review `), detached. 2. Verify your authenticated identity. 3. Verify the PR author — **you must not be the author.** 4. Verify the worktree is clean. 5. Inspect the full diff; confirm scope matches the linked issue; flag unrelated files. 6. Run the tests. 7. **Do not merge if checks fail. Do not merge if the reviewer is the author.** ## G. Merge / cleanup workflow Only an eligible (non-author) reviewer merges. After a real merge: 1. Confirm remote `master` actually contains the merge commit. 2. Close/release the issue; remove `status:in-progress` if used. 3. Delete the remote branch. 4. Remove the local branch. 5. Remove the branch worktree folder (`scripts/worktree-clean --delete-branch `). 6. Fetch/prune. 7. Confirm the main checkout is clean and current (`0 0` vs remote). Never run cleanup before the merge is confirmed on remote `master`. ## H. Fail-closed cases **Stop and report — take no mutating action — if:** - No issue exists and one cannot be created. - Worktree state is unclear or unexpected. - Branch/PR state conflicts with the prompt (e.g. prompt says "merged" but it is not). - A PR is closed but not merged. - Local `master` is ahead of remote unexpectedly. - The authenticated user is the PR author (for review/merge). - Secrets/tokens appear in the diff. - Tests fail. - A cleanup step would delete unmerged work. When in doubt, stop and surface the discrepancy; do not guess or work around a gate. ## I. Recovery patterns - **Dirty worktree from another issue:** do not touch it. Start your issue in its own new worktree; unrelated dirty work must not block you. - **Local `master` ahead of remote unexpectedly:** do not push `master`. Confirm the commits are preserved on a feature branch (local + remote) first, then `git reset --hard /master` to realign. Never discard commits that are not safely pushed elsewhere. - **PR closed but not merged:** the work is not in mainline. Re-push the branch, reopen (or open a replacement) PR, and let an eligible reviewer merge. Do not assume "closed" means "merged" — verify remote `master` contains the commits. - **Branch deleted before merge:** if the commits still exist locally (a branch or reflog), re-push them and reopen the PR; otherwise recover via `git fsck --lost-found`. Preserve first, then proceed. - **Unauthorized/untracked file created:** do not commit it. Leave pre-existing untracked artifacts (e.g. editor/agent dirs, reports) alone; stage only the files your issue names (`git add `, never blind `git add -A`). - **Preserve commits before a reset:** confirm the target commits are reachable from a branch that is pushed to the remote, then reset. Verify with `git branch --contains ` and `git log /`. ## J. Prompt snippets Ready-to-copy templates live in [`templates/`](templates/): - [`start-issue.md`](templates/start-issue.md) — start a new issue. - [`review-pr.md`](templates/review-pr.md) — review a PR. - [`merge-pr.md`](templates/merge-pr.md) — merge a PR (eligible reviewer only). - [`recover-bad-state.md`](templates/recover-bad-state.md) — recover from bad state. - [`worktree-cleanup.md`](templates/worktree-cleanup.md) — clean up after merge. ## Adapting to a project Replace these project-specific names when copying the skill elsewhere: | Placeholder | Meaning | Example here | |-------------|---------|--------------| | `` | Git remote for the forge | `prgs` | | default branch | Integration branch | `master` | | profile env vars | Canonical config + profile selectors | `GITEA_MCP_CONFIG`, `GITEA_MCP_PROFILE` | | `branches/` | Ignored worktree directory | `branches/` | | helper scripts | Worktree helpers | `scripts/worktree-start` / `-review` / `-clean` | The rules in §A–§I are project-agnostic and should not change.