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

5.9 KiB

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 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:

    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:

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:

    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.