pipeline(labels): strip gittensor:priority from issues a maintainer did not author (#9737) - #9862
Conversation
…id 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.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | bca54e2 | Commit Preview URL Branch Preview URL |
Jul 29 2026, 03:39 PM |
|
Caution 🛑 LoopOver review result - fixes requiredReview updated: 2026-07-29 15:58:19 UTC
Review summary Nits — 6 non-blocking
CI checks failing
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9862 +/- ##
==========================================
- Coverage 91.65% 90.77% -0.88%
==========================================
Files 916 917 +1
Lines 112772 112816 +44
Branches 27093 27110 +17
==========================================
- Hits 103357 102407 -950
- Misses 8126 9318 +1192
+ Partials 1289 1091 -198
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…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.
The docs-nav guard (#8385) requires a sidebar entry for every published .mdx page; the new label-policy page had none, failing UI tests.
Bundle ReportChanges will increase total bundle size by 11.68kB (0.15%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: loopover-uiAssets Changed:
|


Closes #9737. With #9847 (#9738), this completes epic #9736.
Why
gittensor:prioritycarries the highest scoring multiplier, which makes it the one label whose application has to be constrained by a rule rather than by judgement — 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 a single comment linking the policy.Maintainer of record comes from the repo's own permissions (
adminormaintain), never a hardcoded login, so the rule means the same thing on every repo ORB manages.writeis deliberately not enough — handing out push access would otherwise silently widen who can mint the highest multiplier.Three properties it is shaped around
Fails open on every uncertainty — unreadable permission, unknown author, absent label. Stripping the highest-value label off a maintainer's own issue because we couldn't 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 — so PRs are skipped before the permission read, and the evaluator refuses them independently.
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 (four siblings already use it) rather than adding a fifth copy of that logic.
Shape
The decision is a pure evaluator — 100% statements and branches, measured. The webhook handler is its I/O, following the
maybeHandle*WebhookEventshape every sibling in that file already uses.Worth noting:
issuesevents were already subscribed viaREQUIRED_INSTALLATION_EVENTSand then dropped on the floor — no handler existed. This is the first one.Every strip writes a ledger event with the rule id, the issue author, the permission that was read and the label, so enforcement history is checkable without reading GitHub.
Policy page
/docs/label-policydocuments both rules of the epic — this one and #9738's eligibility window — since a contributor who meets one will meet the other, and a policy split across two pages is a policy nobody reads. It states the fail-open behaviour and the ledger rule ids explicitly, and says plainly that a strip is not a judgement about the issue.The URL is built from the existing
LOOPOVER_SITE_URLconstant rather than a second hardcoded origin.Validation
npx vitest run --changed=origin/main: 12264 passed.tscclean.writerejected, case-insensitive matching on both label and permission, PRs untouched, label-absent, and four fail-open paths.docs:drift-checkandui:openapi:checkgreen.Not in this PR
The issue also asks for a periodic sweep to catch drift (a label applied while the webhook was down). The event path is the enforcement point and stands on its own; the sweep is a scheduled re-run of the same pure evaluator over open issues, and belongs with the other cron work rather than bolted onto this handler.