Commit cc222943 authored by xuwang's avatar xuwang
Browse files

feat(agentic): resolver picks up issues assigned to its bot



A human had no direct way to steer the resolver at a specific issue: it only
ever claimed status::ready + unassigned, and step-1 triage explicitly LEFT any
assigned issue — including ones assigned to the bot itself.

Each tick the resolver now first sweeps `issue-list --mine` and works the
lowest actionable issue assigned to it (skipping blocked/in-review/merged and
howto/question), ahead of the open queue — it's already assigned, so no assign
race. Triage now leaves only issues assigned to someone OTHER than the bot.
Plumbing (`issue-list --mine`) already existed; this is prompt/runbook only.

Changelog: changed

Co-Authored-By: default avatarClaude Opus 4.8 <noreply@anthropic.com>
parent ef96befe
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@ gather both labelled and unlabelled work:

For each, **adopt it into the workflow**:
- Add a `kind::*` label if missing (read the title/body to classify).
- If the issue is **assigned to a human**, a person likely owns it — add only the
  `kind::*` label and leave it (do not queue it for fixing). Otherwise promote it:
- If the issue is **assigned to someone other than you** (a human or another bot),
  they own it — add only the `kind::*` label and leave it (do not queue it for
  fixing). An issue **assigned to YOU** is human-directed work — add the `kind::*`
  label and you'll pick it up in step 2. Otherwise (unassigned) promote it:
  `scripts/gl-flow.sh issue-relabel <iid> --add "kind::<x>,status::ready" --remove "status::triage"`
  (the `--remove` is a no-op when there was no status label — safe for untracked issues).
For `kind::howto` / `kind::question` that need **no code change**: answer from the
@@ -40,6 +42,17 @@ scripts/gl-flow.sh issue-close <iid>
GitLab issue (there's no MR to auto-close it).

### 2. Claim ONE issue (the lock)
**First, work anything already assigned to YOU** (human-directed, or your own work
resumed after a crash) — directed work takes precedence over the open queue:
`scripts/gl-flow.sh issue-list --mine`. Skip ones that are parked or already past
fixing — `status::blocked`, `status::in-review`, `status::merged` — and skip
`kind::howto`/`kind::question` (answer-and-close those via step 1's path instead).
If any actionable issue remains, take the **lowest iid**, move it to
`status::in-progress` (`issue-relabel <iid> --add "status::in-progress" --remove
"status::ready"` — the `--remove` is a no-op if it wasn't ready), and go straight
to step 3. It's already yours, so there's no assign race to win.

**Otherwise, claim from the open queue:**
`scripts/gl-flow.sh issue-list --labels "status::ready" --unassigned`.
Pick the **lowest iid**. Claim it atomically:
```
@@ -48,7 +61,7 @@ scripts/gl-flow.sh issue-relabel <iid> --add "status::in-progress" --remove "sta
```
Then **re-read** `scripts/gl-flow.sh issue-get <iid>` and confirm `assignee` is YOU.
If not, another resolver won the race — stop this tick.
If there are no ready, unassigned issues, stop — nothing to do.
If nothing is assigned to you and there are no ready, unassigned issues, stop — nothing to do.

### 3. Fix it
- `git fetch origin && git switch -c agent/issue-<iid> origin/main`
+5 −2
Original line number Diff line number Diff line
@@ -55,8 +55,10 @@ Each agent is defined in `.claude/commands/agent-<name>.md`. The flow:
Issues and MRs don't have to originate from the agents. Anything opened by a
person or another tool starts with **no `status::`/`review::` label**, so:
- the **resolver** sweeps `issue-list --untracked` each tick, classifies it
  (`kind::*`), and pulls it into the queue (assigned-to-a-human issues are left
  for that person — only labelled);
  (`kind::*`), and pulls it into the queue; it also sweeps `issue-list --mine`, so
  an issue **assigned to the resolver bot** is worked directly (human-directed
  work, ahead of the open queue). Issues assigned to *someone else* are left for
  that person — only labelled;
- the **reviewer** sweeps `mr-list --untracked`, adopts it (`review::pending`),
  and reviews it like any other;
- the **integrator** treats a **human approval in the GitLab UI** as authoritative
@@ -358,6 +360,7 @@ participates asynchronously, never by being prompted:
| Human wants to… | Do this in GitLab | Agent reacts on next tick |
|---|---|---|
| File work | Open an issue (or `/agent-reporter …`) | resolver adopts it (untracked sweep) |
| Direct the bot at an issue | Assign the issue to the **resolver bot** | resolver works it first (assigned-to-me sweep) |
| Steer / pause an issue | Set `status::blocked` / add a comment | resolver skips blocked; reads notes |
| Send an MR back | Set `review::changes` + comment | integrator won't merge; resolver reworks |
| Approve an MR | Approve in the UI | integrator merges (honors `mr-approvals`) |