rotary

August 20, 2026 · View on GitHub

Mission

Be the best general-purpose coding agent harness: embeddable, light, extensible, protocol-friendly. Product shells live elsewhere (telekinesis).

rotary exposes capabilities, not policy. Scheduling, enabled flags, and lifecycle decisions are the host's job.

Layers

graph TD
  Host["Hosts<br/>telekinesis TUI/CLI · IDEs · CI"]
  Host -->|typed engine API / cargo add rx4| Ctrl
  subgraph Ctrl["rotary control plane"]
    direction TB
    Agent["agent · tools · permissions · hooks · scopes"]
    Sess["sessions · plugins · skills · guardrails · context"]
    Extra["extract · ranking · guardrails · LSP primitives"]
  end
  Ctrl --> Providers["providers (HTTP/SSE)"]
  Ctrl --> CU["computer-use (Praefectus)"]
  Ctrl --> Mem["memory · graph_memory · embeddings"]

Influences (feature adoption)

ProjectAdopted in rotary
Codexsandbox/approvals → permissions; non-interactive headless; skills pattern; bounded tool loops
OpenCodemulti-provider routing; session resume; plugin/tool surface
t3codetyped event boundary; thin host protocol over IPC
pi / Crushevent lifecycle; SKILL.md; hook envelopes
Praefectusauthorized, verified computer-use execution
Hermes Agentself-improving learning loop → background_review, skill_curator
Unthinkclawembeddings module → embeddings

Core contracts

Agent loop

flowchart TD
  before["before_prompt"] --> compact{"auto-compact?"}
  compact -->|yes| ac["compaction"]
  compact -->|no| start["agent_start"]
  ac --> start
  start --> turn["turn_start"]
  turn --> msg["message stream"]
  msg --> tools["tool loop<br/>(permission-gated, scope-filtered)"]
  tools --> after["after_turn"]
  after --> more{"more turns?"}
  more -->|yes| turn
  more -->|no| end["agent_end"]

Scopes

Work scopes (not named product agents): coding | research | plan | ask | computer_use.

Permissions

full_access | read_only | workspace_write | deny_all + allow/deny lists + host approver.

Events

Tagged union pushed to subscribers. A temporary IPC adapter may mirror events as (method: "event"), but hosts must treat the typed event stream as the UI boundary (t3code pattern). See EVENTS.md for the loop diagram and event tables.

Capability vs policy

Modules like dream_scheduler and skill_curator expose the capability to run a consolidation cycle or audit skills. The host decides when to invoke them — rotary never schedules on its own.

Boundary with telekinesis

rotary is the reusable engine. telekinesis is the product host. Rotary owns the loop, providers, tools, permissions primitives, session model, compaction capability, MCP/skills/subagent capabilities, typed lifecycle events, and the opt-in autoresearch controller's Git/checkpoint capability. Telekinesis owns persistence implementations for its product state, scheduling, transport, pi compatibility, ACP, IPC, SSE, slash commands, and surfaces. For autoresearch, Telekinesis owns the user-facing schedule and approval flow while rx4 owns the isolated-worktree mechanics and acceptance invariant.

The current acp.rs, ipc.rs, sse.rs, slash.rs, and binary wiring are compatibility inventory. They migrate to telekinesis adapters in phases; they are not new host contracts.

Session storage follows the same seam: rotary exposes session state and pure snapshot contracts, while hosts choose JSONL, SQLite, or another repository. Compaction algorithms remain engine capabilities; hosts choose when and how to schedule them.

Autoresearch follows the same seam: AutoresearchController exposes one hypothesis-at-a-time execution, measurements, rollback, budgets, cancellation, and typed events. The host supplies hypothesis generation, the agent/session callback, UI, and explicit final-patch consent. See docs/AUTORESEARCH.md for the minimal Telekinesis contract.

The initial refactor stays within this crate. A workspace split happens only when separate release or dependency boundaries are proven necessary.

See the canonical decision record: telekinesis ADR-001.

Versioning

Semver for library API. Bump minor for new modules/tools; patch for harness fixes. Hosts pin rx4 versions via Cargo.