Self-hosted Linux hardware-in-the-loop test runner for the embassy-mcxa
HAL (and any future embassy chip wired into the lab).
Named after Paavo Nurmi — Olympic distance runner — a fit for a test runner whose nightly job is hours-long stability soaks.
cargo install --git https://github.com/felipebalbi/paavo paavo-cli
export PAAVO_HOST=http://lab.local:8080
paavo-cli new my-dma-test --board-kind mcxa266
cd my-dma-test
$EDITOR src/main.rs
paavo-cli run . --board-kind mcxa266 --timeout 30m(Windows developers: same cargo install works. See manual-smoke.nu
for a self-contained dev loop driven by PAAVO_FAKE_RUNNER=1; no
hardware required.)
See docs/deployment.md and
contrib/README.md.
Both server binaries share the same config file format and default location:
| Source | Path |
|---|---|
| Default | /etc/paavo/paavo.toml |
| Environment | PAAVO_CONFIG |
| CLI flag | --config <path> |
For production deployments, place your config at /etc/paavo/paavo.toml and
no flags are needed. For local development, pass --config sample-paavo.toml
explicitly.
See sample-paavo.toml for an annotated example with
all available options.
The CLI resolves the daemon URL in this order:
--hostflagPAAVO_HOSTenvironment variable~/.config/paavo/cli.toml(XDG-compliant; respectsXDG_CONFIG_HOME)- Default:
http://127.0.0.1:8080
The cli.toml file is minimal:
host = "http://your-paavod-server:8090"paavo-cli new scaffolds a test crate from a template tree. The source can
be a git URL or a local directory and is auto-detected. It resolves in this
order:
--templates <url-or-path>flagPAAVO_TEMPLATESenvironment variable- Default:
https://github.com/felipebalbi/paavo(the canonical repo)
So the quick-start one-liner works with no checkout — new clones the
templates for you. The template for a board kind is read from
<source>/<subdir>/<board-kind>/, where <subdir> defaults to templates.
# Default: clone the canonical repo (no checkout needed).
paavo-cli new my-dma-test --board-kind mcxa266
# Working inside a paavo checkout, against your local template edits:
paavo-cli new my-dma-test --board-kind mcxa266 --templates .
# A fork, pinned to a release tag (a tag or commit SHA):
paavo-cli new my-dma-test --board-kind mcxa266 \
--templates https://github.com/acme/paavo-fork --templates-rev v1.2.0The legacy --templates-path flag still works as an alias for --templates,
but now names the tree root (use --templates-subdir . if it points
directly at a templates directory).
Paavo supports automatic nightly (or any cron schedule) test runs via configuration — there is no CLI command or API for creating schedules.
Configure scheduled runs in paavo.toml:
[scheduler]
# 6-field cron: sec min hour dom mon dow
nightly_cron = "0 0 19 * * *" # every day at 19:00:00
[[corpus]]
name = "embassy-mcxa-regression"
kind = "mcxa266"
path = "/srv/paavo/test-crates/embassy-mcxa"
cargo_update = ["embassy-mcxa", "embassy-executor"]When the cron fires, paavod walks each [[corpus]] directory, tars every
test crate it finds, and submits them as Scheduled priority jobs. The
cargo_update field (optional) specifies which dependencies to
cargo update -p <name> before building, ensuring nightly runs test against
the latest upstream.
Multiple [[corpus]] entries are supported for different board kinds or
test suites.
- Full design:
docs/superpowers/specs/2026-06-09-paavo-test-runner-design.md - Implementation plan:
docs/superpowers/plans/2026-06-09-paavo-implementation.md - HW smoke checklist for releases:
docs/hw-smoke-checklist.md
Dual-licensed under MIT or Apache-2.0 at your option.