CLI Reference
cloacinactl is the command-line interface for Cloacina. It manages
local services (daemon, server, compiler), talks to the HTTP API as a
client, and edits the local config file at ~/.cloacina/config.toml.
The command shape is a strict noun-verb pattern, with a handful of
top-level singletons (status, config, admin, completions).
cloacinactl [GLOBAL FLAGS] <noun> <verb> [ARGS]
cloacinactl [GLOBAL FLAGS] <singleton> [ARGS]
These flags apply to every subcommand.
| Flag | Default | Description |
|---|---|---|
-v, --verbose |
false |
Enable debug-level logging on stderr. |
--home <PATH> |
~/.cloacina |
Override the Cloacina home directory. Affects all home-relative paths (config, logs, packages, sockets, PID files, bootstrap key). |
--profile <NAME> |
(default profile from config) | Select a named profile from ~/.cloacina/config.toml. Resolves the server URL and API key. |
--server <URL> |
(from profile) | Override the profile’s server URL. Highest precedence among server-targeting flags. |
--api-key <KEY> |
(from profile) | Override the profile’s API key. Supports the API key schemes below. |
--tenant <NAME> |
public |
Tenant name for tenant-scoped commands. Defaults to the admin “public” schema if unset. |
--json |
false |
Shorthand for -o json. |
-o, --output <FORMAT> |
table |
Output format: table, json, yaml, or id. |
--no-color |
false |
Disable ANSI colors in table output. |
--api-key and the api_key profile field accept several schemes:
| Scheme | Example | Behavior |
|---|---|---|
| Raw | clk_a1b2c3... |
The literal API key. |
env:VAR |
env:CLOACINA_API_KEY |
Read the key from the named environment variable. Errors if the variable is unset or empty. |
file:PATH |
file:/etc/cloacina/key |
Read the first non-empty line of the file. Whitespace is trimmed. |
keyring:NAME |
keyring:prod |
Reserved for v1.1; rejected today with a clear error message. |
| Format | Behavior |
|---|---|
table (default) |
Human-readable aligned columns. Long strings are truncated with …. Respects --no-color. Auto-infers columns from the first object’s keys; not ideal for deeply-nested resources. |
json |
Pretty-printed JSON, one document per response. |
yaml |
YAML output, one document per response. |
id |
One ID per line. Extracts the id or name field from each object. Useful in shell pipelines: cloacinactl execution list -o id | xargs -n1 cloacinactl execution status. |
cloacinactl uses a fixed mapping (per ADR-0003 §6) so scripts can
distinguish failure modes:
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
User error: bad flags, missing files, validation failure, local I/O failure. |
2 |
Network/transport failure: unreachable daemon socket, HTTP connection refused. |
3 |
Resource not found (HTTP 404). |
4 |
Authentication failure (HTTP 401/403). |
5 |
Server-side rejection (HTTP 4xx/5xx other than 404/401/403). |
| Variable | Used By | Description |
|---|---|---|
DATABASE_URL |
server start, compiler start, admin cleanup-events |
PostgreSQL or SQLite connection URL. Overridden by the corresponding --database-url flag where applicable. |
CLOACINA_BOOTSTRAP_KEY |
server start |
Pre-supplied bootstrap admin key. If unset and no keys exist, one is generated. Overridden by --bootstrap-key. |
CLOACINA_REQUIRE_SIGNATURES |
server start |
If true, the server enforces package signature verification at upload. Overridden by --require-signatures. |
RUST_LOG |
All commands | Log filter directive (e.g., info, debug, cloacina=debug). Overridden by -v / --verbose. |
OTEL_EXPORTER_OTLP_ENDPOINT |
server start |
If set, enables OpenTelemetry tracing to the named gRPC collector. |
OTEL_SERVICE_NAME |
server start |
Service name in OpenTelemetry spans. Default: cloacina. |
CLOACINA_VAR_<NAME> |
Workflow context | Read by cloaca.var("NAME") in Python; the CLOACINA_VAR_ prefix is mandatory. |
These commands manage local services. They exec long-running binaries in the foreground or stop them via PID file.
The daemon is a lightweight local scheduler. It watches directories for
.cloacina packages, runs the reconciler, and registers cron + custom-poll
trigger schedules. State lives in ~/.cloacina/cloacina.db (SQLite, WAL
mode). The daemon does not expose an HTTP API; it exposes a Unix-domain
health socket at ~/.cloacina/daemon.sock.
cloacinactl daemon start [--watch-dir <DIR>]... [--poll-interval <MS>]
| Flag | Default | Description |
|---|---|---|
--watch-dir <DIR> |
(none) | Additional package directory to watch. Repeatable. The default watch dir (~/.cloacina/packages/) is always included; CLI dirs and config dirs are merged and deduplicated. |
--poll-interval <MS> |
500 |
Reconciler fallback poll interval in milliseconds. The filesystem watcher provides immediate detection; this is the safety net. |
Behavior:
- Creates
~/.cloacina/{packages,logs}/if missing. - Sets up dual logging: stderr (human-readable) +
~/.cloacina/logs/cloacina.log(JSON, daily rotation). - Opens or creates
~/.cloacina/cloacina.db(SQLite, WAL mode). - Loads
~/.cloacina/config.tomlif present. - Builds the merged watch-directory set (default + CLI + config).
- Initializes a
DefaultRunner(cron + trigger schedulers, intervals from config). - Initializes a
FilesystemWorkflowRegistryacross all watch dirs. - Performs an initial reconciliation (loads existing packages).
- Starts the health socket at
~/.cloacina/daemon.sock. - Enters the event loop: filesystem changes (debounced) trigger reconciliation;
--poll-intervalis the periodic fallback.
Signals:
| Signal | Behavior |
|---|---|
| SIGINT (Ctrl-C) | Graceful shutdown. Drains in-flight workflows up to daemon.shutdown_timeout_s. Exit 0. |
| SIGTERM | Same as SIGINT. |
| SIGHUP | Reload config.toml, update watch directories, trigger reconciliation. No restart. |
| Second SIGINT during shutdown | Force immediate exit. Exit 1. |
cloacinactl daemon stop [--force]
Reads the daemon’s PID file and sends SIGTERM (or SIGKILL with
--force). Exit 0 if stopped cleanly; exit 2 if the PID file is
missing or the process is unreachable.
cloacinactl daemon status
Connects to ~/.cloacina/daemon.sock and prints a status table:
health, uptime, packages loaded, last reconciliation. Respects
--no-color.
cloacinactl daemon health
Terse health probe via the Unix socket at ~/.cloacina/daemon.sock
(or <home>/daemon.sock if --home is set). No output. Exit 0 if
up, 2 otherwise. Use this in scripts and supervisor checks.
The HTTP API server (cloacina-server). Backed by PostgreSQL or
SQLite. Exposes the HTTP API
under the /v1/ prefix and the unauth probes /health, /ready,
/metrics.
cloacinactl server start [--bind <ADDR>] [--database-url <URL>]
[--bootstrap-key <KEY>] [--require-signatures]
[--reconcile-interval-s <N>]
| Flag | Env Var | Default | Description |
|---|---|---|---|
--bind <ADDR> |
127.0.0.1:8080 |
Listen address. | |
--database-url <URL> |
DATABASE_URL |
(required) | Database connection URL. Examples: sqlite:///path/to/cloacina.db, postgres://user:pass@host/dbname. |
--bootstrap-key <KEY> |
CLOACINA_BOOTSTRAP_KEY |
(auto-generated) | Pre-supplied admin key for first startup. If a key is generated, the plaintext is written to ~/.cloacina/bootstrap-key with 0600 perms exactly once. |
--require-signatures |
CLOACINA_REQUIRE_SIGNATURES |
false |
Enforce package signature verification at upload time. |
This subcommand was renamed from serve in an earlier release; older
docs may still mention the old name. Reconciler poll interval and
similar runtime-tuning knobs are not exposed as CLI flags on
cloacinactl server start; they’re hard-coded to safe defaults at
the wrapper layer. If you need to tune them, invoke the underlying
cloacina-server binary directly with the appropriate arguments.
Same shape as the daemon equivalents, but use the server’s PID file
and HTTP-based status (GET /v1/health/status) and health (GET /health) probes instead of a Unix socket.
The compilation service (cloacina-compiler). Polls the database for
pending package builds and produces signed .cloacina archives.
cloacinactl compiler start [--bind <ADDR>] [--database-url <URL>]
[--poll-interval-ms <N>]
[--heartbeat-interval-s <N>]
[--stale-threshold-s <N>]
[--sweep-interval-s <N>]
| Flag | Default | Description |
|---|---|---|
--bind <ADDR> |
127.0.0.1:9000 |
Listen address. |
--database-url <URL> |
from DATABASE_URL |
Connection URL (Postgres or SQLite). |
--poll-interval-ms |
(binary default) | How often to poll for pending build rows. |
--heartbeat-interval-s |
(binary default) | Worker heartbeat cadence. |
--stale-threshold-s |
(binary default) | Seconds before an in-flight build is considered stale and reclaimable. |
--sweep-interval-s |
(binary default) | How often to sweep for stale claims. |
stop / status / health follow the same pattern as server: PID
file for stop, HTTP GET /v1/status for status, HTTP GET /health
for health.
These commands talk to a running cloacina-server over HTTP. They
respect the global --profile / --server / --api-key /
--tenant flags. All require authentication except where noted.
Runs cargo build in <DIR> (must contain a Cargo.toml and
package.toml). With --release, builds the release profile.
Local-only; does not contact the server. Exits 1 on missing files or
build failure.
Calls fidius_core::package::pack_package() to produce a .cloacina
archive. The --sign <KEY> flag is accepted but currently ignored
— detached signature side-car generation is not implemented in the CLI
yet (the side-car infrastructure exists in
cloacina::security::package_signer, the wiring is pending).
build → pack → upload in one shot.
POSTs a .cloacina archive to /v1/tenants/<tenant>/workflows.
Requires --api-key + --server. Server-side signature verification
is enforced if the server was started with --require-signatures.
Exit codes: 1 (user error), 2 (network), 4 (auth), 5 (server reject).
GET /v1/packages. The --filter is applied client-side as a
substring match on the package name.
GET /v1/packages/<id>. Prints a single object respecting
--output.
DELETE /v1/packages/<id>. Interactive confirmation unless
--force.
| Command | HTTP Endpoint | Notes |
|---|---|---|
workflow list [--package <FILTER>] |
GET /v1/tenants/<tenant>/workflows |
Client-side --package substring filter on the package name. |
workflow inspect <NAME> |
GET /v1/tenants/<tenant>/workflows/<name> |
Full workflow metadata: tasks, dependencies, trigger rules, schedules. |
workflow run <NAME> [--context <SOURCE>] |
POST /v1/tenants/<tenant>/workflows/<name>/execute |
--context accepts a path to a JSON file or - for stdin. Defaults to {}. JSON is validated before submission. Prints the execution ID. |
| Command | HTTP Endpoint | Notes |
|---|---|---|
execution list [--workflow <F>] [--status <S>] [--limit <N>] |
GET /v1/tenants/<tenant>/executions?... |
Default limit: 50. |
execution status <ID> |
GET /v1/tenants/<tenant>/executions/<id> |
Returns Pending / Running / Completed / Failed / Cancelled / Paused. |
execution events <ID> [--since <DURATION>] |
GET /v1/tenants/<tenant>/executions/<id>/events?since=<dur> |
--follow is not yet implemented — the flag exists for forward compatibility and currently returns exit 1. |
Per CLOACI-S-0011, graph is the unit of scheduling; reactor is a node inside the graph.
| Command | HTTP Endpoint | Notes |
|---|---|---|
graph list |
GET /v1/health/graphs |
Lists loaded computation graphs with health + reactor pause state. |
graph status <NAME> |
GET /v1/health/graphs/<name> |
Single graph’s health + accumulators + reactor pause state. |
graph accumulators |
GET /v1/health/accumulators |
Lists all accumulators across all graphs. |
Requires an admin-role key.
| Command | HTTP Endpoint | Notes |
|---|---|---|
tenant create <NAME> [--description <STR>] |
POST /v1/tenants |
Creates a new Postgres schema (per-tenant). The schema’s password is never returned — it’s set during provisioning and not surfaced. |
tenant list |
GET /v1/tenants |
Lists tenant schema names. |
tenant delete <NAME> [--force] |
DELETE /v1/tenants/<name> |
Drops the schema. Interactive confirmation unless --force. Note: the server’s TenantDatabaseCache does not evict on delete; restart cloacina-server to reclaim the connection pool. |
| Command | HTTP Endpoint | Notes |
|---|---|---|
key create <NAME> [--role <ROLE>] |
POST /v1/auth/keys (or /v1/tenants/<tenant>/keys if tenant-scoped) |
Roles: admin, write, read. Default read. The plaintext key is shown exactly once. Save it; it cannot be retrieved later. |
key list |
GET /v1/auth/keys |
Returns metadata only (ID, name, role, created_at, last_used_at). No hashes, no plaintext. |
key revoke <ID> [--force] |
DELETE /v1/auth/keys/<id> |
Revokes the key. The server clears its entire auth cache on revoke (not just the revoked key) so revocation is immediate; subsequent requests re-validate against the database. |
| Command | HTTP Endpoint | Notes |
|---|---|---|
trigger list |
GET /v1/tenants/<tenant>/triggers |
Combined cron + custom-poll trigger schedules. |
trigger inspect <NAME> |
GET /v1/tenants/<tenant>/triggers/<name> |
Single trigger metadata + recent executions. |
cloacinactl status
Composite probe: runs daemon status, server status, and
compiler status independently and prints a combined table. Each
probe failure is surfaced individually without affecting the others.
Manage the local config file at ~/.cloacina/config.toml.
Dotted-path key access. set preserves types: integers stay
integers, booleans stay booleans, arrays accept comma-separated
values. The config file is created on first set if missing.
cloacinactl config profile set <NAME> --api-key <KEY> --server <URL> [--default]
cloacinactl config profile list
cloacinactl config profile use <NAME>
cloacinactl config profile delete <NAME>
Profiles live under [profiles.<name>]. The default_profile field
selects which profile is used when --profile is not supplied. See
Profile resolution.
Deletes execution event records older than the threshold. Duration
format: combine d / h / m / s (e.g., 90d, 7d12h,
1d2h30m45s). Case-insensitive. Must be greater than zero. Defaults
to 90d.
--dry-run reports what would be deleted without deleting.
cloacinactl completions <SHELL>
Emits a shell-completion script to stdout. Supported shells: bash,
zsh, fish, powershell. Pipe to your shell’s completion
directory or source it from your rcfile.
Located at ~/.cloacina/config.toml (or <home>/config.toml if
--home is set). Optional; all fields have defaults. The parser
rejects unknown fields to catch typos early.
# Top-level
# Database URL for commands that need it (admin, server start).
database_url = "sqlite:///path/to/cloacina.db"
# Named server-targeting profile selected when --profile is not supplied.
default_profile = "prod"
# Per-profile server-targeting blocks.
[profiles.prod]
server = "https://api.example.com"
api_key = "env:CLOACINA_API_KEY" # or "raw-key", "file:/path"
[profiles.staging]
server = "https://staging.example.com"
api_key = "file:/etc/cloacina/staging-key"
# Daemon settings.
[daemon]
poll_interval_ms = 500 # Reconciler fallback interval
log_level = "info" # trace / debug / info / warn / error
shutdown_timeout_s = 30 # Graceful drain timeout
watcher_debounce_ms = 500 # Filesystem watcher debounce
trigger_poll_interval_ms = 1000 # Custom-poll trigger base interval
# cron_max_catchup = 100 # Max cron catchup executions; omit for unlimited
cron_recovery_interval_s = 300 # Cron recovery sweeper cadence
cron_lost_threshold_min = 10 # Lost-task threshold before reclaim
# Compiler settings (used by `compiler status` / `compiler health` probes).
[compiler]
local_addr = "127.0.0.1:9000"
# Additional package directories for the daemon (~ expansion supported).
[watch]
directories = ["~/my-workflows", "/opt/cloacina/packages"]
Per ADR-0003 §3, server-targeting flags resolve in this order (highest precedence first):
- Explicit
--server/--api-keyflags on the command line. - The named profile from
--profile <name>. - The default profile from
default_profile. - Error: “no server/key configured.”
Within a profile, the API key is decoded by scheme (raw / env: /
file: / keyring:). See API Key Schemes.
The ~/.cloacina/ directory (configurable via --home) holds:
~/.cloacina/
├── config.toml # Configuration file
├── cloacina.db # SQLite database (daemon mode)
├── bootstrap-key # Server bootstrap admin key, mode 0600 (server mode)
├── daemon.sock # Daemon health probe (Unix domain socket)
├── daemon.pid # Daemon PID file (used by `daemon stop` / `health`)
├── server.pid # Server PID file
├── compiler.pid # Compiler PID file
├── packages/ # Default daemon watch directory
│ └── *.cloacina # Discovered packages
└── logs/
├── cloacina.log # Daemon logs (JSON, daily rotation)
└── cloacina-server.log # Server logs (JSON, daily rotation)
- HTTP API Reference — endpoints exposed by
cloacinactl server start. - Configuration Reference —
DefaultRunnerConfigbuilder details. - Environment Variables Reference — full env var list.
- Cron Scheduling Architecture — how the daemon processes cron schedules.
- Reconciler Pipeline — what the daemon’s reconciler does after detecting a new package.