Self-hosting
How chit develops chit, which mode to use, and the discipline that keeps autonomous runs honest
chit builds chit with its own loop. This is the operating guide: which mode to use, what the orchestrator still owns, and the discipline that keeps autonomous runs honest. The loop itself lives above chit (manifests are static DAGs and cannot loop); see supervised convergence for why.
The two modes
Both modes share one shape: an implementer writes a slice, a reviewer checks it, and a human checkpoints. They differ in who implements.
- Supervised. The Claude Code chat implements with its full tools and context; a per-scope Codex advisor reviews each round and inspects the git diff. The chat owns the loop and the checkpoint. Reach for this on nuanced, cross-package, or exploratory slices, where the chat's reasoning and live tools earn their keep.
- Autonomous (converge). The chat sets a task; chit runs both agents, looping to convergence (
examples/converge.json). Drive it MCP-native from the chat withchit_startthenchit_nextper iteration, or from a terminal withchit converge. The chat does not implement and does not babysit each handoff. Reach for this on well-scoped, self-contained slices, and to keep building the self-hosting habit.
The mode is a per-slice choice, not a default. When in doubt on a gnarly change, supervised produces cleaner results faster; on a tight, well-specified change, autonomous is the better demonstration and offloads the writing.
Roles are assigned in the chit, not fixed to a vendor
The autonomous loop is two roles, an implementer and a reviewer, declared as participants in the manifest. The bundled examples/converge.json pairs a write-capable Claude implementer with a read-only Codex reviewer, and that default is a good one (an independent model reviewing catches what a same-model check misses). But the pairing is not baked into the runtime: each participant names its own agent (claude or codex) and its own permissions.filesystem, and the implement / review steps call participants by name. Swap them and a write-capable Codex implements while a read-only Claude reviews. The permission you grant a participant, not its vendor, decides whether it can write; how that boundary is enforced depends on the vendor: a read_only Codex runs under an OS sandbox (--sandbox read-only), while a read_only Claude runs under --permission-mode plan, a permission boundary inside Claude rather than an OS sandbox. (The bundled manifest's role and output text reads in terms of "the implementer" and "the reviewer," so a swapped manifest produces correctly labeled output; update the prose only if you want vendor-specific wording.) The loop driver only requires that the steps are named implement and review, and that the reviewer emits the structured verdict block the manifest asks for.
The orchestrator's job (both modes)
The chat is always the orchestrator. It owns three things the loop does not:
- Sequencing and the human checkpoint. One slice at a time; stop and hand back on a
block, an ambiguous product decision, or anything outward-facing. - The final gates. The reviewer runs read-only and usually cannot even run the tests (its sandbox blocks the temp dirs the suite needs). So the orchestrator runs them itself, every slice, before merge: the full test suite, a live smoke of the real behavior, typecheck, the linter, the browser-safety check when core changed, and a scan for banned characters. A reviewer
proceedis necessary, not sufficient. - The push. Never push without explicit human permission, and only after the gates pass.
Treat the reviewer as an independent second opinion, not ground truth: verify each finding against the code before acting on it. Codex reviews (not a second Claude) precisely because an independent model catches what a same-model check misses.
Running an autonomous slice
-
Branch into a worktree so a wedged or abandoned run stays isolated.
-
Drive the loop. MCP-native from the chat (the primary path):
chit_startwith the task, scope, and the worktree ascwd, thenchit_nextonce per iteration, checkpointing between. Or from a terminal:chit converge --task "<the slice>" --scope <stable-id> --cwd <worktree>Either way it loops implement and check to the reviewer's verdict (
proceedconverges,blockstops, anything else revises and retries up to the budget, default 3; an unparseable verdict is treated asblock, never an implicit proceed). It records the loop under chit's state dir (keyed by repo, not in the working tree) and audits each iteration by default. -
Inspect what happened:
chit_trace(or read the loop log) lists each iteration'sauditRef. Open a transcript withchit_audit_showover MCP (pass thataudit_ref), or withchit audit show <run-id>from the terminal (the CLI takes the audit run id thatchit audit listprints). The transcript carries the prompts, outputs, live adapter events, usage, and the recorded per-participant config. -
Run the final gates yourself (see above). The reviewer could not.
-
Checkpoint with the human. Push only on explicit approval.
chit_start and chit_next drive the loop; chit_status and chit_trace inspect it, and chit_cancel stops it. The same two tools run a non-loop manifest as a one-shot DAG pass when you want a plain run rather than the implement/review loop.
Running unattended: jobs and batches
Foreground (one chit_next per iteration) keeps you in the loop on every round. When a slice is well-specified enough to leave alone, the same loop runs unattended:
- Background.
chit_startwithmode: "background"launches the loop in a detached worker against a git worktree and returns immediately. The worker survives an MCP reconnect. Check on it withchit_status, stop it withchit_cancel(intent-first: it records the cancel, then signals the worker), and read each iteration's receipt with the audit tools. One task, no babysitting. - Batch.
chit_batch_startruns several loop tasks in parallel, one git worktree per task, as background runs. (For a single unattended task, usechit_startwithmode: "background"; don't launch several of those in one repo, since they share the working tree and collide. Batch exists precisely to isolate each task.) You hand it a reviewed task graph; each task declares the files it will touch (claimedPaths, so claim-overlapping tasks serialize rather than race) and optionaldependencies. Dependencies are a launch gate, not integration: a task launches only once its dependencies reachreview_ready, but its worktree branches from the batch base and does not contain their changes, so a task never sees another task's diff (merging is yours). To run a Codex implementer on a task, point itsmanifestPathat a swapped manifest likeexamples/converge-codex-writer.json. There is no daemon: progress happens only when you callchit_batch_advance, andchit_batch_statusis read-only (follow itsnextAction, not the per-task status, to drive the batch). The deliverable is a set of reviewable worktree branches; chit never auto-merges. If you lose a batch id,chit_batch_listrecovers it. Retire the worktrees withchit_batch_cleanup(dry-run by default; it never deletes receipts).
The orchestrator's job does not change in either mode: you still run the final gates yourself and push only on explicit approval. Unattended means chit does the writing and reviewing without you watching each round, not that the work merges itself.
Discipline that bites
- MCP server staleness. The chit MCP server is a persistent process; it runs the adapter and runtime code from when it started. After changing an adapter or the runtime, reconnect the server before any MCP-driven run reflects the change. The reviewer reads files from disk, so reviews stay current; runs through the adapter do not.
- Agent profiles. Set model, reasoning effort, and timeouts on named agents in
~/.config/chit/agents.jsonand reference them from the converge manifest.chit showandchit audit showreport the effective config so you can see what a run used. - Worktrees. Run converge in a worktree; clean it up when the slice lands. Both the audit transcript and the loop log live in the local state dir (keyed by repo), so they survive even after the worktree is removed.
Pointers
- Supervised convergence: the supervised pattern.
examples/converge.json: the autonomous loop manifest.- Audit log: reading transcripts with
chit audit. - MCP surface: the run tools and the one invariant.