Plan before mutation.
Every run computes a reviewable plan from the manifest.plan is non-mutating; mutation requires exact confirmation and crosses the same identity, provider, and ledger boundaries.
$ hostwright plan∙ reading hostwright.yaml∙ validating manifest … ok∙ computing plan (non-mutating) project: api-local + create service/api ghcr.io/example/api:latest + create service/redis redis:7 ~ map ports 8080→8080, 6379→6379 plan: 2 to create, 1 to configure, 0 to destroy ✓ no changes applied. review, then applyApple container is a runtime. Local stacks still need a control plane.
Apple container gives the Mac a native container runtime: lightweight Linux VMs, an OCI image flow, and a command surface built for Apple silicon.
Running a multi-service stack requires more than starting containers: declared state, validation, health checks, restart policy, drift detection between declared and observed state, and ownership-checked cleanup.
Hostwright is that layer. It targets a single Mac first; the same identity, fencing, recovery, and policy model is designed to extend across Macs.
What Hostwright does
Current capabilities of the CLI and daemon.
Declares services in hostwright.yaml
An explicit Manifest v2 subset describes local desired state; legacy v1/versionless input has a deterministic migration preview.
Plans changes before mutation
Plans are deterministic and reviewable; live mutation remains bound to exact confirmation, identity, provider, and state gates.
Routes operations through a RuntimeAdapter
Apple container observation and narrow lifecycle calls cross one typed boundary; no other code path reaches the runtime.
Tracks local state
SQLite schema v7 records desired/observed state, events, operations, ownership UUIDs, provider binding, fencing, and recovery.
Detects drift
Typed deterministic drift and plan actions compare declared and observed state without guessing unsupported runtime shapes.
Runs doctor checks
Runs safe local checks for OS, architecture, Swift, manifest presence, and `container` executable lookup.
Treats destruction as explicit
Cleanup is dry-run first and token-confirmed, limited to exact owned eligible containers. Broad garbage collection is not implemented.
The CLI
hostwright init
hostwright capabilities --json
hostwright migrate preview hostwright.yaml
hostwright validate
hostwright plan
hostwright status --state-db /tmp/hostwright.sqlite
hostwright doctorhostwright up
hostwright down --dry-run
hostwright cluster statusThe command surface is still in design. These are the intended shapes. Commands marked Planned are scheduled on the roadmap.
Architecture
Hostwright owns versioned intent, UUID identity, SQLite ledgers, planning, policy, and recovery state. Apple container owns execution. The Runtime Provider API is the only mutation boundary.
Declare a stack in one file
version: 2
project: api-local
services:
api:
image: ghcr.io/example/api:latest
ports:
- "8080:8080"
env:
APP_ENV: development
health:
command: ["curl", "-f", "http://localhost:8080/health"]
interval: 10s
restart:
policy: on-failure
redis:
image: redis:7
ports:
- "6379:6379"Safety model
Defaults are conservative and mutation is always explicit.
Plan before mutation
Runtime changes are computed and reviewable before they run.
Dry-run for cleanup
Cleanup previews exact identity and eligibility before a separately confirmed owned-resource deletion.
Explicit destructive confirmation
Removing real resources requires an intentional, confirmed action.
Conservative validation
Unsafe or ambiguous manifests are refused, not guessed at.
No hidden runtime mutation
Mutation exists only behind explicit plan/cleanup confirmation and the typed, recorded provider path.
Ownership-tracked cleanup
Cleanup can touch only resources Hostwright can prove it owns; unmanaged resources are never inferred from names.
No secret leakage in logs
Secrets and credentials are kept out of events and log output.

