* feat(mcp): model-free document upload via signed URL (#748)
Adds gnubok_create_document_upload + gnubok_complete_document_upload so
document bytes reach storage through a short-lived signed PUT URL and
never pass through the model context. Fixes silent base64 corruption on
real-size PDFs and the context blowup on batch uploads.
- pending/ staage keys with TTL cleanup; completion validates magic
bytes + SHA-256, moves bytes to the WORM key and adopts the reserved
UUID as document id, making retries and concurrent completions
idempotent
- legacy gnubok_upload_document kept for clients without file access,
description now points to the signed-URL pair; shared mime resolution
and inbox-item creation extracted
- both new tools mapped in TOOL_SCOPE_MAP (transactions:write) and
MCP_TOOL_CAPABILITY_MAP (ai) so the paywall and scope gates hold
- payload guard ceiling 58.5K to 59K after trimming the create tool's
outputSchema to upload_id/upload_url/expires_at
Fixes#748
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): satisfy capability-map lock and phantom-column scanner
The exact-entries lock in capability-maps.test.ts now includes the
signed-URL pair as dispatch-only AI tools, and the inbox insert uses a
literal payload (explicit UUID instead of a conditional spread) so the
no-phantom-columns scanner can resolve every column.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>