You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pr-labeler: several packages/apps scopes have no area mapping, and two of them have no label that fits #4122
.github/workflows/pr-labeler.yaml maps Conventional Commits scopes to area/* labels. Several packages/apps/* names have no entry, so a PR using one lands as area/uncategorized and has to be relabelled by hand.
Measured over the most recent 1000 PR titles, the unmapped scopes and how often each appeared: rabbitmq 5, kubernetes-nodes 3, nats 3, qdrant 3, foundationdb 2, http-cache 2, openbao 2, opensearch 2, vm-disk 1, vpc 1. The workflow's own comment sets the bar for adding an entry at a scope recurring three or more times, so rabbitmq, kubernetes-nodes, nats and qdrant clear it on that sample.
Homes that need no argument: kubernetes-nodes under area/kubernetes, vpc under area/networking, vm-disk under area/virtualization. rabbitmq, nats, qdrant, opensearch and foundationdb are managed data services, and area/database already names kafka in its own description, so filing a message broker there follows an existing decision rather than stretching one.
The scopes with no fit in the current set are openbao, which is secrets management, and http-cache. Those are the ones where the rule in AGENTS.md applies: propose a new area/* through a PR rather than shoehorn the change into a label that does not describe it.
Two drifts nearby, both pre-existing and neither caused by adding entries. The scope table in docs/agents/contributing.md lags the workflow in several rows, and area/dependencies, area/kamaji, area/keycloak and area/tenant have no row there at all; the doc points at the workflow as the authoritative mapping, so this is a summary going stale rather than a contradiction. Separately, the area/* descriptions in .github/labels.yml are example lists rather than definitions, which lets them drift from the workflow the same way.
If the mapping is worth making checkable, the place is a small script comparing those three files against each other. There is none today.
Widening this, because the framing above is narrower than what is actually happening: the gap is not confined to packages/apps/* names.
Taking the scopes off open PRs that currently carry area/uncategorized and checking each against the scopeToArea block, these are absent: networking, workflows, hack, controller, operator, registry, migration, marketplace, external-dns, etcd-operator, monitoring-agents, cozypkg, maintenance, community, observability. Out of that sample only cluster-api is mapped.
Several of those are not package names at all, and some are the most natural word a contributor would reach for. fix(networking): ... falls through to the fallback even though area/networking exists and describes exactly that change. That reads less like a handful of packages nobody got around to and more like the map keying on package directory names while contributors key on subsystem names.
Anyone re-checking this can list the affected pull requests with gh pr list --repo cozystack/cozystack --state open --label area/uncategorized and compare each title's scope against the block in the workflow.
So there is a design question sitting underneath the missing entries, and it is probably the one worth settling first: whether the map should accept an area/* name itself as a scope, so that networking, storage, monitoring and the rest resolve to their own label without needing a per-package row. That would shrink the maintenance surface to genuinely package-specific scopes instead of growing a table that has to anticipate every word.
Correcting the counts in the body. They were taken over the most recent 1000 titles and only the conventional type(scope): form, which reads low for anything with pre-2025 history, where the bracket [scope] form was common.
Re-measured over the whole history, 3088 titles from #8 to #4121, parsed with the labeler's own algorithm rather than a separate regex, so a [Backport ...] prefix, a composite scope and the bracket fallback are all handled the way the workflow handles them:
So vpc, foundationdb and vm-disk clear the bar after all, where the body puts them under it. opensearch is the one that genuinely stays below.
That changes what this issue still holds. #4121 maps the eight that pass, so what is left here is opensearch, under the bar for now; openbao and http-cache, which have no existing label that describes them and so need the new-area conversation rather than a row; and the wider point in the previous comment, that the fallback also fires on subsystem scopes such as networking and workflows which are not package names at all.
Numbers for the wider point above, measured the same way as the corrected counts, over the whole history with the labeler's own parsing.
These scopes are not package names, clear the same bar the table sets, and still land in area/uncategorized: etcd-operator 9, networking 8, kubevirt-operator 7, multus 7, keycloak-configure 5, kubevirt-instancetypes 5, changelogs 4, kubeovn 3, kubevirt-cdi 3, changelog 3, testing 3, flux-shard-operator 3, piraeus-operator 3.
Homes for most of them are as unambiguous as the ones just added: etcd-operator sits next to the existing postgres-operator and mariadb-operator, kubevirt-cdi next to cdi, and changelog against an area/release description that names changelogs outright.
kubeovn is a different problem in the same list. It is an unhyphenated spelling of kube-ovn, which is already mapped, so it is not a missing entry but a missing normalisation. Adding a row for it would work and would also invite a row per spelling forever.
So the two questions this issue should settle, in order: whether the map accepts an area/* name as a scope directly, which removes most of the list above at a stroke, and whether scopes are normalised before lookup, which removes kubeovn and whatever the next spelling turns out to be. Adding thirteen rows answers neither and leaves the table growing by one entry per contributor habit.
One more thing belongs with this, because it is what would keep the mapping honest rather than correct once.
pr-labeler.yaml has no test. Its sibling workflows do: hack/issue-triage-contract.bats, hack/codeowners-invariant.bats and hack/downstream-trigger-map.bats all pin the contract of the file they cover. The scope map is now 83 entries with nothing guarding either of its two silent failure modes. A duplicate key in the object literal overrides the earlier value and looks like an ordinary added line in review. A value naming an area/* that does not exist in .github/labels.yml applies nothing at all, and the run stays green.
Both are cheap to pin, and neither needs the design questions above to be settled first: parse the map, assert no key appears twice, assert every target resolves in labels.yml. That much is true regardless of whether the map later grows area-name scopes or a normalisation step.
Worth noting how the entry count itself came up, since it argues for the same thing. Two reviewers counted the map independently and got 83 and 81. The 81 came from a pattern that missed seaweedfs-cosi-driver and objectstorage-controller, and those two are also the only entries whose value does not sit on the common column, so the same miss produced both an undercount and a confident claim that the alignment was uniform. A parser in the repository, run in CI, is what stops that class of thing from depending on who counted.
A fourth class, distinct from the thirteen above and arguably the more interesting one: scopes that clear the same bar and have no area/* at all, not merely no entry.
dx 15, hack 12, lineage 8, ouroboros 4. Measured the same way as the rest, over the full history with the labeler's own parsing.
The thirteen in the previous comment each have an obvious destination and are missing only a row. These four have nowhere to point. hack and dx describe developer tooling and repository ergonomics, lineage and ouroboros name platform mechanisms that no current label separates from the rest of area/platform. So they are the population where the rule in AGENTS.md actually applies: propose a new area rather than shoehorn, or accept area/platform deliberately and say so.
That makes three groups to decide separately, and only the first is a table edit. Scopes with a home and no row, which a row fixes. Scopes with no home, which need a label decision first. And spellings of an already-mapped scope such as kubeovn, which need normalisation rather than either.
Activity
lexfrei commentedon Sep 7, 2026
Widening this, because the framing above is narrower than what is actually happening: the gap is not confined to
packages/apps/*names.Taking the scopes off open PRs that currently carry
area/uncategorizedand checking each against thescopeToAreablock, these are absent:networking,workflows,hack,controller,operator,registry,migration,marketplace,external-dns,etcd-operator,monitoring-agents,cozypkg,maintenance,community,observability. Out of that sample onlycluster-apiis mapped.Several of those are not package names at all, and some are the most natural word a contributor would reach for.
fix(networking): ...falls through to the fallback even thougharea/networkingexists and describes exactly that change. That reads less like a handful of packages nobody got around to and more like the map keying on package directory names while contributors key on subsystem names.Anyone re-checking this can list the affected pull requests with
gh pr list --repo cozystack/cozystack --state open --label area/uncategorizedand compare each title's scope against the block in the workflow.So there is a design question sitting underneath the missing entries, and it is probably the one worth settling first: whether the map should accept an
area/*name itself as a scope, so thatnetworking,storage,monitoringand the rest resolve to their own label without needing a per-package row. That would shrink the maintenance surface to genuinely package-specific scopes instead of growing a table that has to anticipate every word.lexfrei commentedon Sep 7, 2026
Correcting the counts in the body. They were taken over the most recent 1000 titles and only the conventional
type(scope):form, which reads low for anything with pre-2025 history, where the bracket[scope]form was common.Re-measured over the whole history, 3088 titles from #8 to #4121, parsed with the labeler's own algorithm rather than a separate regex, so a
[Backport ...]prefix, a composite scope and the bracket fallback are all handled the way the workflow handles them:vm-instance14,nats9,vpc8,rabbitmq6,qdrant4,foundationdb4,kubernetes-nodes3,vm-disk3,opensearch2.So
vpc,foundationdbandvm-diskclear the bar after all, where the body puts them under it.opensearchis the one that genuinely stays below.That changes what this issue still holds. #4121 maps the eight that pass, so what is left here is
opensearch, under the bar for now;openbaoandhttp-cache, which have no existing label that describes them and so need the new-area conversation rather than a row; and the wider point in the previous comment, that the fallback also fires on subsystem scopes such asnetworkingandworkflowswhich are not package names at all.lexfrei commentedon Sep 7, 2026
Numbers for the wider point above, measured the same way as the corrected counts, over the whole history with the labeler's own parsing.
These scopes are not package names, clear the same bar the table sets, and still land in
area/uncategorized:etcd-operator9,networking8,kubevirt-operator7,multus7,keycloak-configure5,kubevirt-instancetypes5,changelogs4,kubeovn3,kubevirt-cdi3,changelog3,testing3,flux-shard-operator3,piraeus-operator3.Homes for most of them are as unambiguous as the ones just added:
etcd-operatorsits next to the existingpostgres-operatorandmariadb-operator,kubevirt-cdinext tocdi, andchangelogagainst anarea/releasedescription that names changelogs outright.kubeovnis a different problem in the same list. It is an unhyphenated spelling ofkube-ovn, which is already mapped, so it is not a missing entry but a missing normalisation. Adding a row for it would work and would also invite a row per spelling forever.So the two questions this issue should settle, in order: whether the map accepts an
area/*name as a scope directly, which removes most of the list above at a stroke, and whether scopes are normalised before lookup, which removeskubeovnand whatever the next spelling turns out to be. Adding thirteen rows answers neither and leaves the table growing by one entry per contributor habit.lexfrei commentedon Sep 7, 2026
One more thing belongs with this, because it is what would keep the mapping honest rather than correct once.
pr-labeler.yamlhas no test. Its sibling workflows do:hack/issue-triage-contract.bats,hack/codeowners-invariant.batsandhack/downstream-trigger-map.batsall pin the contract of the file they cover. The scope map is now 83 entries with nothing guarding either of its two silent failure modes. A duplicate key in the object literal overrides the earlier value and looks like an ordinary added line in review. A value naming anarea/*that does not exist in.github/labels.ymlapplies nothing at all, and the run stays green.Both are cheap to pin, and neither needs the design questions above to be settled first: parse the map, assert no key appears twice, assert every target resolves in
labels.yml. That much is true regardless of whether the map later grows area-name scopes or a normalisation step.Worth noting how the entry count itself came up, since it argues for the same thing. Two reviewers counted the map independently and got 83 and 81. The 81 came from a pattern that missed
seaweedfs-cosi-driverandobjectstorage-controller, and those two are also the only entries whose value does not sit on the common column, so the same miss produced both an undercount and a confident claim that the alignment was uniform. A parser in the repository, run in CI, is what stops that class of thing from depending on who counted.lexfrei commentedon Sep 7, 2026
A fourth class, distinct from the thirteen above and arguably the more interesting one: scopes that clear the same bar and have no
area/*at all, not merely no entry.dx15,hack12,lineage8,ouroboros4. Measured the same way as the rest, over the full history with the labeler's own parsing.The thirteen in the previous comment each have an obvious destination and are missing only a row. These four have nowhere to point.
hackanddxdescribe developer tooling and repository ergonomics,lineageandouroborosname platform mechanisms that no current label separates from the rest ofarea/platform. So they are the population where the rule inAGENTS.mdactually applies: propose a new area rather than shoehorn, or acceptarea/platformdeliberately and say so.That makes three groups to decide separately, and only the first is a table edit. Scopes with a home and no row, which a row fixes. Scopes with no home, which need a label decision first. And spellings of an already-mapped scope such as
kubeovn, which need normalisation rather than either.fix(ci): map the recurring app scopes to their area labels (#4121)
fix(ci): harden the PR labeler's title parsing and map recurring scop…