Skip to content

native-files: share Native file request handling - #1363

Merged
NancyKwongPerplexity merged 1 commit into
mainfrom
native-files-shared-handling
Nov 3, 2026
Merged

NancyKwongPerplexity merged 1 commit into
mainfrom
native-files-shared-handling

Conversation

@NancyKwongPerplexity

@NancyKwongPerplexity NancyKwongPerplexity commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Moves everything space-api's Native files:* handlers do apart from authorization, the idempotency binding and the controller calls into pplx-space-native-files, so another server answering these routes applies the same rules:

  • Limits and field checks: the size and body limits, and every field check, with the same invalid_request messages (FileRequestError, in limits.rs and request.rs). This includes chunked base64 decoding for files:write and batch decoding with its 3 MiB cap for files:write_batch.
  • Worker requests and answers: the worker request each operation sends, and how stat, list and modified answers map to the public shapes (worker.rs). The controller's stat and list requests use the same builders.
  • Parents writes: write_creating_parents and its :parents retry key (parents.rs). It is now generic over the failure type through FileCallFailure and returns that failure unmapped. The handlers map it exactly as before.
  • Failure mapping: how a failed sandbox call becomes a public error (failure.rs).
    • WorkerFailure holds the gRPC-to-HTTP table, the guest-storage-full and retry-hint markers, and the refused-before-start and guest-path-not-found flags. ControllerError's From<tonic::Status> now builds on it, so both servers classify a worker status the same way.
    • file_call_error and unprotected_mutation_error are the files mapping that was files.rs:964-1024, including the no-blind-retry rule for mkdir, remove and change tracking. They return a FileCallError value, and space-api renders it as the same PublicApiError.

space-api keeps the handlers, their order of checks, owner scope, bind_request_key and the controller calls. No behaviour change.

Validation

At this head (03f4885b), on main at 0271415a:

  • Rebased onto native-files: share the file-request fingerprints and guest key #1362's new head with no conflicts; the commit is unchanged (git range-diff reports it identical).
  • cargo fmt --all -- --check, scripts/generate-env-contract.sh --check, scripts/check-rust-error-policy.sh and scripts/source_guards/env_test_hook_boundary.py pass.
  • cargo clippy --locked --all-targets --all-features -p pplx-space-native-files -p pplx-space-api -- -D warnings passes.
  • cargo check --workspace --all-targets --locked passes.
  • cargo arch against main's baseline, renames and ARCHITECTURE.toml: 0 required findings and 112 advisory, the same findings as main.
  • cargo nextest run --config 'profile.test.package.pplx-space-api.opt-level=0' --all-features --all-targets, one package at a time, with Postgres and Redis from the nextest setup scripts and SPACE_CI_REQUIRE_TEST_DEPS=1: pplx-space-api 2193 passed, 1 skipped; pplx-space-native-files 1 passed.

The existing routes/public/files/tests.rs suite stays in space-api, unchanged apart from imports. One test now maps the generic helper's error with controller_error, as the handlers do. Keeping the suite in place shows the moved code behaves as before through the real handlers.

Severity and risk

Severity: does not apply (refactor).

Risk: a changed message, check order or status mapping would change what Native clients see. Every message is the same string (the #[error] text equals the old literal), every handler keeps its check order, and the envelope tests (a_full_sandbox_disk_is_not_a_retryable_rate_limit, guest_refusals_and_timeouts_are_retryable_with_their_hint, unprotected_mutations_do_not_invite_a_blind_retry, only_a_guest_missing_path_carries_the_path_detail) pass. To roll back, revert this PR.

Stack

This is PR 2 of 5 and depends on #1362 (native-files-shared-request). Merge in order:

  1. native-files: share the file-request fingerprints and guest key #1362 (native-files-shared-request)
  2. this PR
  3. public-api-http: make Native error rendering usable outside space-api #1364 (native-error-rendering-shared)
  4. api: serve native file access RPCs on the activation listener #1365 (native-file-access-rpcs)
  5. auth: let the data-plane identity call the native file access RPCs #1371 (data-plane-native-file-access-authz)

AI assistance: Claude Code drafted the code, tests, and this description; the author reviewed them.

@nikhilbirmiwal-pplx nikhilbirmiwal-pplx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Checked the move into pplx-space-native-files against the parent: limits, every invalid_request message, check order in each handler, the worker request builders (incl. remove missing_ok / mkdir exist_ok), the gRPC->HTTP table with storage-full and the 1-60s Retry-After clamp, file_call_error/unprotected_mutation_error (lock-contention first, no-blind-retry rule), and write_creating_parents now returning the raw failure mapped once by callers. All behaviour-preserving; no blocking issues.

@NancyKwongPerplexity
NancyKwongPerplexity force-pushed the native-files-shared-request branch from 619f917 to cbe1c6a Compare November 3, 2026 19:39
@NancyKwongPerplexity
NancyKwongPerplexity force-pushed the native-files-shared-handling branch from f99ebdc to 03f4885 Compare November 3, 2026 19:39
Base automatically changed from native-files-shared-request to main November 3, 2026 20:08
Move what space-api's files:* handlers do besides authorization into
pplx-space-native-files, so another server answering these routes
applies the same rules:

- the size limits and body limits, and every field check, with the same
  invalid_request messages (FileRequestError);
- chunked base64 decoding of files:write and the batch decoding and
  size cap of files:write_batch;
- the worker requests each operation sends, and how stat, list and
  modified answers read in the public shapes;
- write_creating_parents, the parents retry and its derived key;
- how a failed sandbox call becomes a public error: the gRPC-to-HTTP
  table, the storage-full and retry-hint markers (WorkerFailure), and the
  files mapping with its no-blind-retry rule for unkeyed mutations
  (FileCallError). ControllerError's conversion from tonic::Status uses
  the same table.

space-api keeps the handlers, the owner check, the idempotency binding
and the controller calls, and renders FileRequestError and FileCallError
as PublicApiError exactly as before. No behaviour change; the existing
files tests stay where they are and pass.
@NancyKwongPerplexity
NancyKwongPerplexity force-pushed the native-files-shared-handling branch from 03f4885 to 194d52c Compare November 3, 2026 20:09
@NancyKwongPerplexity
NancyKwongPerplexity added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 518e02e Nov 3, 2026
37 checks passed
@NancyKwongPerplexity
NancyKwongPerplexity deleted the native-files-shared-handling branch November 3, 2026 20:41
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.

2 participants