SKILL.md called `exclusive` "an org-labels-only flag" and concluded that applying a Kind/*, Priority/* or Status/* label "must replace the one already there, not stack on it". Live `list_repo_labels` on this repo returns `exclusive` on every REPO label: all seven Kind/* plus Compat/Breaking are false, while Priority/*, Reviewed/* and Status/* are true. So the field is not org-only, and the replace rule would strip a valid Kind/* label — a destructive write from a false premise. The nuance kept: label_write's `exclusive` parameter genuinely is annotated org-only, so that row was schema-accurate. The error was generalising a write-parameter restriction into a claim about where the field exists. The row is qualified rather than deleted. The rule is now per-label: where exclusive is true the server drops the sibling itself, so do not pre-remove; where it is false the label is legitimately stackable. Also fixes the org-label fallback, which treated any list_org_labels failure as proof the owner is a user account with no org pool and said so was "an answer, not an error to report". Under the token scopes this skill declares the call fails with required=[read:organization] before any org-vs-user determination is made, so a capability gap was being reported as an absent label. Scope errors are now distinguished and reported. Verified live against gitea-mcp v1.7.0, read-only calls. Refs #99
gitea-labels-milestones
Read and write Gitea labels and milestones, and resolve label/milestone identity for the skills that apply them to issues and PRs.
What it does
This skill handles label and milestone CRUD (label_read/label_write, milestone_read/milestone_write) — listing repo or org labels, creating/editing/deleting a label, resolving a label name to the numeric ID required to apply it to an issue or PR, and listing/creating/updating/closing/deleting a milestone. It also owns label inference: mapping conversation context (bug report, feature request, urgency language) to this repo's Kind/*/Priority/*/Status/* taxonomy.
Composition
This is a cross-cutting shared skill. gitea-issues and gitea-prs both compose it whenever they need to apply a label or assign a milestone, rather than duplicating label/milestone logic: they call in for name/title → ID resolution, then their own issue_write/pull_request_write calls apply the resolved IDs. The split is deliberate — identity resolution lives here once, and the write that attaches an ID to a specific issue or PR lives with the skill that owns that object.
That relationship is documented here rather than in the skill description, which is preloaded into every session and carries routing information only: an agent reaches this skill because the user asked about labels or milestones, not because two other skills call it.
Usage
/gitea-labels-milestones
Describe the label or milestone task: list labels, resolve a name to an ID, create/edit/delete a label, or list/create/update/close/delete a milestone. For applying already-resolved labels or a milestone to a specific issue or PR, use gitea-issues or gitea-prs instead.
Files
| File | Purpose |
|---|---|
SKILL.md |
Skill instructions for agents — dispatch table and Gotchas |
references/labels.md |
Execution detail for label_read/label_write |
references/milestones.md |
Execution detail for milestone_read/milestone_write |
references/label-inference.md |
Context-pattern → Kind/*/Priority/*/Status/* label inference guide |
references/sources.md |
Research sources backing the label/milestone guidance |