CLI Reference
On this page
Overview
Canopy uses cargo xtask for project automation. All commands are defined in xtask/src/cmd/ and run via:
cargo xtask <command> [flags]
dev — Devstack Management
Manages the Docker Compose development environment (per ADR-005 deployment profiles).
dev start
Start the local development environment.
cargo xtask dev start [--shared-db] [--profile <name>]
| Flag | Description |
|---|---|
|
Use a single PostgreSQL instance for all databases (saves resources) |
|
Deployment profile: |
Runs the staleness guard to detect changes since last start. Creates SHA-256 markers in .devstack/ for source, dependencies, Dockerfile, compose, migrations, and seed data.
dev reload
Rebuild changed services and restart. Preserves data volumes.
cargo xtask dev reload [--shared-db] [--profile <name>]
dev restart
Wipe all data and start completely fresh (equivalent to clean + start --no-cache).
cargo xtask dev restart [--shared-db] [--profile <name>]
dev refresh
Auto-detect what changed and perform the minimum rebuild/restart. Uses the staleness guard to compare SHA-256 markers against current state:
-
Source changes (.rs files) → rebuild affected services
-
Dependency changes (Cargo.lock) → full rebuild
-
Dockerfile changes → rebuild images
-
Docker Compose changes → recreate containers
-
Migration changes → restart services (migrations run on startup)
-
Seed data changes → re-seed databases
cargo xtask dev refresh
test — Test Suite
Runs format check, clippy, and cargo-nextest (capped at 8 threads to avoid devstack saturation).
cargo xtask test [--unit] [--integration] [--no-refresh]
| Flag | Description |
|---|---|
|
Run only unit tests (lib + bin tests, no devstack required) |
|
Run only integration tests ( |
|
Skip automatic devstack refresh before integration tests |
Without flags, runs both unit and integration tests. Integration tests use infrastructure_available() guard — skips gracefully when devstack is down (unless CANOPY_CI=true, then panics).
e2e — End-to-End Tests
Runs Playwright E2E tests against the running devstack. The bare, unfiltered
invocation is the blocking pre-push battery (#1386): it defaults to the
full devstack profile, requires the test-clock build (probed before the
suite), and fail-loud-verifies the journey lane afterwards (>0 executed,
0 skipped, fresh walkthrough artifacts — see
Testing).
Any trailing Playwright filter or --devstack-profile snap-only marks the
run as targeted and skips the gate.
cargo xtask e2e [--no-refresh] [--devstack-profile full|snap-only] [--visual] [--capture] [-- <playwright-args>]
| Flag | Description |
|---|---|
|
Skip automatic devstack refresh before E2E tests |
|
Compose profile to bring up/target; |
|
Pin the generative seed dataset for reproduction |
|
Define the on-demand vb-* visual-baseline capture projects |
|
Define the opt-in screenshot/capture projects ( |
|
Extra arguments forwarded to Playwright (e.g., |
Examples:
cargo xtask e2e # The blocking battery (full profile + test-clock) cargo xtask e2e -- --headed # Targeted: visible browser (gate skipped) cargo xtask e2e -- --grep "dashboard" # Targeted: only matching tests cargo xtask e2e --no-refresh --capture -- --project demo-review # capture sweep
validate — Pre-Push Validation
Comprehensive validation run by the pre-push hook. Checks everything needed before code reaches CI.
cargo xtask validate [--skip-docker] [--timing]
| Flag | Description |
|---|---|
|
Skip Docker build validation (faster, used when only docs change) |
|
Print per-step timing breakdown for debugging slow runs |
Steps (in order):
-
Repository visibility check (must be public)
-
Commit signing configuration check
-
Mandatory docs check (Tier 3 files exist and are non-empty)
-
SPDX header check on
.rsfiles -
cargo deny check(advisories + licenses + bans) -
cargo fmt --check -
cargo clippy --profile test(shares compilation cache with nextest) -
cargo nextest run(8 threads) -
Docker build validation (unless
--skip-docker)
check-docs — Tier 1 Doc Integrity
Verifies that Tier 1 (universal) docs match the upstream template by comparing SHA-256 hashes.
cargo xtask check-docs [--fix [--yes]]
| Flag | Description |
|---|---|
|
Download and overwrite drifted Tier 1 docs from the template. Shows a diff summary. |
|
Skip confirmation prompt when using |
Template source: gitlab.com/gadhs/templates/claude-quickstart — synced .claude/rules/ digests + docs/modules/standards/ pages (see .claude/sync-manifest.toml).
seed — Database Seeding
Seeds the devstack databases with deterministic test data for development and E2E testing.
cargo xtask seed [--seed <number>] [--households <count>] [--jurisdiction <name>]
| Flag | Default | Description |
|---|---|---|
|
(random) |
RNG seed for deterministic output |
|
9 |
Number of households to generate |
|
|
Jurisdiction name (must match a directory under |
api-docs — OpenAPI Snapshot Diffing
Fetches OpenAPI JSON from all running services and compares against committed snapshots.
cargo xtask api-docs [--update]
Fetches from http://localhost:{port}/api-doc/openapi.json for each of the 11 API services. Reports path count differences, schema changes, and new/removed endpoints.
With --update: overwrites snapshots in test-results/openapi/ to accept current specs.
gen-signing-keys — ECDSA Key Generation
Generates an ECDSA P-256 signing key pair for determination signing (ADR-002).
cargo xtask gen-signing-keys --program <name> [--output-dir <path>]
| Flag | Default | Description |
|---|---|---|
|
(required) |
Program name: |
|
|
Output directory for PEM files |
Produces two files:
* {output-dir}/{program}-private.pem — PKCS#8 private key (set as CANOPY_{PROGRAM}__SIGNING_KEY)
* {output-dir}/{program}-public.pem — SPKI public key (set as CANOPY_VERIFY_KEY_{PROGRAM})
perf — Performance Testing
Runs k6 performance tests against the devstack.
cargo xtask perf [--profile <type>] [--service <name>] [--save-baseline <name>]
| Flag | Default | Description |
|---|---|---|
|
|
Test profile: |
|
(all) |
Target a specific service |
|
— |
Save results as a named baseline for comparison |
init — Project Initialization
Initialize a new project from the claude-quickstart template. Used once during initial project setup.
cargo xtask init --name <project-name> --group <gitlab-group> --owner <username> [--security-contact <email>]
Not used in day-to-day development.