Fix PR dashboard top-level feedback routing#107
Conversation
There was a problem hiding this comment.
Pull request overview
Routes top-level PR feedback using the author’s identity and improves lifecycle handling for implementation-choice feedback.
Changes:
- Adds PR author identity to top-level classification inputs.
- Clarifies participant routing and commit-evidence prompts.
- Adds regression coverage for routing and commit resolution.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
classification.py |
Updates classification input and guidance. |
dashboard.py |
Adds author identity to derived feedback items. |
test_top_level_actions.py |
Covers participant routing and commit evidence. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
557f8ba to
9b79008
Compare
| if c.get("minimized"): | ||
| continue |
| nodes { | ||
| databaseId | ||
| createdAt | ||
| lastEditedAt | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/scripts/pull-request-dashboard/dashboard.py:378
- This condition cannot exclude real minimized comments:
raw["issue_comments"]is populated from the REST issue-comments endpoint, whose payload has nominimizedfield, and the new GraphQL enrichment currently supplies only timestamps. The test passes only because it manually injects this field. FetchisMinimizedin the GraphQL query and merge that metadata into each REST comment before normalization.
if c.get("minimized"):
continue
| endCursor | ||
| } | ||
| nodes { | ||
| databaseId |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/github_cli.py:193
databaseIdis the legacy 32-bit field, but current issue-comment IDs (including the linked5011501871example) exceed that range. GraphQL can therefore return no usable value (or fail serialization), causing the parser to skip the comment andfetch_pr_rawto fall back tocreated_at, which defeats the new content-edit timestamp behavior. Query and parsefullDatabaseId, as the review path already does atgithub_cli.py:139andgithub_cli.py:274-281.
databaseId
.github/scripts/pull-request-dashboard/dashboard.py:382
- This check does not exclude minimized comments in production.
issue_commentscomes from the REST endpoint, whose records are only augmented withcontent_updated_at; the new GraphQL query does not fetch or mergeisMinimized. The test's syntheticminimizedfield therefore never exists for fetched PR data. Fetch minimization state through GraphQL and merge it into each REST comment before normalization.
if c.get("minimized"):
continue
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
.github/scripts/pull-request-dashboard/dashboard.py:382
- This check never sees minimization data in production.
issue_commentscomes from the REST issue-comments endpoint, which does not expose aminimizedfield, while the new GraphQL helper returns only timestamps. As a result, minimized comments still become feedback items despite the PR's stated behavior. FetchisMinimizedin the GraphQL query and merge it into each REST comment (or source the comments from GraphQL) before normalizing.
if c.get("minimized"):
continue
.github/scripts/pull-request-dashboard/classification.py:663
- This adds one serial Copilot process per uncached author comment, with no per-PR bound or batching. A long-lived PR can have hundreds of comments, and each call permits a 180-second timeout, so the first refresh after this change can monopolize the workflow/model quota—the exact failure mode the top-level 200-item cap and batching avoid (RATIONALE.md:211-216). Please batch and/or cap author-reply classification with a safe unclassified fallback that can be retried on later refreshes.
author_reply_classifications = classify_review_threads(
number, author_reply_items, model, cache_in, cache_out
)
.github/scripts/pull-request-dashboard/github_cli.py:195
databaseIdis a nullable GraphQLInt, so modern issue-comment IDs above 2,147,483,647 cannot be represented and come back null; the comments cited in this PR already have IDs around 5,011,501,871. The loop then skips them, andfetch_pr_rawfalls back tocreated_at, so edits to current comments are not detected. Query the GraphQL nodeidand join it to the REST comment'snode_idinstead of joining on the numeric REST ID.
nodes {
databaseId
createdAt
lastEditedAt
…hor comment lifecycle
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/scripts/pull-request-dashboard/dashboard.py:382
- This guard cannot exclude minimized PR comments in production:
raw["issue_comments"]comes from the REST issue-comments endpoint, whose response does not expose minimized state, while the new GraphQL query only returns edit timestamps. As a result,c.get("minimized")is always absent for fetched comments and minimized feedback is still classified. FetchIssueComment.isMinimizedin GraphQL and merge that metadata bydatabaseIdbefore normalization.
if c.get("minimized"):
continue
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/dashboard.py:382
- The production issue-comment payload never supplies this flag.
fetch_pr_rawgets comment bodies from the REST issue-comments endpoint, which does not expose minimization, while the new GraphQL query only requests timestamps and the merge only addscontent_updated_at. As a result, minimized reviewer comments still become feedback (and minimized author comments can still count as replies); the test passes only because it injects a syntheticminimizedfield. FetchisMinimizedthrough GraphQL and carry it into the REST comment records before normalization.
if c.get("minimized"):
continue
.github/scripts/pull-request-dashboard/dashboard.py:781
- A self-deferral or
unclearauthor comment is returned here and masks every later external-blocker comment. For example, “I'll test this” followed by “this is blocked on the upstream spec” leaves the item waiting on the author because the caller only propagates this first outcome when it isexternal. Skip non-external outcomes while searching so a later external handoff can route the earlier feedback externally.
if (
event.get("kind") == "issue-comment"
and event.get("actor_role") == "author"
and timestamp > root_timestamp
and outcome is not None
):
return outcome
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/dashboard.py:382
fetch_pr_raw()builds these objects from the REST issue-comments response plus a GraphQL map containing only edit timestamps. REST issue comments do not expose minimization state, andPR_ISSUE_COMMENT_EDITS_QUERYdoes not requestisMinimized, so production comments never receive thisminimizedkey and minimized feedback is still classified. Fetch the GraphQL minimization flag and merge it into each REST comment before normalization.
if c.get("minimized"):
continue
.github/scripts/pull-request-dashboard/dashboard.py:781
- This returns the first classified author comment after the feedback even when its action is
authororunclear. If the author first promises more work and later reports an upstream blocker, the first outcome prevents the laterexternaloutcome from ever reaching the routing branch, so the PR incorrectly remains waiting on the author. Select the earliest external outcome instead.
if (
event.get("kind") == "issue-comment"
and event.get("actor_role") == "author"
and timestamp > root_timestamp
and outcome is not None
):
return outcome
…ater external handoff
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/dashboard.py:382
- The production REST comment objects are not populated with a
minimizedfield, and the new GraphQL query only joins edit timestamps, so this condition never excludes minimized comments. FetchisMinimizedinPR_ISSUE_COMMENT_EDITS_QUERY(or consume the REST API's actual minimization field) and carry that value onto each REST comment before normalization; otherwise minimized feedback still appears on the dashboard despite this test.
if c.get("minimized"):
continue
.github/scripts/pull-request-dashboard/dashboard.py:780
- This returns the first classified author comment even when it is an
authorself-deferral. If the author first promises future work and later reports an upstream blocker, the caller ignores the first outcome and never reaches the laterexternaloutcome, so the item incorrectly remains waiting on the author. Skip non-external outcomes here; completednonereplies are already handled bycollect_author_evidence.
and outcome is not None
):
… satisfying evidence
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/github_cli.py:193
- Use the 64-bit ID field here. The cited issue-comment IDs already exceed GraphQL's legacy 32-bit
databaseIdrange (for example5011501871), so this field can be null and line 220 then skips the timestamp. Those comments fall back tocreated_at, defeating the non-content-update fix. The existing review query usesfullDatabaseIdfor this reason (github_cli.py:139, with >32-bit coverage attest_github_cli.py:324,351). An alias keeps the parser unchanged.
databaseId
.github/scripts/pull-request-dashboard/dashboard.py:382
- This guard is never populated by the production fetch path.
fetch_pr_rawgets issue comments from the REST endpoint and only mergescontent_updated_at; the GraphQL query requests no minimization field. Consequently, live minimized comments still become feedback (and minimized author comments can still become reply evidence), while the test passes only because it injects a syntheticminimizedkey. FetchisMinimizedfrom GraphQL and propagate it onto the REST comments before normalization.
if c.get("minimized"):
continue
…rnal handoffs by creation
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
.github/scripts/pull-request-dashboard/github_cli.py:193
databaseIdis nullable for modern issue comments whose numeric IDs exceed GraphQL's 32-bitIntlimit; the affected comments named in this PR already have IDs above 5 billion. Those nodes are skipped below, sofetch_pr_rawfalls back tocreated_atand real content edits never advance the feedback timestamp. Join these nodes to the REST comments using the GraphQL nodeid/RESTnode_id(or another full-width identifier) instead ofdatabaseId.
databaseId
.github/scripts/pull-request-dashboard/dashboard.py:382
- This check cannot exclude minimized comments in production:
raw["issue_comments"]comes from the REST issue-comments endpoint, whose payload does not expose minimization state, and the new GraphQL enrichment only adds timestamps. As a result, the new test passes only because it injects aminimizedkey thatfetch_pr_rawnever produces. FetchisMinimizedvia GraphQL and merge it into each REST comment before normalization.
if c.get("minimized"):
continue
Resolves #106
Improve review-feedback routing by giving top-level classification the PR author identity, so requests and questions directed to other participants are not assigned to the author. Prefer commit evidence for implementation-choice feedback so later author commits clear those items, distinguish completed author replies from promises of future work, exclude minimized PR comments, and use content edit timestamps so non-content comment updates do not reopen feedback.
This corrects reported statuses on open-telemetry/opentelemetry-proto#340, open-telemetry/weaver#1600, open-telemetry/opentelemetry-java#8076, and open-telemetry/semantic-conventions-genai#197 and #188, and addresses part of #106.