GitHub Issue Hierarchy
The GitHub Issue Hierarchy page shows GitHub issues with their parent/child relationships for repositories where those relationships have been resolved and cached by ActivityPulse.
Use it to answer questions like:
- What are the parent epics for the issues my team is working on?
- Which sub-issues belong to a given parent?
- Which open issues lack a parent and may need triage?
Getting started
Navigate to Issue Hierarchy → GitHub in the sidebar. The GitHub data source must be configured.
- Pick a repository from the dropdown (populated by the configured token’s visible repositories).
- Type into the search box — either issue numbers or search qualifiers. Leaving it empty is fine, and returns everything.
- The page renders matching issues with their resolved parent chain, depth indicators, and direct links to GitHub.
What you can type in the search box
The box accepts two different kinds of input, and decides which one you meant from what you typed. There is no mode switch.
Mode 1 — issue numbers (exact lookup)
Used when every token you typed is an issue number. The page fetches exactly those issues by number and adds their parents and children as context rows.
| You type | Result |
|---|---|
173 | issue 173 |
#173 | issue 173 — the # is optional |
137 173 | issues 137 and 173 |
137, 173 | same — commas work as separators |
137 OR 173 | same — OR (any capitalization) is treated as a separator |
173 173 137 | issues 173 and 137 — duplicates are dropped, your order is kept |
Separators are spaces, tabs, and commas. Numbers must be positive whole numbers.
These are not accepted as numbers, and fall through to Mode 2 as text: 0, -5, # on its own, 17a, 1#7.
Number mode applies no state filter — an issue is returned whatever state it is in.
Mode 2 — search qualifiers
Used for anything else. Your text is passed to GitHub’s issue search verbatim, scoped to the selected repository. The syntax is exactly GitHub’s issue search syntax — the full list of qualifiers lives there; the common ones:
| You type | Meaning |
|---|---|
| (empty) | every issue in the repository, any state |
is:open / is:closed | filter by state |
label:bug | has the bug label |
label:bug label:p1 | has both labels |
assignee:@me | assigned to the token’s own account |
no:assignee | unassigned |
milestone:"Q2 hardening" | in that milestone — quote values containing spaces |
author:some-user | opened by that account |
updated:>2026-01-01 | changed since a date |
payment retry | free-text search of title, body, and comments |
Plain words are a full-text search. GitHub indexes comment bodies, so a word can match an issue that only mentions it in a comment — this is why numbers get their own exact-lookup mode.
Qualifiers that are rejected
These are blocked because they would move the search outside the repository you selected, past the access your administrator granted. Using any of them returns an error instead of results:
repo: · org: · user: · archived: · fork:
The check is case-insensitive and matches anywhere in your text. To search a different repository, pick it from the dropdown.
Things the page always applies for you
You do not need to type these, and they cannot be overridden:
is:issue— pull requests never appear in the hierarchy, even if you typeis:pr.- Sorting by last updated, newest first.
- The selected repository as the search scope.
Issue state
An empty query matches issues in every state — open and closed. Add is:open or is:closed to narrow it. This matches the GitLab, Azure DevOps, and Jira hierarchy pages.
| Data source | Default state filter | How to narrow |
|---|---|---|
| GitHub | All states | is:open / is:closed |
| GitLab | All states | state=opened / state=closed selector |
| Azure DevOps | All states | State selector |
| Jira | All states | JQL, e.g. statusCategory != Done |
Show parents / Hide parents
The Show parents / Hide parents selector next to the Load button controls ancestor context:
- Show parents (default) — issues that did not match your query are still shown when they are the parent of something that did, so you can see the epic a matched sub-issue belongs to. These rows are dimmed.
- Hide parents — unmatched ancestors are dropped and matched issues become top-level rows. Children of matched issues are still shown.
Changing it re-renders immediately; you do not need to click Load again. The setting is part of the page URL, so it survives sharing and reload.
How hierarchy is resolved
For each matching issue, ActivityPulse looks up the parent chain from its local cache. The cache is populated when ActivityPulse resolves parent relationships (for example, when issues are explicitly fetched with hierarchy data). Cache entries are retained for 24 hours per (organization, repo, issue).
v1 behavior: If the cache has not been warmed for a repository, issues will appear as a flat list with no parent chain shown. The page will not display the “sub-issues unavailable” banner unless ActivityPulse has confirmed that the repository host does not support sub-issues at all. Parent chain resolution via live GitHub API traversal is planned for a future release.
Rate limits
The page consults two separate GitHub REST quotas:
- Repository list counts against the Core quota (5,000 requests/hour for personal tokens). Repos are cached client-side for ten minutes, so the dropdown rarely hits the API after the first load.
- Issue search counts against the Search quota (30 requests/minute for personal tokens). The page submits one search per explicit user action — there is no auto-refresh.
If you exceed either quota, the BE returns a 429 Too Many Requests and the page shows the remaining wait time.
Limitations
- v1 returns a flat list when the cache is cold. The first search in a repository will show all issues without parent chains if they haven’t been enriched yet. Cache warming from live GitHub API traversal is a planned follow-up.
- The search results are capped at 100 issues per query — the maximum GitHub’s search API returns in one page. Results are ordered by last updated, newest first, so the cap drops the least recently updated matches. When it does, the page shows an amber “more issues matched than can be shown” notice; narrow the search with additional qualifiers to reach the rest.
- Because an empty query now matches every state, wide-open searches on long-lived repositories hit that cap far more often than they used to. Add a qualifier (
is:open,label:…,milestone:…) when you need completeness. - Cycles in the sub-issues graph are detected and broken — a cycle never causes the page to spin.
Related pages
- Worklog — recent activity on the issues you find via the hierarchy.
- Value Stream — cycle-time analysis for the issues that surface here.