pub struct Store { /* private fields */ }Expand description
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.
Implementations§
Source§impl Store
impl Store
Sourcepub fn candidates(&self) -> Result<Vec<Candidate>>
pub fn candidates(&self) -> Result<Vec<Candidate>>
Scheduler input: every task in a scored state, joined with its project, excluding weight-0 (parked) projects entirely (§7).
Sourcepub fn explain(&self, task_id: i64) -> Result<ScoreBreakdown>
pub fn explain(&self, task_id: i64) -> Result<ScoreBreakdown>
Score decomposition for any single task, whatever its state — the
TUI popup today, voro explain <task> later.
Sourcepub fn proposed_count(&self) -> Result<i64>
pub fn proposed_count(&self) -> Result<i64>
Count of untriaged tasks. Parked (weight-0) projects are hidden here too.
Sourcepub fn state_counts(&self) -> Result<StateCounts>
pub fn state_counts(&self) -> Result<StateCounts>
Task counts by state for the header indicator (DESIGN.md §12), so a backlog stays felt even when a low-scoring row falls past the queue’s cap (§7). Parked (weight-0) projects are excluded.
Source§impl Store
impl Store
pub fn open(path: &Path) -> Result<Store>
pub fn open_in_memory() -> Result<Store>
Sourcepub fn default_db_path() -> PathBuf
pub fn default_db_path() -> PathBuf
$XDG_DATA_HOME/voro/voro.db, defaulting to ~/.local/share.
Sourcepub fn data_version(&self) -> Result<i64>
pub fn data_version(&self) -> Result<i64>
SQLite’s PRAGMA data_version, which increments whenever another
connection commits a change to the database. The value is stable across
commits made on this connection, so a caller can poll it to detect
external writes without reacting to its own mutations.
pub fn create_project(&mut self, name: &str, path: &str) -> Result<Project>
pub fn project(&self, id: i64) -> Result<Project>
pub fn projects(&self) -> Result<Vec<Project>>
pub fn set_weight(&mut self, project_id: i64, weight: i64) -> Result<()>
Sourcepub fn set_review_action(
&mut self,
project_id: i64,
action: &ReviewAction,
) -> Result<Project>
pub fn set_review_action( &mut self, project_id: i64, action: &ReviewAction, ) -> Result<Project>
Set how pr shows this project’s review diffs (DESIGN.md §8/§11a).
Auto stores NULL — the medium goes back to being resolved at use.
Sourcepub fn rename_project(&mut self, project_id: i64, name: &str) -> Result<Project>
pub fn rename_project(&mut self, project_id: i64, name: &str) -> Result<Project>
Tasks reference a project by id, not name, so renaming is a pure label change — no task or dependency is touched.
pub fn set_path(&mut self, project_id: i64, path: &str) -> Result<Project>
Sourcepub fn delete_project(&mut self, project_id: i64) -> Result<()>
pub fn delete_project(&mut self, project_id: i64) -> Result<()>
Delete a project outright — only safe when it has no tasks, since tasks reference their project by id and deleting would orphan history. A project with tasks in any state refuses; weight 0 snoozes without losing history.
pub fn create_task(&mut self, new: NewTask) -> Result<Task>
pub fn task(&self, id: i64) -> Result<Task>
pub fn tasks(&self) -> Result<Vec<Task>>
pub fn update_task(&mut self, id: i64, edit: TaskEdit) -> Result<Task>
Sourcepub fn set_priority(&mut self, id: i64, priority: Priority) -> Result<Task>
pub fn set_priority(&mut self, id: i64, priority: Priority) -> Result<Task>
Re-prioritise a task in isolation (DESIGN.md §7). Unlike update_task
this touches only priority, and it logs the change. Task state is left
untouched.
Sourcepub fn set_pr(&mut self, id: i64, pr_url: Option<&str>) -> Result<Task>
pub fn set_pr(&mut self, id: i64, pr_url: Option<&str>) -> Result<Task>
Track (or, with None, untrack) a GitHub PR on a task (DESIGN.md §11c).
The URL is stored verbatim — validation is the caller’s job — and the
change is logged. Leaves task state untouched.
Sourcepub fn set_branch(&mut self, id: i64, branch: Option<&str>) -> Result<Task>
pub fn set_branch(&mut self, id: i64, branch: Option<&str>) -> Result<Task>
Record (or, with None, clear) the git branch a task’s work lives on —
the intended name a human sets for dispatch to inject, or the name an
agent reports through voro done --branch. Stored verbatim (Voro never
runs git) and logged; task state is left untouched.
Sourcepub fn set_summary(&mut self, id: i64, summary: &str) -> Result<Task>
pub fn set_summary(&mut self, id: i64, summary: &str) -> Result<Task>
Set or replace a task’s completion summary outside done (DESIGN.md §8):
append a summary event, which latest_summary supersedes with, so the
PR body, detail view, and incomplete-report flag all pick up the newest.
This amends a stale PR body or supplies a missing [incomplete report]
summary without a reject → re-done round trip. Allowed only on a
running or review task; it never touches tasks.state.
pub fn add_dep( &mut self, task_id: i64, depends_on: i64, kind: DepKind, ) -> Result<()>
pub fn remove_dep(&mut self, task_id: i64, depends_on: i64) -> Result<()>
Sourcepub fn deps_by_task(&self) -> Result<HashMap<i64, Vec<DepRef>>>
pub fn deps_by_task(&self) -> Result<HashMap<i64, Vec<DepRef>>>
Every dependency edge of every kind, keyed by the depending task and
resolved to the dependency’s current title and state — the forward
direction a detail view renders as blocked by #N. One query feeds every
pane, so the render path never issues a per-row lookup.
Sourcepub fn dependents_by_task(&self) -> Result<HashMap<i64, Vec<DepRef>>>
pub fn dependents_by_task(&self) -> Result<HashMap<i64, Vec<DepRef>>>
The reverse edges: every dependency keyed by the task depended on, resolved to the depending task — who a task blocks (or spawned).
pub fn deps_of(&self, task_id: i64) -> Result<Vec<Dep>>
Sourcepub fn create_session(
&mut self,
task_id: i64,
agent: &str,
pid: Option<i64>,
log_path: Option<&str>,
) -> Result<Session>
pub fn create_session( &mut self, task_id: i64, agent: &str, pid: Option<i64>, log_path: Option<&str>, ) -> Result<Session>
Open a session for a running task, stamping started_at. ended_at and
outcome stay NULL until end_session.
Sourcepub fn set_session_ref(&mut self, id: i64, session_ref: &str) -> Result<Session>
pub fn set_session_ref(&mut self, id: i64, session_ref: &str) -> Result<Session>
Record the agent’s own reference for a session (task #75), captured
after launch — the row necessarily exists before the reference does,
so this is an update rather than a create_session parameter.
Sourcepub fn end_session(
&mut self,
id: i64,
outcome: SessionOutcome,
) -> Result<Session>
pub fn end_session( &mut self, id: i64, outcome: SessionOutcome, ) -> Result<Session>
Close a session with its outcome, stamping ended_at.
pub fn session(&self, id: i64) -> Result<Session>
pub fn sessions_for(&self, task_id: i64) -> Result<Vec<Session>>
Sourcepub fn latest_sessions(&self) -> Result<HashMap<i64, Session>>
pub fn latest_sessions(&self) -> Result<HashMap<i64, Session>>
Every task’s newest session, keyed by task id, in one query — what the
TUI loads per refresh to answer “what is/was this session doing?” without
querying the store mid-draw. Session ids are monotonic, so max(id) is
the latest.
Sourcepub fn live_sessions(&self) -> Result<Vec<Session>>
pub fn live_sessions(&self) -> Result<Vec<Session>>
Sessions that have not yet ended, newest first.
Sourcepub fn incomplete_report_flag(&self, task_id: i64) -> Result<bool>
pub fn incomplete_report_flag(&self, task_id: i64) -> Result<bool>
Whether task_id is a review task carrying a partial completion
report — exactly one of its branch and summary present (DESIGN.md §8).
Neither is deliberately not flagged (a planning task produces neither),
both is complete. Gated on review, derived fresh rather than stored.
Sourcepub fn running_rows(&self) -> Result<Vec<RunningRow>>
pub fn running_rows(&self) -> Result<Vec<RunningRow>>
Rows for the cockpit’s running strip (DESIGN.md §9): every running
task, joined with its open session if it has one. The strip filters on
task state, so review/needs-input tasks (session still open) do not
appear. A hand-started task with no session shows with session_id/
agent NULL. The one-open-session invariant (§8) bounds the join to one
row per task; elapsed is computed in SQL so the TUI only formats it.
Sourcepub fn latest_summary(&self, task_id: i64) -> Result<Option<String>>
pub fn latest_summary(&self, task_id: i64) -> Result<Option<String>>
The most recent completion summary a task recorded (DESIGN.md §8): the
detail of its newest summary event, logged by done --summary or
amended by set --summary (set_summary). This is the PR body when
pr opens a pull request. None when the task never carried a summary.
pub fn events_for(&self, task_id: i64) -> Result<Vec<Event>>
Source§impl Store
impl Store
Sourcepub fn legal_actions(state: TaskState, human: bool) -> Vec<Action>
pub fn legal_actions(state: TaskState, human: bool) -> Vec<Action>
Legal target of action from state, if any. Exposed so interfaces can
offer exactly the legal actions without duplicating the machine. Order
matters: interfaces render the first entry selected, so the most common
action leads (for triage, ready). human shortens the running path
(DESIGN.md §6): no ask, and completion leads since it goes straight to
done.
pub fn apply(&mut self, task_id: i64, action: Action) -> Result<Task>
Sourcepub fn record_dispatch(
&mut self,
task_id: i64,
agent: &str,
pid: Option<i64>,
log_path: Option<&str>,
) -> Result<(Task, Session)>
pub fn record_dispatch( &mut self, task_id: i64, agent: &str, pid: Option<i64>, log_path: Option<&str>, ) -> Result<(Task, Session)>
Dispatch’s atomic write (DESIGN.md §8): move the task ready → running
(or stalled → running) and open its session in one transaction, so a
running task always has a session and a session always has a running
task. Spawning the process is the caller’s job, before this commits.
Sourcepub fn record_continuation(
&mut self,
task_id: i64,
agent: &str,
pid: Option<i64>,
log_path: Option<&str>,
) -> Result<(Task, Session)>
pub fn record_continuation( &mut self, task_id: i64, agent: &str, pid: Option<i64>, log_path: Option<&str>, ) -> Result<(Task, Session)>
Record a continuation session (DESIGN.md §6/§8): the answer to a
needs-input question is fed back not through a live pipe but by
dispatching a fresh session over the task body, now carrying the appended
## Answers section. Unlike record_dispatch,
this asserts the task is already running, so it never weakens the
ready-only rule — it only adds a session to a task the transition API
already moved.
Sourcepub fn reconcile_session(
&mut self,
session_id: i64,
pid_alive: bool,
likely_capped: bool,
) -> Result<Option<(Session, Task)>>
pub fn reconcile_session( &mut self, session_id: i64, pid_alive: bool, likely_capped: bool, ) -> Result<Option<(Session, Task)>>
Reconcile an open session against its task’s state (DESIGN.md §8). The
session’s life follows the task, not the process listing, so the terminal
transitions close healthy sessions; reconciliation only catches a crash
or cap mid-running and finalises sessions stranded on already-closed
tasks. pid_alive/likely_capped are supplied by the caller (voro-core
does no process or log I/O) and matter only for a running task:
- session already ended: no-op (
Ok(None)), so a repeated sweep can’t double-finalise it. running,pid_alive: left untouched.running, process gone: outcome recorded (capped/failed) and the task goesrunning → stalled(DESIGN.md §6/§8) — an attention row never handed out byvoro next; a latedonelands it inreviewon the dead session’s behalf. A stalled task with an open blocker demotes toparked.needs-input/review/waiting: the session stays open on purpose (reused by the continuation), so this leaves it alone (Ok(None)) regardless of liveness.- task already closed or off the active path: the session is stale, so it
is finalised now (
completedfordone, elseaborted) with no event.
Sourcepub fn set_blocks_deps(
&mut self,
task_id: i64,
depends_on: &[i64],
) -> Result<Task>
pub fn set_blocks_deps( &mut self, task_id: i64, depends_on: &[i64], ) -> Result<Task>
Replace the blocks dependencies of a task with the given set, then
reconcile its readiness. This is the dep-editing entry point for
interfaces; add_dep/remove_dep reconcile too.
Sourcepub fn block_tasks(
&mut self,
blocker_id: i64,
dependents: &[i64],
) -> Result<Vec<(Task, TaskState)>>
pub fn block_tasks( &mut self, blocker_id: i64, dependents: &[i64], ) -> Result<Vec<(Task, TaskState)>>
The reverse authoring direction of
set_blocks_deps: make blocker_id a blocker
of each task in dependents. Additive and idempotent (replacing the set
here would detach edges other tasks authored). Each dependent’s readiness
is reconciled in the same write; the returned pairs carry its prior state
so callers can surface a demotion.