Daemon
hostwrightd is a foreground development loop. It is not an installed
launch agent, background service, privileged helper, or unattended mutation
engine, and it runs only when you start it:
hostwrightd --foreground --config hostwright.yaml --state-db /tmp/hostwright.sqliteRequired: --foreground, --config <path>, --state-db <path>. Optional:
| Flag | Default | Purpose |
|---|---|---|
--interval <seconds> |
30 | Base reconciliation cadence. |
--jitter <seconds> |
5 | Deterministic jitter cap. |
--max-backoff <seconds> |
300 | Repeated-error backoff cap. |
--max-iterations <count> |
— | Stop after a bounded number of iterations. |
--lock-file <path> |
<state-db>.hostwrightd.lock |
Single-instance lock. |
No default config path, state path, or user-global daemon location exists.
Loop contract
Section titled “Loop contract”Each iteration:
- Reads and validates the explicit manifest path.
- Maps the manifest into desired runtime state.
- Observes runtime state through the RuntimeAdapter.
- Runs bounded in-process loopback health checks for configured running
services (the allowlisted
curl/wget/true/falseprobe shapes — see the manifest reference). - Persists health results and restart policy state.
- Computes a deterministic plan with restart-state blocking.
- Persists desired/observed snapshots, a daemon operation record, and events.
- Sleeps according to cadence, jitter, and backoff.
Failed iterations persist a failed operation and a daemon.reconcile.failed
event with a redacted diagnostic code — they never claim a snapshot was
recorded.
Recorded events include daemon.started, daemon.reconcile.succeeded,
daemon.reconcile.failed, daemon.backoff, daemon.sleep_wake_resumed,
daemon.stopped, health.check.*, and restart.policy.state — all readable
with hostwright events.
Locking and shutdown
Section titled “Locking and shutdown”A non-blocking single-instance file lock is taken before state is opened or migrated; if another instance holds it, the new process exits before running the loop. SIGINT and SIGTERM request shutdown, checked between iterations and during sleep.
Sleep/wake
Section titled “Sleep/wake”Sleep/wake is treated as a scheduler event: a wake-aware clock reports that
sleep resumed, the daemon records daemon.sleep_wake_resumed, and continues.
No macOS power notifications or launchd keepalive are installed.
Current limitations and owners
Section titled “Current limitations and owners”Launch agent installation, installers, privileged helpers, default state paths, unattended runtime mutation, aggressive crash-loop enforcement, broad lifecycle management, and image/volume cleanup are not implemented today. Trusted installation/defaults belong to Phase 02, lifecycle to Phase 04, and autonomous daemon/recovery/finalizers/GC to Phase 08. Unmanaged cleanup remains permanently prohibited. See Limitations.
