Skip to content

usb-debug/MCP: expose file read/write (Airlock primarily) for automated testing #15

Description

@ObjSal

Summary

Please expose file read/write over the usb-debug MCP interface, primarily for the Airlock volume (Internal/User would be a useful phase 2, with the caveats below).

Today foundation-passport-drive's MCP surface has tap, swipe, input_text, screenshot, get_logs, launch_app, load_app and friends — everything needed to drive an app, but no way to put a file in front of one or read back what it produced. input_text is the only data path in, which limits fixtures to text that can be typed through the on-screen keyboard.

Why Airlock specifically

Airlock is the natural transfer boundary, but there is a concrete blocker that makes this more than a convenience request:

Airlock's USB export mode is set in the Files app (Airlock ▸ ••• ▸ Read Only / Read & Write). With the cable in and a mode selected, macOS mounts /Volumes/AIRLOCK — but the DEVICE side unmounts it for the duration (Files > Airlock shows "Connected by USB"). The exclusivity is USB-configuration-level, so a device app can never read Airlock while the automation cable is connected.

So the two things we want — a host that can place a file, and an app that can read it — are mutually exclusive today. We are not asking to mount Airlock as mass storage. We are asking for file I/O over the debug channel that is already open, so Airlock stays device-owned and the mode conflict never arises.

That is also why Airlock is the right first target from a security standpoint: it is the volume already designed as untrusted exchange space, so a debug-gated write there is the least sensitive place to add this.

Why read matters as much as write

Write unblocks fixtures. Read is what makes assertions honest: today we verify an app's output by taking a screenshot and comparing pixels, because we cannot look at the artifact. With read we could assert on the real bytes — a detached .sig, an exported .asc, a generated PNG, a signed transaction hex — instead of inferring from the screen.

The primitive already exists

load_app streams a multi-file bundle onto the device over usb-debug and writes it into keyos/sideloaded-apps/<app-id>/:

Loaded b0c9c989… into keyos/sideloaded-apps/b0c9c989… (app.elf: 6926956 bytes,
manifest.json: 3757 bytes, icon.bin: 48456 bytes, icon-dark.bin: 48456 bytes, …)

So the transport, the chunking and the device-side write path are all there. This request is largely "point that at a user-visible volume and expose it as a tool" — the same shape as #13, which you closed by mirroring the existing usb-debug Tap/InputText into the simulator.

Sketch

MCP tools (and matching foundation-passport-drive subcommands, e.g. push-file / pull-file / ls):

list_dir    { location: "airlock", path: "/" }              -> entries + sizes
read_file   { location: "airlock", path: "/note.txt" }      -> base64 bytes
write_file  { location: "airlock", path: "/fx.pdf", data }  -> base64 bytes in
delete_file { location: "airlock", path: "/fx.pdf" }
  • location: airlock is what we need; internal (User volume) would be a bonus — see below.
  • Chunking or a size cap is fine; our fixtures are KBs, not MBs.
  • Developer Mode gating (as usb-debug already is) is expected and welcome.

On the Internal/User volume

Useful but deliberately secondary, and we would understand it being declined or deferred: that volume holds app data and, for some apps, exported key material, so read there has real exfiltration weight in a way Airlock does not. If it is offered at all, Developer-Mode-only (as today) seems right, and write is more valuable to us than read.

What this unblocks for us

We drive full UI suites against both the simulator and a real Passport Prime over usb-debug (the harness behind our sideloaded apps). Concretely:

  • Fixtures for viewer apps. Our PDF and image viewers cannot be tested on device at all right now: there is no way to get a .pdf or .png onto the device without physically moving an SD card, and Airlock is unavailable while the cable is in.
  • Real assertions instead of pixel-diffing. See above.
  • The simulator too. Seeding the hosted sim currently means writing into its FAT image with the simulator STOPPED (fs-server holds it open and caches FAT state), so fixtures cannot be staged mid-run. --sim file I/O would remove that constraint entirely.

Happy to test a build against our suites and report back, as with #13.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions