Skip to content

Scope MCP work proof guidance by repo#352

Closed
TUPM96 wants to merge 3 commits into
ramimbo:mainfrom
TUPM96:codex/bounty-315-repo-scoped-guidance
Closed

Scope MCP work proof guidance by repo#352
TUPM96 wants to merge 3 commits into
ramimbo:mainfrom
TUPM96:codex/bounty-315-repo-scoped-guidance

Conversation

@TUPM96
Copy link
Copy Markdown
Contributor

@TUPM96 TUPM96 commented May 26, 2026

Refs #315
Bounty #315

Summary

  • Add an optional repo selector for MCP submit_work_proof calls that use issue_number.
  • Preserve existing ambiguous issue-number protection when no repo is provided.
  • Update the MCP tool description to mention repo and structured/text formats.

Validation

  • python -m pytest tests/test_api_mcp.py -k submit_work_proof
  • python -m pytest
  • python -m ruff check .
  • python -m ruff format --check .
  • python -m mypy app

Summary by CodeRabbit

  • New Features

    • Optional repository selector for work-proof submissions to scope issue lookups across repos.
  • Documentation

    • Expanded tool description to mention repository and text/json format options.
  • Bug Fixes

    • Safer handling of redirect targets by URL-decoding and validating inputs to prevent unsafe redirects.
  • Tests

    • Added tests covering repo-scoped selection, additional argument validation, and extended redirect-security cases.

Review Change Stack

Copilot AI review requested due to automatic review settings May 26, 2026 01:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7bd36ff5-113e-4e8f-9d72-bd48e228f4d5

📥 Commits

Reviewing files that changed from the base of the PR and between d16094c and 78f39be.

📒 Files selected for processing (3)
  • app/ledger/service.py
  • app/main.py
  • tests/test_security.py

📝 Walkthrough

Walkthrough

Adds an optional normalized repo selector to the MCP submit_work_proof tool (validated and usable only with issue_number) and narrows issue_number-based bounty lookups by repo when provided; hardens _safe_next_path to decode URL-encoded inputs; updates tests and removes a few unnecessary typing casts.

Changes

Repository-scoped work proof submission

Layer / File(s) Summary
Tool description and tests
app/mcp.py, tests/test_api_mcp.py
Expanded submit_work_proof description to mention repo and output format; added test verifying repo-scoped selection when two bounties share an issue number across repos and extended invalid-argument cases to include repo scenarios.
Repository selector parsing and validation
app/main.py
Added optional_repo_selector_arg() to trim, lowercase, and enforce repo length; require issue_number when repo is used and preserve existing mutual-exclusion validation.
Repository-scoped bounty lookup
app/main.py
When resolving by issue_number, optionally filter DB matches by case-insensitive equality with the normalized repo_selector.

Security hardening and typing/test tweaks

Layer / File(s) Summary
_safe_next_path decoding and tests
app/main.py, tests/test_security.py
Decode percent-encoded next inputs and apply safety checks to the decoded value; add tests for percent-encoded slashes/backslashes and CRLF/header-like payloads asserting normalized "/me".
Ledger typing simplification
app/ledger/service.py
Remove cast/CursorResult typing imports and stop wrapping session.execute(...) results in casts; assign execute results directly while keeping rowcount checks in pay_bounty and close_bounty.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ramimbo/mergework#287: Both PRs modify the MCP submit_work_proof tool handling and its issue_number/bounty-selection logic; this PR extends that behavior with a normalized repo selector.
  • ramimbo/mergework#339: Related changes to MCP submit_work_proof and tests; that PR adds structured availability/can_submit metadata while this PR scopes selection by repo.

Suggested reviewers

  • TateLyman
  • weilixiong
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: scoping MCP work proof guidance by repository selector.
Description check ✅ Passed The description includes a clear summary of changes, references related bounty/issue, and provides comprehensive validation steps covering tests, linting, formatting, and type checking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds repo-scoped selection for the submit_work_proof MCP tool so issue_number lookups can disambiguate bounties across repositories.

Changes:

  • Add optional repo argument parsing/validation and require it to be used only with issue_number.
  • Apply repo scoping to the bounty lookup query (case-insensitive match).
  • Add tests covering repo-scoped selection and new invalid selector cases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tests/test_api_mcp.py Adds coverage for repo-scoped issue_number selection and validates new selector rules.
app/mcp.py Updates MCP tool description to mention repo and output format options.
app/main.py Implements repo argument parsing and applies repo scoping to issue_number bounty lookup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/main.py
if repo is None:
return None
if len(repo) > 200:
raise ValueError("repo is too long")
Comment thread app/main.py
Bounty.issue_number == positive_int_arg("issue_number")
)
if repo_selector is not None:
issue_query = issue_query.where(func.lower(Bounty.repo) == repo_selector)
Comment thread app/mcp.py
Comment on lines +42 to +43
"Return submission instructions, optionally for a bounty_id or issue_number "
"and repo, with text or json format"
@TUPM96
Copy link
Copy Markdown
Contributor Author

TUPM96 commented May 26, 2026

Closing this duplicate because it includes unrelated follow-up commits. #351 is the focused PR for the Bounty #315 repo-scoped MCP guidance change.

@TUPM96 TUPM96 closed this May 26, 2026
Copy link
Copy Markdown
Contributor

@TateLyman TateLyman left a comment

Choose a reason for hiding this comment

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

Blocking issue: current head fails the required type check because app/ledger/service.py removed the CursorResult casts around the conditional update(...) calls in pay_bounty() and close_bounty(), but the code still reads claimed.rowcount. SQLAlchemy's typed Session.execute() result is inferred as Result[Any], so mypy rejects rowcount. This is also visible in hosted CI.\n\nEvidence:\n- GitHub Quality, readiness, docs, and image checks is failing in the Type check step.\n- Local repro: uv run --extra dev python -m mypy app/ledger/service.py app/main.py app/mcp.py -> app/ledger/service.py:670: error: "Result[Any]" has no attribute "rowcount" and app/ledger/service.py:741: error: "Result[Any]" has no attribute "rowcount".\n- The failing lines are the post-update guards in pay_bounty() and close_bounty(). Restoring the CursorResult[Any] cast or otherwise typing those update results as a cursor result should unblock mypy.\n\nAdditional validation:\n- uv run --extra dev python -m pytest tests/test_api_mcp.py::test_mcp_submit_work_proof_scopes_issue_number_by_repo tests/test_api_mcp.py::test_mcp_submit_work_proof_rejects_invalid_bounty_selectors -q -> 12 passed.\n- uv run --extra dev python -m pytest tests/test_security.py::test_oauth_next_path_rejects_external_or_headerlike_paths -q -> 14 passed.\n- uv run --extra dev ruff check app/ledger/service.py app/main.py app/mcp.py tests/test_api_mcp.py tests/test_security.py -> passed.\n- uv run --extra dev ruff format --check app/ledger/service.py app/main.py app/mcp.py tests/test_api_mcp.py tests/test_security.py -> passed.\n- git diff --check origin/main...HEAD -> clean.\n\nScope note: this PR also includes OAuth redirect hardening and ledger typing edits beyond the repo-scoped MCP guidance, so after the mypy fix it may be worth keeping only the distinct #315 change if PR #351 remains the cleaner version.

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