Skip to content

Expand GitHub memory sync from assignee-only to GitHub's involves: qualifier (covers author + assignee + mentions + commenter) #59

@ElioNeto

Description

@ElioNeto

Original issue tinyhumansai#2418 by @justinhsu1477 on 2026-05-21T06:24:53Z


Summary

The initial GitHub Memory Provider (tinyhumansai#2413, in review) scopes the periodic sync to assignee:<viewer_login> — issues explicitly assigned to the connected user. That covers manager / dev-handoff workflows but misses three large slices of real-world GitHub usage:

  1. External contributors open issues but rarely get assigned (assignee is a maintainer action). Their own issue history doesn't reach Memory Tree.
  2. Reviewers / commenters participate in issues without being assigned.
  3. @-mention recipients are de facto involved but never appear in the assignee filter.

Expanding the search query to GitHub's involves:<viewer_login> qualifier — a superset of author, assignee, mentions, and commenter — covers all four naturally and matches the mental model of "issues I'm involved with" that the GitHub Notifications inbox already presents.

Problem

Verified live against my own GitHub account (justinhsu1477):

Query Issue count returned
assignee:justinhsu1477 is:issue 0
author:justinhsu1477 is:issue 11
involves:justinhsu1477 is:issue (superset of the above; not yet measured)

Concrete consequence: under the current MVP query in tinyhumansai#2413, I — the author of the GitHub provider — would see zero issues in Memory Tree after connecting, because nobody on the OpenHuman project assigned my issues to me. That's a meaningful gap between "what the user expects to see" and "what the provider syncs".

For users who DO have assignee-driven workflows (typical PM dev orgs), the current behaviour is correct. But for the much larger class of GitHub users — OSS contributors, reviewers, community participants — the assignee-only scope under-delivers.

Solution

Change one line in src/openhuman/composio/providers/github/provider.rs::sync():

// Today (PR #2413):
let query = format!("is:issue assignee:{viewer_login} sort:updated-desc");

// Proposed:
let query = format!("is:issue involves:{viewer_login} sort:updated-desc");

involves: is documented at https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests#search-by-a-user-thats-involved-in-an-issue-or-pull-request as "the issue or pull request involves a certain user. The involves qualifier is a logical OR between the author, assignee, mentions, and commenter qualifiers".

Privacy posture stays intact

The change is strictly broader within "things the connected user has standing in" — every result is an issue the user authored, was assigned to, was @-mentioned in, or commented on. Other teammates' private issues that the user has no relationship with stay out of scope, same as today.

The qualifier is still constructed inside the provider, never accepted from a caller — privacy boundary unchanged.

Volume bounds

GitHub Search caps results at 1000 regardless of qualifier. The existing daily request budget (500 calls/day) and MAX_PAGES_PER_SYNC = 20 already cap total work. involves: will pull more issues per pass than assignee: for active users, but the rate limits don't change.

For active OSS contributors who'd hit the 1000-cap, a follow-up could add a created_at:>=<N days ago> cutoff, but that's a separate decision once we have real usage data.

Acceptance criteria

  • GitHubProvider::sync builds the search query with involves:<viewer_login> instead of assignee:<viewer_login>.
  • Unit-level update: no test should break (the query string isn't asserted in tests.rs; it's an opaque arg to GITHUB_SEARCH_ISSUES).
  • Manual sanity check: gh api 'search/issues?q=involves:<your_login>+is:issue&per_page=2' returns at least as many items as assignee:<your_login> for the same user.
  • Diff coverage ≥ 80% — change is ~1 line, no new branches.
  • Documentation note inside provider.rs explaining the qualifier choice and linking to GitHub's involves docs.

Out of scope (further follow-ups)

  • Settings UI for custom query qualifiers (e.g. "only sync issues from specific repos"). Belongs to a UI ticket if/when the orchestration around per-provider config matures.
  • Pull-request ingest. involves: would still only return issues because the query keeps is:issue; PRs as memory documents need their own provider design (different content shape, different states).
  • created_at:>=<cutoff> window. Only worth adding once real-world usage shows the 1000-cap being hit.
  • Notifications-based ingest (/notifications endpoint). Different sync model, separate provider.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions