Concepts
The sealed box
Every run gets a brand-new box with the same fixed rules. The program can't change them, and PyBox checks them before the program starts.
Where the box lives#
PyBox keeps a small private Linux virtual machine on your Mac, called pybox. Inside it, every run gets a fresh container, the "box". Your Mac talks to the VM through a private channel that only PyBox uses. The program in the box gets its source code in and its output out, and nothing else.
| Place | What's there | Trusted? |
|---|---|---|
| Your Mac | PyBox itself: the supervisor that decides everything | Yes |
| The private VM | The container engine, and a small watcher that reads the box's counters | Yes, but kept separate from the program |
| The box | Your program, and a timer that stops it | No. Everything it says is treated as untrusted |
The rules#
| Rule | What it means |
|---|---|
| No folders from your Mac | Your files simply aren't in the box |
| No internet | No network connection of any kind |
| Read-only system | It can't change the box's own files, only a small scratch area |
| Not an administrator | Runs as an ordinary user with every special permission removed |
| Limited memory | 128 MiB, with no extra swap |
| Limited processes | At most 32 at once, including PyBox's own two |
| Limited CPU | Half of one core. It slows the program down; it doesn't stop it |
| Limited open files | 128 at a time |
| A time limit | 2 seconds by default (up to 30 if you ask), plus a backup timer inside the box |
| A fixed image | Always the same Python, pinned by its fingerprint, never downloaded at run time |
The exact engine settings are listed in the Reference.
None of these can be changed by the program or by whoever sends it. A caller can only choose from fixed options: the time limit (up to 30 s; for MCP, up to what the server allows), how much output to keep, the data image, whose own limits are 512 MiB, 64 processes and one CPU, and copies of files in and out. Each choice is verified like every other setting and recorded on the receipt.
Checked before the program starts#
A setting you asked for isn't the same as a setting you got. After creating the box, PyBox asks the container engine to describe it and compares every rule above with what the engine reports. If anything differs, the box is removed and the program never starts. The receipt records whether this check passed: "policy_verified_before_start": true.
Each protection was tested twice#
A failed action proves little on its own. A write can fail for many reasons. So most protections were tested in pairs: once with the protection, once with only that one protection removed. Thirteen restriction checks were recorded on 19 October 2026. Some of them:
| Check | With the protection | With only that protection removed |
|---|---|---|
| Write to a system folder | Refused (read-only) | Allowed |
| Write 17 MB to scratch | Stopped at 16 MB | Fit in a 20 MB scratch |
| Change a file's owner, as admin with permissions dropped | Refused | Allowed with just that one permission added back |
| Open a network connection or look up a name | Unreachable | Reached a private test server |
| Signal the timer (the box's first process) to stop or pause | Timer still fired at 3.03 s | — |
A summary of all of them is on the evidence page.
What this doesn't prove. Thirteen checks show these specific cases work. They don't prove the box resists every possible attack. Nobody can prove that with a finite list. PyBox is a local research prototype, not a sandbox approved for hostile code from the public internet.
The other runner: not sealed#
PyBox also includes a native learning runner (pybox run --unsafe-local). It's part of the project's history: it shows how a parent process supervises a child. It runs the program on your Mac with your permissions. It's never used for MCP or AI, never used as a fallback, and you should only use it for code you wrote yourself.