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
pipeline(labels): strip gittensor:priority from issues a maintainer did not author (#9737) (#9862)
* pipeline(labels): strip gittensor:priority from issues a maintainer did not author (#9737)
`gittensor:priority` carries the highest scoring multiplier, which makes it the one label whose
application has to be constrained by a RULE rather than by judgment -- otherwise the highest-value
label is whatever anyone says it is. Priority marks work the MAINTAINER originated and triaged, so on
an issue somebody else authored it is now removed automatically, with one comment linking the policy.
Maintainer-of-record is read from the repo's own permissions (`admin` or `maintain`), never a
hardcoded login, so the rule means the same thing on every repo ORB manages. `write` is deliberately
NOT enough: handing out push access would otherwise widen who can mint the highest multiplier.
Three properties the implementation is shaped around:
- FAILS OPEN on every uncertainty -- an unreadable permission, an unknown author, an absent label.
Stripping the highest-value label off a maintainer's own issue because WE could not read a
permission is a worse error than leaving one wrongly applied, and the next label event re-judges it.
- NEVER touches a pull request. The same label name is also the PR TYPE label for a content
submission, which ORB applies itself -- conflating the two would have this rule fighting the
labeller.
- IDEMPOTENT by construction. Re-labelling re-runs the rule, so the comment carries a marker and is
updated rather than re-posted; it reuses the existing marked-comment upsert instead of a sixth copy
of that logic.
The decision is a pure evaluator with 100% statement and branch coverage; the webhook handler is its
I/O, following the `maybeHandle*WebhookEvent` shape every sibling here already uses. `issues` events
were already subscribed and previously dropped on the floor -- this is the first handler for them.
Every strip is written to the ledger with the rule id, the author, the permission read and the label,
so enforcement history is checkable without reading GitHub.
The policy page the comment links to documents BOTH rules of the epic -- this one and #9738's
eligibility window -- since a contributor meeting one will meet the other.
* test(labels): cover the issues.labeled enforcement path end to end (#9737)
Codecov put the patch at 60%: the DECISION was fully covered by its own unit tests, but the I/O the
decision drives -- the permission read, the label removal, the marked comment, the ledger event -- was
not exercised at all, and neither was the wrapper in comments.ts.
13 cases through the real webhook processor with GitHub stubbed. Half of them assert that nothing
happens: a maintainer-authored issue, an unreadable permission, a pull request carrying the same
label, a different label, a non-labeled action, an issue with no author. A rule that strips the
highest-value label does its damage in the paths where it should have stayed still.
Two fixture corrections the tests forced, both of which say something about the code: the marked-comment
upsert only ever updates a comment authored by the App ITSELF (user.type === Bot and a matching login),
so a fixture without those is correctly ignored and a second comment posted -- which is the right
behaviour and now pinned. And typeLabels is config-as-code only, so the custom-label case stubs the
settings RESOLVER rather than writing a manifest fixture: what this file asserts is that the handler
reads the resolved label, not how a repo comes to have one.
228 added lines across the three files: zero uncovered, zero partial branches.
* fix(ui): add the label-policy docs page to the sidebar
The docs-nav guard (#8385) requires a sidebar entry for every published
.mdx page; the new label-policy page had none, failing UI tests.
title: Label policy — which labels carry scoring weight, and the rules for each
3
+
description: The labels that affect a contribution's score, who may apply them, and when work on them opens. Every rule here is enforced mechanically in the pipeline, not by judgement, and every enforcement is written to the ledger.
4
+
eyebrow: Contributors
5
+
---
6
+
7
+
Three labels categorise an issue, and they are not equal: `gittensor:priority` carries the
8
+
highest scoring multiplier. That makes it the one label whose application has to be
9
+
constrained by a **rule** rather than by judgement — otherwise the highest-value label is
10
+
whatever anyone says it is.
11
+
12
+
Both rules below are enforced by the pipeline, on every label event. Neither is a
13
+
discretionary decision, neither is applied to some contributors and not others, and each
14
+
enforcement is written to the decision ledger with its rule id, so the history is
15
+
independently checkable.
16
+
17
+
## The scoring labels
18
+
19
+
| Label | Meaning | Who may apply it |
20
+
| --- | --- | --- |
21
+
|`gittensor:bug`| A fix, test, doc, chore, refactor, perf, ci, build or style change | Anyone |
22
+
|`gittensor:feature`| Genuinely new functionality | Anyone |
23
+
|`gittensor:priority`| Work the maintainer originated and triaged as most valuable |**Only valid on maintainer-authored issues**|
24
+
25
+
## Rule 1 — priority is only valid on maintainer-authored issues
26
+
27
+
`gittensor:priority` marks work **the maintainer originated**. If it is applied to an issue
28
+
somebody else authored — by anyone, including a maintainer — the pipeline removes it and
29
+
posts a single comment linking here.
30
+
31
+
**Maintainer of record** is read from the repository's own permissions (`admin` or
32
+
`maintain`), never a hardcoded list of names, so the rule means the same thing on every repo
33
+
LoopOver manages. `write` access is deliberately *not* enough: handing out push access would
34
+
otherwise widen who can mint the highest multiplier.
35
+
36
+
The rule **fails open**. If the author's permission cannot be read, nothing is stripped — a
37
+
label is never removed on the strength of a failed lookup, and the issue is re-judged next
38
+
time it is labelled.
39
+
40
+
Removing the label is not a judgement about the issue. It stays open, and contributions to
41
+
it remain welcome under its other labels.
42
+
43
+
Rule id: `priority-label-author-eligibility`.
44
+
45
+
## Rule 2 — priority issues open for work after a short window
46
+
47
+
Priority issues carry the highest payout, so assignment fairness matters most there. First-come
48
+
pickup is only fair if everyone can *see* the issue before anyone can act on it: a PR opened
49
+
moments after the label lands means the window between "issue becomes valuable" and "issue is
50
+
claimed" was effectively zero for everyone else watching the repo.
51
+
52
+
So a PR closing a priority issue becomes gate-eligible once the label has been publicly present
53
+
for a short window — **30 minutes by default**, configurable per repo via
54
+
`gate.priorityEligibilityWindow`, and `0` turns it off.
55
+
56
+
A PR opened inside that window is **not rejected**. It is held, with a comment naming the exact
57
+
moment it becomes eligible, and it proceeds normally once the window passes. There is no penalty
58
+
beyond waiting and nothing to resubmit.
59
+
60
+
The clock is anchored to the **earliest** time the label was applied, so re-applying the label
61
+
never resets the window for anyone, and "when does this issue open for work" is a single instant
62
+
that cannot move.
63
+
64
+
Rule id: `priority-eligibility-window`.
65
+
66
+
## What is not in scope
67
+
68
+
The multiplier *values* themselves are registry-side and are not set here. These two rules govern
69
+
which issues may carry the label and when work on them opens — not what the label is worth.
0 commit comments