security.label is declared, defaults to security, documented as "label applied to PRs that resolve an advisory", and read by the security-only auto-merge condition.
Nothing applied it.
That makes it a quietly broken safety feature rather than merely dead config. A repository could configure security-only auto-merge, see no validation error, watch Buddy open advisory-resolving pull requests — and have the condition never once match, because the label it tests for was never there.
The logic already existed
In generatePRLabels, which had zero callers:
const resolvesAdvisory = group.updates.some(u => (u.securityAdvisories?.length ?? 0) > 0)
if (resolvesAdvisory)
labels.add(this.config.security?.label ?? 'security')It is now part of labelsFor, alongside the automatic set, pullRequest.labels and rule labels — so every path that opens or refreshes a pull request applies it.
Deleting the dead twin
generatePRLabels is removed rather than left as a second implementation. Its other branches were already covered by the live path: the dependencies label, the update-type labels, the configured labels. Its bulk-update branch only re-added dependencies.
One behaviour is deliberately not carried over. It labelled a mixed group with every update type present; the live path labels it with the group's overall type. One accurate label beats three noisy ones, and changing it would alter labels on existing pull requests for no gain — so that is a decision, not an oversight.
What counts as a security update
Whether any update in the group carries a securityAdvisories entry from OSV.dev. An earlier implementation matched a hardcoded list of security-adjacent package names, which both missed every real vulnerability outside that list and mislabelled routine updates to packages that merely sound security-related. The dead code's comment already said so; this keeps it.
Tests
Six, pinning the end-to-end claim from both sides:
- a group resolving an advisory gets the label; a routine update does not
- a renamed
security.labelis applied instead of the default security-onlynow admits a major update purely because it resolves an advisory — the thing that could never happen before- a renamed label is matched by the condition while
securityis not
Docs
docs/features/auto-merge.md said Buddy does not apply this label and you have to arrange it yourself. That was true when written — I wrote it during the docs sweep — and is not now.
Verification
- 1929 pass / 0 fail (+6), lint clean, typecheck clean
check:docsgreen: 75 pages, 33 commands, 221 config keys- Docs site builds: 73 pages
- Net −60 lines of source
🤖 Generated with Claude Code