If you are building an agent orchestrator, the hardest decision is where to draw the line between the kernel and the capabilities it hosts. We drew it aggressively. In Animus v0.5 we deleted the in-tree workflow runner, every bundled provider adapter, and all fallback queue paths. Then v0.5.3 pulled out the OAI runner and dropped another crate, shrinking the Rust workspace from 17 crates to 12. What replaced all that code is a language-agnostic JSON-RPC protocol, a cosign keyless signing pipeline, and an animus.toml dependency model that lets any team ship a first-class plugin without forking Rust. Here is what changed, and how you can use it.
Why the monolith had to go
Before v0.5, the Animus daemon shipped with a built-in workflow runner (workflow-runner-v2), in-tree subject adapters, queue handlers, store modules, and a bundled agent-runner sidecar. The kernel was policy and mechanism in one box. That made swapping an LLM provider or changing an issue tracker as hard as patching the core.
The v0.5 release removed roughly 14,000 lines of workflow runner code and another 1,055 lines of in-tree fallback paths. The cleanup did not stop there. v0.5.3 extracted the oai-runner sidecar (5,483 lines) and deleted the orchestrator-git-ops crate (1,472 lines), bringing the workspace down to 12 crates. The team performed 120 review passes across the v0.5 arc, spun up 18 standalone plugin repositories, and added 443 plugin-side tests.
Today the kernel owns only scheduling, plugin lifecycle, control-plane routing, signing, and state-directory conventions. Every policy decision, which LLM provider, which issue backend, which durability store, lives in an isolated, installable plugin. The team calls this the "Linux distro model applied to AI agent orchestration." The kernel is small, stable, and unopinionated. Curated "flavors," bundles of plugins and packs, sit on top and can be swapped without touching the core.
What the wire contract looks like
Plugins are not Rust crates linked into the daemon. They are standalone child processes that speak newline-delimited JSON-RPC 2.0 over stdin and stdout. Stderr is reserved for human diagnostics and is never parsed by the host.
The host spawns a plugin, optionally requesting its manifest via --manifest. The plugin prints its metadata and exits, or enters a five-phase lifecycle: initialize, initialized, steady state, shutdown, exit. During initialize the host advertises its protocol version and capabilities; the plugin replies with its own. Hosts enforce major-version compatibility, so a v1.1.0 plugin can talk to a v1.0.0 host, but a v2.x plugin cannot.
Error codes reuse standard JSON-RPC 2.0 ranges for parse and method errors, and add Animus-specific codes in the -32000 band for plugin_not_initialized, method_not_supported, request_cancelled, and timeout.
Plugin kinds declare the method family the host will call. A provider plugin handles agent/run, agent/resume, and agent/cancel. A subject_backend plugin implements subject/list, subject/get, subject/update, and so on. As of v1.1.0 the protocol also recognizes workflow_runner, queue, durable_store, and memory_store kinds.
Manifests, signing, and lockfiles
Plugins are discovered from ~/.animus/plugins.yaml, project-local binaries, the global install directory, $ANIMUS_PLUGIN_PATH, and optionally $PATH. The host probes each candidate with --manifest, parsing name, version, kind, protocol version, capabilities, and required environment variables.
Security is built on cosign keyless verification against the Sigstore stack. There is no baked-in public key. Trust anchors on the signer identity embedded in the per-signing Fulcio certificate. For launchapp-dev/* releases the identity regex is pinned to the GitHub Actions workflow that produced the artifact, and the OIDC issuer is https://token.actions.githubusercontent.com.
Install policy defaults to Warn so existing workflows do not break during the migration, and Strict is available for teams that want hard failure on missing or untrusted signatures. Every install records the artifact SHA256 and an optional signature-bundle SHA256 in plugins.lock. The animus plugin lock verify command re-hashes installed binaries and reports mismatches, preventing silent replacement.
The Cargo moment for plugins
Pre-v0.6, plugin intent was scattered across flavors/default.toml, default-install.json, plugins.yaml, and plugins.lock. v0.6 collapses this into a two-file pattern familiar from Cargo and npm.
animus.toml is the hand-edited manifest of intent. It declares the kernel version range, required plugins, packs, and local path overrides. animus.lock is generated and authoritative. It records exact versions, source provenance, and per-target archive SHA256s. Platform-aware locking means a lock generated on macOS carries hashes for every published platform, so a Linux container can install from the same lock and verify integrity without re-downloading.
A "flavor" is simply a curated starter animus.toml. Teams can fork a flavor, add a private provider plugin, and pin it in the lock, all without forking the kernel.
First-class plugins in any language
Because compatibility is defined by the NDJSON-RPC wire shapes, not by Rust crate linkage, a plugin can be written in Python, TypeScript, Go, or any language that can read stdin and write stdout. The spec authors explicitly state: "A Python or TypeScript plugin that conforms to spec.md is a first-class Animus plugin."
Plugins can be installed from public GitHub releases with automatic keyless verification, from a local path for internal development, or from a direct HTTPS URL with an expected SHA256. The host never loads third-party code as a dynamic library. Every plugin runs in its own isolated child process with a cleared environment and only a small base allowlist of variables, plus anything declared in its manifest.
To keep quality high, the animus-plugin-testkit repository provides a conformance harness that runs the exact scenarios the official CI runs. Provider plugins are exercised against mock CLIs. Subject, transport, trigger, and log-storage backends are validated against handshakes, CRUD round-trips, watch streams, and schema health checks. Plugin authors can run the same suite locally before publishing, with no network or API keys required.
What to do next
The move from monolith to SDK is not a refactor. It is a protocol bet. By shrinking the kernel to the invariant parts and expressing every policy capability as an isolated, versioned, signed, stdio-speaking plugin, Animus becomes an extensible orchestration substrate.
If you are currently maintaining a fork to swap LLM providers or patch queue behavior, stop. Write a plugin instead. Read the Animus protocol spec, grab the conformance testkit, and ship your first provider or backend in whatever language your team already knows. If you are evaluating Animus for production, start pinning dependencies with animus.toml and enable Strict cosign verification. Your future upgrades will be smaller, safer, and fully under your control.