docs: add portable llm-project-workflow skill + templates (#46)
Extract the project's operating rules into a reusable, project-agnostic skill so any repo can adopt the same safe LLM workflow. - skills/llm-project-workflow/SKILL.md: issue-first; isolated branch worktrees (main checkout = orchestration only); distinct author/reviewer identities and profile safety (secrets by reference only; stop if authenticated user == PR author); branch naming; start/review/merge/cleanup workflows; fail-closed cases; recovery patterns; and an "Adapting to a project" table for the forge-specific names. - templates/: copy/paste prompts for start-issue, review-pr, merge-pr, recover-bad-state, worktree-cleanup. - Link the skill from README.md and docs/llm-workflow-runbooks.md (the runbook is framed as the Gitea-specific application of the portable skill). Docs-only; no code, no secrets, safe placeholder examples only. No change to MCP runtime, Gitea API, credential storage, or worktree helpers. Checks: full suite 287 passed / 0 failures; git diff --check clean; secret scan of skills/ clean. Closes #46. Refs #38, #39. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
---
|
||||
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 <remote> --prune
|
||||
git worktree add -b fix/issue-123-example branches/fix-issue-123-example <remote>/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 <remote> --prune`.
|
||||
3. Confirm local `master` equals remote `master` (`git rev-list --left-right --count <remote>/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 <branch>`), 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 <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 <remote>/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 <files>`, 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 <sha>` and `git log <remote>/<branch>`.
|
||||
|
||||
## 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 |
|
||||
|-------------|---------|--------------|
|
||||
| `<remote>` | 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.
|
||||
Reference in New Issue
Block a user