test(memory-sync/github): assert involves: query qualifier#2664
Conversation
Locks in the `involves:{login}` GitHub Search-Issues qualifier so the
periodic sync cannot silently regress to the narrower `assignee:{login}`
scope and drop author / mention / commenter coverage for users who are
rarely explicitly assigned.
Extracts the inline query builder into `build_search_query` so the
contract can be exercised without spinning up the full sync pipeline.
Closes tinyhumansai#2418.
📝 WalkthroughWalkthroughThe GitHub provider's search-query construction is refactored by extracting inline ChangesGitHub Search Query Builder Extraction
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
M3gA-Mind
left a comment
There was a problem hiding this comment.
Clean extraction + targeted regression coverage. A few notes:
What's correct
build_search_query — the extraction is exact. state.cursor.as_deref() correctly converts Option<String> → Option<&str> matching the function signature. pub(super) is the right visibility — visible to tests.rs, not exported further.
Tests — four tests covering: cursor-less exact match, explicit negative guard against assignee: regression, cursor-present exact match, and a non-trivial login (hyphens/underscores/digits). The negative assertion in test 2 is intentionally redundant with test 1 — having it spelt out explicitly is the point, so a future reader knows why the assignee: guard exists.
Nit
build_search_query_interpolates_login_verbatim uses assert!(query.contains(...)) rather than an exact equality check. If the format string ever gains extra tokens (e.g. a sort clause), the test keeps passing silently. Low risk given the function is a two-branch match on a format string, but an exact assert_eq! would be tighter.
No concerns
No behaviour change — the produced query string is byte-identical to the original inline match. Closes #2418. CI green, no conflicts.
LGTM.
Summary
involves:{login}GitHub Search-Issues qualifier introduced in feat(composio): promote GitHub from catalog-only to native memory provider #2413 — the qualifier itself shipped with that PR, but no test asserted it, so it could silently regress to the narrowerassignee:{login}scope and lose author / mention / commenter coverage.GitHubProvider::sync()into a free function (build_search_query) so the qualifier contract is unit-testable without spinning up the full sync pipeline.involves:{login}±updated:>{cursor}).Problem
src/openhuman/memory_sync/composio/providers/github/provider.rsbuilt the search query inline insidesync():There was no unit test asserting either the
involves:qualifier or the cursor clause, even thoughinvolves:(vs.assignee:) is the core privacy / coverage contract of the provider:assignee:{login}returns only items the user is explicitly assigned to — typical of PM dev orgs, narrow for OSS contributors.involves:{login}is GitHub's logical-OR overauthor,assignee,mentions, andcommenter— matches the GitHub Notifications mental model.Without test coverage, a refactor or a "small simplification" could quietly drop back to
assignee:and ship undetected. Issue #2418 calls this out explicitly:Solution
matchintopub(super) fn build_search_query(login: &str, cursor: Option<&str>) -> Stringat the bottom ofprovider.rs. Call site insync()becomes a single line.tests.rs:build_search_query_uses_involves_qualifier_without_cursor— exact string match on the cursor-less variant.build_search_query_does_not_fall_back_to_assignee_qualifier— explicit negative assertion guarding against regression toassignee:.build_search_query_appends_updated_clause_when_cursor_present— exact string match on the cursor variant.build_search_query_interpolates_login_verbatim— covers non-trivial logins with hyphens / underscores / digits.involves:qualifier (covers author + assignee + mentions + commenter) #2418 so future readers know why the negative test exists.Visibility is
pub(super)so only the siblingtests.rsmodule can reach it — no expansion of the provider's public API.Submission Checklist
build_search_query_*tests insrc/openhuman/memory_sync/composio/providers/github/tests.rs, covering both the cursor-less / with-cursor branches and the explicit negativeassignee:regression guard.build_search_queryfunction (covered by all four new tests) or the one-line call site that those tests exercise indirectly via the contract they pin.## Related— N/A: no new feature IDs introduced; the existing GitHub Composio Memory Provider feature is unchanged in behaviour.docs/RELEASE-MANUAL-SMOKE.md) — N/A: no user-visible surface touched.Closes #NNNin the## Relatedsection —Closes #2418below.Impact
match.involves:qualifier still returns only items GitHub itself authorises for the connected user.Related
involves:qualifier (covers author + assignee + mentions + commenter) #2418AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
Validation Run
pnpm --filter openhuman-app format:check— N/A: pure Rust change, no frontend files touched.pnpm typecheck— N/A: pure Rust change, no TypeScript touched.cargo test --lib openhuman::memory_sync::composio::providers::github::tests— 25/25 passed locally, including the 4 newbuild_search_query_*regression tests.cargo fmt --checkclean;cargo checkclean against changed files.app/src-tauri/files touched.Validation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract