Skip to content

[WIP] Block self-assignment for a cooldown after an inactivity removal #127

Open

Description

@akolson

Overview

The weekly sweep unassigns a contributor for inactivity. The contributor comments /assign and
the bot assigns them again within hours. The removal carries no weight, and a contributor who was
waiting loses the issue.

Block self-assignment for a cooldown period after the bot removes a contributor for inactivity.
During the cooldown, only a maintainer can assign them. The block covers every issue in the
community repos, not only the issue they left.

Context

On learningequality/kolibri#14261, a maintainer unassigned a contributor on 2026-10-23 at 13:07
UTC. Someone else asked for the issue the next morning. At 05:04 UTC the removed contributor
asked to be assigned again, the bot replied "Comment /assign to assign yourself", and at 05:07
the bot assigned them. The maintainer removed them a second time on 2026-10-26.

scripts/contributor-issue-comment.js reads recent unassignments and adds them to the
assignment count instead of blocking:

const totalSlots = assignedIssues.length + filteredUnassignments.length;
if (totalSlots >= MAX_ASSIGNED_ISSUES) { ... }

MAX_ASSIGNED_ISSUES is 2, so one removal leaves a free slot and /assign passes.

getRecentUnassignments in scripts/utils.js reads event.assignee.login and ignores
event.actor.login, so it cannot tell who removed the contributor.

Two bot messages send the contributor back. BOT_MESSAGE_KEYWORD_GOOD_FIRST_ISSUE tells any
contributor to comment /assign, and the unassignment comment in
scripts/unassign-inactive-issues.js says "please message us here, and we'll assign you again".

The Change

Classify each unassignment by actor. Return unassignedBy from event.actor.login:

Actor Meaning Effect
The contributor Self-drop Consumes a slot, as it does today
learning-equality-bot[bot] Inactivity removal Starts the cooldown
Anyone else Not an inactivity removal No cooldown

Unassignment for inactivity belongs to the sweep, so the bot is the actor and no marker is
needed. A maintainer using the assignee menu starts no cooldown, because that removal was not
for inactivity.

Block /assign during the cooldown. Check it in handleAssignCommand before the limit
check. A block is not a slot, and the issue the contributor left is no exception. Only a
maintainer can assign them during the cooldown, by hand.

Add REMOVAL_COOLDOWN_DAYS to scripts/constants.js, set to 7.
getRecentUnassignments takes the longer of the two windows, and each rule reads its own.

Add a block message that names the days remaining and says that a maintainer can assign them
by hand. Send BOT_MESSAGE_KEYWORD_GOOD_FIRST_ISSUE only to a contributor who is not under
cooldown, and reword the unassignment comment to name the cooldown instead of promising
re-assignment.

Out of Scope

Acceptance Criteria

  • A contributor whom the bot removed for inactivity within the cooldown cannot self-assign
    the issue they left, or any other issue in a community repo.
  • A maintainer can assign a contributor under cooldown by hand.
  • A removal by a maintainer through the assignee menu starts no cooldown.
  • A self-drop keeps the current behaviour, that is it consumes a slot and does not block.
  • Once the cooldown expires, /assign works again.
  • The block message names the days remaining and does not tell the contributor to comment
    /assign.
  • The bot does not post BOT_MESSAGE_KEYWORD_GOOD_FIRST_ISSUE to a contributor under
    cooldown.
  • The unassignment comment names the cooldown and promises no re-assignment.

Testing

Test in test-actions. See
testing the automations.
The contributor cases need an account outside the organization.

  1. Label an issue help wanted and good first issue, then comment /assign from the
    contributor account. Expect an assignment.
  2. Dispatch the sweep so that the bot unassigns the contributor, then comment /assign again.
    Expect a refusal that names the days remaining.
  3. Comment /assign on a second good first issue. Expect the same refusal.
  4. Assign the contributor by hand. Expect the assignment to hold.
  5. Unassign the contributor through the assignee menu, then comment /assign. Expect an
    assignment, because a maintainer removal starts no cooldown.
  6. Unassign yourself from the contributor account, then comment /assign on a second issue.
    Expect an assignment, because one slot is free.

References

The real case is learningequality/kolibri#14261. #128 fixes what the sweep counts as inactivity,
and this issue depends on it, because the sweep is the actor that starts the cooldown.

AI usage

I used Claude Code to read the assignment gate, to trace the timeline of kolibri#14261, and to
confirm that getRecentUnassignments ignores the actor. I decided that the cooldown blocks
rather than consumes a slot, that it covers every issue, and that only an inactivity removal by
the bot starts it.

Activity

  1. changed the title [-]Block self-assignment for a cooldown after a maintainer unassigns a contributor[/-] [+]Block self-assignment for a cooldown after an inactivity removal[/+] on Oct 26, 2026
  2. added this to the OSC Automations milestone on Oct 26, 2026
  3. changed the title [-]Block self-assignment for a cooldown after an inactivity removal[/-] [+][WIP] Block self-assignment for a cooldown after an inactivity removal[/+] on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions