Use cloacina-compiler Locally
This guide shows how to use the cloacinactl package commands to
check, validate, and pack .cloacina archives on your laptop or in
CI, without running the long-lived cloacina-compiler service. This
is the path most developers want for iterating on a workflow before
deploying it.
The key fact: a
.cloacinaarchive is a source archive (tar + bzip2). The shared library is compiled server-side by thecloacina-compilerservice after upload — nothing you build locally ships in the archive. Localpackage buildis purely a catch-errors-early compile check.
- Rust toolchain (stable) for Rust packages; nothing extra for Python packages.
cloacinactlon yourPATH.- A package source tree in the canonical shape — scaffold one with
cloacinactl package new(see Creating Your First Package). Rust packages need no[lib] crate-type, nopackagedfeature, and nobuild.rs: the compiler service injects the build wiring.
cd path/to/my-workflow
# 1. (Rust only) Compile check — catches errors before upload.
cloacinactl package build .
# 2. Validate the source tree against the canonical package format.
cloacinactl package validate .
# 3. Pack the source + manifest into a .cloacina archive.
cloacinactl package pack .
package validate also accepts a packed archive
(cloacinactl package validate ./my-workflow.cloacina), so you can
smoke-test the artifact you’re about to upload.
cloacinactl package build <DIR> [--release]
A thin wrapper over cargo build run in <DIR>. For Python packages
([metadata].language = "python" or inferred) it is a no-op — there
is nothing to compile locally.
This step is optional: the server-side compiler performs the real build. Running it locally just means you find compile errors on your laptop instead of in the server’s build queue.
Common failure modes:
package.tomlmissing → the language probe errors before invoking cargo.- Dependencies still reference
cloacina(the full crate) instead of the slim packaged pair (cloacina-workflow+cloacina-workflow-plugin) → slow builds and a bloated artifact. See Migrating to Service Mode.
cloacinactl package validate <DIR | ARCHIVE>
Checks the source tree (or archive) against the canonical package
format without uploading: manifest schema, Python workflow/ module
layout, rejected legacy keys (package_type, [[metadata.triggers]]),
and common footguns.
cloacinactl package pack <DIR> [--out <PATH>] [--sign <KEY>]
Validates, then packs the source tree into a .cloacina archive
(tar + bzip2, manifest resolved to its full form). Build output, VCS
dirs, and prior archives are excluded automatically.
# Default output: <DIR>/<name>.cloacina
cloacinactl package pack .
# Custom output path
cloacinactl package pack . --out /tmp/my-workflow-1.0.0.cloacina
--signfails hard. Workflow-package signing is not implemented (tracked under I-0103): passing--signmakespackage pack(andpackage publish) exit non-zero with an error telling you to remove the flag. Do not script around it — there is currently no way to produce a signed workflow package from the CLI, even though the server can require signatures (--require-signatures). See Package Signing for the current state.
The packed archive is the artifact you upload to the server
(package upload) or drop into a daemon’s watch directory.
When you want build + pack + upload in a single command:
cloacinactl package publish . \
--release \
--tenant acme \
--server https://cloacina.example.com \
--api-key env:CLOACINA_API_KEY
Equivalent to running package build, package pack, and
package upload in sequence. Useful in deploy scripts. (Remember the
upload only becomes runnable once a cloacina-compiler service builds
it — see below.)
The compiler service is not optional for running Rust packages: an
uploaded Rust package sits at build_status = pending until a
cloacina-compiler process polling the same database claims and
builds it. What’s local-optional is only the pre-upload authoring
loop above.
Run the service (locally or in your deployment) when:
- You want an uploaded Rust package to actually load and execute.
- Multiple authors submit packages and you want centralized, reproducible builds.
- You want to enforce build-time policy (vendored dependencies, resource limits, timeouts).
cloacinactl compiler start --database-url "$DATABASE_URL"
Python packages skip the compiler entirely — the server imports them directly at reconcile time.
See Run cloacina-compiler in Production for the service-side deployment posture: threat model, vendor curation, resource limits, audit-event reference.
- Creating Your First Package — scaffold → validate → pack → upload from zero.
- Migrating to Service Mode — converting an embedded workflow crate to the packaged shape.
package!()Macro Reference — what the compiled plugin actually exports.- Reconciler Pipeline — what happens when a package is loaded.
- CLI Reference — full
cloacinactl packageflag list. - Compiler Deployment Runbook — running
cloacina-compileras a service.