The sandbox boundary
Running a pull request means running a stranger's code. Where that happens, and what is allowed across the line.
Running a pull request means running a stranger's code
pip install alone executes a package’s setup.py before any of your own code runs.
That is not a hazard Cujo introduces; it is the hazard Cujo exists to measure. What follows from it is that all of it has to run somewhere holding no credentials, with no path back, and that gets thrown away afterwards.
Two zones, one narrow bridge
| Zone | Holds |
|---|---|
| Trusted | The harness, the Cujo service, the MCP server that posts reviews, and every secret — the App’s private key, the model key, the Discord token. |
| Untrusted and disposable | The pull request’s code and its dependencies, the checks’ own scripts, Cujo’s sensor code, and the logging proxy. One box per turn, destroyed after it. |
Four things cross into the sandbox, and one comes back:
- The pull request’s code and its public metadata.
- The names of the dependencies it added.
- Cujo’s own sensor script and the commands the checks run. Ours, carrying no secret — the instrument, not the specimen.
- A public run’s own id, so a report can name itself. An id and never a URL, so no hostname crosses either.
- Out: JSON reports. Nothing else.
What is armed inside the box
- A decoy secret. A plausible credentials file that nothing legitimate has any reason to open. Reading it is a hard rule.
- A logging proxy. Every connection made through it is recorded by host, port and byte count — and only that. There is no TLS interception, so no payload is ever read.
- A filesystem diff. Taken before and after every sensed command, hashing content wherever a silent edit would be the attack.
- A Python audit hook. A second, independent witness to file opens, socket connects and subprocesses, which rides into every Python child including pip’s own.
The harness is also configured so that a file written inside the box cannot be fetched back out through it. The reports are the only channel.
Where it is blind, and why it says so
A sensor that can be off must say when it was off, or a quiet report reads as a clean one. So every report carries which sensors were armed and where a cap cut the evidence short, and an unarmed proxy or decoy produces a warn of its own.
The known gap is a process that opens a socket directly instead of honouring the proxy variables. That is a missed observation, not a false one — which is the direction the whole sensing design is biased in.