Skip to content

Fix MCP file uploads without model encoding or sandbox credentials - #1528

Merged
obsessixnv merged 1 commit into
mainfrom
fix/workspace-upload-handoff
Sep 17, 2026
Merged

obsessixnv merged 1 commit into
mainfrom
fix/workspace-upload-handoff

Conversation

@obsessixnv

@obsessixnv obsessixnv commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

What changed, and why

MCP uploads could get stuck when the file lived in a sealed sandbox: shell PUTs required a ticket credential, while copying base64 through model output hit output suppression or truncation. Fleet now accepts a hash-bound workspace file reference for a top-level MCP string property explicitly annotated contentEncoding: base64. Both interactive and scheduled runs read through sandbox FileOp, encode the exact byte range, and dispatch through the original scoped MCP broker after the existing approval and policy gates.

Ticket responses also exposed a redaction bug: scrubbing an escaped Authorization example could corrupt the enclosing JSON and leave another copy of the bearer in an unfamiliar field. Structured JSON redaction now preserves framing and number precision and removes repeated bearer values without permanently retaining temporary credentials.

This is a generic engine capability; connector tool names, upload sequences, final publication and reconciliation remain server/bundle responsibilities. Companion adoption: ElcanoTek/pages#97 and https://github.com/ElcanoTek/elcano-config/pull/149. Upgrade those components and regenerate saved prompts to use the new path.

How you verified it

  • Changed-package tests passed for agentcore, redaction and sandbox workspace readers, including an exact multi-chunk UTF-8 transfer, approval refusal, invalid hashes/ranges and path/symlink confinement.
  • Build, tagged vet and the complete lint gate passed. The local Go lint timeout was extended for this memory-constrained machine.
  • make ci-web passed: audit, lint, typecheck, 1,674 tests and production build. Guides are synchronized.
  • The full Go suite and both mocked/live browser suites passed in CI. Locally the full Go run passed every package except container fixtures under /root; those failing cases passed after setting both TMPDIR and GOTMPDIR to an accessible directory. The local browser retry was stopped after resource-related timing failures; CI's complete browser runs are green.
  • make govulncheck passed with no reachable vulnerabilities. All PR CI checks passed, including the full race suite, container-image vulnerability scan, CodeQL, Semgrep and the required CI gate. The redundant local race run was stopped after CI completed successfully to release this machine's resources.

Scope and deviations

Shipped: opt-in top-level base64 arguments, whole-file SHA-256 binding, raw byte ranges, a 2 MiB whole-file cap, sandbox-only reads, shared dispatch and JSON-safe redaction. No host file fallback, direct HTTP uploader, credential export, connector special case or approval bypass. Larger streaming files, nested/JSON/text references and automatic multi-call upload orchestration are deliberately deferred. Design and boundaries are documented in docs/MCP-WORKSPACE-FILES.md and ADR-0066.


  • Title and description explain the behavior and operator action
  • Feature design note added
  • ADR added for the transport boundary
  • Scoped diff without unrelated refactoring

@obsessixnv
obsessixnv merged commit 0351879 into main Sep 17, 2026
21 checks passed
@obsessixnv
obsessixnv deleted the fix/workspace-upload-handoff branch September 17, 2026 11:14
obsessixnv added a commit to ElcanoTek/pages that referenced this pull request Sep 17, 2026
## What changed, and why

Uploads built in a sealed or redacting agent runtime could stall because
the instructions required a credential-bearing shell PUT or
model-generated base64. Advertise `contentEncoding: base64` for upload
chunks so capable clients can forward exact workspace file ranges.
Prepared prompts and staging responses prefer that capability and
preserve accepted chunks instead of encouraging cancel/restart loops.
Ticket uploads remain available to other clients.

A successful managed refresh also previously displayed an older blocked
check beside its new timestamp. Return explicit latest-outcome fields
and the historical check timestamp, and use them in the admin tooltip
without deleting check history. Clarify that the 20 KB threshold selects
transport and is not a server rejection limit.

## Validation

- `npm test`: 279 passing.
- `npm run test:browser`: 298 passing.
- `bash test/run-integration.sh`: passing, including official MCP SDK
capability discovery and refresh outcome ordering.
- Shell syntax checks passing; production audit passes the repository's
high-severity threshold (one existing moderate transitive advisory
remains).

File-reference expansion is implemented by
ElcanoTek/fleet#1528; bundle instructions are
updated in ElcanoTek/elcano-config#149. Pages
continues to accept canonical base64 strings on the wire. Publication
gates, source reconciliation and optimistic concurrency are unchanged.
No live pages were refreshed during this work.
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.

1 participant