Cross-validate numeric project IDs in MCP add_branch

What does this MR do and why?

add_branch already cross-validates a URL against an unencoded path-form project_id. Numeric project_id values currently skip that consistency check, so a URL for Project A and a numeric ID for Project B can proceed against Project A.

This MR adds equivalent cross-validation for numeric identifiers.

Before

url: https://gitlab.example.com/group/project-a
project_id: <numeric ID for project-b>

Result: the request proceeds against project-a.

After

url: https://gitlab.example.com/group/project-a
project_id: <numeric ID for project-b>

Result: ArgumentError:
Project mismatch: project_id is '...' but url contains '...'

Matching canonical and zero-padded numeric IDs continue to succeed.

Implementation notes

When the unchanged Gitlab::ResourceLookup::INTEGER_ID_REGEX guard identifies a numeric project_id, the consistency check compares its integer value with the already-resolved URL project's ID. It does not perform a second project lookup, avoiding dependence on lookup or authorization of the conflicting project.

The URL-resolved project still uses the existing access-aware finder, and the project-ID-only path is retained. A conflicting numeric ID for an inaccessible private project now raises Project mismatch.

Zero-padded compatibility is confirmed through Gitlab::ResourceLookup behavior and a regression test. URL decoding and encoded paths remain out of scope. Branch creation and GraphQL flow are unchanged.

How to test

Focused matrix:

bin/rspec \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:74 \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:91 \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:110 \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:130 \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:149 \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb:167

Result: 6 examples, 0 failures.

Related specs:

bin/rspec \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb \
  spec/services/mcp/tools/repositories/branches/add_branch_service_spec.rb \
  spec/services/mcp/tools/concerns/resource_finder_spec.rb

Result: 72 examples, 0 failures.

bundle exec rubocop \
  app/services/mcp/tools/repositories/branches/add_branch_tool.rb \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb

Result: 2 files inspected, no offenses detected.

git diff --check -- \
  app/services/mcp/tools/repositories/branches/add_branch_tool.rb \
  spec/services/mcp/tools/repositories/branches/add_branch_tool_spec.rb

Result: passed.

Risk

Low. The change adds consistency validation only when both a URL and numeric project_id are supplied. Existing URL-only, project-ID-only, and matching-identifier behavior is retained.

References

Closes #628334 (closed)

AI assistance

AI tooling assisted with investigation and drafting. The contributor independently reviewed the implementation, reproduced the bug locally, verified the regression and fix, and takes responsibility for this change.

Edited by Whale Tech

Merge request reports

Loading
Loading