bug(ci): stale sweep ignores linked PR and sub-issue activity
@purp is already working on this.
Since Sep 4, 2026.
- Dominant language
- Rust
- Stars
- 8.7k
- Forks
- 1.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 253
Description
User Story
As an OpenShell maintainer on triage duty,
I want an issue with active linked work to stay out of the stale sweep,
so that epics and tracked bugs are not mislabeled state:stale while a pull request implementing them is under review.
Problem Statement
The stale sweep in .github/workflows/stale.yml decides staleness from an issue's updated_at timestamp. GitHub does not bump updated_at when an issue is cross-referenced by a pull request, when a linked PR is pushed to or reviewed, or when a sub-issue is updated. As a result, an issue with active implementation work in flight is treated as inactive and receives state:stale after 14 days.
Only direct activity on the issue itself — a comment, a label change, an edit — clears or prevents the label.
Impact / Why This Matters
Today the label is cosmetically wrong but operationally harmful in three ways:
- It misrepresents queue state. During triage,
state:stalesignals "nobody is working on this." A maintainer scanning the backlog cannot distinguish a genuinely abandoned issue from an epic with an open PR against it. - It requires manual, repeating cleanup. The only workaround is for a human to comment on the issue to bump
updated_at, or to hand-apply an exempt label. This has to be redone every 14 days for the life of the work. - It becomes destructive when closing is enabled.
days-before-issue-closeis currently-1(dry-run), so nothing closes today. When that is set to7as the comment anticipates, an issue with an open, actively reviewed PR will be auto-closed asnot_planned.
Observed on #2174:
| Time (UTC) | Event |
|---|---|
| 2026-08-28T12:07:01Z | Stale bot commented and applied state:stale |
| 2026-08-31T08:34:58Z | Cross-referenced by PR #3027 (Part of #2174) |
| 2026-09-02, 09-04 | PR #3027 pushed and reviewed |
| — | updated_at still reads 2026-08-28T12:07:01Z |
The same pattern appears earlier in that issue's history: state:stale applied 2026-07-25, cross-references from #2497 (07-27) and #1129 (08-01) did not clear it, and the label was only removed on 08-02 after a human comment.
Sub-issue activity has the same shape — a parent issue's updated_at does not move when a child issue is updated.
Acceptance Criteria
- An open issue cross-referenced by an open, non-draft pull request is not marked
state:stale. - An open issue whose sub-issue has recent activity is not marked
state:stale. - When an issue already labeled
state:stalegains a linked open PR or sub-issue activity, the label is removed on the next sweep without a human comment. - Issues with no direct activity and no linked PR or sub-issue activity are still marked stale on the existing 14-day schedule.
- The behavior holds once
days-before-issue-closeis set to a positive value, so no issue with active linked work is auto-closed.
Reproduction Steps
- Open an issue and leave it without direct activity for 14 days so the sweep applies
state:stale. - Open a pull request whose body references the issue (
Part of #<n>orCloses #<n>). Confirm thecross-referencedevent appears in the issue timeline. - Push commits to that PR and leave a review on it.
- Run
gh api repos/NVIDIA/OpenShell/issues/<n> --jq .updated_atand observe it is unchanged from step 1. - Wait for the next scheduled sweep (
17 8 * * *). Thestate:stalelabel remains.
Live example, no setup required:
gh api repos/NVIDIA/OpenShell/issues/2174 --jq '{updated_at}'
gh api repos/NVIDIA/OpenShell/issues/2174/timeline --paginate \
--jq '.[] | select(.event=="cross-referenced") | "\(.created_at)\t\(.source.issue.number)"'
Environment
- Repository automation, not the OpenShell runtime
- Workflow:
.github/workflows/stale.yml - Action:
actions/stalev11.0.0 (4391f3da665fdf50b6810c1a66712fb9ba21aa93) - Schedule:
cron: "17 8 * * *" - Current config:
days-before-issue-stale: 14,days-before-issue-close: -1(dry-run) - Exempt labels today:
state:triage-needed,state:validated,state:accepted,agent:*,roadmap
Notes
actions/stale has no built-in option to consider linked pull requests or sub-issues; it filters and sorts on updated_at only. A fix likely needs a pre-step that queries each candidate issue's timeline for cross-referenced events pointing at open PRs, and the sub-issues API for recent child activity, then feeds the results to exempt-issue-labels or skips those issues.
Applying an exempt label such as state:accepted works as a per-issue mitigation but does not generalize, since it conflates "a maintainer decided to pursue this" with "keep the bot away from this."
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.