Skip to content

Add automated triage bot for metadata-only issues - #422

Merged
twcclegg merged 6 commits into
mainfrom
claude/metadata-issue-bot-1bkszq
Aug 27, 2026
Merged

Add automated triage bot for metadata-only issues#422
twcclegg merged 6 commits into
mainfrom
claude/metadata-issue-bot-1bkszq

Conversation

@twcclegg

Copy link
Copy Markdown
Owner

Changes

Setup required after merge

This uses the modern (PAT-free) way of running Copilot CLI in Actions: permissions: copilot-requests: write plus the built-in GITHUB_TOKEN. That requires GitHub Copilot CLI usage to be enabled for the twcclegg account (the "Allow use of Copilot CLI" policy) — see https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions. No repository secret needs to be created.

Test plan

  • Validated the workflow YAML parses and the embedded github-script blocks are syntactically valid JavaScript.
  • Confirmed actions/ai-inference pinned SHA corresponds to its v3 tag (the current Copilot-CLI-only major version — v1/v2 default to the now-retired GitHub Models API and would not work).
  • Can't fully exercise the issues: opened trigger from a PR — once merged, open a throwaway test issue that mirrors e.g. SA mobile numbers starting with 579 are rejected by IsValidNumber (IsPossibleNumber=true) #313 ("SA mobile numbers rejected") to confirm it gets classified, labeled, commented, and closed automatically, and a normal bug/question issue to confirm it's left alone.

Generated by Claude Code

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.27%. Comparing base (e75ae83) to head (e6829c6).
⚠️ Report is 43 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #422      +/-   ##
==========================================
- Coverage   87.42%   87.27%   -0.15%     
==========================================
  Files          41       41              
  Lines        3856     3828      -28     
  Branches      990      978      -12     
==========================================
- Hits         3371     3341      -30     
  Misses        283      283              
- Partials      202      204       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Owner Author

Pushed a follow-up commit per feedback:

  • Replaced the handful of hardcoded examples in the classifier's system prompt with two exhaustive, human-verified files: metadata_examples.md (30 confirmed "redirect to Google" issues) and not_metadata_examples.md (26 confirmed real bugs/questions/build issues), both compiled by reading through this repo's closed-issue comment history rather than guessing.
  • The workflow now closes each list into the system prompt at runtime (cat into a temp file, fed via system-prompt-file).
  • Added a step that, whenever the bot closes a new issue as a metadata issue, opens a PR appending that issue to metadata_examples.md — so the classifier's grounding keeps growing from real outcomes instead of staying frozen at this snapshot. That needed contents: write and pull-requests: write added to the workflow's permissions.

Generated by Claude Code

twcclegg pushed a commit that referenced this pull request Aug 26, 2026
Every issue from #1 through #422 is now either a PR, a listed metadata
issue, or implicitly a non-metadata issue by not appearing in the list -
there's no separate "not metadata" file anymore. Went back through the
full closed-issue history (including several titles that didn't obviously
scream "metadata" but turned out to be, like #14, #25, #109, #149, #165,
#181, and #91) to make the positive list genuinely exhaustive rather than
a curated sample, taking it from 30 to 39 entries.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WVGRJyQwtvBGXAmWswxyqW

Copy link
Copy Markdown
Owner Author

Pushed another update per feedback:


Generated by Claude Code

A large fraction of issues filed here are reports about upstream Google
libphonenumber metadata (unrecognized prefixes, outdated numbering plans)
rather than bugs in this C# port's code, and maintainers have been closing
these by hand with a pointer to google/libphonenumber for years. Add a
GitHub Actions workflow that runs the GitHub Copilot CLI against each new
issue to classify it, and when confident it's a metadata report, labels it,
posts a canned comment redirecting to upstream, and closes it - noting the
closure was automatic and inviting a reopen if it's a false positive.

The classifier is grounded in .github/triage/metadata_examples.md, an
exhaustive, human-verified list of every metadata issue in this repo's
history (#1 through #422): every issue in that range is either a PR, a
listed metadata issue, or - by not appearing in the list - implicitly a
non-metadata issue, with no separate negative list needed. Every time the
workflow closes a new issue as a metadata issue, it opens a PR appending it
to that file, so the classifier's grounding keeps growing from real,
maintainer-confirmed outcomes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WVGRJyQwtvBGXAmWswxyqW
@twcclegg
twcclegg force-pushed the claude/metadata-issue-bot-1bkszq branch from b090034 to e57f156 Compare August 26, 2026 13:48
twcclegg and others added 5 commits August 26, 2026 09:40
"Every issue from #1 through #422" would need updating every time the
issue counter moves. State what the list is without pinning it to a
number that's already stale by the time this merges.
Same fix as f03c3d1 for metadata_examples.md - "#1 through #422"
goes stale the moment the issue counter moves past it.
Same fix as f03c3d1/d27cd897 - the automated-triage section had the
same "#1 through #422 at time of writing" pattern.
The exhaustivity/absence-is-negative-signal details already live in
metadata_examples.md and system_prompt.md themselves; the README only
needs to say what the workflow does and where it learns from. Dropped
the maintainer-skip and confidence-gating asides too - implementation
detail an average reader doesn't need to know.
…lure

- Pin @github/copilot to 1.0.80 instead of always installing latest,
  matching every other dependency in this workflow (SHA/version pinned).
- Replace getLabel+createLabel with a direct createLabel that ignores a
  422 (label already exists) - the previous getLabel catch-all meant a
  transient getLabel error (rate limit, 5xx) would fall through to
  createLabel and throw an uncaught 422, aborting labeling/commenting/
  closing entirely.
- Extract the classifier's JSON verdict by taking the last line that looks
  like a complete JSON object, instead of a greedy regex spanning from the
  first '{' to the last '}' in the whole response - the greedy version
  would swallow a legitimate verdict if the model ever emits a stray brace
  in preamble text before it.
- Surface a failed examples-list PR in the job summary, not just a log
  warning, so a silently-broken growth mechanism doesn't go unnoticed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WVGRJyQwtvBGXAmWswxyqW
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.

2 participants