docs(#2569): address argus review — add Errors/Panics doc sections + fix ClearTodo keyless-clear semantics

This commit is contained in:
damocles 2026-07-19 02:03:44 +02:00 committed by mara
commit 565b1b90fc
3 changed files with 61 additions and 5 deletions

View file

@ -106,6 +106,10 @@ pub fn for_agent(coord: &Coordinator, agent: &str) -> Result<Vec<LooseEnd>> {
/// This agent's dynamic todos as `LooseEnd::Todo` rows, optionally
/// filtered to one `subsystem`. Shared by [`for_agent`] and the
/// `ListTodos` handler so the row-mapping lives in one place.
///
/// # Errors
///
/// Propagates the todo-store query failure.
pub fn todos_for(
coord: &Coordinator,
agent: &str,

View file

@ -79,6 +79,11 @@ pub struct Todos {
}
impl Todos {
/// Open (creating if needed) the todo store at `path`.
///
/// # Errors
///
/// Propagates sqlite open / schema-apply / migration failures.
pub fn open(path: &Path) -> Result<Self> {
let conn = crate::db::open(path, "todos")?;
conn.execute_batch(SCHEMA).context("apply todos schema")?;
@ -97,6 +102,14 @@ impl Todos {
/// new OR its `summary`/`source` actually differed — the caller uses
/// this to decide whether to coalesce a wake (re-pushing an identical
/// keyed todo is a no-op and must not re-wake).
///
/// # Errors
///
/// Propagates sqlite query / execute failures.
///
/// # Panics
///
/// Panics if the connection mutex is poisoned.
pub fn upsert(
&self,
agent: &str,
@ -138,8 +151,20 @@ impl Todos {
Ok((conn.last_insert_rowid(), true))
}
/// Clear a producer-resolved todo, keyed by `(agent, subsystem, key)`.
/// Returns the number of rows deleted (0 when nothing matched).
/// Clear producer-resolved todo(s) by `(agent, subsystem, key)`.
/// `key = Some(k)` targets the one keyed row; `key = None` matches
/// `subsystem_key IS NULL`, i.e. **all** keyless todos for that
/// subsystem (keyless rows have no distinguishing key — clear a
/// specific one via [`Todos::mark_done`] by id instead). Returns the
/// number of rows deleted (0 when nothing matched).
///
/// # Errors
///
/// Propagates the sqlite delete failure.
///
/// # Panics
///
/// Panics if the connection mutex is poisoned.
pub fn clear(&self, agent: &str, subsystem: &str, key: Option<&str>) -> Result<usize> {
let conn = self.conn.lock().unwrap();
let n = conn.execute(
@ -152,6 +177,14 @@ impl Todos {
/// Clear every todo `agent`'s `subsystem` owns — used by a producer
/// that rebuilds its whole set on restart (cancel-and-recreate).
/// Returns the number of rows deleted.
///
/// # Errors
///
/// Propagates the sqlite delete failure.
///
/// # Panics
///
/// Panics if the connection mutex is poisoned.
pub fn clear_subsystem(&self, agent: &str, subsystem: &str) -> Result<usize> {
let conn = self.conn.lock().unwrap();
let n = conn.execute(
@ -164,6 +197,14 @@ impl Todos {
/// The agent marks one of *its own* todos done, by id. Scoped to
/// `agent` so one agent can't clear another's. Returns the number of
/// rows deleted (0 when the id was unknown / not owned / already gone).
///
/// # Errors
///
/// Propagates the sqlite delete failure.
///
/// # Panics
///
/// Panics if the connection mutex is poisoned.
pub fn mark_done(&self, agent: &str, id: i64) -> Result<usize> {
let conn = self.conn.lock().unwrap();
let n = conn.execute(
@ -176,6 +217,14 @@ impl Todos {
/// List `agent`'s todos, newest-updated first. `subsystem = Some(..)`
/// filters to one producer's set (so a producer can enumerate +
/// reconcile only its own); `None` returns all of the agent's.
///
/// # Errors
///
/// Propagates the sqlite prepare / query failures.
///
/// # Panics
///
/// Panics if the connection mutex is poisoned.
pub fn list(&self, agent: &str, subsystem: Option<&str>) -> Result<Vec<Todo>> {
let conn = self.conn.lock().unwrap();
let mut stmt = conn.prepare(

View file

@ -453,9 +453,12 @@ pub enum Request {
#[serde(default, skip_serializing_if = "Option::is_none")]
source: Option<String>,
},
/// Clear a producer-resolved todo by `(subsystem, key)`. `key = None`
/// targets the keyless one-off; `all = true` wipes the producer's
/// whole set (cancel-and-recreate on daemon restart).
/// Clear producer-resolved todo(s) by `(subsystem, key)`. `key =
/// Some(k)` clears the one keyed row; `key = None` clears **all** of
/// the subsystem's keyless todos (rows with no key can't be told
/// apart — clear a specific one via `MarkTodoDone` by id). `all =
/// true` wipes the producer's whole set (cancel-and-recreate on
/// daemon restart).
ClearTodo {
subsystem: String,
#[serde(default, skip_serializing_if = "Option::is_none")]