Skip to content

Enrich issue_read get with hierarchy relationship signals#2764

Open
zwick wants to merge 4 commits into
mainfrom
zwick-enrich-issue-read-hierarchy
Open

Enrich issue_read get with hierarchy relationship signals#2764
zwick wants to merge 4 commits into
mainfrom
zwick-enrich-issue-read-hierarchy

Conversation

@zwick

@zwick zwick commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Enrich the issue_read get payload with layered hierarchy relationship signals, derived from a single combined GraphQL round-trip (no added round-trips on get).

Why

The default get payload surfaced no relationship data, so an agent calling the most obvious tool got zero hierarchy signal and had to drop to raw REST (parent_issue_url) or scan sibling sub-issues. This also addresses the #2726 review note asking for cheap has_parent / has_children routing booleans as a follow-up.

Refs github/planning-tracking#3306

What changed

  • issue_read get now returns has_parent / has_children (always emitted), plus parent and sub_issues_summary when those relationships exist.
  • Replaced the single-issue field-values GraphQL call with one combined query (fetchIssueReadEnrichment) returning field values + parent + subIssuesSummary.
  • Best-effort enrichment: a query failure still returns the base issue and never fails get.
  • Parent title is sanitized (may be cross-repo) and redacted under lockdown mode unless the parent content is verified safe; counts/booleans are always emitted.
  • get_parent / sub_issue_write behavior unchanged; tool descriptions now clarify optional hierarchy summaries and write routing via sub_issue_write.

MCP impact

  • Tool schema or behavior changed — issue_read get response gains hierarchy fields; issue_read and sub_issue_write method descriptions updated.

Prompts tested (tool changes only)

  • "Read issue #2990 in github/github-mcp-server" — expect has_parent: true and parent (#2820) without raw REST / sibling scanning. Covered by unit tests; live MCP verification noted as a manual follow-up.

Security / limits

  • Data exposure, filtering, or token/size limits considered — parent titles are sanitized and redacted under lockdown mode when the (possibly cross-repo) parent content cannot be verified as safe; numeric/structural fields stay intact.

Tool renaming

  • I am not renaming tools as part of this PR

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Updated (README / docs / examples)

The default issue_read `get` payload surfaced no hierarchy data, forcing
agents to drop to raw REST (parent_issue_url) or scan sibling sub_issues
to discover relationships. Enrich `get` with a layered, zero-extra-round-trip
relationship signal derived from a single combined GraphQL query:

- has_parent / has_children: cheap, always-emitted routing booleans
  (addresses Sam Morrow's #2726 review note).
- parent: compact ref (number/title/state/url/repository) mirroring the
  existing get_parent payload keys; omitted when there is no parent.
- sub_issues_summary: native subIssuesSummary counts (total/completed/
  percent_completed); omitted when there are no sub-issues.

The single-issue field-values GraphQL call in GetIssue is replaced by one
combined query (fetchIssueReadEnrichment) returning field values + parent +
subIssuesSummary, so `get` adds no round-trips. Enrichment is best-effort:
a query failure still returns the base issue and never fails `get`. Parent
titles are sanitized (parent may be cross-repo) and redacted under lockdown
mode unless the parent content can be verified as safe; numeric/structural
fields and counts stay intact. get_parent / sub_issue_write behavior is
unchanged; tool descriptions clarify hierarchy is read here but written via
sub_issue_write (no writable parent field).

Refs github/planning-tracking#3306

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zwick zwick self-assigned this Jun 25, 2026
@zwick zwick force-pushed the zwick-enrich-issue-read-hierarchy branch 2 times, most recently from ef3362d to d7f0c8c Compare June 26, 2026 14:18
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zwick zwick force-pushed the zwick-enrich-issue-read-hierarchy branch from d7f0c8c to a8ed349 Compare June 26, 2026 14:25
Align issue_read get parent enrichment with the codebase's existing
lockdown patterns: rather than introducing a third, redaction-with-sentinel
behavior, omit the whole parent reference when its (possibly cross-repo)
content cannot be verified safe. This mirrors how unsafe comments, sub-issues,
and PR reviews are filtered out. has_parent stays true so an agent can still
route to get_parent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zwick zwick marked this pull request as ready for review June 26, 2026 15:59
@zwick zwick requested a review from a team as a code owner June 26, 2026 15:59
Copilot AI review requested due to automatic review settings June 26, 2026 15:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enriches the issue_read tool’s get response with lightweight issue hierarchy signals (parent/children presence) and optional relationship summaries, sourced from a single combined GraphQL query and designed to be best-effort (never failing get).

Changes:

  • Added hierarchy relationship fields (has_parent, has_children, optional parent, optional sub_issues_summary) to the minimal issue payload returned by issue_read get.
  • Replaced the prior field-values-only GraphQL enrichment with a combined enrichment query (fetchIssueReadEnrichment) and applied it via applyIssueReadEnrichment, including lockdown-aware parent redaction.
  • Updated tool/README descriptions and added unit tests covering hierarchy enrichment and failure behavior.
Show a summary per file
File Description
README.md Updates generated docs to clarify issue_read get hierarchy signals and sub_issue_write routing guidance.
pkg/github/minimal_types.go Extends MinimalIssue with hierarchy fields and adds helper types for parent reference and sub-issue summary.
pkg/github/issues.go Implements combined GraphQL enrichment for issue_read get and lockdown-safe parent surfacing.
pkg/github/issues_test.go Adds tests for hierarchy enrichment, lockdown redaction behavior, and best-effort fallback on query failure.
pkg/github/toolsnaps/sub_issue_write.snap Updates schema snapshot for revised sub_issue_write method description.
pkg/github/toolsnaps/issue_read.snap Updates schema snapshot for revised issue_read method description.

Review details

  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment on lines +346 to +353
// Hierarchy relationship signals. HasParent and HasChildren are always emitted
// (an explicit false is itself a useful routing signal); SubIssuesSummary is populated
// when children exist, and Parent when a parent exists and may be surfaced (under lockdown
// an unverified parent reference is omitted while HasParent stays true).
HasParent bool `json:"has_parent"`
HasChildren bool `json:"has_children"`
Parent *MinimalIssueRef `json:"parent,omitempty"`
SubIssuesSummary *MinimalSubIssuesSummary `json:"sub_issues_summary,omitempty"`
Comment on lines +356 to +358
// MinimalIssueRef is a compact reference to a related issue (e.g. a parent issue).
// Its keys mirror the get_parent (GetIssueParent) payload so both surfaces agree.
type MinimalIssueRef struct {
Comment thread pkg/github/issues_test.go
Comment on lines +634 to +637
{
name: "has_children is false when total is zero even with completed nonzero",
parent: nil,
summary: map[string]any{"total": 0, "completed": 0, "percentCompleted": 0},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants