Skip to main content

Casals logo

Casals

General-purpose canister lifecycle orchestrator for the Internet Computer — built for managed multi-tenant IC deployments with shared upgrade governance.

Casals is fully on-chain: the conductor is a canister that creates, upgrades, snapshots, and rolls back other canisters by calling the IC management canister directly. Sheets, WASM catalog, cycles policy, and audit history all live in Casals' stable state — there is no off-chain worker in the deploy path. The CLI and frontend are thin clients that submit update calls; execution and rollback logic run inside the conductor.

Any project can operate its own Casals conductor to manage a canister fleet. Realms GOS is the reference consumer — it deploys Casals per network and drives rollouts from consumer-side fleet config. Casals also powers provisioning on the gos.earth GOS-as-a-Service platform.

Casals lets a project create, upgrade, roll back, and retire its canisters under that coordinator — organized into sections, stands, and canisters. Governance is pluggable: each section delegates to one or more commanders (principals or external governance canisters). Casals provides the structure and executes approved actions; it never embeds voting logic inside the conductor.

Live demo — https://igz53-6qaaa-aaaao-bbapa-cai.icp0.io

Design rationale — docs/philosophy (why orchestra / sections / stands / conductor / baton)


Model

Term Meaning
Section A logical group of stands with a shared role (e.g. "Application", "Infra").
Stand A logical unit inside a section — typically one deployed application instance.
Canister An actual canister. Stands contain one or more canisters.
Conductor The Casals orchestrator canister — controller of managed canisters; runs all lifecycle calls on-chain.
Commander A principal authorized by a section or stand to perform scoped lifecycle actions.
Baton / Multisig Optional orchestration canisters (in packages/orchestration/) for managed upgrades and committee approval on target canisters.

Key features

  • Lifecycle — create, chunked install/upgrade, snapshot, module_hash verification, all-or-nothing rollback across a stand.
  • Sheets — declare a whole orchestra in one JSON document; deploy_sheet idempotently brings it to life.
  • Canister pool — reuses existing canisters before creating new ones (creation is expensive).
  • Cycles management — native treasury, per-section/stand/canister policy, optional on-chain autopilot, or an off-chain monitor (casals-monitor) that polls balances, runs auto top-ups, and serves the Cycles UI without burning conductor cycles on hourly samplers.
  • Authorized WASMs — ships with hello-world templates (Motoko, Rust, Basilisk, certified-assets frontend) plus orchestration templates (Baton, multisig); more added via governed list.
  • Commanders & permissions — multiple commanders per section/stand; granular permission keys for create, upgrade, subnet whitelist, and shell access.
  • Frontend — SvelteKit + Internet Identity (1-week delegation, no idle logout): Orchestra tree, Commanders, Orchestration consoles, sheet editor, cycles dashboard, WASM catalog, settings. Open the ☰ menu (top-left) for app navigation.

Off-chain cycle monitor

For production deployments, cycle observation and auto top-ups can run in casals-monitor instead of on-chain timers.

