Projection, recovery, and stable surfaces
September 8, 2026 · View on GitHub
Rotary keeps the session log append-only. Compaction is a projection of that log, not a rewrite of it.
PrefixShape and prune-then-fold
PrefixShape is the canonical byte digest of the live system prefix. Prune
drops old turns and must leave those bytes unchanged. Fold (a summary inserted
after the prefix) runs only when prune still cannot fit the trigger threshold.
Dropped turns are archived as verbatim JSONL (RavenArchive), not as a second
summary. Hosts may persist the archive beside session.jsonl.
Request reconstruction
Provider requests rebuild from the session log (Session::serialize_provider_request
/ replay_provider_request). Mutating a live Vec<Message> does not change a
request reconstructed from session.jsonl.
Semantic and automatic compaction persist an append-only projection event
(summary + archived_ids). Replay applies that ledger so the next provider
request still includes the summary. Repeated compact() does not re-archive
the same dropped turns.
Empty-turn recovery
recover_empty_turn / recover_stuck_tool classify Prefill, Nudge,
Retry, or Halt. The engine emits Event::Recovery (action + reason);
the host decides whether to continue.
Sandbox escalate
On OS-sandbox deny the engine retries once at the next layer:
userspace → nested FS (seatbelt/bwrap) → .git remounted read-only.
Event::RetryReason is emitted. There is no silent pass after the last layer.
Tool spill
Oversized tool bodies are written to .rx4/spill/. The model sees a preview
plus a locator. Previews truncate on a UTF-8 character boundary. If the spill
write fails, the model still receives a bounded preview and hosts get a typed
SpillStatus::SpillFailed notice (Event::ToolSpill / ToolResult.spill).
complete_subtask
Claims only go down the task tree. The model-facing tool is fail-closed
(ApprovalRequired) and does not accept actor_id or adjudication. The host
adjudicates via Agent::complete_subtask; the engine records an evidence
ledger. Complements AVO scoring. A child cannot mark a parent complete.
Stable MCP surface
When the mcp feature is on, the prefix exposes tool_search and
use_capability so child schemas do not churn the cached prefix.
Trajectory cassette
ReplayProvider replays recorded turns, including CassetteTurn.tool_calls.
detect_divergence / detect_tool_divergence report the first mismatch.
Agent::enable_cassette_replay simulates recorded tools instead of executing
them.
Other host capabilities
- Unified exec sessions drain stdout/stderr, expose the
exectool (spawn/stdin/wait/kill), and emitProcessStart/ProcessStdin/ProcessEnd. GuardianAuthorizeris fail-closed; hosts install the review callback.apply_patchis an optional bulk tool. Hashline remains the editor.- Plan accept wipes
<planning>/[planning]/PLAN:tokens. WritePathSchedule: omit paths = whole workspace = serialize writes.ContextCapsulegives subagents zero ambient inheritance.- File snapshots and observed-version guards are host opt-in (
enable_file_guards). TwoSessionCoordinatormoves messages only on explicit routes.- Skills with
required_toolsstay silent when those tools are not loaded. ModelBindingis per request; it is not a process-global default.ShadowGitcheckpoints live in.rx4/shadow.gitwhen the host enables it.HunkLogrecords hashline edits for rewind without replacinghashline::apply.- Explore subagents default to depth 1 and do not inherit the parent transcript.