Skip to main content

Crate voro_core

Crate voro_core 

Source
Expand description

Core logic for Voro: the SQLite store, the task state machine, and the scheduler/scoring. Pure of terminal I/O; every interface (TUI, CLI verbs) is a thin consumer of this crate. Concepts and invariants are specified in docs/DESIGN.md.

Re-exports§

pub use scheduler::ActionRow;
pub use scheduler::AttentionCosts;
pub use scheduler::Candidate;
pub use scheduler::DigestRow;
pub use scheduler::EffectiveScore;
pub use scheduler::Queue;
pub use scheduler::QueueRow;
pub use scheduler::ScoreBreakdown;
pub use scheduler::StateCounts;
pub use scheduler::WipGate;

Modules§

config_edit
Comment-preserving edits to the user’s voro.toml (DESIGN.md §5). Where crate::agent::AgentsConfig reads the file, this writes it: the single helper the TUI Config screen and the voro viewer CLI verbs both route through, so the two never diverge on formatting or validation.
scheduler
The scheduler (DESIGN.md §7): pure scoring and the ordering of the two views. The store supplies candidates (with age_days already computed); everything here is deterministic arithmetic on those rows.
seed
The dev store’s fixture (DESIGN.md §5).

Structs§

AccountCap
What an agent’s cap verb says about the account it dispatches on: the instant its usage window reopens (DESIGN.md §8).
AgentSessionEntry
One session from an agent’s sessions command output: a JSON array of objects, of which the fields below are read and everything else ignored. sessionId (falling back to id) is the durable reference substituted into {session}; cwd and startedAt (ms epoch) identify a fresh dispatch’s session among its siblings; state and pid together say whether the session is still going (AgentSessionEntry::liveness).
AgentTemplate
A named set of verb templates from voro.toml. dispatch (or its alias cmd) is required and always contains PROMPT_FILE_PLACEHOLDER; it may also carry the optional SESSION_NAME_PLACEHOLDER and TASK_ID_PLACEHOLDER. The rest are optional, with their {session}/{prompt_file} placeholders validated at parse time.
AgentsConfig
The effective agent config: the built-in agents with any voro.toml merged on top, plus the user’s default_agent and viewers. Each agent carries its Provenance so agent list can show where it came from.
CapReading
What a session’s output says about a usage cap. Held in memory only: it is a reading of the current output tail, retaken on the next pass, so it clears itself once the operator continues the session and new output displaces the cap message (§8). Nothing about it reaches the database.
CapWindow
When a capped session’s window reopens and whether it has: the one answer the badge and the nudge sweep both read, resolved from the two sources that can give it (DESIGN.md §8).
CompletionReport
What a reviewer reads a task against (DESIGN.md §8): the completion summary the current cycle came back with, and — on a task that has been sent back — the rejection feedback that summary answers.
Dep
DepRef
A dependency edge resolved for display: the task at the other end of the edge with its current title and state, plus the edge’s kind. Which end is “other” depends on the query — the dependency for Store::deps_by_task, the dependant for Store::dependents_by_task.
Doc
A plan or design document a project’s work derives from (DESIGN.md §3), and the thing tasks link to so “which tasks came from this plan?” is a query rather than a grep over task bodies. Owned by one project — which is where a relative location resolves — but linkable from a task in any project, since one plan routinely spawns work across several.
Event
GithubIssue
One issue from gh issue list --json number,title,body,url. Those four fields are all gh documents for this command; anything else it emits is ignored.
LaunchSpec
Everything a verb template needs bound to become a command line: which launch this is, the prompt file written for it, and whether the task earns the deeper model. Assembled by the caller that wrote the prompt, rendered by ResolvedAgent::launch_command or ResolvedAgent::plan_launch_command.
NewTask
Initial state for a task created by a human. proposed is quick capture; parked/ready mean the creator has already triaged their own task.
PrPlan
Everything the forge needs to open a PR for a review task (DESIGN.md §8): the branch to push and the title and body of the pull request. Assembled by plan_pr once the task is proven PR-ready.
PrRef
A parsed reference to a GitHub pull request. The base repo is recorded explicitly (owner/repo/host) rather than inferred from a checkout’s origin, so a PR opened from a fork is still addressed against the repo where the diff and its review comments live (DESIGN.md §11c).
PrRevisions
A tracked PR’s revisions, read from gh pr view --json headRefOid,commits: the current head, and the commits the PR contains. The latter is what answers “is the revision I reviewed still on this branch?” — a rework that appends commits keeps it, and a force-push or rebase drops it.
Project
RenderedMessage
A message template rendered into a runnable command line, plus the reference the session will answer to afterwards where the agent forks (NEW_SESSION_PLACEHOLDER). The caller records that reference only once the send is under way, so a command that never ran leaves the session pointing where it did.
Repo
A checkout a project’s work runs in (DESIGN.md §3): the execution target dispatch, pr/open, worktree cleanup, and import resolve against. A project owns at least one, exactly one of which is its default.
ResolvedAgent
The agent a task will be dispatched with: the task’s own override if it has one, otherwise the config’s global default, with every verb template resolved.
RunningRow
A row of the cockpit’s running strip (DESIGN.md §9): one per running, refining, or waiting task, joined with its open session if it has one. A task with no open session (started by hand) still shows, with session_id/ agent None. started_at is what elapsed_secs counts from — the session for work under way, the hand-off for a waiting task — and elapsed_secs is computed in SQL against the database’s clock, so the TUI only has to format it. pr_url carries the strip’s PR marker.
Session
Store
Owns the SQLite database. All writes go through this type; task state in particular is only ever changed by the transition API in transition.rs.
Task
TaskEdit
Content edits. State is deliberately absent — use Store::apply.
ViewerTemplate
A viewer command template from voro.toml (DESIGN.md §11a): a shell command run in a task’s checkout — or its worktree — to open its diff. Defined as a named [viewers.<name>] table or the anonymous [viewer] default. The placeholders {path} (checkout/worktree dir), {branch} (the task’s branch), and {base} (the checkout’s default branch) are all optional, so nothing is validated at parse time.

