# Issue tracker: GitLab

Issues and specs for this repo live as GitLab issues. Use the [`glab`](https://gitlab.com/gitlab-org/cli) CLI for all operations.

## Conventions

- **Create an issue**: `glab issue create --title "..." --description "..."`. Use a heredoc for multi-line descriptions. Pass `--description -` to open an editor.
- **Read an issue**: `glab issue view <number> --comments`. Use `-F json` for machine-readable output.
- **List issues**: `glab issue list -F json` with appropriate `--label` filters.
- **Comment on an issue**: `glab issue note <number> --message "..."`. GitLab calls comments "notes".
- **Apply / remove labels**: `glab issue update <number> --label "..."` / `--unlabel "..."`. Repeat the flag or use a comma-separated value for multiple labels.
- **Close**: post the explanation with `glab issue note <number> --message "..."`, then run `glab issue close <number>`.
- **Merge requests**: use `glab mr create`, `glab mr view`, `glab mr note`, and the other `glab mr` commands.

Infer the repo from `git remote -v` — `glab` does this automatically when run inside a clone.

## Merge requests as a triage surface

**MRs as a request surface: no.** _(Set to `yes` if this repo treats external merge requests as feature requests; `/triage` reads this flag.)_

When set to `yes`, MRs run through the same labels and states as issues:

- **Read an MR**: `glab mr view <number> --comments` and `glab mr diff <number>`.
- **List external MRs for triage**: `glab mr list -F json`, then keep only contributions whose author is not a project member or owner.
- **Comment / label / close**: `glab mr note`, `glab mr update --label`/`--unlabel`, `glab mr close`.

Unlike GitHub, GitLab numbers issues and MRs separately, so `#42` is unambiguous once the surface is known.

## When a skill says "publish to the issue tracker"

Create a GitLab issue.

## When a skill says "fetch the relevant ticket"

Run `glab issue view <number> --comments`.

## `/to-qa` support

Use a stable body marker for the parent/child relationship: the first line of every implementation child's description is `Part of #<parent-iid>`.

Fetch all matching issues across every response page, then retain only the exact first-line marker:

```bash
glab api --method GET "projects/:fullpath/issues" \
  -f scope=all -f state=all -f search="Part of #<parent-iid>" \
  -f in=description -f per_page=100 --paginate --output ndjson \
  | jq -s '[.[] | select(.description | startswith("Part of #<parent-iid>\n"))]'
```

Include only children whose `state` is `closed`; report every open child as a warning. Read each included child with `glab issue view <child-iid> --comments -F json`. Do not mutate GitLab issues during `/to-qa`.

During setup, run the paginated query against the selected repository. If the host or credential cannot return the complete set, stop and ask the user for another concrete parent convention and full-set query. Do not emit an incomplete `/to-qa` configuration.

## Wayfinding operations

Used by `/wayfinder`. The **map** is a single issue with child issues as tickets.

- **Map**: create one issue labelled `wayfinder:map`; its body holds Destination, Notes, Decisions so far, Not yet specified, and Out of scope. A native epic may hold the map when the GitLab tier supports one.
- **Child ticket**: put `Part of #<map>` at the top of the description and apply one `wayfinder:<type>` label plus the mapped mode label: `ready-for-agent` for AFK or `ready-for-human` for HITL.
- **Blocking**: use GitLab's native blocking link by posting `/blocked_by #<blocker>` as a note. If unavailable, use `Blocked by: #<n>, #<n>` near the top of the description.
- **AFK frontier**: list the map's open children, exclude assigned tickets and tickets with an open blocker, then keep the mapped `ready-for-agent` label. Only this frontier may be dispatched autonomously.
- **HITL frontier**: apply the same open, unblocked, and unassigned filters, then keep the mapped `ready-for-human` label and surface those tickets to the human. Preserve map order within each mode.
- **Claim**: `glab issue update <n> --assignee @me` as the session's first write.
- **Resolve**: post the answer, close the child, then add a one-line gist and link to the map's Decisions so far.
