Skip to main content

dry-exec

Deterministic ephemeral execution primitive for autonomous loops.

Explore state mutations without consequences. Commit only what you approve.

License: MIT Rust Python Platform CI


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_run decorator — 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 clonefile hardware 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

MIT

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)

Source distribution for dry-exec 0.1.0
File Size Uploaded Provenance
dry_exec-0.1.0.tar.gz 72.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dry-exec 0.1.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page