Use the hosted monitor (no account; your conductor's settings are the credential):

  1. In Settings → Cycle operations, choose Off-chain monitor, paste the service base URL (https://casals.realmsgos.dev or https://service.ic-casals.tech) under Hosted monitor service and click Use this service. Casals reads the service's principal from GET /v1/service and fills in Monitor service URL (<base>/v1/<this conductor's canister id>) and Monitor principal.
  2. Save. Casals stores monitor_enabled / monitor_principal / monitor_service_url on-chain, grants the monitor read access to managed canisters (Sync controllers), then calls POST /v1/instances on the service, which verifies those settings and starts polling. The Hosted monitor status card shows state (active / consent revoked / unreachable), last poll and cadence; Register / check status re-runs the registration.
  3. To leave, switch back to On-chain (or change the principal) and save: the service stops auto top-ups at its next pass and disables the instance after 24 h. Nothing else is needed.

A self-hosted casals-monitor works the same way; its host must be added to connect-src in frontend/static/.ic-assets.json5, or you fill the two fields by hand.

This disables on-chain balance sampling and autopilot on the conductor (cycles_sampling: false, cycles_autopilot: false) while the monitor paymaster tops up from the same Casals treasury. Optional Alert emails in Settings notify operators when the treasury cannot fund a top-up or when the monitor sees consent withdrawn.

For scripted wiring, see scripts/examples/wire_monitor.py (JSON config with monitor_url, monitor_principal, casals_backend, casals_frontend).


Toolchain

  • icp-cli for build & deploy (icp.yaml); dfx is not used.
  • Basilisk + ic-basilisk-toolkit for the backend.
  • casals-wasms — the WASM store: a certified-assets canister (chunked batch upload, on-chain sha256, pinned directories) that casals up creates and seeds; every install streams from it — and every frontend asset bundle (docs/BUNDLES.md). Upload from the CLI (casals up) or from the browser on /files.

Quick start

pip install ic-basilisk-toolkit
icp network start -e local          # terminal 1 — keep replica running

python3 -m casals_cli.main -e local up seed/sheets/demo.json --yes   # bootstrap + build the demo orchestra

casals up <sheet> is the day-one deploy path: it validates the sheet, builds and deploys the conductor and the casals-wasms store, uploads the referenced WASMs into it, and builds what the sheet declares (set_sheet → plan → apply). From then on the orchestra is operated imperatively — the UI, casals upgrade, create_stand, upgrade_to, … — with no on-chain reconciliation loop (issue #52).

Open http://casals_frontend.local.localhost:8000/ — log in with Internet Identity using a principal listed on Commanders (or a Casals controller).

After code changes: re-run casals up (it rebuilds the conductor WASM when sources changed).

Mainnet:

python3 -m casals_cli.main -e ic --identity casals up <sheet> --yes

CLI

Install the casals command:

pip install ic-casals

Run from your project directory (where icp.yaml lives):

casals status                                      # version + object counts
casals tree                                        # Section → Stand → Canister tree
casals events                                      # audit log
casals wasms                                       # authorized WASM catalog
casals bundle dist/ -o app-1.2.0.tgz               # pack a frontend build into a hashed bundle (docs/BUNDLES.md)
casals up sheet.json --yes                         # day one: build the orchestra the sheet declares
casals upgrade sheet.json --wasm my-backend        # release: move every canister running that family to the pinned build
casals upgrade sheet.json --content my-frontend    # release: every frontend with that content serves the pinned bundle
casals cycles                                      # treasury + per-canister balances
casals pool                                        # canister pool
casals export sheet.json                           # the sheet the conductor was built from + bindings
casals new [-y]                                    # build, deploy, and seed (fresh canisters)
casals new ids.json [-y]                           # deploy with existing canister IDs
casals new -e ic --identity casals ids.json        # mainnet upgrade from ID map

casals -e ic --identity casals status              # mainnet, explicit identity

All output is JSON. Errors go to stderr as {"ok": false, "error": "..."} with exit code 1.

Without installing, the same commands are available via:

python3 scripts/casals.py status
make cli ARGS="status"

API

JSON-in / JSON-out text endpoints. Returns {"ok": true, …} or {"ok": false, "error": "…"}.

Kind Method Purpose
query get_tree full Section→Stand→Canister tree
query get_sheet / list_pool stored day-one sheet + canister pool
query get_cycle_history balance samples over time
query list_permissions assignable commander permission keys
query list_backend_controllers Casals canister IC controllers (for Commanders UI)
update create_section / create_stand / create_canister structure
update propose_upgrade / sync_content imperative release of a baton-governed member / a frontend bundle
update set_commander / set_permissions commander principals + permission grants
update upgrade_to stand/canister upgrade with snapshot rollback
update add_authorized_wasm / remove_authorized_wasm WASM catalog
update top_up / reconcile / set_cycle_policy cycles management
update sync_controllers add monitor co-controller on managed canisters

Full endpoint list: AGENTS.md.


About the name

Named after Pablo Casals — cellist and conductor. This project coordinates canisters the way a conductor coordinates an orchestra.


Disclaimer

This software is not production-ready. Do not deploy to mainnet or use with real canisters, cycles, or governance authority you cannot afford to lose.

Casals is in early development (alpha). It may contain bugs, breaking changes, and unknown security vulnerabilities. It has not undergone an independent security audit. Use at your own risk.

  • Not recommended for production deployments on the Internet Computer
  • No guarantee of correctness, availability, or security
  • APIs and behavior may change without notice

License

MIT — see LICENSE.

Release files for ic-casals 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ic-casals 0.2.0
File Size Uploaded
ic_casals-0.2.0.tar.gz 89.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ic-casals 0.2.0
File Interpreter ABI Platform
ic_casals-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 183.9 kB

Release files / ic_casals-0.2.0.tar.gz

Download URL ic_casals-0.2.0.tar.gz
Size 89.2 kB
Tags Source
SHA-256 checksum
How to use checksums
8a54bfce89d420a0123967945f2e4e70ee1aafe3a1b4b9761512c32370402e35
BLAKE2b-256 checksum
How to use checksums
ca8ec1b1f28adda42845e8ae65d3365e02e711668e36443c5df0f566d70661e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / ic_casals-0.2.0-py3-none-any.whl

Download URL ic_casals-0.2.0-py3-none-any.whl
Size 94.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a26d245dd0480e733fbba1ef8e83d8c3af16992206d9ed91894e36d81fe2f55
BLAKE2b-256 checksum
How to use checksums
ba2f3db861a76da2289229fe752a7b8e67ebd62413fe7138b441e9e89c75271f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page