chit

Concepts

Agents, chits, and surfaces, and why manifests are static.

chit has a few layers and one rule: the manifest is the artifact, and a shared runtime executes it.

Agents

An agent is an invocable participant: Codex CLI, Claude CLI, or anything else reachable through an adapter. Agents live in a registry built from layered config (see Config layering below): the built-in codex and claude entries, plus the agents your global config (~/.config/chit/config.json) and the repo's chit.config.json define alongside them. The built-in ids cannot be redefined. A manifest never talks to a vendor directly; it names a participant, and the registry resolves it to an adapter.

Roles

A role is a reusable participant profile, defined in the roles section of the same config file: instructions (the persona), a session policy, permissions, and optionally a default agent. A participant can reference a role by name instead of spelling those fields out, and override any of them. A role with no default agent is model-agnostic: the chit that references it supplies the agent. Roles keep a shared persona and its governance in one place, so the same reviewer profile is declared once and reused across chits instead of copied into each one.

Recipes

A recipe is a named reference to a manifest you have vetted, defined in the recipes section of the same config file. It carries a mode (only converge today), a manifestPath pointing at the manifest, and optional runtime defaults: maxIterations, callTimeoutMs, and a description. That is the whole surface. A recipe never redeclares participants, prompts, checks, or approval policy; all of that stays in the manifest it points at. Recipes are references, not a second place to write routines.

Runs, plans, and batches can select recipes by id. A single chit_start recipe run resolves the recipe once at start and stamps what ran into the run receipts. Plans and batches add the approval gate: a dry run resolves the recipe to its manifest, content digest, participant summary, and default budgets, then binds that resolved surface into the approval hash. A later recipe, manifest, or agent/model change forces re-approval or pauses coordinated launch before a worker runs. Studio also shows recipes in the config drawer and shows the approved recipe plus bound manifest in a live run's topology.

Config layering

Config is read in layers. Later layers win:

  1. Built-ins - the codex and claude agents. Always present. No layer can redefine them.
  2. Global config - ~/.config/chit/config.json. Your agents, roles, and recipes, on your machine.
  3. Repo config - chit.config.json at the repo root (the git top-level, or the working directory outside git). The project's agents, roles, and recipes, committed and shared with the repo.

A later layer replaces an agent, role, or recipe by id, whole. There is no field merging: the effective definition is exactly one file's definition. chit doctor reports which layer defined each agent and recipe, and which config files were read.

Repo config is project input, not operator input, so it stays inside a trust boundary: env and strictMcp are rejected in chit.config.json with a hard error. Set those in the global config instead. A repo recipe's manifestPath must stay inside the repo: absolute paths and .. are rejected with a hard error. The global config may point a recipe anywhere on your machine.

The file lives at the repo root on purpose: visible, diffable, and reviewed like any other file in the repo.

Chits

A chit is a JSON manifest. It declares:

  • participants - named slots in the routine, each either inline over a registry agent or a reference to a named role, carrying instructions (its persona), a session policy, and permissions.
  • steps - a map of step id to a call (invoke a participant) or a format (a pure string template).
  • inputs and output - what flows in, and which step's output is the result.

Context flows through templates. A step that references steps.ask_codex.output depends on ask_codex; steps with no cross-reference run in parallel. The dependency graph is computed from the references, not declared by hand.

Surfaces

A surface exposes a chit to a caller: MCP tools (the primary surface, inside Claude Code), a CLI command, or a Claude Code skill. Each surface declares the capabilities it offers (can it render markdown, pass files, provide a stable scope). Install fails if a chit needs a capability the surface does not have. The same runtime backs every surface, so a chit behaves the same wherever it runs.

Static by design

Manifests are static DAGs. No loops, no conditionals, no dynamic routing. This is a choice, not a missing feature: a static graph is one you can read, diff, and check before it fires.

Iteration still happens, but it lives in an orchestrator on top of the runtime, never inside the manifest. The recurring "one agent implements, another reviews, repeat" loop runs in two modes:

  • Supervised - your Claude Code chat owns the loop and the human checkpoint; a chit reviewer checks each round.
  • Autonomous - a loop run drives both agents to convergence against a git worktree (MCP-native with chit_start then chit_next, or from a terminal with chit converge), and you inspect the result.

See supervised convergence and self-hosting for the loop in practice.

On this page