A conventions slot for projects that mandate a label on every PR. Optional and additive — leave it out and nothing changes.
Added
-
pr.labels— a configurable mandatory-PR-label policy forpull-requests. Some organisations require every PR to carry exactly one label from a fixed vocabulary, chosen by a question the diff cannot answer: who wrote the first working version, which change class this is, which compliance category applies. There was no slot for that —praccepted onlytitle_format,template_path,gatesandrisk, and rejects unknown keys, so the policy could not even be forward-declared. The remaining option was the guideline layer, which is compiled intoCLAUDE.md/AGENTS.mdand loaded in every session, so a rule that only matters when a PR is created cost tokens on every unrelated task.Declared in
boost.php, the policy renders inside thepull-requestsskill instead, where it is read only when that skill activates:'pr' => [ 'labels' => [ 'require_exactly_one' => true, // false ⇒ at most one 'exempt_bot_authors' => true, // skip for Dependabot & friends 'rule' => 'Who wrote the first working version of the main change?', 'rule_doc' => 'docs/pr-label-policy.md', // optional prose 'options' => [ ['name' => 'Label A', 'when' => 'criterion for A'], ['name' => 'Label B', 'when' => 'criterion for B', 'on_doubt' => true], ], ], ],
The slot carries the mechanism only. Label names, the deciding question, and the policy prose are yours — no vocabulary and no semantics are fixed by the package, and
optionshas no mandated length beyond needing at least one entry.The skill applies the
nameverbatim. These vocabularies are usually aggregated outside the repo, where a translated or re-cased name does not fail loudly; it just stops counting, and the repo drops out of the aggregation unnoticed.How the label is decided: the agent answers
rulefrom first-hand knowledge when the work happened in the session, treats repository evidence (commit history, trailers, the diff) as an input rather than an answer when the branch predates it, and asks the author otherwise — batched into the existing pre-PRAskUserQuestioncall alongside the risk and description-direction questions.on_doubtmarks the option an uncertain author falls back to; the agent may not use it to skip asking. A resolved label reaches the PR viagh pr create --label.The package applies the label, it does not enforce it. Nothing here blocks an unlabelled PR — add a CI check on the PR event if you need a hard gate.
-
final-verification-reviewreports the label policy in its closeout check. A configured mandate is now visible before the PR exists rather than at creation time. An unresolved label is a note, since the pre-PR question resolves it; only a config that cannot be satisfied — an emptyoptionslist, or several options claimingon_doubt— is reported as blocking.
Notes
- Absent ⇒ no behaviour change. With no
pr.labelsdeclared, both skills render an explicit no-op and there is no label step. Existing configs are unaffected. - No
schema-versionbump. This is additive to v1;schema-versionstays1. - Orthogonal to
pr.risk. A risk tier's ownlabelis routing metadata applied by tier score;pr.labelsis an author-declared policy. Declare either, both, or neither — with both, a PR carries both labels.
Full Changelog: 2.23.1...2.24.0