Skip to content

Extract MCP work proof guidance helpers#354

Closed
TUPM96 wants to merge 3 commits into
ramimbo:mainfrom
TUPM96:codex/bounty-320-mcp-guidance-module
Closed

Extract MCP work proof guidance helpers#354
TUPM96 wants to merge 3 commits into
ramimbo:mainfrom
TUPM96:codex/bounty-320-mcp-guidance-module

Conversation

@TUPM96
Copy link
Copy Markdown
Contributor

@TUPM96 TUPM96 commented May 26, 2026

Refs #320

Summary

  • Extract submit_work_proof guidance shaping out of app/main.py into app/mcp.py so MCP-specific response text and structured JSON live beside the MCP transport helpers.
  • Add direct MCP guidance tests while preserving the existing MCP endpoint behavior covered by tests/test_api_mcp.py.
  • Keep CI green by preserving the ledger CursorResult casts required for rowcount type-checking and keeping the existing OAuth redirect hardening intact.

Complexity reduced

app/main.py no longer carries the work-proof guidance message builders. Future MCP guidance changes can be reviewed in the MCP module with focused helper tests instead of inside the route/API monolith.

Tests

  • python -m pytest -> 337 passed
  • python -m pytest tests/test_mcp_guidance.py tests/test_api_mcp.py tests/test_wallet_api.py::test_github_login_stores_safe_default_for_backslash_next -> 79 passed
  • python -m ruff format --check . -> 49 files already formatted
  • python -m ruff check . -> All checks passed
  • python -m mypy app -> Success: no issues found in 14 source files

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

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@TUPM96, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 5 minutes and 15 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4a258160-7e26-4c8f-a5fc-d47d2945827a

📥 Commits

Reviewing files that changed from the base of the PR and between 682e960 and 015c68b.

📒 Files selected for processing (1)
  • app/ledger/service.py
📝 Walkthrough

Walkthrough

This PR refactors MCP work-proof guidance generation by extracting helper functions into app/mcp.py, hardens OAuth redirect validation in app/main.py, updates SQLAlchemy patterns in the ledger service, and wires the new guidance helpers into the submit_work_proof tool handler.

Changes

MCP Guidance Refactoring & Integration

