No description
  • Rust 73.4%
  • TypeScript 25.3%
  • Shell 0.6%
  • Dockerfile 0.2%
  • PLpgSQL 0.2%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-18 19:48:47 +00:00
.anima The AI gate ships no review instructions: WI-221's stub / unbuildable / concurrency checks were orphaned by the anima-ai retirement 2026-08-01 23:18:26 +00:00
.claude chore(skills): vendor the babysit-anima skill into the repo 2026-08-15 14:09:28 +02:00
.design-sync chore: design-sync setup — anima-pwa Violet Void → claude.ai/design 2026-07-11 11:41:45 +02:00
.forgejo build: stop publishing anima-runner, and pin the short-sha length (WI-558) 2026-08-15 10:12:36 +02:00
.solstice ci: disable cargo incremental so sccache can actually cache 2026-08-11 21:40:59 +02:00
anima-pwa feat: dependency edge API surface — gRPC, MCP tools, PWA codegen (WI-485) 2026-08-16 10:48:07 +02:00
crates chore: drop the runner's .anima-owner worktree tag from the branch 2026-08-18 12:13:34 +02:00
deploy build: one script for the runner image, and keep :latest current (WI-558) 2026-08-15 11:37:36 +02:00
docs Merge pull request 'WI 1 (SPIKE, gates the rest) — hypervisor pick + refraction-forger rootfs with sccache inside' (#433) from claude/wi-019f9079-wi-1-spike-gates-the-rest-hypervisor-pic into main 2026-08-18 19:48:47 +00:00
images/anima-runner-vm docs(design): WI 1 spike — Firecracker-via-vm-manager verdict + refraction-forger rootfs recipe 2026-07-29 14:28:18 +00:00
node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709 Quick-reply dedup — options render as bullets AND chips 2026-08-01 16:39:15 +00:00
proto/anima/v1 feat: dependency edge API surface — gRPC, MCP tools, PWA codegen (WI-485) 2026-08-16 10:48:07 +02:00
scripts mark_implementation_complete advances working → testing without checking the AI gate, so every item skips review and strands unmergeable in the merge queue 2026-08-16 19:10:36 +02:00
.dockerignore feat: add multi-stage Dockerfile and docker-compose for all services 2026-04-12 18:06:47 +02:00
.gitignore Reject never reaches the implementer: lingering reviewer session + tick-order race burn both review rounds on an unchanged diff 2026-07-28 13:00:13 +02:00
Cargo.lock Merge pull request 'Add one shared OTLP observability initializer for Anima services' (#542) from claude/wi-019fe0f2-add-one-shared-otlp-observability-initia into main 2026-08-11 09:24:27 +00:00
Cargo.toml fix(cargo): point repository at the canonical forge 2026-08-14 10:00:56 +00:00
CONTEXT.md docs: amend ADR 0034 with cancelled_drain, the fifteenth TurnOutcome 2026-08-14 10:31:26 +02:00
DEPLOY_NOTES.md Migration 086 cannot run under sqlx; index the superseded_by_id FK permanently 2026-07-31 22:03:01 +00:00
docker-compose.runner.yml Lane quota detection uses a total-turn timeout, so it kills healthy long turns: 13 work items parked as "produced no durable output" while their transcripts show 40+ tool calls 2026-08-16 11:16:15 +02:00
docker-compose.yml chore: bump version to 0.1.1, add bootstrap password to Helm chart 2026-04-14 21:41:19 +02:00
Dockerfile Multi-arch images: build anima-server + anima-runner for arm64 — Pi fleet schedulable 2026-07-11 09:52:41 +00:00
Dockerfile.runner build: one script for the runner image, and keep :latest current (WI-558) 2026-08-15 11:37:36 +02:00
IMPLEMENTATION_SUMMARY.md A fully-cleared exit bar does not advance the work item: the scheduler keeps re-dispatching implementation sessions until the item parks 2026-08-09 14:58:02 +00:00
LICENSE Initial commit 2026-04-11 20:17:06 +00:00
main.pen Update design and claude files 2026-06-27 11:18:03 +02:00
projectbrief.txt Create initial screens and brief 2026-04-11 22:17:42 +02:00
rca-d1-d2-agent-diff-pollution.md feat: Investigate: how did diagnostic-dump-only patches end up in WI.agent_diff for D1/D2? (019dd3b5) 2026-04-30 23:15:59 +00:00
README.md docs: a real README 2026-08-14 10:00:56 +00:00

Anima

Anima is a command centre for AI-driven software development. A human defines a unit of work precisely; AI coding agents implement it as tightly-scoped vertical slices. The quality comes from the plan, not from the implementer's exploration.

It is not a chat wrapper and not an autonomous "do my project" agent. It is the scheduling, review and bookkeeping layer around agent sessions: what gets dispatched, to which agent, with what prompt, under what budget, and what has to be true before the work moves on.

  • Licence: MPL-2.0
  • Canonical repository: https://code.aopc.cloud/toasterson/Anima
  • Status: v0.1.1, pre-release and self-hosted. First commit 11 April 2026; ~1300 commits since. Anima runs its own development — most merges in the log are agent sessions dispatched by the system on its own repository.

The model

Six nouns carry the whole system. They are defined once, in CONTEXT.md, and the code uses no synonyms for them.

Term Meaning
Plan The human-defined intent and its decomposition. The Define-side anchor.
Slice The 1:1 execution wrapper for a Plan; the operator's monitoring surface.
Work Item One small vertical slice of implementation — a thin path through the layers. Carries its own forcing prompt.
Workflow A reusable ordered set of Phases, attached to the Define side, the Implement side, or both.
Phase One step in a Workflow, carrying the prompt that drives it.
Phase kind Who acts: Agent (an ACP session, consumes a slot), Human (opens a thread message and waits), Machine (triggers CI).

Three design decisions are worth calling out, because they are what make the loop safe to leave running:

Forcing prompts. A Work Item is not handed to an agent as a title. It carries a prompt assembled from the Plan plus the Phase's own prompt, so the agent's context is constructed rather than discovered. anima-ai is the assembler.

Graph versioning. A Work Item is pinned on entry to an immutable revision of the phase graph. Rewiring a workflow never moves in-flight items — they finish on their version, new items start on the current one. This is what lets an operator edit the flow while work is running, and what lets per-(item, phase) counters survive the rewire.

Bounded redispatch. Phases have exit bars and a loop guard, so an item that cannot pass its own gate strands visibly instead of burning tokens in a cycle. Agent lanes carry quotas; a lane that is failing is backed off rather than probed.

The reasoning behind these is recorded as 37 ADRs in docs/adr/, starting at 0001 — plan/slice one-to-one.

Agents are pluggable — Anima is not tied to a vendor

Agent sessions are hosted over the Agent Client Protocol (ACP) on stdio, one subprocess per slot. The executors are configuration, not code: claude-code, gemini-cli, codex, opencode and ollama-cloud lanes are all driven through the same path, and the runner never spawns containers of its own — the server assigns work to advertised slots.

The separate anima-ai service, used for prompt assembly and summarisation rather than for coding, addresses three configurable tiers (MINIMAL, STANDARD, REASONING), each with its own base URL, key and model name. Pointing a tier at a local or self-hosted endpoint is an environment variable, not a patch.

Architecture

A Rust workspace of twelve crates, a gRPC/Protobuf API, PostgreSQL, and a React PWA speaking Connect-Web to the same schema.

Crate Role
anima-core Domain types, auth, RBAC, the diff gate
anima-proto Generated types for 27 .proto service and message files
anima-db SQLx repositories and 100 ordered migrations
anima-server The gRPC service surface, plus an MCP endpoint exposing Anima's own tool catalogue
anima-ai Forcing-prompt assembly and the tiered model client
anima-runner Static stateful ACP runner; advertises slots, hosts agent subprocesses over stdio
anima-forgejo Forgejo REST client — pull requests and repository metadata
anima-git A VcsClient trait with a shell-out git implementation
anima-solstice Dispatch and log retrieval against the Solstice CI system
anima-mq RabbitMQ topology for the execution and streaming fabrics
anima-bridge Diagnostic CLI for inspecting work item state
anima-anthropic Thin Messages API client. Not a workspace member — present in-tree, unwired.

Cross-cutting: tokio, tonic 0.13 for gRPC and gRPC-Web, sqlx 0.8 against PostgreSQL 18, lapin for AMQP, axum, and OpenTelemetry 0.31 for OTLP traces and metrics. The PWA is React 19 with @connectrpc/connect-query, TanStack Query, Tailwind and Vite, tested with Vitest and Testing Library.

Running the development stack

docker compose up --build postgres anima-server

That brings up PostgreSQL 18 — migrations run on server start — and anima-server, with gRPC on 50051 and the MCP endpoint on 50054.

Known gap: docker-compose.yml also declares anima-ai and anima-mail, and neither builds. The current multi-stage Dockerfile defines only anima-server and anima-runner targets, and there is no anima-mail crate in the tree at all — mailbox support lives inside anima-core, anima-db and anima-server rather than in a separate service. Name the services explicitly, as above, to skip both. anima-ai is a normal workspace member and builds with cargo build -p anima-ai.

The compose file ships development-only defaults (BOOTSTRAP_ADMIN_PASSWORD: admin, literal service tokens, postgres://anima:anima@postgres/anima). Change all of them before exposing anything. The model tiers need MINIMAL_API_URL / MINIMAL_API_KEY and their STANDARD_ and REASONING_ counterparts in the environment.

The runner is deliberately not in that compose file. It is a long-lived process that dials out to the server's RunnerService and needs the agent CLIs on its own PATH — see Dockerfile.runner and docker-compose.runner.yml. The PWA in anima-pwa/ is a normal Vite app (npm install && npm run dev).

Licensing, dependencies and IP boundaries

  • Anima itself is MPL-2.0 (LICENSE) — file-level copyleft. You can link it into a larger work under other terms; modifications to Anima's own files stay MPL.
  • All dependencies are third-party upstream packages pulled from crates.io and npm at their published versions, under their own licences (predominantly MIT/Apache-2.0). None are vendored-and-modified; Cargo.lock and package-lock.json pin the exact set.
  • No proprietary code, datasets or model weights are included, and none are required to build. Anima trains nothing and ships no weights.
  • Model providers are external services reached over their public APIs. Anima holds no provider credentials of its own; keys are supplied by the operator through the environment. ACP agents (claude-code, gemini-cli, codex, opencode) are separately installed third-party programs under their own licences and terms — Anima executes them, does not redistribute them, and does not depend on any single one.
  • Anima's own outputs — plans, prompts, work items, generated diffs — belong to the operator. Nothing is transmitted to the project's authors; there is no telemetry callback, and the OpenTelemetry exporter points wherever the operator configures it.