Files
sow-tools/docs/agents/issue-tracker.md
T
archvillainette a02e06d644 docs(agents): record that tea 0.14 cannot apply org-level labels (#98)
`tea issues edit --add-labels` and `--remove-labels` resolve label names against
the repository's own label set only. Every `Kind/*`, `Priority/*`, `Reviewed/*`
and `Status/*` label lives at the org level, so none of them match: the command
exits 0, prints the issue, and applies nothing. Repo-local labels
(`wayfinder:*`, `ready-for-agent`) work normally, which makes the failure look
intermittent instead of categorical.

Upstream tea fixed this in v0.15 — `modules/task/labels.go` now queries
`ListOrgLabels` alongside the repo labels. nixpkgs pins 0.14.0, so this note
expires when tea is bumped. `tea labels` has the same repo-only limitation and
will not show the org set; `tea api orgs/ShadowsOverWestgate/labels` will.

The second bullet is the more durable half: re-read a label change before
believing it. An earlier version of this branch confidently documented the
opposite cause, because a label that a human had applied by hand was read back
as proof that the CLI had applied it. `tea issues ls -o json` exposes a `labels`
field; a zero exit code does not.

Identical addition in all seven repos carrying `docs/agents/issue-tracker.md`.Reviewed-on: #98

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
2026-08-05 11:38:35 +00:00

109 lines
6.6 KiB
Markdown

# Issue tracker: Gitea (via tea)
Issues for this repo live in Gitea at `git.westgate.pw`, repo
`ShadowsOverWestgate/sow-tools`. Use the `tea` CLI for all operations —
`gh` does not work here. For anything `tea` lacks a subcommand for, use
`tea api <endpoint>` (Gitea's API mirrors GitHub's closely).
Authenticate with your own `tea` login (`tea login add`); never commit tokens
or tea config into this repo. Note Gitea blocks self-review, so approving a PR
needs a different account than the one that opened it.
## Where work lives
Markdown in this repo is **reference, law, or an ADR — nothing else**
(`sow-codebase` ADR-0001). Four homes, no overlap:
- **Live work** → wayfinder maps + Gitea issues. Closeable, assignable,
queryable. Never a markdown file.
- **Settled decisions** → ADR files in `docs/adr/`. Immutable, findable, never
closed, never edited — only superseded by a later ADR pointing back. When an
issue ends in a durable decision, write the ADR, then close the issue
pointing at it. Decisions spanning repos go to `sow-platform/docs/adr/`.
- **Standing law** → `DOCTRINE.md`, `AGENTS.md`, `CONTEXT.md`. Rules that are
always true and vocabulary everyone shares — not the record of one decision.
- **Current-state reference** → docs describing what the code does now, kept
honest by review touching them.
Anything else — implementation plans, design specs, concepts, handoffs,
progress trackers, scratch — is **process**. It does not live in this repo. It
lives in a Gitea issue or a wayfinder map, where it can be assigned, closed,
and superseded. Small tasks need no written plan at all.
Deleting a process doc is not destroying history — `git log -- <path>` recovers
it. But *unfinished intent* (a design never built, an open question still
wanted) is live, not history: harvest it to a Gitea issue before deleting.
`sow-docs` is deprecated and read-only. Never add to it, never send work there.
## Which repo gets the issue
Issues follow ownership. File the issue in the repo that **owns the work**
see the Repo/Owns/Produces table in the workspace root `AGENTS.md`. Standing
in one repo is not a reason to file there.
If work spans repos, file it in the repo that owns the *outcome* and reference
the others from it. A wrong-repo issue is a routing bug, not a filing
preference — move it.
## Conventions
- **Create an issue**: `tea issues create --title "..." --description "..."`
- **Read an issue**: `tea issues <number>` and
`tea api repos/ShadowsOverWestgate/sow-tools/issues/<number>/comments` for comments.
- **List issues**: `tea issues list --state open` (add `--labels ...` to filter).
- **Comment**: `tea comment <number> "..." </dev/null`
Always redirect stdin. `tea` reads stdin to EOF and appends it to the body,
so any non-interactive shell (every agent) hangs forever without
`</dev/null`. Same trap on `tea issues create --description` and
`tea pr create`.
- **Apply / remove labels**: `tea api --method PATCH` on the issue, or
`tea api repos/ShadowsOverWestgate/sow-tools/issues/<number>/labels` endpoints.
- **Org-level labels (`Kind/*`, `Priority/*`, `Reviewed/*`, `Status/*`)**: `tea
issues edit --add-labels` / `--remove-labels` do **not** apply these on tea
0.14.0, the version nixpkgs pins. Name resolution searches only this repo's
own label set, so an org label matches nothing and the command exits 0,
prints the issue, and changes nothing — no error, no warning. Repo-local
labels (`wayfinder:*`, `ready-for-agent`) are unaffected. PRs no-op the same
way. Upstream fixed it in v0.15 (`modules/task/labels.go` now also queries
`ListOrgLabels`), so this expires when tea is bumped; until then apply org
labels in the web UI. Note `tea labels` lists repo labels only, so it will
not show you the org set either — `tea api orgs/ShadowsOverWestgate/labels`
does.
- **Verify every label change by re-reading it.** `tea issues ls -o json` has a
`labels` field; use it. A label command exiting 0 is not evidence it applied,
and assuming otherwise has already cost one investigation several wrong turns.
`tea issues edit --add-labels` works too, org-level labels (`Kind/*`,
`Priority/*`) included, but a read-back straight afterwards can still show
the old set — `tea issues ls` has returned stale labels for several seconds
after an edit that succeeded. Never conclude an edit failed from a single
immediate list; re-read after a pause, or use the `labels` endpoints above,
whose response *is* the resulting label set and needs no second call.
- **Close**: `tea issues close <number>`
`tea` infers the repo from the git remote when run inside the clone.
Gitea shares one number space across issues and PRs.
## Pull requests as a triage surface
**PRs as a request surface: no.**
## When a skill says "publish to the issue tracker"
Create a Gitea issue with `tea issues create`.
## When a skill says "fetch the relevant ticket"
Run `tea issues <number>` plus the comments API call above.
## Wayfinding operations
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `tea issues create --title "..." --description "..." --labels wayfinder:map`.
- **Child ticket**: this Gitea instance (v1.27) has no native sub-issue hierarchy, so a child issue carries `Part of #<map>` at the top of its description, and is also added to a task list in the map body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
- **Blocking**: Gitea's **native dependencies API** — the canonical, UI-visible representation (shows as "Depends on" / "Blocks" on the issue page). Add an edge with `tea api -X POST repos/ShadowsOverWestgate/sow-tools/issues/<child>/dependencies -f owner=ShadowsOverWestgate -f repo=sow-tools -F index=<blocker>`, where `<blocker>` is the blocker's issue **index** (its `#number` — Gitea's dependency API takes the index directly, unlike GitHub's numeric database id). Check status with `tea api repos/ShadowsOverWestgate/sow-tools/issues/<child>/dependencies` (GET) — a ticket is unblocked when every returned issue's `state` is `closed`.
- **Frontier query**: list the map's open children (`tea issues list --state open`, keep the ones whose description contains `Part of #<map>`), drop any with an open dependency (per the GET above) or an assignee; first in map order wins.
- **Claim**: `tea issues edit <n> --add-assignees <username>` — the session's first write.
- **Resolve**: `tea comment <n> "<answer>" </dev/null`, then `tea issues close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.