Host launcher
The host launcher is the Go binary at cmd/launcher in
kenaz-workbench. It
provisions and manages the sandbox substrate (Tart on macOS, WSL2 on
Windows), hosts the host-side sigild event daemon and ledger, and
exposes a minimal operator UI.
UI: localhost HTML page
Per ADR 0007,
the launcher UI is not a Wails native window. It is a static HTML page
served by the binary on 127.0.0.1:8181. When the launcher starts, it
binds the port and opens the page in the system browser automatically.
The page is a single-file HTML/CSS/JS bundle embedded into the binary via
go:embed. It calls a small set of JSON endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/api/sigild/status | GET | Orchestrator + ledger lifecycle state |
/api/workbench/status | GET | Substrate lifecycle state (closed / opening / open / closing) |
/api/workbench/open | POST | Provision the substrate, emit vm.spawn, spawn the in-guest workbench-app |
/api/workbench/close | POST | Tear down: emit vm.teardown, destroy the substrate |
/api/events | GET | Recent in-memory event log (ring buffer, last 200 entries) |
The HTTP server binds loopback-only (127.0.0.1). It refuses to bind to
any other interface — the orchestrator API has no authentication beyond
loopback ownership.
Session lifecycle
- User opens the launcher (double-click the binary, or
launcher gui). The launcher starts the HTTP server and opens the browser athttp://127.0.0.1:8181. - User clicks Open Workbench. The browser POSTs to
/api/workbench/open; the launcher responds202 Acceptedimmediately. - In the background the launcher:
- Constructs an
orchestrator.Orchestratorwith the per-OS substrate config (WSL or Tart). - Calls
orch.Start(ctx), which provisions the substrate if needed and emits avm.spawnevent to the host ledger. - Execs
whoamiinside the guest as a reachability probe. - Spawns
workbench-appinside the guest via the substrate exec channel (detached vianohup). On Windows, WSLg surfaces the resulting Wayland window. On macOS, Tart's built-in VNC viewer surfaces it.
- Constructs an
- The browser polls
/api/workbench/statusuntilstatebecomes"open". - User closes the workbench. The browser POSTs to
/api/workbench/close; the launcher callsorch.Stop, which emitsvm.teardownand destroys the substrate.
Subcommands
launcher [subcommand] [flags]
If no subcommand is given, the gui subcommand runs (same as
launcher gui).
| Subcommand | Purpose |
|---|---|
gui | Start the localhost HTML UI on 127.0.0.1:8181 (default) |
provision-exec-destroy | Provision a sandbox, exec whoami, destroy — smoke entrypoint used by scripts/smoke-macos.sh and scripts/smoke-windows.ps1 |
gui flags
| Flag | Default | Description |
|---|---|---|
--addr | 127.0.0.1:8181 | Bind address (must be loopback) |
--no-browser | false | Do not auto-open the system browser |
--name | kenaz-workbench (macOS) / kenaz-workbench-test (Windows) | Substrate name |
--image | ghcr.io/cirruslabs/ubuntu:24.04 | [macOS] Tart source image |
--tarball | out/kenaz-workbench.tar | [Windows] Rootfs tarball path |
--install-dir | <tmp>/kenaz-workbench-vhd | [Windows] WSL vhdx parent directory |
Makefile targets (development)
From the repo root:
# Build every Go module in the workspace
make build
# Run unit tests
make test
# Run go vet + gofmt check
make lint
# Smoke-test the substrate end-to-end (see scripts/ for the platform scripts)
make smoke
# macOS — build arm64 guest binaries, then bake the Tart image
make binaries-arm64
make image-macos
# Windows — build amd64 guest binaries, then build the WSL tarball
make binaries
make tarball
Data directories
All Kenaz products share the ~/.kenaz root (the Harness uses
~/.kenaz/harness/), so the launcher stores its data under
~/.kenaz/workbench/ — the same path on every platform:
| What | Path |
|---|---|
| Host ledger + keystore | ~/.kenaz/workbench/ |
| Cached guest images | ~/.kenaz/workbench/images/ |
The ledger file is ledger.db (SQLite). It is distinct from any
user-installed sigild data directory. If you ran an earlier build that used
a per-OS location (e.g. ~/Library/Application Support/kenaz-workbench/), the
launcher moves it under ~/.kenaz/workbench/ automatically on first run.