Enums§

Action
DepKind
Error
Launch
What a launch is (DESIGN.md §8): the one place a backgrounded or foreground agent session’s identity is composed. A launch names its session, its prompt and log files, and its line in the launch log from this single value, so a new flavour of launch cannot inherit one of those and forget another — which is exactly how a refine came to be named voro-{task_id}, literally, on every task at once.
LivenessSource
Which source of liveness is authoritative for a session (DESIGN.md §8), recorded by the code that spawned the process because only it knows what it spawned. The two differ in one respect: whether the pid the session row holds is the work itself or a launcher that spawned it and exited.
Mergeability
GitHub’s mergeability verdict for a tracked PR (gh pr view --json mergeable, DESIGN.md §8): whether a review task’s branch still merges cleanly with its base. Read fresh and never stored — the same rendered-not-stored shape as the incomplete-report flag — it is what turns a CONFLICTING PR into the informational [branch conflicts] marker.
NextAction
The verb a task’s queue row asks of the human (DESIGN.md §3), derived from state × fields rather than stored.
Priority
Provenance
Where an effective agent came from once the built-ins and voro.toml are layered, surfaced by voro agent list so it is clear which half of the config owns each agent.
RefineOutcome
How a refine round ended (DESIGN.md §6). It rides the refining → proposed transition, is logged as the detail of a refine event, and picks the outcome the round’s session closes with — so the markers on the returned proposal are derived from the round that just concluded rather than from the whole history of the task.
ReviewDiff
How much of a task’s work to put in front of the operator.
SessionLiveness
What a listing entry says about its session, as far as pure logic can tell (DESIGN.md §8). AgentSessionEntry::liveness classifies; the voro crate resolves SessionLiveness::WhileProcessLives with the process check, so voro-core still never touches a process.
SessionOutcome
TaskState
Triage
Where a proposed task goes at triage.

Constants§

