Skip to main content

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:

EndpointMethodPurpose
/api/sigild/statusGETOrchestrator + ledger lifecycle state
/api/workbench/statusGETSubstrate lifecycle state (closed / opening / open / closing)
/api/workbench/openPOSTProvision the substrate, emit vm.spawn, spawn the in-guest workbench-app
/api/workbench/closePOSTTear down: emit vm.teardown, destroy the substrate
/api/eventsGETRecent 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

  1. User opens the launcher (double-click the binary, or launcher gui). The launcher starts the HTTP server and opens the browser at http://127.0.0.1:8181.
  2. User clicks Open Workbench. The browser POSTs to /api/workbench/open; the launcher responds 202 Accepted immediately.
  3. In the background the launcher:
    • Constructs an orchestrator.Orchestrator with the per-OS substrate config (WSL or Tart).
    • Calls orch.Start(ctx), which provisions the substrate if needed and emits a vm.spawn event to the host ledger.
    • Execs whoami inside the guest as a reachability probe.
    • Spawns workbench-app inside the guest via the substrate exec channel (detached via nohup). On Windows, WSLg surfaces the resulting Wayland window. On macOS, Tart's built-in VNC viewer surfaces it.
  4. The browser polls /api/workbench/status until state becomes "open".
  5. User closes the workbench. The browser POSTs to /api/workbench/close; the launcher calls orch.Stop, which emits vm.teardown and destroys the substrate.

Subcommands

launcher [subcommand] [flags]

If no subcommand is given, the gui subcommand runs (same as launcher gui).

SubcommandPurpose
guiStart the localhost HTML UI on 127.0.0.1:8181 (default)
provision-exec-destroyProvision a sandbox, exec whoami, destroy — smoke entrypoint used by scripts/smoke-macos.sh and scripts/smoke-windows.ps1

gui flags

FlagDefaultDescription
--addr127.0.0.1:8181Bind address (must be loopback)
--no-browserfalseDo not auto-open the system browser
--namekenaz-workbench (macOS) / kenaz-workbench-test (Windows)Substrate name
--imageghcr.io/cirruslabs/ubuntu:24.04[macOS] Tart source image
--tarballout/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:

WhatPath
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.