Run and deploy

Run a local stack with polychrome doctor, init, and start, using a stub provider until you configure a model. Use the Kubernetes overlays for cluster deployments.

Prerequisites

Rust 1.97.1 (pinned via rust-toolchain.toml), protoc, and libprotobuf-dev. just check runs fmt, clippy, and the tests.

Shell
just check
cargo build --workspace

Quickstart (no cluster)

Use the polychrome CLI to start and stop a local stack without a Kubernetes cluster.

Shell
cargo build --release -p polyc-cli   # or: cargo install --path crates/cli
polychrome doctor                    # preflight: engine, free ports, disk, platform
polychrome init                      # write a config.toml pinned to this CLI version
polychrome start                     # bring the stack up, print the API URL
polychrome send <conv-id> "hello" --idempotency-key <key>   # safely retry one turn

doctor reports a next action for each failed check. start selects container mode when a container engine (container/docker/podman/nerdctl) is on PATH, otherwise native mode, which supervises host processes. Override this choice with --mode. With no model set, the stack runs a stub provider; set POLYCHROME_MODEL (plus provider config) as an environment variable before start to select a model provider. polychrome stop stops the local stack.

Run the control plane and harness directly

For debugging, run the control plane and harness directly. First start the state plane and set POLYCHROME_STATE_ADDR for the control plane. An HTTPS State endpoint also requires POLYCHROME_STATE_CLIENT_TLS_CA, POLYCHROME_STATE_CLIENT_TLS_CERT, and POLYCHROME_STATE_CLIENT_TLS_KEY. Without a reachable, configured state plane, the control plane does not become ready. See the configuration reference for State listener and certificate settings.

Shell
# harness — stub provider unless POLYCHROME_MODEL is set
POLYCHROME_HARNESS_ADDR=127.0.0.1:50053 \
POLYCHROME_SIDE_ADDR=127.0.0.1:8181 \
cargo run -p polyc-harness

# control plane — routes turns through the harness above
POLYCHROME_GRPC_ADDR=127.0.0.1:50052 \
POLYCHROME_SIDE_ADDR=127.0.0.1:8081 \
POLYCHROME_HARNESS_ADDR=http://127.0.0.1:50053 \
cargo run -p polyc-control-plane --bin polychrome-control-plane

Use the CLI to send a framed Connect request. crates/slack/tests/integration.rs provides a client example.

Run the WhatsApp edge

polychrome-whatsapp connects WhatsApp Business Cloud API webhooks to the control plane. Configure POLYCHROME_AGENT_ADDR and enroll the edge with POLYCHROME_EDGE_ID, POLYCHROME_EDGE_BEARER_KEY, and POLYCHROME_EDGE_SIGNING_KEY_HEX. Supply the Meta app secret, webhook verify token, and outbound access token through secret-backed environment variables.

SettingPurpose
POLYCHROME_WHATSAPP_APP_SECRETVerify webhook POST signatures; missing configuration returns 503.
POLYCHROME_WHATSAPP_VERIFY_TOKENVerify Meta's GET subscription handshake; missing configuration returns 503.
POLYCHROME_WHATSAPP_ACCESS_TOKENAuthorize outbound Cloud API sends.
POLYCHROME_WHATSAPP_PHONE_NUMBER_IDBusiness phone number id for outbound messages. Both this and the access token are needed for replies; otherwise the edge is receive-only.
POLYCHROME_WHATSAPP_TEMPLATE_NAMEApproved template for sends outside the 24-hour window. Optional language code and static body variables use the corresponding TEMPLATE_LANGUAGE_CODE and TEMPLATE_VARIABLES settings.

The default webhook listener is :8102; health and metrics use :8101. Route Meta's HTTPS callback to /whatsapp/webhook. The Kustomize component at manifests/components/edges/whatsapp is included by the k3s and gke overlays. Replace its placeholder credentials and configure the business phone number before use. See supported interactions and messaging limits.

Cluster

The k3s and gke overlays pull prebuilt public images from GHCR. For local-cluster, scripts/cluster.sh build-load builds images and loads them into the cluster's containerd. These paths do not require a Docker daemon.

Shell
scripts/cluster.sh up           # boot a Docker-free local cluster (Apple micro-VM / bare k3s)
scripts/cluster.sh build-load   # build the images, straight into the cluster's containerd

polychrome install --overlay local-cluster   # Apple micro-VM (macOS) / bare k3s (Linux)
polychrome install --overlay k3s             # self-hosted k3s — Docker-free (GHCR images)
polychrome install --overlay gke             # GKE Autopilot or Standard (Regional PD)

Run install on a new cluster. It installs the CRDs, tenancy namespace, and Agent catalog in addition to the overlay. Use up to reapply an overlay after installation; it omits those prerequisites.

The k3s overlay uses k3s's bundled containerd and network-policy support. To manage a remote k3s cluster, your machine needs kubectl and the CLI. On macOS, run k3s in a Linux VM with limactl start template://k3s or colima start --kubernetes.

For local-cluster, scripts/cluster.sh up starts k3s through Apple's container runtime on macOS. This requires Apple silicon and macOS 26. On Linux, the script starts k3s directly on the host. The CLI recognizes polychrome-apple* and polychrome-linux* context names. The overlays select storage classes for the state-plane journal and control-plane persistent volumes. manifests/README.md documents the cloud service account's workload-identity binding.

Configuration

Polychrome settings generally use the POLYCHROME_ prefix. Configure a managed provider or a self-hosted chat-completions-compatible endpoint through the LlmProvider interface. Common settings include:

Environment variableWhat it does
POLYCHROME_MODELModel id; an empty value selects the stub provider
POLYCHROME_PROVIDERS, POLYCHROME_OPENAI_BASE_URLComma-separated provider backends in preference order. The harness selects the first that initializes successfully. Set POLYCHROME_PROVIDERS=openai with POLYCHROME_OPENAI_BASE_URL=http://host:port/v1 to point at a self-hosted, chat-completions-compatible backend
POLYCHROME_PREFLIGHTStartup probe of the openai backend (tool calling and structured output): off / warn / strict
POLYCHROME_SUMMARY_MODELModel used for anchored-iterative summarization
POLYCHROME_HARNESS_ADDRShared-service harness address (http://host:port)
POLYCHROME_PER_CONVERSATION_HARNESSResolve a harness pod per Conversation CR
POLYCHROME_EVENTLOG_DIRCommonware journal storage root
POLYCHROME_LEASE_NAMESPACEEnables cross-replica single-writer via a Lease
POLYCHROME_APPROVAL_MODEHow a gated call is resolved: human (default), reviewer (review eligible calls for automatic approval), or approve-all-dangerous (verification rigs only)

Observability works the same way in every binary: OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_SERVICE_NAME enable the OTLP exporter, and RUST_LOG / RUST_LOG_FORMAT tune the tracing subscriber.