docs + AGENTS: worktree workflow, predictable branch naming, PR body template, review iteration, scope discipline

This commit is contained in:
Achmad Setyabudi Susilo
2026-06-28 16:27:37 +07:00
parent c22c33ab7e
commit 179f5fe2f8
+105
View File
@@ -18,6 +18,111 @@ The work is split into issues in the remote Gitea repo: https://git.achmad.dev/a
Tooling: the Gitea MCP tools are available (`gitea-mcp_list_issues`, `gitea-mcp_issue_read`, `gitea-mcp_pull_request_write`, etc.) — use them instead of the CLI when interacting with the remote. Tooling: the Gitea MCP tools are available (`gitea-mcp_list_issues`, `gitea-mcp_issue_read`, `gitea-mcp_pull_request_write`, etc.) — use them instead of the CLI when interacting with the remote.
### Worktree workflow
When the user provides an issue number to work on, the agent works in a dedicated git worktree so multiple agents can run in parallel without file conflicts. The main checkout stays on `main` and is used for integration only.
**Setup, on receiving an issue number:**
1. Read the issue with `gitea-mcp_issue_read` (owner `admin`, repo `ledgerr`). If the issue is already closed, stop and tell the user.
2. Derive a branch name from the issue labels. The first matching label wins:
- `bug``fix/<number>-<slug>`
- `enhancement` or `feature``feat/<number>-<slug>`
- `chore``chore/<number>-<slug>`
- `refactor``refactor/<number>-<slug>`
- `documentation` or `docs``docs/<number>-<slug>`
- No matching label → `feat/<number>-<slug>` (default)
The slug is lowercase, ASCII, dash-separated, max ~40 chars, taken from the issue title. Strip non-ASCII, punctuation, and stop words. Examples: issue `Add chart to dashboard` labeled `enhancement``feat/42-add-chart-to-dashboard`; issue `CSV export broken` labeled `bug``fix/43-csv-export-broken`.
3. Create the worktree at a sibling path: `../ledgerr-<branch>` (slashes in the branch name become dashes in the path).
```bash
git fetch origin
git worktree add ../ledgerr-feat-42-add-chart-to-dashboard -b feat/42-add-chart-to-dashboard origin/main
```
4. `cd` into the worktree and continue all subsequent work there. Run `./gradlew`, tests, and the IDE from inside the worktree — never edit files in the main checkout.
If the worktree for that issue already exists (resuming work, or another agent on the same issue), `cd` into it and `git pull` — do not create a duplicate.
**Conventions:**
- Worktree path: `../ledgerr-<branch-with-slashes-as-dashes>` (sibling of the main checkout, not nested inside it)
- Branch name: `<prefix>/<number>-<slug>` where prefix comes from the issue's labels (see mapping above)
- Base branch: `origin/main` (fall back to local `main` if `origin/main` is not fetched yet)
- One worktree per issue. If a single issue needs multiple parallel work streams, split it into sub-issues first.
- The main checkout (`./Ledgerr/`) stays on `main` and is for integration only.
**When work is complete:**
1. Wait for explicit user sign-off (the No-implementation rule still applies).
2. On "open a PR" or equivalent: commit, push with `git push -u origin <branch>`, then `gitea-mcp_pull_request_write` with base `main` and the body filled in from the PR template below.
3. Do **not** merge and do **not** close the issue — the user does that.
4. Leave the worktree in place until the user asks to clean it up: `git worktree remove ../ledgerr-<prefix>-<number>-<slug>` (slashes in the branch name become dashes in the path).
**PR body format** — always use this template, filled in from the actual work:
~~~markdown
## Summary
- <what changed, 13 bullets>
## Test plan
- [ ] <how it was verified: unit tests, manual steps, etc.>
Closes #<number>
~~~
- Summary bullets come from the diff, not invented. One bullet per logical change, not per file.
- Test plan mirrors the issue's acceptance criteria, or lists the manual steps exercised.
- Do not add extra sections (Screenshots, Breaking changes, etc.) unless they apply.
- `Closes #<number>` must be the last line — it is what auto-closes the issue on merge.
**Iteration after review:**
When the user asks to address review feedback, the user asking to address it is the explicit sign-off for that round — the agent commits and pushes as part of the same step, no extra "commit" / "push" prompt needed for review fixes.
1. Read the review with `gitea-mcp_pull_request_read` (methods `get_reviews`, `get_review_comments`).
2. Make the requested changes in the worktree.
3. Commit and push with plain `git push` — **do not force-push, squash, amend, or rebase**. Add new commits on top so the review history is preserved. "Address the review" is the one exception to the Git rule against committing/pushing without explicit ask; everything else (drive-by edits, "while you're at it" changes) still needs its own sign-off.
4. Force-push is allowed only if the user explicitly asks for a rebase or squash, and only on the agent's own branch — never on `main` or any shared branch.
5. Update the PR description if the scope of the change shifted (e.g. new dependencies, new migration). Reuse the same template.
**Scope discipline for review commits:**
A review commit must contain only changes that directly address the reviewer feedback. "Address the review" is **not** a license to bundle unrelated changes — those need their own explicit sign-off.
In scope (no extra ask needed beyond the review):
- Fix a typo, rename, or comment the reviewer called out
- Adjust logic for an edge case they raised
- Add a test for the case they identified
Out of scope (needs its own ask, ideally a separate commit):
- Refactors the reviewer didn't request
- Style/formatting cleanups in unrelated files
- "While we're at it" fixes to other bugs
- Dependency bumps, version changes
- Any change the reviewer didn't ask for
Rule of thumb: if you can't point to a specific review comment that justifies a line in the diff, it doesn't belong in the review commit.
**After the PR is merged:**
The user does the merge (per the rule above). `Closes #<number>` auto-closes the issue. Once the merge is visible on `origin/main`, the worktree and local branch are stale — ask the user before cleaning up, then:
```bash
git worktree remove ../ledgerr-<prefix>-<number>-<slug>
git branch -d <branch>
git fetch origin --prune
```
The remote branch is deleted automatically by Gitea on merge (or the user can do it from the PR page).
**Coordination across agents:**
- `git worktree list` shows all active worktrees.
- Never run two agents in the same worktree — they will race on edits and on KSP/Room/Compose generated code.
- Shared state: `~/.gradle/caches` is shared across worktrees (good — no re-downloads). Each worktree has its own `build/` and project-level `.gradle/` (~200500 MB each). `rm -rf */build` reclaims space when done.
--- ---
## Package structure ## Package structure