fix(mcp): harden project context issue provider and prove shared audit path
- Share cursor decoding in foundation.decode_offset_cursor so both tools reject an invalid cursor identically, before any upstream call. - Add regression coverage that a malformed repo slug (owner/repo/extra, missing owner, empty segment) is refused before any network call. - Add evidence that BOTH project context tools inherit the shared MCP client audit record and untrusted-content fence, instead of each tool shipping its own. No audit subsystem is duplicated.
This commit is contained in:
@@ -62,6 +62,23 @@ class ProviderError(RuntimeError):
|
||||
self.retryable = retryable
|
||||
|
||||
|
||||
def decode_offset_cursor(cursor: str | None) -> int:
|
||||
"""Shared opaque-cursor decoding for every paginated provider.
|
||||
|
||||
Rejected before any backend call so an invalid cursor never costs an
|
||||
upstream request.
|
||||
"""
|
||||
if cursor is None:
|
||||
return 0
|
||||
try:
|
||||
offset = int(cursor)
|
||||
except ValueError as exc:
|
||||
raise ProviderError("INVALID_INPUT", "cursor is not valid.", retryable=False) from exc
|
||||
if offset < 0:
|
||||
raise ProviderError("INVALID_INPUT", "cursor is not valid.", retryable=False)
|
||||
return offset
|
||||
|
||||
|
||||
ToolHandler = Callable[[ContractModel, Any], dict[str, Any]]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user