refactor(gitea-labels-milestones): retrofit to the ADR-0020 context contract

Description 835 -> 214 chars, body 669 -> 426 words, Gotchas 8 entries/63% of
body -> 3/20.4%. Clears the description FAIL, all three Vale CompositionNote
errors and both Gotchas suggestions. 63% was the worst Gotchas ratio in the
corpus.

Cut the composition sentence to README -- it changes no routing decision and an
agent picks this skill because the user asked about labels, not because two
other skills call it. Cut the capability enumeration; 'list, create, edit,
delete' decompose 'reading or writing' and add no trigger.

Boundary clauses are now one arrow per target. The resolver extracts only the
first name per arrow clause, so the previous '-> gitea-issues / gitea-prs' left
gitea-prs neither dangling nor checked while validate.sh reported 1 of 1. Now
2 of 2.

Makes org-scoped label resolution executable. The org label pool was reachable
in principle -- four *_org_label* methods, and a claim to own name-to-ID
resolution -- but list_org_labels takes org, and Step 1 derived only owner and
repo, so both resolution procedures stalled at the fallback. Fixed once at the
identity step rather than per-procedure. get_user_orgs is outside allowed-tools,
so the failing call is the discriminator: a failure means the owner is a user
account with no org pool, which is an answer, not an error.

Corrects a Gotcha that was false for create_repo_label/create_org_label and
collided with the literal tool name label_write. Same false claim removed from
README.

Refs #99
This commit is contained in:
2026-08-30 12:29:18 +00:00
parent 78015893d4
commit 37382cb72a
4 changed files with 34 additions and 26 deletions

View File

@@ -62,9 +62,15 @@ label_read method: "get_repo_label" owner: <owner> repo: <repo> id: <id>
## Resolve a name to an ID
There is no direct name lookup. List all repo labels (paginating if needed), scan for a
case-insensitive name match, and extract `id`. This is the required first step before any label
application on an issue or PR — the actual `add_labels`/`replace_labels`/`remove_label` call lives
in `gitea-issues`/`gitea-prs` via `issue_write`/`pull_request_write`, which take numeric IDs only.
case-insensitive name match, and extract `id`. Both pools can apply to one issue: if the name is
not in `list_repo_labels`, also check `list_org_labels` before reporting it unresolved. That method
takes `org`, not `owner`/`repo` — pass the repo's `owner` as `org`, which is what it means when the
owner is an organisation. If that call fails, the owner is a user account, there is no org pool, and
the miss is a real miss.
Resolution is the required first step before any label application on an issue or PR — the actual
`add_labels`/`replace_labels`/`remove_label` call lives in `gitea-issues`/`gitea-prs` via
`issue_write`/`pull_request_write`, which take numeric IDs only.
## Create a label