Run the pull request before you trust the pull request
A diff shows the final tree. It cannot show what an install script attempted, what the branch contacted, or whether the tests ever ran. A detached box lets you find out without giving the branch your machine.
origin, and cannot be applied or rebased into the parent. External code leaves only through export.A pull request is executable input long before you run its application. Package manifests select install hooks. Build files select plugins. Test fixtures feed parsers. Editor and agent configuration can alter startup behavior. “I only want to read the diff” stops being true the moment a realistic review builds the branch.
1. Create a detached box
$ h5i box create review-1234 --pr 1234 --profile agent-claude
$ h5i box status review-1234--pr accepts a number, #number, or pull-request URL. h5i fetches the head on the host, pins it, then gives the box an independent repository with no inherited network remote.
The host-side fetch uses access you already have, then ends. The box receives Git objects and a pinned revision—not the SSH agent, GitHub token, or a remote it can push to. This split lets private repositories be reviewed without turning repository access into a standing capability inside untrusted code.
2. Read the boundary before the branch
Confirm three things in status: the box is detached, the requested isolation tier is enforced, and network access is no broader than the review needs. Do this before running a package manager; install hooks are code execution.
$ h5i box capabilities review-1234 --json
$ h5i box secrets review-1234secrets shows declared grants and dry-run resolution, never secret values. A review that needs no authenticated service should have no grant.
Also verify that origin is absent inside the box. Dropping the remote is not a complete network control, but it removes a ready-made authenticated handle and makes the detached shape obvious to tools that inspect Git configuration.
3. Build and test inside the box
$ h5i box shell review-1234
box$ npm ci
box$ npm test
box$ npm run dev
# In another host terminal: h5i box view review-1234
box$ exitUse the project's real install and test commands. If it is a web change, start the server in the same session and drive the isolated browser. The app, browser, and agent then agree on what localhost means.
Test the claim the pull request makes, not merely the command its author suggests. A dependency change deserves an install from the pinned lockfile. A migration deserves a disposable database. A browser fix deserves console and failed-request evidence, not only a screenshot. The box makes destructive setup cheap enough to reproduce instead of infer.
4. Review evidence in the right order
$ h5i box export review-1234 --out ./review-1234
$ less ./review-1234/report.md
$ less ./review-1234/patch.diffRead the report before the prose supplied by the author or agent:
- Denied egress attempts. Unexpected destinations deserve an explanation first.
- Commands and exit codes. Check that the meaningful tests ran.
- Browser errors and failed requests. A visually plausible page can still be broken.
- The patch. Now read the code with the execution history beside it.
- The proposal. Treat it as testimony, not evidence.
microvm network stack can enforce an allowlist without producing a per-request egress tally. A missing summary at that tier does not mean no connection was attempted.5. Keep the bundle, discard the box
$ h5i box rm review-1234
$ h5i box gcYou can apply an accepted patch wherever you choose with git apply --3way. h5i refuses box apply for this detached box by design.
Signals that deserve a second look
| Signal | Benign explanation | Review question |
|---|---|---|
| Denied telemetry host | A dependency phones home by default | Does this dependency belong in the change? |
| Test exits zero unusually fast | Cache hit or focused test target | Did the meaningful suite actually execute? |
| Generated file outside expected tree | Build tooling creates metadata | Is it required, reproducible, and safe to apply? |
| Browser has no captured evidence | No browser was started | Was the user-visible behavior exercised at all? |
| Agent proposal omits a failed run | The agent retried and summarized the final state | What changed between failure and success? |
None of these is a verdict. They are attention routing. A useful report helps a reviewer spend time where the branch's behavior diverged from its story.
Why detached is stronger than “remember not to merge”
The command surface itself refuses apply and rebase for external sources. That turns repository origin into a type-level lifecycle decision. An agent or hurried reviewer cannot accidentally use the convenient local landing path on code that arrived from somewhere else.
Export remains available because review still needs an outcome. Its patch passes path validation before leaving: symlink escapes, nested Git repositories, and agent-introduced gitlinks are rejected. You can inspect the bundle, move it elsewhere, or discard it with no mutation to the parent repository.
Common review failures
If the pull-request ref cannot be fetched, use the full URL and confirm the host—not the box—has repository access. If dependency installation is denied, add the exact registry hosts to a review profile rather than switching to host networking. If the application needs a service, declare or start it inside the same session so the review does not silently depend on a host database.
Reference
- Box source shapes and detached semantics.
- The output gate and path validation.
- Why the report and diff answer different questions.
- How to exercise a web change inside the box.
Questions that come up
Do GitHub credentials enter the box?
Why not check out the branch in a normal worktree?
Can an agent perform the review?
Write the boundary down
Turn filesystem, network, and resource assumptions into a checked-in profile.
Review behavior, not just text
Give untrusted code somewhere safe to execute before you decide whether to take it.