{"id":51560635,"url":"https://github.com/h1d3mun3/augur","last_synced_at":"2026-07-10T10:30:50.029Z","repository":{"id":366166077,"uuid":"1190475576","full_name":"h1d3mun3/augur","owner":"h1d3mun3","description":"Run Claude Code in an isolated Docker container or macOS VM","archived":false,"fork":false,"pushed_at":"2026-07-08T23:52:51.000Z","size":1532,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-09T01:18:22.134Z","etag":null,"topics":["claude-code","cli","codex","docker","gemini-cli","macos-vm","sandbox"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/h1d3mun3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security-reviews/2026-06-28-full-review.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-24T10:15:05.000Z","updated_at":"2026-07-08T23:52:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/h1d3mun3/augur","commit_stats":null,"previous_names":["h1d3mun3/augur"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/h1d3mun3/augur","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h1d3mun3%2Faugur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h1d3mun3%2Faugur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h1d3mun3%2Faugur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h1d3mun3%2Faugur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h1d3mun3","download_url":"https://codeload.github.com/h1d3mun3/augur/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h1d3mun3%2Faugur/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35329609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-10T02:00:06.465Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","cli","codex","docker","gemini-cli","macos-vm","sandbox"],"created_at":"2026-07-10T10:30:47.515Z","updated_at":"2026-07-10T10:30:50.013Z","avatar_url":"https://github.com/h1d3mun3.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"left\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-0c90b4.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/auger.png\" alt=\"augur\" width=\"320\"\u003e\n\u003c/p\u003e\n\nRun Claude Code in an isolated environment.\nWorks in any directory — only the current directory is exposed to the container or VM.\n\nTwo modes are available:\n\n| | Container mode | macOS VM mode |\n|---|---|---|\n| **Isolation** | Linux container | macOS VM (Apple Virtualization Framework) |\n| **Xcode / xcodebuild** | ✗ | ✓ |\n| **iOS Simulator** | ✗ | ✓ |\n| **Setup time** | ~5 min (image build) | ~75 min (VM build) |\n| **Disk usage** | ~2 GB | ~70 GB+ |\n| **Requires** | Apple Container (macOS 26+) | augur-vm (bundled), IPSW, Xcode XIP |\n\n---\n\n## Container mode (default)\n\nLightweight Linux container. Suitable for most projects that don't need Xcode.\n\nThe container is hosted by **Apple Container** (`container`, github.com/apple/container) on **macOS 26+** — native to macOS, no Docker Desktop, no licensing; each container runs in its own lightweight Linux VM. `augur status` shows the active engine.\n\n### Setup\n\n```bash\n# 1. Run the install script\nbash install\n\n# 2. Reload shell config\nsource ~/.zshrc  # or source ~/.bashrc\n\n# 3. Build the image\naugur build\n```\n\nThe install script copies `Dockerfile` and `augur` to `~/.augur/` and configures `PATH`. Safe to re-run.\n\n\u003e **Apple Container only:** `augur build`/`augur update` implicitly starts a BuildKit \"builder\" VM (~2 CPU/2GiB) that keeps running after the build finishes, to speed up the next one. It's a single instance shared by every `container build` on the machine — not scoped to a project — so augur deliberately never stops it for you (doing so from one project's `down`/`build` could kill another project's in-flight build). If you want to free the RAM/CPU, run `container builder stop` yourself once you're sure nothing else is building.\n\n### Usage\n\n```bash\ncd ~/projects/my-app\n\naugur up [--swift VERSION]      # start the container\naugur claude                    # launch Claude Code\naugur shell                     # open a bash shell (for debugging)\naugur setup-token               # get a Claude subscription token (runs in the guest, saves on the host)\naugur down                      # stop and remove the container\naugur status                    # show status, toolchain, and auth info\naugur build [--swift VERSION]   # build the container image\naugur update [--swift VERSION]  # rebuild image with latest tool versions\naugur init-conf                 # scaffold ./.augur/{allowlist,resources}.conf\naugur version                   # show augur version\n```\n\n### File access\n\n| Path | Description |\n|------|-------------|\n| Current directory | mounted at `/workspace-\u003cproject\u003e` (read/write), named after the directory |\n| `~/.claude/projects/-workspace-\u003cproject\u003e` | **only this project's** Claude history is shared (read/write) — not the rest of `~/.claude`, so other projects' transcripts and host auth/settings stay invisible |\n| `~/.config/gh/` | mounted **read-only** (the container can read but not rewrite it; the token is injected via `GH_TOKEN`) |\n| `~/.gitconfig` | mounted read-only |\n| Claude auth | injected via env (`CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`) — the host's credential store is never mounted |\n| Everything else | **not visible to the container** |\n\n\u003e Auth is env-based in both modes now. If you only ever logged in via the browser, run `augur setup-token` (or set `ANTHROPIC_API_KEY`); see [API keys and authentication](#api-keys-and-authentication). Upgrading from an older augur requires a one-time `augur build` (the image now pre-creates the scoped history dir).\n\n\u003e Claude Code's `--worktree` isn't specially supported (`augur claude --worktree ...` won't forward the flag). If you want it anyway: run `augur shell`, then type `claude --worktree \u003cname\u003e` yourself at the prompt — the worktree's files/git state persist fine, but its conversation history does not survive `augur down \u0026\u0026 up` (only the main checkout's project leaf is persisted). See `docs/claude-worktree-support-design.md` for the full trade-offs.\n\n### Requirements\n\n- **Apple Container** (`container`) on macOS 26+\n- bash\n\n---\n\n## macOS VM mode (`--macos`)\n\nFull macOS VM built from an Apple-signed IPSW. Supports Xcode, xcodebuild, and iOS Simulator.\nThe VM is isolated per project — each directory gets its own thin clone of the base VM.\n\n### Setup\n\n#### 1. Build the VM backend\n\naugur ships its own VM backend (`augur-vm`), a small Swift CLI built directly on\nApple's Virtualization.framework — no third-party tools required.\n\n```bash\n# on the macOS host (needs the Xcode / Swift toolchain)\nbash install        # builds \u0026 installs augur-vm into ~/.augur\n```\n\n#### 2. Download Apple-signed assets\n\n- **IPSW** — macOS restore image: System Preferences \u003e Software Update\n- **Xcode XIP** — Xcode installer: https://developer.apple.com/download/all/\n\n#### 3. Build the base VM (one-time, ~75 min)\n\n```bash\naugur build --macos --ipsw ~/Downloads/macOS.ipsw --xcode-xip ~/Downloads/Xcode.xip\n```\n\nThis will:\n1. Create a macOS VM from your IPSW (`augur-vm create --from-ipsw`)\n2. Open the VM window for manual Setup Assistant completion (credentials: `admin` / `admin`, Remote Login enabled)\n3. Install Xcode, Homebrew, GitHub CLI, and Claude Code\n4. Download the iOS Simulator runtime (Xcode installed from a XIP does not bundle it)\n5. Save the result as a reusable base VM (`augur-macos-base`)\n\nBy default only the **iOS** Simulator runtime is baked in. Use `--platforms` to bake in others —\nbaking them into the base VM means every project clone gets them without re-downloading:\n\n```bash\n# iOS + watchOS\naugur build --macos --ipsw ... --xcode-xip ... --platforms iOS,watchOS\n\n# every platform Xcode offers (watchOS, tvOS, visionOS, …) — many extra GB\naugur build --macos --ipsw ... --xcode-xip ... --platforms all\n```\n\n\u003e **Supply chain note:** The base VM is built entirely from Apple-signed assets (IPSW + Xcode XIP).\n\u003e No third-party automation scripts are used.\n\n### Usage\n\n```bash\ncd ~/projects/my-app\n\naugur up --macos        # clone base VM and start (first run clones automatically)\naugur up --macos --gui  # same, but also open a VM window (display + keyboard + pointer)\naugur claude --macos    # launch Claude Code  (starts VM if not running)\naugur shell --macos     # open a bash shell   (starts VM if not running)\naugur setup-token --macos  # get a Claude subscription token (runs in the VM, saves on the host)\naugur down --macos      # stop the VM (keeps the clone — next up is fast)\naugur destroy --macos   # stop and remove the project VM clone\naugur status --macos    # show VM status, toolchain, and auth info\naugur list --macos      # list all VMs and their state\naugur update --macos    # update Claude Code in the base VM\naugur version --macos   # show augur version (macOS mode)\n```\n\n### Authentication\n\nOn macOS, Claude Code stores its OAuth login in the Keychain, which is unreadable over SSH and\nabsent from a freshly cloned VM. So macOS mode injects a credential through the environment on\nevery `up` (the same way it does for the GitHub token):\n\n- `CLAUDE_CODE_OAUTH_TOKEN` — subscription token; either set the env var / save it to\n  `~/.claude_code_oauth_token`, or run **`augur setup-token`**: it runs `claude setup-token`\n  inside the guest (so you don't install Claude Code on the host), then you paste the token\n  back once and augur saves it to `~/.claude_code_oauth_token`.\n- `ANTHROPIC_API_KEY` — Console API key (env or `~/.anthropic_api_key`). Takes priority if both are set.\n\n### File access\n\n| Path | Description |\n|------|-------------|\n| Current directory | exposed at `~/workspace-\u003cproject\u003e` in the VM (read/write, virtiofs auto-mount) |\n| `~/.gitconfig` | copied on VM start (HTTPS `git push` uses `GH_TOKEN`) |\n| `~/.config/gh/` | shared **read-only** (token also injected via `GH_TOKEN`) |\n| Claude history | **only this project's** history is shared, in a per-VM isolated dir (`~/.augur/claude-projects/\u003cvm\u003e`), so other projects' transcripts stay invisible. Cross-mode (container↔macOS) resume is no longer shared. |\n| Claude auth | **not** shared — injected via env (the macOS Keychain is unreadable over SSH; see above) |\n| Everything else | **not visible to the VM** |\n\n\u003e The macOS guest auto-mounts the shared directory under `/Volumes/My Shared Files/workspace-\u003cproject\u003e`; augur\n\u003e symlinks it to `~/workspace-\u003cproject\u003e`. The sealed system volume can't host a symlink at `/workspace`, so the\n\u003e per-project `~/workspace-\u003cproject\u003e` path is used in the VM (container mode uses `/workspace-\u003cproject\u003e`).\n\n\u003e Same caveat as container mode for Claude Code's `--worktree`: not specially supported, but `augur shell --macos` +\n\u003e manually running `claude --worktree \u003cname\u003e` works today. Unlike container mode, its conversation history *does*\n\u003e survive `augur down --macos`/`up --macos` (the VM's disk is stopped, not destroyed, until `augur destroy --macos`).\n\u003e See `docs/claude-worktree-support-design.md`.\n\n### Running `xcodebuild test`\n\n`xcodebuild test` needs an Aqua (GUI) login session to reach `testmanagerd`; a headless SSH login\nhas none. Two things make that session exist at boot: the base VM is built with **auto-login**\nenabled, and the VM is always run with a **virtual display device** (macOS only starts an Aqua\nsession when a framebuffer exists — `--no-graphics` suppresses only the host-side window, not the\ndisplay device). With both in place, `xcodebuild test` works over SSH for all test types. Recommended\ninvocation (SwiftData's `@Model` macro needs `-skipMacroValidation` in a headless VM):\n\n```bash\nNSUnbufferedIO=YES xcodebuild test \\\n  -scheme \u003cScheme\u003e \\\n  -destination 'platform=macOS,arch=arm64' \\\n  -parallel-testing-enabled NO \\\n  -skipMacroValidation \\\n  -derivedDataPath ~/DerivedData \\\n  CODE_SIGNING_ALLOWED=NO\n```\n\nIf builds are flaky from the shared mount (virtiofs is not tuned for heavy I/O — occasional\n\"project is damaged\" errors), copy the project to local disk first: `rsync -a ~/workspace-\u003cproject\u003e/ ~/Developer/\u003capp\u003e/`.\n\n### Requirements\n\n- macOS (Apple Silicon)\n- Xcode / Swift toolchain (to build the bundled `augur-vm` backend via `bash install`)\n- macOS IPSW (Apple-signed)\n- Xcode XIP (Apple-signed, from developer.apple.com)\n\n---\n\n## Egress allowlist (`.augur/allowlist.conf`)\n\nRestrict the container/VM to a set of domains — everything else is blocked. Enforcement runs in a small proxy on the **host, as your user — it never needs `sudo`**. Useful for sandboxing an agent so it can only reach the services it should.\n\n**On by default.** Filtering is always active using a **managed baseline** (`~/.augur/augur.conf.default`, shipped with sensible defaults and refreshed on every install). Add your own always-on domains to `~/.augur/augur.conf`, or per-project ones to a `./.augur/allowlist.conf` in the project root. To disable for one run, pass `--no-egress`.\n\n```bash\ncd ~/projects/my-app\n\n# Optional: extend the baseline with project-specific domains\naugur init-conf   # scaffolds ./.augur/allowlist.conf\ncat \u003e\u003e .augur/allowlist.conf \u003c\u003c'EOF'\nregistry.example.com\napi.myservice.com\nEOF\n\naugur up            # container, egress on (baseline + augur.conf + allowlist.conf if present)\naugur up --macos    # macOS VM, same\naugur up --no-egress  # disable egress filtering for this run\naugur up --egress     # force egress filtering on (re-enables if AUGUR_EGRESS=0)\naugur status        # shows: Egress on/off + the active allowlist\n```\n\nFiltering is on by default; set `AUGUR_EGRESS=0` to disable it persistently, or `AUGUR_EGRESS=1` to force it on. The `--no-egress` / `--egress` flags override that environment variable for a single run.\n\n### `.augur/allowlist.conf` format\n\nOne pattern per line, `#` for comments:\n\n| Pattern | Matches |\n|---|---|\n| `example.com` | that exact host (the apex) only |\n| `*.example.com` | subdomains only (`api.example.com`, not `example.com`) |\n| `.example.com` | the apex **and** all subdomains |\n\nThe effective list is three layers merged (union — a layer can only widen, never narrow):\n\n1. **Managed baseline** (`~/.augur/augur.conf.default`) — shipped defaults for Claude Code / GitHub / npm / Homebrew. augur owns this file and **refreshes it on every install**, so shipped domain updates reach you automatically. Don't edit it; your changes are overwritten.\n2. **Your global additions** (`~/.augur/augur.conf`) — always-on domains you add. **Never overwritten** by install.\n3. **Project** (`./.augur/allowlist.conf`) — per-project domains.\n\nThe merge happens on the host, so the guest can't widen its own policy by editing the mounted file. Edits take effect on the next `augur up`.\n\n**Project domains require approval (trust-on-first-use).** Because `./.augur/allowlist.conf` ships inside a repository you may not fully trust, augur shows the domains it adds and asks you to approve them on first sight and again whenever the file changes — the same model as SSH host keys. The approval fingerprint is stored host-side under `~/.augur/project-hashes/` (never in the project tree or a mounted share), so a compromised guest that rewrites `./.augur/allowlist.conf` cannot get the change honored without a fresh host-side approval. `augur status` shows the project's domains and whether they're approved. For non-interactive / disposable runs (CI), set `AUGUR_ACCEPT_PROJECT_CONF=1` to accept automatically; without a TTY and without that variable, an unapproved/changed conf fails closed.\n\n### How it works\n\n| Mode | Enforcement |\n|------|-------------|\n| **Container** | The agent runs on a **host-only** `--internal` network (internet severed; the host reachable) with `NET_ADMIN` dropped and `--no-dns` (external DNS fails closed). The **host-side** `augur-proxy` is its only egress, reached via the host-only gateway. A boot self-test fails closed if direct egress is ever reachable. **Trade-off:** host-only also lets the agent reach other host services bound to `0.0.0.0`; closing it would need host `pf` rules (sudo), which augur avoids. |\n| **macOS VM** | The guest's only NIC is a host-owned socket (`VZFileHandleNetworkDeviceAttachment`); a bundled `gvproxy` runs the guest's network on the host and funnels every connection to the proxy. Needs no special entitlement. |\n\nIn every mode the proxy decides by domain (the CONNECT host, or the TLS SNI / HTTP Host) and connects out by name.\n\n### Requirements\n\n`install` builds the proxy (`augur-proxy`, Swift) automatically — both container and macOS VM modes run the native host `augur-proxy`. **macOS VM egress also needs Go** (for `augur-gvproxy`) — `brew install go`, then re-run `bash install`. Without it, macOS VM egress is unavailable but everything else works.\n\nThe host ports the proxy uses are derived per-project so two egress-enabled projects can run at once; override with `AUGUR_PROXY_HTTP_PORT` / `AUGUR_PROXY_SOCKS_PORT` / `AUGUR_SSH_FWD_PORT` if needed.\n\n\u003e **Scope.** This guarantees *\"the guest can only reach allowlisted domains.\"* DNS is gated on the same allowlist (a name resolves only if it's connectable), so the guest can't tunnel data out via DNS queries either. It is still **not** exfiltration-proof: an allowlisted, writable host (e.g. `github.com` with your `GH_TOKEN`) and the shared workspace are intentional channels. See `augur-proxy/README.md` and `gvproxy/README.md`.\n\n---\n\n## Container memory (`.augur/resources.conf`)\n\nApple Container's per-container default memory (~1 GB) is too tight for running an agent, so augur passes `--memory 4g` by default.\n\nTo change the default for a project — and have it apply consistently everywhere you clone or open that project, unlike an environment variable that only exists on the machine where you set it — commit a `.augur/resources.conf` (`augur init-conf` scaffolds one alongside the allowlist):\n\n```bash\naugur init-conf                   # or by hand: mkdir -p .augur\necho \"MEMORY=8g\" \u003e .augur/resources.conf\n```\n\nPrecedence: an `AUGUR_CONTAINER_MEMORY` environment variable (if set) overrides `.augur/resources.conf`, which overrides the built-in `4g` default. `augur status` shows the effective value. Like `.augur/allowlist.conf`, this file is guest-writable (it lives inside the mounted workspace) — but unlike the allowlist, it carries **no approval gate**: a guest requesting more or less memory for itself isn't a containment breach the way widening egress is, so it just takes effect on the next `augur up`.\n\n---\n\n## API keys and authentication\n\nSet the key you need. Add to `~/.zshrc`:\n\n```bash\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"   # for Claude Code\n```\n\nAlternatively, place the key in a file (`~/.anthropic_api_key`).\n\n**Account-based auth** (subscription, no API key needed): augur never mounts the host's\nClaude credential store into the guest — auth is injected via the environment in both\nmodes. The easiest way to get a long-lived subscription token is **`augur setup-token`**,\nwhich runs `claude setup-token` inside the guest (no Claude install on the host) and saves\nthe token for you. Or generate one yourself if you already have Claude Code on the host:\n\n```bash\nclaude setup-token            # prints a token for CLAUDE_CODE_OAUTH_TOKEN\nexport CLAUDE_CODE_OAUTH_TOKEN=\"...\"   # or save it to ~/.claude_code_oauth_token\n```\n\naugur reads `CLAUDE_CODE_OAUTH_TOKEN` (env or `~/.claude_code_oauth_token`) and injects it\ninto the container/VM. `ANTHROPIC_API_KEY` takes priority if both are set.\n\n**GitHub CLI:**\n\n```bash\nbrew install gh\ngh auth login\n```\n\n`gh` credentials are shared automatically in both modes (token injected via `GH_TOKEN`;\nthe host's `~/.config/gh` is mounted read-only so the guest can't rewrite it).\n\n---\n\n## Testing \u0026 CI\n\naugur's tests are split by what each layer can prove on a free runner, and by which bugs\neach layer actually catches.\n\n```bash\nmake unit           # Swift build/test + shellcheck + version smoke              (CI: macos-26)\nmake offline-tests  # seam + command-construction shell tiers (shimmed engine)   (CI: ubuntu)\nmake container-e2e  # LOCAL egress FAIL-CLOSED proof on Apple Container (macOS 26+)\nmake e2e            # LOCAL pre-release gate: macOS VM boot + xcodebuild test (never in CI)\n```\n\nThe shell test tiers live in `tests/` and run via `tests/run.sh` (see `tests/README.md`);\neach live tier self-skips when its prerequisites are absent, so the same command is safe in\nCI, the Linux dev container, and on a Mac.\n\n### Continuous integration (`.github/workflows/ci.yml`)\n\nCI runs on **free GitHub-hosted runners only**, and **no CI job boots a VZ guest**:\n\n| Job | Runner | What it proves |\n|-----|--------|----------------|\n| `build-unit` | `macos-26` | `swift build`/`swift test` the CLIs (`augur-vm` builds, `augur-proxy` builds + tests), `shellcheck`, and a side-effect-free `augur version` smoke. No engine, no VM. |\n| `offline-tests` | `ubuntu-latest` | The seam + command-construction tiers: drive the real `cmd_up`/`cmd_claude` against a `container` shim and assert the built argv is byte-identical to the seam's declaration. No engine/VM needed. |\n\nBoth jobs are **secrets-zero** — the coding agent is never authenticated in CI. So\n`pull_request` runs from forks are safe: there is nothing to exfiltrate.\n\n**Why the live E2Es are *not* in CI.** GitHub's arm64 macOS runners are themselves\nVirtualization.framework guests with **no nested virtualization** (confirmed by GitHub; the\nrequest to enable it was closed as not planned). So anything that boots a VM/microVM — the\nmacOS VM mode or Apple Container mode — **cannot run on any GitHub-hosted runner** (standard\n*or* larger). A bigger runner gives more cores/RAM, not nesting. Those heavy paths — the\nApple Container egress fail-closed proof (`make container-e2e`) and the macOS VM E2E (`make\ne2e`) — are gated locally instead.\n\n### Pre-release gate (`make e2e`, local only)\n\nBefore tagging a release, run the macOS-VM E2E on a real Mac:\n\n```bash\n# from your project directory (boots the VM; verifies mount + testmanagerd + egress fail-closed)\nmake -C /path/to/augur e2e\n# add a real in-VM build:\nAUGUR_E2E_PROJECT=/path/to/app AUGUR_E2E_SCHEME=App make -C /path/to/augur e2e\n```\n\nThis boots the macOS VM, checks the **virtiofs** workspace mount and **testmanagerd**\nreachability, optionally runs **`xcodebuild test`** inside the VM, and re-proves the\n**egress fail-closed** guarantee for the VM datapath (the macOS-VM variant of the\n`container-e2e` assertions). It's local-only for the nested-virtualization reason above, and\nbecause it needs Apple-signed IPSW/XIP that can't live in CI.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh1d3mun3%2Faugur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh1d3mun3%2Faugur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh1d3mun3%2Faugur/lists"}