Replace summary workflow with full §0–§38 canonical PR review/merge rules. Align review-merge-final-report schema with §37 controller handoff fields. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
635 lines
27 KiB
Markdown
635 lines
27 KiB
Markdown
---
|
|
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.
|
|
|
|
## Task mode router (#333)
|
|
|
|
**Identify task mode before any mutation.** Load the matching workflow file and
|
|
final-report schema; do not apply rules from other modes.
|
|
|
|
| Task mode | Workflow | Final report schema |
|
|
|-----------|----------|---------------------|
|
|
| `review-merge-pr` | [`workflows/review-merge-pr.md`](workflows/review-merge-pr.md) (canonical; §0–§38) | [`schemas/review-merge-final-report.md`](schemas/review-merge-final-report.md) |
|
|
| `create-issue` | `workflows/create-issue.md` (planned — #333) | `schemas/create-issue-final-report.md` (planned) |
|
|
| `work-issue` | `workflows/work-issue.md` (planned — #333) | `schemas/work-issue-final-report.md` (planned) |
|
|
|
|
Mode isolation:
|
|
|
|
- **review-merge-pr** — reviewer namespace only; no issue creation, no code edits, no approve/merge replay after terminal review
|
|
- **create-issue** — author namespace; duplicate search + `create_issue` capability; no PR review/merge
|
|
- **work-issue** — author namespace; implement, validate, commit, PR; no approve/merge
|
|
|
|
Shared gate references (all modes): `gates/identity-capability-rules.md`,
|
|
`gates/mutation-ledger-rules.md`, `gates/proof-wording-rules.md` (planned — #333).
|
|
|
|
Until `create-issue.md` and `work-issue.md` land, author rules remain in this
|
|
file (§A, §E) and review rules live in
|
|
[`workflows/review-merge-pr.md`](workflows/review-merge-pr.md).
|
|
|
|
---
|
|
|
|
|
|
## Definitions
|
|
|
|
- **Merged**: Gitea PR metadata says `merged=true`.
|
|
- **Landed**: Equivalent content is present on remote `master`, but PR metadata may not say merged.
|
|
- **Closed-not-merged**: PR state is closed and `merged=false`.
|
|
- **Reconciled**: A human/LLM verified whether closed-not-merged content landed, partially landed, or was lost, and repaired issue/label/tracker state.
|
|
|
|
## 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.
|
|
|
|
Additional issue-first rules:
|
|
|
|
- Do not implement code without an issue unless explicitly authorized.
|
|
- **Design-only work uses a discussion/RFC issue** — create one or comment on
|
|
the existing one. Design debates belong on the issue, where other LLMs
|
|
comment directly. Discussion-only tasks must **not** create branches or PRs;
|
|
their comments should include recommendations, risks, open questions, and a
|
|
Controller Handoff (§K; compact format unless high-risk).
|
|
- **If the repo/tracker home for the work is unclear, stop and ask for an
|
|
owner decision.** Do not create a new repository or a new tracker unless
|
|
explicitly approved by the owner.
|
|
|
|
## Work Selection Rule for LLMs
|
|
|
|
Before starting any issue or PR work, acquire or verify a work lease.
|
|
|
|
Do not begin coding, reviewing, fixing, branching, committing, pushing,
|
|
commenting, or creating a PR until you prove the target is not already being
|
|
worked.
|
|
|
|
Required checks:
|
|
|
|
1. List open PRs.
|
|
2. Search for PRs linked to the target issue.
|
|
3. Search local and remote branches for the issue number.
|
|
4. Search registered worktrees for the issue branch.
|
|
5. Check dirty worktrees.
|
|
6. Check active leases or recent handoffs.
|
|
7. Check whether the issue was already completed by a merged PR.
|
|
|
|
If another active LLM/session owns the lease, stop.
|
|
|
|
Allowed responses:
|
|
|
|
- continue as the lease owner,
|
|
- review the existing PR if reviewer capability allows,
|
|
- produce a handoff,
|
|
- request takeover after lease expiry,
|
|
- stop with "work already claimed."
|
|
|
|
Never create a parallel branch or PR for the same issue unless the old branch
|
|
is proven abandoned and the takeover is recorded.
|
|
|
|
For Gitea-Tools: `gitea_lock_issue` is the fail-closed lease gate before author
|
|
mutations; `status:in-progress` and claim comments are supporting lease signals.
|
|
Use `review_proofs.classify_issue_for_selection` when reporting fresh issue
|
|
selection (#188).
|
|
|
|
## Global LLM Worktree Rule
|
|
|
|
The main project checkout is a stable control checkout. It must stay on the
|
|
configured stable branch: `master`, `main`, or `dev`.
|
|
|
|
All LLM task work must happen inside the project's `branches/` directory.
|
|
|
|
Before any mutation, prove:
|
|
|
|
1. current project root
|
|
2. current working directory
|
|
3. current branch
|
|
4. stable branch for the main checkout
|
|
5. session-owned worktree path under `branches/`
|
|
|
|
If `cwd` is not inside `branches/`, stop. Do not edit, create, delete, format,
|
|
test-write, commit, merge, rebase, checkout task branches, resolve conflicts,
|
|
or run cleanup.
|
|
|
|
There are no exceptions for small fixes, docs, tests, cleanup, PR review fixes,
|
|
conflict resolution, or emergencies.
|
|
|
|
The main checkout may only be used for read-only inspection, fetching,
|
|
stable-branch update after merged PRs, creating `branches/` worktrees, or
|
|
explicit control-checkout repair.
|
|
|
|
## Shell Spawn Hard-Stop Rule
|
|
|
|
A shell tool result of `exit_code: -1` with empty stdout/stderr means the
|
|
executor failed to spawn — it is not a command failure, and retrying the same
|
|
call cannot succeed.
|
|
|
|
1. On the first spawn failure, run one trivial probe (`echo ok` or `pwd`).
|
|
If the probe also fails, mark shell unavailable for the session.
|
|
2. After two consecutive spawn failures, hard-stop all further shell tool
|
|
use for the session. Never retry the same failing spawn.
|
|
3. Stop and emit a recovery report instead of improvising fallbacks. The
|
|
report must tell the operator to: restart the session, kill hung
|
|
background terminals (a hung test runner is a known contributor), and
|
|
prefer MCP-native paths (for example `gitea_commit_files`) for any
|
|
remaining mutations.
|
|
|
|
Retry spirals are a real failure mode (issue #258: 100+ tool calls on a
|
|
trivial encode-and-commit task). The hard-stop is fail-closed: no shell means
|
|
stop-and-report, not workarounds.
|
|
|
|
## B. Isolated worktree rule
|
|
|
|
**Never implement or review in the main checkout** (Global LLM Worktree Rule).
|
|
The main checkout is for orchestration and status only (issue creation,
|
|
`git status`, creating worktrees) and must remain on the stable branch.
|
|
|
|
- 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.
|
|
|
|
Every implementation branch **must include its issue number** so it is
|
|
traceable end to end: **issue → branch → worktree folder → PR → cleanup.**
|
|
|
|
Allowed implementation patterns:
|
|
|
|
- `fix/issue-123-short-description`
|
|
- `feat/issue-123-short-description`
|
|
- `docs/issue-123-short-description`
|
|
- `chore/issue-123-short-description`
|
|
|
|
Review-only branches:
|
|
|
|
- `review/pr-456-short-description`
|
|
|
|
Use a filesystem-safe folder under `branches/` by replacing slashes with
|
|
hyphens, for example `branches/fix-issue-123-short-description`.
|
|
|
|
`scripts/worktree-start` **enforces** this: it rejects an implementation branch
|
|
that does not match `(fix|feat|docs|chore)/issue-<number>-…` (or a
|
|
`review/pr-<number>-…` branch), unless `--allow-unlinked` is passed. Traceability
|
|
is maintained by:
|
|
|
|
- the branch name (contains the issue number),
|
|
- a claim comment on the issue, e.g.
|
|
`Claimed. Branch: fix/issue-123-short-description. Worktree: branches/fix-issue-123-short-description.`,
|
|
- the PR body — `Closes #123` or `Fixes #123` when the PR should close the issue
|
|
(do NOT use `Implements #123` or `Refs #123` to close, as Gitea will not auto-close),
|
|
- cleanup after merge — remove the remote branch, local branch, and the issue
|
|
worktree folder, and drop `status:in-progress`.
|
|
|
|
For projects using `Gitea-Tools` helpers:
|
|
|
|
```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
|
|
- **Dual-Profile MCP Launcher Pattern (Recommended):** To avoid relaunch bottlenecks and PR-author deadlocks, register multiple instances of the same MCP server in the client's configuration simultaneously (e.g., `gitea-author` and `gitea-reviewer`), each pointing to its respective `GITEA_MCP_PROFILE`.
|
|
- Tool calls become namespace-scoped: `mcp__gitea-author__*` and `mcp__gitea-reviewer__*`.
|
|
- **Trust Model:** Separate tokens remain separate. Profile gates enforce allowed operations, `whoami` is still checked, and self-review/self-merge prevention remains mandatory. This pattern is for convenience and does not bypass security gates.
|
|
- **Deadlock Warning:** Reviewer/merge identities must not be used to create PRs, as this makes the reviewer the PR author in Gitea and blocks independent review. PRs should normally be created by the author/work identity, keeping the reviewer identity available for reviews.
|
|
- **Fallback:** If a dual-server launcher is not available in the client, relaunch or restart the client with the correct profile environment variable before claiming work.
|
|
- **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
|
|
|
|
0. Acquire or verify a work lease (Work Selection Rule) — complete all seven
|
|
checks before any claim, branch, or PR work.
|
|
0b. Global LLM Worktree Rule — prove project root, `cwd`, branch, main-checkout
|
|
stable branch, and session-owned `branches/` worktree path. If `cwd` is not
|
|
under `branches/`, stop before any mutation (no exceptions).
|
|
1. Verify the orchestration checkout (right repo, clean tree, on stable branch).
|
|
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).
|
|
4b. **Issue lock from your scratch clone (#249):** when using
|
|
`gitea_lock_issue`, pass `worktree_path` pointing at your own clean
|
|
scratch clone (or set `GITEA_AUTHOR_WORKTREE`). The lock gate validates
|
|
*that* path — clean tree on `master`/`main`, no tracked edits yet —
|
|
not the shared MCP/orchestration checkout. Another session's dirty
|
|
feature branch in the shared dev worktree must not block your lock.
|
|
Never stash, reset, or checkout files in the shared worktree to satisfy
|
|
the gate. Pass the same `worktree_path` to `gitea_create_pr` so the PR
|
|
gate matches the lock record.
|
|
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).
|
|
Record the branch name and `HEAD` SHA at validation time — the drift
|
|
check in step 9 compares against exactly this state.
|
|
9. **Branch proof before commit (#177):** prove and state, immediately
|
|
before staging/committing (`author_proofs.verify_branch_for_commit`,
|
|
`author_proofs.detect_branch_drift`):
|
|
- current branch (`git branch --show-current`) equals the intended
|
|
feature branch from the issue claim
|
|
- current branch is not `master`, `main`, `develop`, `development`, or
|
|
`dev`
|
|
- branch and `HEAD` have not changed since validation (step 8) — in a
|
|
shared checkout another session may switch branches mid-session;
|
|
treat that as expected and **stop before committing** when detected
|
|
If any check fails, stop and reconcile; do not commit.
|
|
10. Commit with an issue-linked message.
|
|
11. **Branch proof before push (#177):** prove that the local branch, the
|
|
push target branch, and the intended issue branch all match, and that
|
|
none of them is a protected branch
|
|
(`author_proofs.verify_push_target`). If a commit accidentally landed
|
|
on a protected branch, do **not** push: report the accident and the
|
|
exact repair steps (`author_proofs.assess_protected_branch_commit`) —
|
|
never silently continue after a repair.
|
|
12. Push the branch.
|
|
13. Open a PR to `master`. The final report must include the branch proofs
|
|
from steps 9 and 11 (`author_proofs.build_commit_push_report`).
|
|
14. **If you are the author, stop before review/merge.**
|
|
15. **Normal issue work must not directly push to `master`.** PR content should be merged through the forge PR merge mechanism.
|
|
16. Direct push to `master` is allowed only as a documented recovery exception. If used, the final report must include:
|
|
- why the PR merge path could not be used
|
|
- exact commits pushed
|
|
- PR metadata state
|
|
- issue labels/state repaired
|
|
- whether the PR is closed-not-merged
|
|
|
|
|
|
## F. Review workflow
|
|
|
|
Moved to [`workflows/review-merge-pr.md`](workflows/review-merge-pr.md) (#334).
|
|
Load that file for PR inventory, validation, review mutation, merge preflight,
|
|
cleanup, and reviewer hard walls. Final report:
|
|
[`schemas/review-merge-final-report.md`](schemas/review-merge-final-report.md).
|
|
|
|
## G. Merge / cleanup workflow
|
|
|
|
Moved to [`workflows/review-merge-pr.md`](workflows/review-merge-pr.md) §6–§7
|
|
and [`templates/worktree-cleanup.md`](templates/worktree-cleanup.md). Load the
|
|
workflow file before any merge mutation.
|
|
|
|
## 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 (closed with `merged=false`). In this case:
|
|
- stop normal review/merge
|
|
- do not delete branches/worktrees
|
|
- do not start dependent work
|
|
- run reconciliation
|
|
- 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. For Gitea-Tools
|
|
author flows, lock the issue from your scratch clone (`worktree_path` on
|
|
`gitea_lock_issue`) — do not manipulate the shared dev checkout.
|
|
- **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 (`merged=false`):** do not merge. Run reconciliation: compare PR content to remote `master` and decide:
|
|
- **fully landed:** comment that content is present on `master`, remove `status:in-progress`, keep/close issue as appropriate, clean up only after content equivalence is confirmed.
|
|
- **partially landed:** do not clean up, reopen issue if needed, create corrective issue/PR for missing pieces.
|
|
- **not landed:** reopen issue if needed, reopen PR or create replacement PR, do not clean up source branch/worktree.
|
|
- **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.
|
|
- [`reconcile-closed-not-merged-pr.md`](templates/reconcile-closed-not-merged-pr.md) — reconcile a closed-not-merged PR.
|
|
- [`worktree-cleanup.md`](templates/worktree-cleanup.md) — clean up after merge.
|
|
- [`release-tag.md`](templates/release-tag.md) — create a release tag.
|
|
|
|
## K. Controller Handoff (required, every task)
|
|
|
|
Every LLM task **must end with a `Controller Handoff`** (exact title) — whether the
|
|
task was implementation, review, merge, issue triage, documentation,
|
|
discussion-only, or blocked planning. It lets a controller LLM understand the
|
|
current state immediately, without rereading the conversation.
|
|
|
|
The section title must be exactly "Controller Handoff" (or "Controller Handoff Summary" for long form). Reports without it are downgraded (see review_proofs.assess_controller_handoff).
|
|
|
|
**The compact format is the default.** It is written for controller-LLM
|
|
readability, not as a full human status report. PR bodies still carry the
|
|
full review detail — the handoff never replaces PR documentation.
|
|
|
|
Compact format (default, canonical field set per issue #182):
|
|
|
|
```md
|
|
## Controller Handoff
|
|
|
|
- Task:
|
|
- Repo:
|
|
- Role:
|
|
- Identity:
|
|
- Issue/PR:
|
|
- Branch/SHA:
|
|
- Files changed:
|
|
- Validation:
|
|
- Mutations:
|
|
- Current status:
|
|
- Blockers:
|
|
- Next:
|
|
- Safety:
|
|
```
|
|
|
|
Role-specific fields (append to the compact block):
|
|
|
|
- review/merge tasks: use
|
|
[`schemas/review-merge-final-report.md`](schemas/review-merge-final-report.md)
|
|
(includes `Selected PR:`, `Reviewer eligibility:`, `Pinned reviewed head:`,
|
|
`Review decision:`, `Merge result:`, `Linked issue status:`, `Cleanup status:`,
|
|
and precise mutation categories — not `Workspace mutations`)
|
|
- issue-filing tasks (#191): `Issue created or updated:`, `Related issues:`;
|
|
body must cite exact issue number/title, duplicate-search summary (issues
|
|
searched, closest matches, why update rejected / new issue justified), full
|
|
40-char SHAs when citing commits, exact mutation capability per change, and
|
|
`Only mutation(s):` when a single mutation was performed
|
|
(`review_proofs.assess_issue_filing_final_report`).
|
|
- author tasks: `Selected issue:`, `Claim/comment status:`,
|
|
`PR number opened:`, `No review/merge:` (explicit confirmation)
|
|
- continuation tasks (#188): `Continuation mode:`, `Existing PR:`,
|
|
`PR author:`, `Branch:`, `Old PR head:`, `New PR head:`,
|
|
`Session authored PR:`, `Why continuation allowed:` — issues with open
|
|
PRs are excluded from fresh selection unless operator explicitly requests
|
|
continuation (`review_proofs.classify_issue_for_selection`,
|
|
`assess_issue_selection_final_report`)
|
|
- queue/inventory tasks: `Repositories checked:`, `Open PR counts:`,
|
|
`Selected PR or reason none selected:`, `Inventory completeness:`
|
|
|
|
The section title must be exactly `Controller Handoff`.
|
|
`review_proofs.assess_controller_handoff()` validates this section; reports
|
|
missing it (or missing required fields) are downgraded. The handoff never
|
|
replaces the full report — it is the compact continuation summary at the end,
|
|
and the full report must still carry exact validation results and mutation
|
|
confirmation.
|
|
|
|
The `Safety:` line is never omitted; it is usually:
|
|
|
|
```text
|
|
no self-review; no self-merge; no tags; no secrets; no prod
|
|
```
|
|
|
|
Rules (both formats):
|
|
|
|
- Never omit the handoff, and never omit the safety confirmations.
|
|
- Never bury blockers in earlier text only — they must appear here.
|
|
- If you opened a PR, state clearly that review is needed.
|
|
- If you reviewed but could not merge, name the exact gate that blocked it.
|
|
- If you only commented on a discussion issue, say no code review is needed
|
|
but owner/design feedback may be needed.
|
|
- If release state was touched, state exactly which tag/commit changed and why.
|
|
- If blocked (permissions, missing repo, missing second reviewer identity,
|
|
stale dependency, unclear tracker home): stop and report clearly; **never
|
|
bypass classifiers, profile gates, missing permissions, or live-consent
|
|
requirements**; give the owner concrete options.
|
|
|
|
**Use the long format below instead of the compact one only when the task was
|
|
high-risk or complex** — i.e. when any of these happened:
|
|
|
|
- a merge, tag, or release
|
|
- failed validation
|
|
- permissions/profile gates blocked work
|
|
- secrets or production access were involved
|
|
- a complicated owner decision
|
|
- multiple repos or cross-issue state
|
|
- the owner explicitly asks for the full format
|
|
|
|
Long format (high-risk/complex tasks only):
|
|
|
|
```md
|
|
## Controller Handoff Summary
|
|
|
|
### Work performed
|
|
|
|
Briefly state what was done.
|
|
|
|
### Current state
|
|
|
|
Include:
|
|
- current repo
|
|
- current branch or master commit
|
|
- issue number(s)
|
|
- PR number(s), if any
|
|
- whether work is complete, blocked, ready for review, or discussion-only
|
|
|
|
### Files changed
|
|
|
|
List files changed, or say `None`.
|
|
|
|
### Validation
|
|
|
|
List commands run and results, or say `Not applicable — discussion only`.
|
|
|
|
### Issues encountered
|
|
|
|
List errors, confusing state, permission/profile problems, stale branches,
|
|
failing tests, missing labels, or blocked decisions.
|
|
|
|
### Review needed?
|
|
|
|
Say one of:
|
|
- `No review needed — discussion/comment only`
|
|
- `Review needed — PR is open`
|
|
- `Independent non-author review needed`
|
|
- `Owner decision needed`
|
|
- `Blocked`
|
|
|
|
### Next recommended action
|
|
|
|
State exactly what should happen next.
|
|
|
|
### Safety confirmations
|
|
|
|
Confirm:
|
|
- no self-review
|
|
- no self-merge
|
|
- no release/tag changes unless explicitly requested
|
|
- no secrets committed
|
|
- no production access used unless explicitly authorized
|
|
```
|
|
|
|
### Example blocked handoff
|
|
|
|
```md
|
|
## Example blocked handoff
|
|
|
|
### Work performed
|
|
|
|
Audited phase-2 MCP Control Plane planning. Found target repo
|
|
`mcp-control-plane` does not exist. Prepared issue pack but did not file it.
|
|
|
|
### Current state
|
|
|
|
- Repo: `Scaled-Tech-Consulting/Gitea-Tools`, unmodified
|
|
- Target repo: `mcp-control-plane`, missing
|
|
- Issues: none open in Gitea-Tools
|
|
- PRs: none open
|
|
- Status: blocked pending owner decision
|
|
|
|
### Files changed
|
|
|
|
None.
|
|
|
|
### Validation
|
|
|
|
Tracker/repo audit only. No code validation required.
|
|
|
|
### Issues encountered
|
|
|
|
Repo creation was denied by permission/classifier because it would be scope
|
|
escalation without live consent.
|
|
|
|
### Review needed?
|
|
|
|
Owner decision needed.
|
|
|
|
### Next recommended action
|
|
|
|
Owner must choose:
|
|
1. create `Scaled-Tech-Consulting/mcp-control-plane`
|
|
2. authorize repo creation while present
|
|
3. file phase-2 issues in Gitea-Tools instead
|
|
|
|
### Safety confirmations
|
|
|
|
- no self-review
|
|
- no self-merge
|
|
- no release/tag changes
|
|
- no secrets committed
|
|
- no production access used
|
|
```
|
|
|
|
## 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–§K are project-agnostic and should not change.
|
|
|
|
## Versioning And Tagging
|
|
|
|
Releases follow SemVer: **`vMAJOR.MINOR.PATCH`** (use **`v0.x.y`** while
|
|
unstable). Choose the bump by the largest change since the last tag:
|
|
|
|
- **PATCH** — bug fixes, docs, tests, wrappers, non-breaking workflow polish.
|
|
- **MINOR** — new tools/helpers/config features; backward-compatible behavior.
|
|
- **MAJOR** — breaking config/schema/API behavior or a changed MCP contract.
|
|
|
|
Tags must:
|
|
|
|
- be created **only from `master`** (the exact commit on remote `master`),
|
|
- be created **only after the full test suite passes**,
|
|
- be **annotated** tags (`git tag -a`), never lightweight,
|
|
- include release notes / a changelog summary referencing the merged PRs/issues.
|
|
|
|
**Never tag** feature branches, dirty worktrees, unreviewed or self-authored
|
|
work, or commits not present on remote `master`.
|
|
|
|
Additional tag rules:
|
|
|
|
- Do **not** create, move, delete, or push tags unless explicitly instructed.
|
|
- Tag only **after** the intended PR is merged, and tag only the **verified
|
|
final master merge commit** (never the PR branch head unless the merge
|
|
commit is exactly that commit).
|
|
- Always **report the tag target commit** in the final report / handoff.
|
|
|
|
Release process (see [`templates/release-tag.md`](templates/release-tag.md)):
|
|
|
|
1. `git fetch <remote> --prune`.
|
|
2. Verify local `master` equals remote `master` (`0 0`) and the tree is clean.
|
|
3. Run the full test suite; stop on any failure.
|
|
4. Inspect merged issues/PRs since the last tag
|
|
(`git log --oneline <last-tag>..<remote>/master`).
|
|
5. Choose the version bump.
|
|
6. Create the annotated tag on remote `master` with release notes.
|
|
7. Push the tag.
|
|
8. Create/update release notes if the forge supports it.
|
|
|
|
Where present, `scripts/release-tag` automates this with all gates built in
|
|
(SemVer, fetch/prune, on-master, clean tree, local==remote master, HEAD on
|
|
remote master, no duplicate tag, tests, annotated-only). Safe by default: no
|
|
push without `--push`; `--dry-run` changes nothing; `--skip-tests` must be
|
|
explicit and warns.
|