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.
just check
cargo build --workspaceQuickstart (no cluster)
Use the polychrome CLI to start and stop a local stack without a Kubernetes cluster.
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 turndoctor 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.
# 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-planeUse 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.
| Setting | Purpose |
|---|---|
POLYCHROME_WHATSAPP_APP_SECRET | Verify webhook POST signatures; missing configuration returns 503. |
POLYCHROME_WHATSAPP_VERIFY_TOKEN | Verify Meta's GET subscription handshake; missing configuration returns 503. |
POLYCHROME_WHATSAPP_ACCESS_TOKEN | Authorize outbound Cloud API sends. |
POLYCHROME_WHATSAPP_PHONE_NUMBER_ID | Business 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_NAME | Approved 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.
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 variable | What it does |
|---|---|
POLYCHROME_MODEL | Model id; an empty value selects the stub provider |
POLYCHROME_PROVIDERS, POLYCHROME_OPENAI_BASE_URL | Comma-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_PREFLIGHT | Startup probe of the openai backend (tool calling and structured output): off / warn / strict |
POLYCHROME_SUMMARY_MODEL | Model used for anchored-iterative summarization |
POLYCHROME_HARNESS_ADDR | Shared-service harness address (http://host:port) |
POLYCHROME_PER_CONVERSATION_HARNESS | Resolve a harness pod per Conversation CR |
POLYCHROME_EVENTLOG_DIR | Commonware journal storage root |
POLYCHROME_LEASE_NAMESPACE | Enables cross-replica single-writer via a Lease |
POLYCHROME_APPROVAL_MODE | How 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.