Layer / File(s) Summary
MCP guidance helpers and tests
app/mcp.py, tests/test_mcp_guidance.py
Introduces work_proof_guidance, work_proof_guidance_json, and generic_work_proof_guidance_json to generate text and structured JSON guidance for bounties. Tests validate that guidance includes bounty identifiers, status, submission eligibility, acceptance text, and submission rules.
Ledger SQLAlchemy import and execution pattern
app/ledger/service.py
Removes cast and CursorResult type annotations and updates pay_bounty and close_bounty to assign session.execute() results directly, preserving rowcount checks and exception handling.
OAuth redirect path validation hardening
app/main.py
Adds urllib.parse.unquote to decode redirect "next" values and validates both original and decoded forms against unsafe patterns (// prefix, backslashes, control/Unicode characters).
MCP guidance helper wiring in main.py
app/main.py
Imports the new guidance helpers from app.mcp and updates submit_work_proof to use them instead of local implementations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ramimbo/mergework#317: Modifies submit_work_proof MCP guidance handling and related guidance flow in app/main.py.
  • ramimbo/mergework#339: Adds structured availability fields (availability, can_submit, availability_warnings) that are directly incorporated into the new guidance JSON structure.
  • ramimbo/mergework#287: Implements MCP submit-work-proof guidance and related test coverage that overlaps with this refactoring effort.

Suggested reviewers

  • weilixiong
  • TateLyman
  • ayskobtw-lil
🚥 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 'Extract MCP work proof guidance helpers' clearly and concisely describes the main refactoring objective of moving guidance functions from app/main.py to app/mcp.py.
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.
Description check ✅ Passed The pull request description includes a clear summary of changes, evidence of testing with multiple test runs, and references the related issue.

✏️ 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

@liangtovi-debug liangtovi-debug left a comment

Choose a reason for hiding this comment

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

Requested changes: the ledger typing cleanup breaks the required mypy check.

The PR removes the CursorResult[Any] casts around conditional update(...) calls in app/ledger/service.py, but pay_bounty() and close_bounty() still read claimed.rowcount. With SQLAlchemy typing, session.execute(update(...)) is inferred as Result[Any], so .rowcount is not available to mypy.

Local repro on PR head 682e960:

  • uv run --extra dev python -m mypy app/ledger/service.py app/main.py app/mcp.py -> fails with Result[Any] has no attribute rowcount at app/ledger/service.py:670 and app/ledger/service.py:741.
  • uv run --extra dev python -m pytest tests/test_mcp_guidance.py tests/test_api_mcp.py -q -> 78 passed.
  • uv run --extra dev ruff check app/main.py app/mcp.py app/ledger/service.py tests/test_mcp_guidance.py -> passed.
  • uv run --extra dev ruff format --check app/main.py app/mcp.py app/ledger/service.py tests/test_mcp_guidance.py -> passed.
  • git diff --check origin/main...HEAD -> clean.

Please either restore the CursorResult[Any] cast/import around those update results or otherwise type the result as a cursor result before checking rowcount. Since that change is unrelated to the MCP guidance extraction, the lowest-risk fix is probably to drop the ledger cleanup from this PR.

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.

This PR extracts “work proof guidance” helpers into app.mcp, adds tests for their output shape, tightens redirect next_path sanitization by checking decoded values, and simplifies SQLAlchemy DML execution typing in ledger service code.

Changes:

  • Move work_proof_guidance* helpers out of app.main into app.mcp
  • Add unit tests covering guidance text/JSON structure
  • Harden _safe_next_path by validating decoded values; simplify session.execute(update(...)) usage

Reviewed changes

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

File Description
tests/test_mcp_guidance.py Adds tests asserting guidance helpers produce expected text and JSON fields.
app/mcp.py Introduces reusable guidance helper functions (text + JSON variants).
app/main.py Uses imported guidance helpers and improves _safe_next_path by validating decoded paths.
app/ledger/service.py Removes explicit casting around session.execute(update(...)) results.

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

Comment thread app/main.py
Comment on lines 285 to 299
def _safe_next_path(next_path: str | None) -> str:
decoded_next_path = unquote(next_path) if next_path else ""
if (
not next_path
or not next_path.startswith("/")
or next_path.startswith("//")
or len(next_path) > 2048
or "\\" in next_path
or decoded_next_path.startswith("//")
or "\\" in decoded_next_path
or any(ord(char) < 32 or 127 <= ord(char) < 160 for char in next_path)
or any(ord(char) < 32 or 127 <= ord(char) < 160 for char in decoded_next_path)
):
return "/me"
return next_path
Comment thread app/mcp.py
Comment on lines +117 to +138
def generic_work_proof_guidance_json() -> dict[str, Any]:
return {
"bounty_id": None,
"issue_number": None,
"status": "generic_guidance",
"availability": "unknown_without_bounty",
"can_submit": None,
"availability_warnings": [],
"awards_remaining": None,
"reward_mrwk": None,
"repository": None,
"issue_url": None,
"acceptance": None,
"submission_format": (
"Open a focused PR or issue, reference the MRWK bounty, include test "
"evidence, and wait for a maintainer to apply mrwk:accepted."
),
"safety_rules": [
"Do not include private keys, seed material, secrets, deployment "
"credentials, private vulnerability details, or price claims."
],
}
Comment thread app/mcp.py
Comment on lines +105 to +113
"submission_format": (
"Open a focused PR or issue that links this bounty, include specific "
"test or behavior evidence, then comment /claim with the PR or "
"evidence URL and verification summary."
),
"safety_rules": [
"Do not include private keys, seed material, secrets, deployment "
"credentials, private vulnerability details, or price claims."
],
Comment on lines +14 to +16
with session_scope(sqlite_url) as session:
ensure_genesis(session)
bounty = create_bounty(
Copy link
Copy Markdown
Contributor

@newmattock newmattock left a comment

Choose a reason for hiding this comment

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

Follow-up review on current head 015c68b: the earlier mypy blocker from the removed CursorResult[Any] casts is resolved. The PR now keeps the rowcount paths type-checkable with explicit Any annotations, and the MCP guidance extraction remains focused in app.mcp with direct helper coverage.

Evidence checked:

  • Inspected app/mcp.py, app/main.py, app/ledger/service.py, and tests/test_mcp_guidance.py.
  • Verified work_proof_guidance, work_proof_guidance_json, and generic_work_proof_guidance_json moved out of app.main without changing the /mcp submit_work_proof behavior covered by endpoint tests.
  • Rechecked the exact earlier blocker: pay_bounty() and close_bounty() still read claimed.rowcount, and current typing no longer fails on those paths.
  • Confirmed the OAuth encoded-next hardening remains present on current head.

Validation:

  • uv run --extra dev python -m mypy app/ledger/service.py app/main.py app/mcp.py -> success.
  • uv run --extra dev python -m pytest tests/test_mcp_guidance.py tests/test_api_mcp.py tests/test_wallet_api.py::test_github_login_stores_safe_default_for_backslash_next -q -> 79 passed.
  • uv run --extra dev python -m ruff check app/main.py app/mcp.py app/ledger/service.py tests/test_mcp_guidance.py -> passed.
  • uv run --extra dev python -m ruff format --check app/main.py app/mcp.py app/ledger/service.py tests/test_mcp_guidance.py -> 4 files already formatted.

@ramimbo ramimbo added the mrwk:needs-info More information needed label May 26, 2026
@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 26, 2026

Maintainer note after #320 filled: this PR still references closed bounty #320. If you want it considered for the current code-health round, rebase against main, update the bounty reference to #377, and keep the scope distinct from already accepted #328, #337, #364, #375, and #376. This is not accepted or paid as-is.

@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 26, 2026

Closing this stale bounty submission. It still references a closed/filled bounty round and is dirty or unstable against current main after the route/test extraction batches. A future attempt needs a fresh PR against current main, a currently open bounty reference, and scope distinct from work already accepted.

@ramimbo ramimbo added the mrwk:rejected Submission rejected label May 26, 2026
@ramimbo ramimbo closed this May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mrwk:needs-info More information needed mrwk:rejected Submission rejected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants