Files
dionotes-client/docs/agents/issue-tracker.md
MDietermann 50ffab0252 docs: Branch- und PR-Workflow im Tracker-Doc festhalten
Ab jetzt laufen Aenderungen ueber eigene Branches und Pull Requests statt
direkt auf main, damit die logische Trennung sichtbar bleibt. Das gehoert
neben die tea-Kommandos, sonst kennt es nur die Sitzung, in der es vereinbart
wurde.

Festgehalten ist auch die Faustregel fuer den Zuschnitt: Wenn die
Commit-Nachricht "und ausserdem" braucht, sind es zwei Branches. Und dass das
Mergen dem Menschen gehoert, nicht der Umsetzung.
2026-08-28 09:24:00 +02:00

116 lines
5.9 KiB
Markdown

# Issue tracker: Gitea (via `tea`)
Issues and specs for this repo live as **Gitea** issues at
<https://gitlab.hive-brain.de/RDietermann/dionotes-client>.
> The host is named `gitlab.hive-brain.de`, but the server is **Gitea 1.25.5**, not GitLab.
> `glab` will not work. Use the [`tea`](https://gitea.com/gitea/tea) CLI (v0.15 installed).
Run `tea` from inside the clone — it resolves owner/repo from `git remote`. It prints
`NOTE: no login matched this repository, falling back to login 'hive'` on every call;
that is harmless. Add `--login hive` to silence ambiguity, or `--repo RDietermann/dionotes-client`
when running from outside the clone.
## Conventions
- **Create an issue**: `tea issues create --title "..." --description "..." --labels "a,b"`.
Use a heredoc piped through a shell variable for multi-line descriptions — `--description`
takes a single string, there is no `-F file` flag.
- **Read one issue**: `tea issues <index>`. For machine-readable output or fields the CLI
omits, use `tea api repos/RDietermann/dionotes-client/issues/<index>`.
- **List issues**: `tea issues ls --output json --fields index,title,state,labels,assignees,body`
with `--labels`, `--assignee`, `--state` filters as needed.
- **Read comments**: `tea comments ls <index>`.
- **Comment on an issue**: `tea comments add <index> --description "..."`.
(The subcommand is `add`, not `create`.)
- **Apply / remove labels**: `tea issues edit <index> --add-labels "a,b"` / `--remove-labels "a"`.
- **Assign**: **not** `tea issues edit --add-assignees` — that flag posts to
`POST /issues/<index>/assignees`, which Gitea does not have, and fails with a bare 404.
Assignees are set by patching the issue:
```bash
tea api --method PATCH "repos/RDietermann/dionotes-client/issues/<index>" \
-F assignees='["RDietermann"]'
```
This replaces the whole list, so include existing assignees when adding one.
- **Close**: `tea issues close <index>`. It takes no closing comment, so post the explanation
first with `tea comments add`, then close.
- **Create a label** (they are not auto-created): `tea labels create --name "..." --color "#rrggbb"`.
- **Escape hatch**: `tea api <path>` makes an authenticated call against the Gitea API for
anything the CLI does not model. `--method POST -d '<json>'` for writes.
The auth token carries `write:issue,write:repository,write:user` — but **not**
`write:organization`. Creating repos or issues under an org will fail; personal-account
operations work.
## Pull requests as a triage surface
**PRs as a request surface: no.** _(Set to `yes` if this repo treats external pull requests as
feature requests; `/triage` reads this flag.)_
When set to `yes`, PRs run through the same labels and states as issues, using `tea pulls ls`,
`tea pulls <index>`, and the same `tea comments` / `tea issues edit` commands — in Gitea, PRs
share the issue index space, so `#42` is either an issue or a PR, never both.
## When a skill says "publish to the issue tracker"
Create a Gitea issue.
## When a skill says "fetch the relevant ticket"
Run `tea issues <index>` plus `tea comments ls <index>`.
## Branch- und PR-Workflow
Änderungen werden **nicht direkt auf `main`** committet, sondern auf einem eigenen Branch
pro logischer Einheit — `feat/`, `fix/`, `refactor/`, `chore/`, `docs/`. Eine Einheit ist,
was man in einem Satz begründen kann; wenn die Commit-Nachricht „und außerdem" braucht,
sind es zwei Branches.
Zurück nach `main` geht es über einen **Pull Request in Gitea**, nicht per lokalem Merge:
```bash
git push -u origin <branch>
tea pulls create --title "..." --description "..."
```
`--description` nimmt wie bei Issues nur eine Zeichenkette; für längere Texte eine Datei
schreiben und mit `$(cat datei)` übergeben. Bezieht sich der PR auf ein Ticket, gehört
`Closes #<n>` in die Beschreibung, damit Gitea es beim Mergen schließt.
Gemergt wird in der Weboberfläche — das Mergen ist eine Entscheidung des Menschen, nicht
Teil der Umsetzung.
## Wayfinding operations
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
- **Map**: an issue labelled `wayfinder:map`, holding the Destination / Notes /
Decisions-so-far / Not-yet-specified / Out-of-scope body.
`tea issues create --title "..." --labels wayfinder:map --description "..."`.
- **Child ticket**: an issue carrying `Part of #<map>` as the first line of its description,
plus a `wayfinder:<type>` label (`research` / `prototype` / `grilling` / `task`).
Gitea 1.24+ has native sub-issues, but `tea` does not expose them — the `Part of #<map>`
line is the convention here, and Gitea renders it as a cross-reference on the map.
- **Blocking**: Gitea has **native issue dependencies**, which is what renders the frontier in
the web UI. `tea` does not wrap them, so use the API — **verified working**:
```bash
tea api "repos/RDietermann/dionotes-client/issues/<child>/dependencies" \
-F index=<blocker> -f owner=RDietermann -f repo=dionotes-client
```
The body must repeat `owner` and `repo` — the path alone is not enough, and omitting them
fails with a misleading `repository does not exist [owner_name: ]`. The `{owner}`/`{repo}`
placeholders `tea api` documents do **not** get substituted here either; write them out.
Read the blockers back with a plain GET on the same path. A ticket is unblocked when every
blocker is closed.
- **Frontier query**: `tea issues ls --output json --labels wayfinder:grilling,wayfinder:research,wayfinder:prototype,wayfinder:task`,
keep those whose body says `Part of #<map>`, drop any with an assignee (claimed) or an open
blocker; first in map order wins.
- **Claim**: assign the ticket via the PATCH call under "Assign" above — the session's first write.
- **Resolve**: `tea comments add <index> --description "<answer>"`, then
`tea issues close <index>`, then append a context pointer (gist + link) to the map's
Decisions-so-far.