BUILTIN_VIEWER_NAMES
The built-in viewers by name, in the order they are probed against PATH when nothing user-configured resolves: the first one installed wins (DESIGN.md §11a). Public because the messages that say what was looked for are written where the failure is surfaced, and none of them should spell the list again.
CAP_SIGNATURES
Phrases that mean “held at a usage cap”, checked case-insensitively.
NEW_SESSION_PLACEHOLDER
The fresh-reference substitution in the message template, bound to a v4 UUID Voro generates for the send (DESIGN.md §8). An agent whose sessions are held by a supervisor cannot be resumed headlessly while that supervisor lives; it can be forked, which continues the same conversation under a reference the caller names up front. A message template carrying this placeholder is declaring that shape, and the session row follows the fork: what Voro binds here becomes the session’s reference. Optional — a template without it resumes in place and keeps the reference it had.
PROMPT_FILE_PLACEHOLDER
The prompt-file substitution in the dispatch, plan and message templates. The working directory is handled by the spawner, not the template.
REVIEWED_EVENT
The event kind recording the branch revision the operator reviewed. The events table carries it, so nothing about delta re-review needs a column.
SESSION_NAME_PLACEHOLDER
The session-name substitution in the dispatch and plan templates: the name Voro composes for the session a launch opens (Launch::session_name), so every backgrounded session is findable by a name Voro chose. Optional, and refused on the session verbs for the same reason [MODEL_PLACEHOLDER] is — they act on a session that already exists and has its name.
SESSION_PLACEHOLDER
The session-reference substitution in the attach, resume, message, logs and stop templates: the agent-opaque reference captured at dispatch (a Claude session UUID, a Codex session id, a tmux session name).
TASK_ID_PLACEHOLDER
The task-id substitution in the dispatch template, the numeric id of the task. Optional — a template that omits it dispatches unchanged — so a template can put the id somewhere other than the session name. Refused on plan, which serves targets that have no task id to bind.
VIEWER_BASE_PLACEHOLDER
The substitution in a viewer command template for the checkout’s default branch — the base a task branch is diffed against (DESIGN.md §8).
VIEWER_BRANCH_PLACEHOLDER
The substitution in a viewer command template for the task’s git branch, or empty when the task has none. Paired with VIEWER_BASE_PLACEHOLDER it lets a viewer express a diff range ({base}...{branch}) rather than a bare directory (DESIGN.md §8).
VIEWER_PATH_PLACEHOLDER
The substitution in a viewer command template (DESIGN.md §11a): the checkout path of the task’s project — or the task’s worktree, when it has a branch checked out in one (DESIGN.md §8). Optional — a viewer that acts on the current directory (git difftool -d) needs no placeholder.

Functions§

