CRONOS-AI · User guide
Cronos-AI · Reference

Agent integration contracts

Understand how Cronos-AI coordinates Pi, Herdr, Git, and local state.

This records the locally installed integration surfaces checked for the MVP (Pi 1.1.0 and Herdr 0.9.3; Herdr API schema protocol 22). No live agent was started during this check.

Task runner and step planner

Each active task is driven by its own Rust task runner: the TUI starts cronos-ai --data-dir <dir> internal workflow run-task <project-id> <task-id> in its own process group. The runner loops over the task's agent steps and stops at a human approval, the local merge, Error, or Completed. Each progress line it prints on stdout is shown in the dashboard; a non-zero exit carries the end of its stderr as the error. Rust is the source of truth for project and task state and for every human control.

Before each agent step the runner asks a step planner for the agents. It is a one-shot Pi run in the task worktree, pi -p --mode text --no-session --no-approve with discovery off and only read-only tools (read,grep,find,ls), on the project's planner model when one is set (project set-planner-model). Its prompt carries the task and its OpenSpec change, the step's job and agent limits, the profiles allowed in the step, the current attempt's changes_requested findings (from reviewers, verifiers, the check command, and merges), the human's revision note, and any clarification. Its answer must contain {"agents": [{"name": ..., "prompt": ..., "profile_id": ...}]}; Rust validates it exactly like a run-step request. When the planner fails, takes more than five minutes, or proposes an invalid plan, the runner runs a default one-agent plan with a templated prompt carrying the same context and records the reason as orchestrator activity. Rust then appends its own contract to every prompt and starts the agents through Herdr. tests/live_smoke.rs checks the real step planner and one real Pi agent when CRONOS_LIVE_SMOKE=1 is set.

Herdr agent API

Herdr 0.9.3 exposes agent operations through its socket API and CLI. The installed API schema advertises agent.start, agent.prompt, agent.wait, agent.read, and agent.send_keys.

CLI help and the installed API schema confirm these command/parameter contracts. The Rust adapter invokes Herdr with argument vectors (never a shell), validates agent names, parses pane IDs from Herdr responses, and waits for a settled state after sending ctrl+c. A workflow step creates no-focus sibling panes only after explicit task start, and only in the task's validated worktree under the Cronos data directory. Startup preflight checks pi, herdr, openspec, and git by running their version commands; if any are unavailable it prompts for manual installation and retries, but never installs tools. Only the explicit scripts/cronos-ai launcher creates its dedicated Herdr workspace, avoiding existing user panes. Automated launcher tests use fake Herdr commands; live pane/agent launch, prompt, output, and cancellation checks must run in an explicitly isolated test session, not the current user session.

Git worktrees and local merge

Projects store the canonical root of a user-selected local Git repository. When a task is started, Rust creates an isolated worktree under the Cronos data directory and a branch named cronos-ai/<task-id>/attempt-<n>. Recovery removes the exact validated prior-attempt worktree and branch before assigning a fresh attempt. Specification and code generation agents commit their own work. Final-code approval gates the documentation step, after which Rust archives the OpenSpec change and makes one documentation commit. When the task runner stops at local merge, Rust requires both the base repository and task worktree to be clean and performs a local git merge --no-ff --no-edit. If the merge leaves unmerged paths, Rust aborts it and returns the task to code generation to resolve the conflict; any other merge failure is aborted and marks the task Error. With the push publish mode, Rust then pushes the base branch to the project's remote with an explicit refspec; with pull-request, it pushes the task branch instead of merging and opens (or reuses) a pull request with gh pr create. Git and gh run with GIT_TERMINAL_PROMPT=0 and GH_PROMPT_DISABLED=1, so missing credentials fail the step instead of prompting. Agents themselves never push.

Check command

The project check command runs without a shell in the task worktree after the verification agents, in its own process group so reaching the project's check time limit (60 minutes unless the project sets 1 to 480) stops everything it started. Output goes to .cronos/check-output.log, which Cronos creates fresh and never writes through a symlink. A non-zero exit, or new files left in the worktree, sends the task back to code generation. A relative program such as ./scripts/check.sh runs the task branch's version; if the branch changed it, Cronos records a warning for the human reviewer.

Trust boundary

Agents and the planners have no way to change task status, approvals, or worktree paths through Cronos: agents only write their result files, and the planners only answer with plans that Rust validates. Rust validates every step, profile, and transition and checks the worktree after each step. Workers, however, are full Pi sessions with shell access running with your operating-system permissions: a worker's shell could edit Cronos data files, leave the worktree, change tests or the check program, or push. The human approval gates and the review view are the real protection.

With project set-sandbox on, each worker instead runs in a write sandbox (sandbox-exec on macOS, bubblewrap on Linux): it can still write its worktree, the repository's Git objects, build caches, and temporary files, but not Cronos data, the base checkout, or the repository's .git/hooks and .git/config. The sandbox does not limit network access or reading files, and a worker can still weaken tests inside its worktree, so the human gates remain the real protection. Run Cronos-AI as a dedicated OS user or in a container for untrusted work.

Prioritizer (Jev)

The original design picked Jev, a fast selection model, to choose the next task. Cronos-AI runs that decision as a one-shot Pi call instead, so it works with any model Pi can reach: pi -p --mode text --no-session --no-tools --no-approve with discovery off and --model from project set-prioritizer --model (Pi's default model otherwise). Set the model to Jev once Pi can run it.

The prompt lists only the tasks the scheduling rules already allow to start, under keys T1, T2, ..., plus the running tasks. The answer must contain {"order": ["T2", "T1"], "reason": "..."}; Rust rejects unknown or repeated keys, keeps omitted tasks after the ranked ones in built-in order, and falls back to the built-in order on any failure or after two minutes. The reason is recorded as prioritizer activity on the first task started.

Return to the user guide