dry-exec
Deterministic ephemeral execution primitive for autonomous loops.
Explore state mutations without consequences. Commit only what you approve.
What is dry-exec?
One AI agent is a cool demo. Running 100 in production is a state-management problem:
- commands can write files before review;
- migration code can touch the wrong database;
- API calls can leak real credentials or spend real money;
- rollback becomes someone’s pager.
dry-exec gives each proposed action an ephemeral trial. The action runs behind native Linux or macOS boundaries. The SDK returns a structured StateDelta containing observed memory, filesystem, network, stdout, stderr, and exit-code changes. You review that receipt before committing anything durable.
The useful mental model: git diff for a runtime action.
What it covers
| Production risk | Trial result |
|---|---|
| Unreviewed filesystem writes | Isolated filesystem mutation list |
| Failed command hidden behind a wrapper | Captured stdout, stderr, and exit code |
| Real API call during exploration | Schema-driven HTTP mock proxy |
| Host changes during a dry run | Linux namespaces or macOS Seatbelt/APFS boundaries |
| Agent decision made from raw logs | Typed StateDelta and decision receipt |
Linux real-command execution and HTTP/HTTPS mock interception are verified in the container harness. macOS /bin/echo real-command execution is covered by native E2E.
Installation
pip install dry-exec
Quickstart
Path 1: The 3-Line Autonomous Agent Loop
Let an autonomous execution loop propose actions, test them ephemerally, evaluate state deltas, and self-correct:
import asyncio
from dry_exec import Agent
async def main():
agent = Agent(task="Clean up old temp files and migrate user records")
result = await agent.run()
print(f"Success: {result.success}, Trials: {result.trials_conducted}, Committed: {result.committed}")
asyncio.run(main())
Path 2: Direct Ephemeral Client Execution
Run an isolated trial and inspect the exact StateDelta receipt before approving mutations:
import asyncio
from dry_exec import Action, DryExecClient, Environment
async def main():
client = DryExecClient()
env = Environment(name="sandbox", allowed_mutation_targets={"*"})
action = Action(
action_id="act_001",
target_resource="shell_command",
mutation_type="execute",
payload={"command": ["/bin/sh", "-c", "echo hello > test.txt"]},
)
delta = await client.execute_ephemeral_action(env, action)
print(f"Decision: {delta.decision.choice}, Risk: {delta.decision.risk_score}")
print(f"Filesystem mutations: {delta.fs_mutations}")
asyncio.run(main())
Path 3: The @dry_exec.dry_run Decorator
Wrap any function to run inside an ephemeral kernel sandbox. Returns the computed StateDelta:
import dry_exec
@dry_exec.dry_run
def update_balance(account_id: str, amount: int):
# Runs in ephemeral sandbox; database is untouched
db.execute("UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, account_id)
delta = update_balance("acc_101", 500)
print(f"{delta.total_bytes_mutated} bytes mutated in {delta.duration_nanos}ns")
Or execute directly with functional dry_exec.run():
delta = dry_exec.run("python seed_data.py")
Architecture: Dual-Backend Engine
dry-exec features a native dual-backend architecture. It automatically detects the host operating system and compiles to native kernel primitives with sub-millisecond execution latencies:
dry-exec Architecture
│
┌─────────────────────────┴─────────────────────────┐
▼ ▼
Linux Backend macOS Backend
(Production & Cloud) (Local Development)
───────────────────────── ─────────────────────────
• Linux Namespaces (PID, NET, MNT) • Apple Seatbelt (sandbox_init)
• seccomp-BPF TRAP filter • APFS Copy-on-Write (clonefile)
• /proc/[pid]/pagemap soft-dirty • Transparent Loopback Proxy
• Zero Docker needed • Zero Docker needed
Autonomous Execution Loop (Python SDK)
┌──────────────────────────────────────────────┐
│ @dry_exec.dry_run or Agent(task=...).run() │
│ Async FFI dispatch (GIL released) │
└──────────────┬───────────────────────────────┘
│ PyO3 FFI
▼
Rust Control Plane (Linux & macOS Router)
┌──────────────────────────────────────────────┐
│ Linux: Namespaces + seccomp + pagemap │
│ macOS: Seatbelt MAC + APFS CoW clone │
│ Transparent proxy for mock endpoints │
│ System-One Decision Layer (O(1) in delta) │
└──────────────┬───────────────────────────────┘
│
▼
StateDelta { memory, fs, network, decision }
Features
- 3-line agent loop — Propose → dry-run → evaluate → self-correct → commit
@dry_exec.dry_rundecorator — Zero boilerplate ephemeral execution for Python functions- Kernel-level Linux isolation — Linux namespaces (PID, NET, MNT, IPC, UTS) with seccomp-BPF filtering
- Native macOS support — Kernel-level Seatbelt MAC sandboxing and APFS
clonefilehardware CoW - $O(P_{\text{dirty}})$ state diffing — Soft-dirty pagemap tracking, no app-level hashing
- Transparent network proxy — Schema-driven mock responses, zero external egress
- Deterministic System-One Decision Engine — $O(1)$ scalar projection routing safe actions to Auto-Commit in nanoseconds
Optional local System-One scorer
dry-exec-core includes an opt-in laya feature for local Laya inference through the published
Rust laya-rs runtime. The feature loads a checkpoint from a caller-provided local directory;
it never downloads weights implicitly. Deterministic boundary decisions remain first: blocked or
violated actions do not invoke Laya, while allowed actions may blend deterministic risk (40%) with
the local model score (60%). If checkpoint loading fails, callers can retain deterministic-only
routing. This feature is disabled by default because Laya checkpoints are large and latency must
be measured on the target hardware rather than assumed from upstream benchmarks.
cargo check -p dry-exec-core --features laya
Examples
| Example | Description |
|---|---|
quickstart.py |
3-line setup with @dry_exec.dry_run |
native_agent.py |
3-line self-correcting agent loop |
type_safe_db_migration.py |
DB migration recovering from schema boundary rejections |
api_payment_exploration.py |
Payment API exploration with mock interception |
langchain_tool.py |
LangChain tool wrapper |
Verification
Native Local Verification (Linux & macOS)
Run the local test harness directly on your machine (zero Docker required):
./scripts/test.sh
Containerized Linux Verification (Cross-Platform)
To test the complete Linux kernel primitive suite inside Docker:
./docker/build.sh
docker run --rm --privileged --cap-add=SYS_ADMIN --cap-add=SYS_PTRACE dry-exec-test-harness
Contributing
See CONTRIBUTING.md for development setup and terminology conventions.
License
Metadata
Release files for dry-exec 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| dry_exec-0.1.0.tar.gz | 72.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dry_exec-0.1.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 1.1 MB
Release files / dry_exec-0.1.0.tar.gz
| Download URL | dry_exec-0.1.0.tar.gz |
|---|---|
| Size | 72.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bd33df0bf5c6855e7e12705cd5ae7341f00ce2391c9d0b6c7c29e28559b7b2d
|
|
BLAKE2b-256 checksum How to use checksums |
4ec57c398e3d8d4e62d275379b180a7805c38a54b06efb68aa1610d6a0b915cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|
Release files / dry_exec-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | dry_exec-0.1.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.0 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8fd3e6c0bf2149dffa693aa75d3affac6b38e03c80e613e083d70114245a07af
|
|
BLAKE2b-256 checksum How to use checksums |
f717811ce16ec7a761d647635b7092b76204ec0aaff869827c3110f59b4170b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|
Security for dry-exec 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.