already_imported
Whether body (an existing task’s body) already carries this issue’s URL — the idempotency check that lets import be run repeatedly without creating duplicate tasks.
completion_report
Read a task’s current completion report off its event log. None when the cycle in hand has reported nothing: a task that never completed, and a rework still in flight, whose newest summary belongs to the round that was rejected and so answers neither the feedback nor the operator’s question of what changed this time.
format_review_feedback
Build a reject-with-feedback body from a PR’s reviews and inline comments (DESIGN.md §11c), so a GitHub review reaches the agent without retyping. Reviews with an empty body are skipped; the inline comments carry their own text. Returns an empty string when there is nothing to relay.
is_builtin_viewer
Whether a name is a built-in viewer. The write surfaces ask, so removing or editing one is refused as “built in, override it” rather than reported as a viewer that isn’t there.
issue_new_task
An issue mapped to a task, always landing in proposed: imports are untriaged like any other machine-generated task, and priority is not guessed from labels in v1 — triage assigns it. repo_id carries the repo the issues were fetched from, so an imported task dispatches into the checkout it came from rather than the project default.
issue_task_body
The task body for an imported issue: the URL and issue number stamped at the top (both for human reference and as the idempotency marker checked by already_imported), followed by the issue body verbatim.
location_is_url
Whether a doc location is a URL rather than a path. Deliberately a narrow scheme test, so a bare docs/plan.md never has to be escaped to read as a path.
model_for_depth
Bind a session verb’s one placeholder: the reference Voro captured at launch, shell-quoted so a reference carrying shell metacharacters reaches the agent as itself. Serves logs, whose whole contract is a session in and that session’s recent output out. Which model a launch at a given depth runs with (DESIGN.md §8): the deeper one for a deep task where the agent names one, the workhorse otherwise. The one place that rule lives, because two callers now depend on agreeing about it — the launch itself, and the cap reading that has to ask about the window that model is metered against.
parse_mergeable
Read GitHub’s mergeability verdict out of gh pr view --json mergeable output ({"mergeable":"CONFLICTING"}). Only the two definite verdicts map to themselves; anything else — UNKNOWN, a missing field, malformed JSON, or the empty string a missing or unauthenticated gh leaves behind — degrades to Mergeability::Unknown, so no signal is ever mistaken for a conflict. Pure of I/O; the gh call lives in the voro crate.
parse_pr_revisions
Read a PR’s head and commit list out of gh pr view --json headRefOid,commits output. Malformed or missing fields degrade to empty — no head and no commits — which plan_review_diff turns into the full diff, so an unreachable gh never blocks a review.
parse_reset_epoch
Read an agent’s cap verb output as the instant its window reopens, or None when it said nothing (DESIGN.md §8).
parse_sessions_json
Parse a sessions command’s stdout. Entries without any id are skipped rather than failing the whole listing; anything that is not a JSON array is an error, so a misconfigured sessions verb surfaces rather than reading as “no sessions”.
plan_pr
Validate that a task can have a PR opened from its done-time state, and if so assemble the PrPlan (DESIGN.md §8): a review task carrying both a branch (the work to push) and a completion summary (the PR body; the caller supplies the latest). Each gap fails naming what is missing — state, branch, or summary. The branch gap is the one no advertised verb leads to: a review task without one asks for accept rather than pr (DESIGN.md §6), so this refusal is reached only by an operator naming pr on it directly. Pure of I/O.
plan_review_diff
Decide what a review should show (DESIGN.md §8). last_reviewed is the revision recorded when the operator rejected, head the branch’s current tip, and still_on_branch whether that recorded revision is still reachable from the head — false after a force-push or a rebase rewrote it away.
projects_for_new_task
The projects a new task can be created in, in the order to offer them (DESIGN.md §9). Archived projects are dropped — Store::create_task refuses them (§5), so offering one is offering a choice that can only fail, and in the $EDITOR and planning flows it fails only after the operator has written the task out. The rest sort by weight descending, which is the one per-project priority Voro holds (§7), with name ascending inside a weight so the order is stable. Weight 0 is a snooze rather than a retirement, so a parked project stays offered and sorts last.
read_cap
Read a session’s output tail as a cap reading, or None when nothing in it says the session is capped.
render
Fill template from bindings in a single left-to-right pass: each bound placeholder’s value is emitted verbatim and never re-scanned, so a value containing another placeholder survives whatever order the bindings are given in. An unrecognised {…} is copied through untouched, which is what makes composing nested blocks safe — render the inner block first, then bind the finished text.
render_cap
A cap template rendered into a runnable command line (DESIGN.md §8). The model is bound exactly as a launch binds it — pasted in as the opaque name the operator configured, Voro being model-blind — and a template naming no model renders unchanged, which is what makes the per-model question optional rather than required.
render_message
Bind a message template’s placeholders in one pass, so no value’s own braces are re-scanned: the session reference Voro captured at dispatch, the file holding the message, and — for a template that forks — a freshly generated v4 UUID for the session the send opens. All are shell-quoted; the references are agent-opaque text, not tokens Voro may assume are bare.
render_session
shell_quote
Single-quote a path for safe substitution into an sh -c command line.
strip_ansi
Drop terminal escape sequences, keeping the spacing the surviving text had on screen.
was_rejected
Whether a task has been reviewed and sent back at some point — what makes a redispatch a rework rather than a first attempt (DESIGN.md §8).

Type Aliases§

Result