Drop-in, agent-native GitHub Actions that runs locally, or self-hosted.
Verify code at the speed agents write it.
Preloop is an agent-native CI engine, built in Rust. Every job runs in its own hardware-isolated microVM that boots in under 200 milliseconds on macOS, Linux, or Windows. The same engine runs locally or self-hosted: a workflow that passes on your machine passes in CI.
00:00.00 SYS REQ_RECEIVED PR #402
00:00.01 PROV ALLOCATING MICRO_VM (linux-arm64)
00:00.17 OK VM_BOOT_COMPLETE [174ms]
00:00.18 EXEC PULLING REPO /agent-generated-patch
00:00.24 EXEC RUN: cargo test --workspace
00:01.01 OUT test result: ok. 142 passed; 0 failed;
00:01.07 EXEC RUN: npm run lint
00:01.14 OUT All files pass linting.
00:01.15 OK WORKFLOW_COMPLETE [1.15s]
00:01.16 SYS TEARDOWN_INITIATED
01 THE_BOTTLENECK
THE OLD VERIFICATION STACK WAS BUILT FOR HUMAN-SPEED OUTPUT.
Legacy CI was built for human-speed output: minutes to provision a runner, containers that share your host kernel, and failure pages designed for manual inspection.
When an AI agent ships code all day, every change is untrusted by default. Waiting four minutes for a runner to boot nullifies the advantage of automated generation.
02 EXECUTION_MODEL
[A] GHA_PARITY
{ .YML } → ||
Drop-in GitHub Actions compatibility. Your existing workflows run unchanged, verified against the official runner, not approximated.
[B] MICROVM_ENV
[ μVM ]
Every job gets its own dedicated microVM. A real kernel, hardware-isolated, not a shared one. Boots in under 200 ms on macOS, Linux, or Windows.
[C] LIVE_DEBUG
>_ ↔ █
Pause-on-failure. When a job fails, the machine freezes. Open a shell at the exact failure state, or fork the machine and retry from the step that broke.
[D] DAP_DEBUG
▸_ ↔ DAP
Built-in Debug Adapter Protocol bridge. Attach a DAP client like VS Code to a paused job and step through the failure. Built in, coming soon.
[E] X86_ON_ARM
x86 → arm64
Run x86_64 workflows on an Apple Silicon Mac. Rosetta translation keeps them near native speed, so amd64 CI does not need an amd64 machine.
[F] 95% CACHING_RATE
[ ▓▓▓░ ]
After the first run the whole filesystem stays warm. Dependencies, compiled output, and package caches are still there, so the next run skips the install phase entirely.
03 ARCHITECTURE_DELTA
- LOCAL-FIRST PARITY The same engine runs on your laptop and on self-hosted workers. If it passes locally, it passes in CI. Zero environment drift. Hand a warm machine snapshot to a bigger host and continue with every cache intact.
- FULL STACK OWNERSHIP The runner, the control plane, and the CLI are built in Rust. One fast binary, no Node runtime, no JVM, no orchestration sprawl.
- AGENT-OPERABLE API Built to be operated by agents, not just triggered.
- DENY-BY-DEFAULT Network is off until you switch it on. Secrets are referenced from the host at launch, so they are never baked into a machine or its snapshots. Agent-generated code stays quarantined.
04 THE_AGENT_LOOP
- RUN WHAT IS ON YOUR DISK. preloop run tests your working tree as it is, uncommitted and untracked files included. Checkout inside the job pulls your local tree instead of a pushed commit, and your git index is never touched.
- THE FAILED JOB STAYS ALIVE. A failing step holds its microVM open by default, with the checkout, toolchain, services, and warm caches exactly as the test left them. There is nothing to reproduce.
- FIX IT, RETRY THE STEP. preloop debug attaches to the paused step. Edit the code, run :retry, and only that step runs again. Build caches survive, the debris from the failed attempt does not.
- TAKE THE FIX WITH YOU. Edits you made inside the VM come back to your workspace as a patch with preloop debug --export. Add --json and an agent drives the identical loop.
$ preloop run
→ VERDICT: FAILED, step 3/8 (cargo test)
→ VM PAUSED, caches warm, services up
$ preloop debug
› :retry
→ RE-RAN STEP 3/8 ONLY
→ VERDICT: PASS [1.2s]
$ preloop run --sync
→ PUSHED TESTED SHA, PR #402 UPDATED
05 NO_WEBHOOK_REQUIRED
THE SHA THAT LANDS ON GITHUB IS THE SHA THAT WAS TESTED.
Every other CI waits for GitHub to hand it a webhook. When that delivery path breaks, a tunnel drops, a secret rotates, or GitHub has an incident, CI goes dark and the missed events never come back.
Preloop inverts it. You submit the run straight to the server and it starts immediately. GitHub becomes the place results land, not the thing runs wait on.
- PUSH_CONFIRM. preloop run --sync runs CI on your workspace, then pushes the tested commit and confirms it on the PR with check runs. The push happens after the verdict, not before.
- ONLY TESTED CODE GETS PUSHED. When the run finishes, the CLI pushes the exact commit it tested. Fast-forward or a new branch only. A force push never happens on its own.
- THE PR UPDATES ITSELF. The server opens or updates the pull request, draft by default, and reports check runs against the tested commit.
- SAFE TO REPLAY. GitHub unreachable? The push retries on its own, and preloop sync replays the whole thing. Every step is idempotent.
06 SYSTEM_SPECS
| GHA_COMPATIBILITY | Drop-in for existing workflows. Property-tested, formally verified, with wire compatibility steps. |
| COLD_START_LATENCY | 400ms |
| PLATFORMS | macOS (Apple Silicon) · Linux · Windows |
| WORKSPACE | Runs your working tree, uncommitted and untracked files included |
| CONTROL_PLANE | Rust end to end: runner, control plane, CLI |
| ISOLATION | One dedicated microVM per job; network off by default |
| MEM_FOOTPRINT | Elastic. The host commits only what a job actually uses |
| SELF_HOSTING | preloop serve runs the control plane and microVM pool on your own box |
07 DEMOS
[A] DROP_IN
An existing GitHub Actions workflow, run as-is. No config changes, no rewrites.
[B] DEBUG_LOOP
A failing job, a split terminal. Fix the file on the host, rerun, and the same warm machine goes green.
[C] AGENT_LOOP
An agent drives the loop: submit, read the verdict, patch, resubmit. Machine-readable end to end.
08 ACT_VS_AKSH
ACT REIMPLEMENTS THE RUNNER. WE REIMPLEMENTED THE CONTROL PLANE AND THE RUNNER, WITH THE REAL WIRE PROTOCOL BETWEEN THEM.
act is a pragmatic Go binary that runs steps in Docker containers on your host kernel. Fast to start, but it cannot guarantee parity: no wire protocol, no OIDC, no concurrency groups, no debugger. On the same 39-scenario benchmark, act gets 29/39 right, aksh gets 31/39 — with typical runs in 400-800 ms.
| FEATURE | ACT | AKSH |
| SCOPE | Runner only (Go CLI) | Control plane + runner (Rust) |
| FIDELITY | Behavioral, mostly works | Official wire protocol, the runner cannot tell the difference |
| EXECUTION | Docker containers on your kernel | One dedicated microVM per job |
| VERIFICATION | Community bug reports | Golden wire captures replayed, differential + property tests |
| CONTROL_PLANE | Runner only (Go CLI) | Control plane + runner (Rust) |
| DEBUGGING | None | DAP debugger, breakpoints, stepping |
| OIDC + CONCURRENCY | Not supported | Full OIDC provider, concurrency groups |
| PLATFORM | Linux Docker only | macOS, Linux, Windows |
FULL COMPARISON → DOCS/PRELOOP_VS_OTHERS.MD (act vs agent-ci vs aksh vs Gitea Actions, with the full 39-scenario benchmark)
INSTALL_CLI
curl -fsSL https://preloop.dev/install.sh | sh