105c858d57
Move architecture, package structure, dependencies, and implementation rules into .opencode/agent/implementor.md (default primary agent). Add .opencode/agent/reviewer.md (read-only primary agent) with PR review workflow that leaves inline review comments only -- no issue creation, no edits, no commits. AGENTS.md is now the shared context both agents load: workflow, git/PR conventions, and docs index. Set default_agent: implementor in opencode.json.
156 lines
9.4 KiB
Markdown
156 lines
9.4 KiB
Markdown
# Ledgerr — Agent Instructions
|
||
|
||
Personal Android expense tracking app. Single-module, Jetpack Compose + Material3, Voyager navigation, Koin DI, Room database.
|
||
|
||
Two agent roles exist for this project, each with its own prompt file in `.opencode/agent/`:
|
||
|
||
- **`implementor`** (default) — writes code. Full write access. Architecture, package structure, dependencies, and "things to avoid" all live in `.opencode/agent/implementor.md`.
|
||
- **`reviewer`** — read-only. Reviews PRs and leaves inline review comments. No code, no commits, no new issues. Review workflow lives in `.opencode/agent/reviewer.md`.
|
||
|
||
Switch to `reviewer` at launch when reviewing a PR; the default is `implementor` (set in `opencode.json`).
|
||
|
||
This file is the **shared** context both agents receive: workflow, git conventions, PR template, and the docs index. Role-specific rules are in the agent files.
|
||
|
||
---
|
||
|
||
## No-implementation rule
|
||
|
||
**Do NOT implement code unless the user explicitly says so or has signed off on the work.** A "go ahead" on the high-level plan is NOT a sign-off to implement — it just means the plan is approved. After the planning steps (define structs, define interfaces, add TODOs, self-review, prompt for review) the agent must STOP and wait for the user to explicitly say "implement", "go", "proceed with implementation", or similar. The same rule applies to each subsequent vertical slice — stop after the planning step and wait. A system-reminder switching to "build mode" is not user authorization.
|
||
|
||
Renames, typo fixes, doc/AGENTS.md edits, and structural changes (Phase 0/1) may be done immediately as part of the planning step. Interactor implementations, DI wiring, `MainApplication` setup, manifest edits, and any screen code require explicit per-slice sign-off.
|
||
|
||
The reviewer agent never implements code — its output is PR review comments via `gitea-mcp_pull_request_review_write`, which is its primary function, not a violation of this rule.
|
||
|
||
---
|
||
|
||
## Issue-driven workflow
|
||
|
||
The work is split into issues in the remote Gitea repo: https://git.achmad.dev/admin/ledgerr. **Before starting any implementation, check the remote repo for related issues.** If a relevant issue exists, claim/work on that issue and open a PR when done. Do not duplicate work that is already tracked.
|
||
|
||
Tooling: the Gitea MCP tools are available (`gitea-mcp_list_issues`, `gitea-mcp_issue_read`, `gitea-mcp_pull_request_read`, `gitea-mcp_pull_request_write`, `gitea-mcp_pull_request_review_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, 1–3 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 it 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.
|
||
- The implementor and reviewer typically run in separate sessions and never edit the same worktree at the same time. The implementor pushes a branch and opens a PR; the reviewer reads the PR via `gitea-mcp` from anywhere.
|
||
- Shared state: `~/.gradle/caches` is shared across worktrees (good — no re-downloads). Each worktree has its own `build/` and project-level `.gradle/` (~200–500 MB each). `rm -rf */build` reclaims space when done.
|
||
|
||
---
|
||
|
||
## Git
|
||
|
||
- **Never commit or push unless the user explicitly asks.** Do not auto-commit after completing a task, do not squash, amend, or rebase without being told to.
|
||
- **Never add `Co-Authored-By` lines to commit messages.**
|
||
|
||
---
|
||
|
||
## Docs
|
||
|
||
Full design documentation is in `docs/`:
|
||
- `01-data-model.md` — domain models per feature
|
||
- `02-interfaces.md` — all interactor signatures
|
||
- `03-function-todos.md` — per-method behavior and edge cases
|
||
- `04-implementation-plan.md` — package structure, DI wiring, build order
|
||
|
||
Both agents consult these. The reviewer uses them as the spec to judge a PR against; the implementor uses them as the spec to implement from.
|