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.

  1. Pick a repository from the dropdown (populated by the configured token’s visible repositories).
  2. Type into the search box — either issue numbers or search qualifiers. Leaving it empty is fine, and returns everything.
  3. The page renders matching issues with their resolved parent chain, depth indicators, and direct links to GitHub.

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 typeResult
173issue 173
#173issue 173 — the # is optional
137 173issues 137 and 173
137, 173same — commas work as separators
137 OR 173same — OR (any capitalization) is treated as a separator
173 173 137issues 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 typeMeaning
(empty)every issue in the repository, any state
is:open / is:closedfilter by state
label:bughas the bug label
label:bug label:p1has both labels
assignee:@meassigned to the token’s own account
no:assigneeunassigned
milestone:"Q2 hardening"in that milestone — quote values containing spaces
author:some-useropened by that account
updated:>2026-01-01changed since a date
payment retryfree-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 type is: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 sourceDefault state filterHow to narrow
GitHubAll statesis:open / is:closed
GitLabAll statesstate=opened / state=closed selector
Azure DevOpsAll statesState selector
JiraAll statesJQL, 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.

  • Worklog — recent activity on the issues you find via the hierarchy.
  • Value Stream — cycle-time analysis for the issues that surface here.