Codex Handbook
state/src/runtime/goals.rs 1639 lines
use super::*;use crate::model::ThreadGoalRow;use uuid::Uuid;#[derive(Clone)]pub struct GoalStore {    pool: Arc<SqlitePool>,}impl GoalStore {    pub(crate) fn new(pool: Arc<SqlitePool>) -> Self {        Self { pool }    }    pub(crate) async fn close(&self) {        self.pool.close().await;    }}pub struct GoalUpdate {    pub objective: Option<String>,    pub status: Option<crate::ThreadGoalStatus>,    pub token_budget: Option<Option<i64>>,    pub expected_goal_id: Option<String>,}pub enum GoalAccountingOutcome {    Unchanged(Option<crate::ThreadGoal>),    Updated(crate::ThreadGoal),}#[derive(Clone, Copy, Debug, Eq, PartialEq)]pub enum GoalAccountingMode {    ActiveStatusOnly,    ActiveOnly,    ActiveOrComplete,    ActiveOrStopped,}impl GoalStore {    pub async fn get_thread_goal(        &self,        thread_id: ThreadId,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        let row = sqlx::query(            r#"SELECT    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_msFROM thread_goalsWHERE thread_id = ?            "#,        )        .bind(thread_id.to_string())        .fetch_optional(self.pool.as_ref())        .await?;        row.map(|row| thread_goal_from_row(&row)).transpose()    }    pub async fn replace_thread_goal(        &self,        thread_id: ThreadId,        objective: &str,        status: crate::ThreadGoalStatus,        token_budget: Option<i64>,    ) -> anyhow::Result<crate::ThreadGoal> {        let goal_id = Uuid::new_v4().to_string();        let now_ms = datetime_to_epoch_millis(Utc::now());        let status = status_after_budget_limit(status, /*tokens_used*/ 0, token_budget);        let row = sqlx::query(            r#"INSERT INTO thread_goals (    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms) VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)ON CONFLICT(thread_id) DO UPDATE SET    goal_id = excluded.goal_id,    objective = excluded.objective,    status = excluded.status,    token_budget = excluded.token_budget,    tokens_used = 0,    time_used_seconds = 0,    created_at_ms = excluded.created_at_ms,    updated_at_ms = excluded.updated_at_msRETURNING    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms            "#,        )        .bind(thread_id.to_string())        .bind(goal_id)        .bind(objective)        .bind(status.as_str())        .bind(token_budget)        .bind(now_ms)        .bind(now_ms)        .fetch_one(self.pool.as_ref())        .await?;        thread_goal_from_row(&row)    }    pub async fn insert_thread_goal(        &self,        thread_id: ThreadId,        objective: &str,        status: crate::ThreadGoalStatus,        token_budget: Option<i64>,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        let goal_id = Uuid::new_v4().to_string();        let now_ms = datetime_to_epoch_millis(Utc::now());        let status = status_after_budget_limit(status, /*tokens_used*/ 0, token_budget);        let row = sqlx::query(            r#"INSERT INTO thread_goals (    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms) VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)ON CONFLICT(thread_id) DO UPDATE SET    goal_id = excluded.goal_id,    objective = excluded.objective,    status = excluded.status,    token_budget = excluded.token_budget,    tokens_used = 0,    time_used_seconds = 0,    created_at_ms = excluded.created_at_ms,    updated_at_ms = excluded.updated_at_msWHERE thread_goals.status = 'complete'RETURNING    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms            "#,        )        .bind(thread_id.to_string())        .bind(goal_id)        .bind(objective)        .bind(status.as_str())        .bind(token_budget)        .bind(now_ms)        .bind(now_ms)        .fetch_optional(self.pool.as_ref())        .await?;        row.map(|row| thread_goal_from_row(&row)).transpose()    }    pub async fn update_thread_goal(        &self,        thread_id: ThreadId,        update: GoalUpdate,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        let GoalUpdate {            objective,            status,            token_budget,            expected_goal_id,        } = update;        let objective = objective.as_deref();        let expected_goal_id = expected_goal_id.as_deref();        let now_ms = datetime_to_epoch_millis(Utc::now());        let result = match (status, token_budget) {            (Some(status), Some(token_budget)) => {                sqlx::query(                    r#"UPDATE thread_goalsSET    objective = COALESCE(?, objective),    status = CASE        WHEN status = ? AND ? IN (?, ?) THEN status        WHEN ? = 'active' AND ? IS NOT NULL AND tokens_used >= ? THEN ?        ELSE ?    END,    token_budget = ?,    updated_at_ms = ?WHERE thread_id = ?  AND (? IS NULL OR goal_id = ?)            "#,                )                .bind(objective)                .bind(crate::ThreadGoalStatus::BudgetLimited.as_str())                .bind(status.as_str())                .bind(crate::ThreadGoalStatus::Paused.as_str())                .bind(crate::ThreadGoalStatus::Blocked.as_str())                .bind(status.as_str())                .bind(token_budget)                .bind(token_budget)                .bind(crate::ThreadGoalStatus::BudgetLimited.as_str())                .bind(status.as_str())                .bind(token_budget)                .bind(now_ms)                .bind(thread_id.to_string())                .bind(expected_goal_id)                .bind(expected_goal_id)                .execute(self.pool.as_ref())                .await?            }            (Some(status), None) => {                sqlx::query(                    r#"UPDATE thread_goalsSET    objective = COALESCE(?, objective),    status = CASE        WHEN status = ? AND ? IN (?, ?) THEN status        WHEN ? = 'active' AND token_budget IS NOT NULL AND tokens_used >= token_budget THEN ?        ELSE ?    END,    updated_at_ms = ?WHERE thread_id = ?  AND (? IS NULL OR goal_id = ?)            "#,                )                .bind(objective)                .bind(crate::ThreadGoalStatus::BudgetLimited.as_str())                .bind(status.as_str())                .bind(crate::ThreadGoalStatus::Paused.as_str())                .bind(crate::ThreadGoalStatus::Blocked.as_str())                .bind(status.as_str())                .bind(crate::ThreadGoalStatus::BudgetLimited.as_str())                .bind(status.as_str())                .bind(now_ms)                .bind(thread_id.to_string())                .bind(expected_goal_id)                .bind(expected_goal_id)                .execute(self.pool.as_ref())                .await?            }            (None, Some(token_budget)) => {                sqlx::query(                    r#"UPDATE thread_goalsSET    objective = COALESCE(?, objective),    token_budget = ?,    status = CASE        WHEN status = 'active' AND ? IS NOT NULL AND tokens_used >= ? THEN ?        ELSE status    END,    updated_at_ms = ?WHERE thread_id = ?  AND (? IS NULL OR goal_id = ?)            "#,                )                .bind(objective)                .bind(token_budget)                .bind(token_budget)                .bind(token_budget)                .bind(crate::ThreadGoalStatus::BudgetLimited.as_str())                .bind(now_ms)                .bind(thread_id.to_string())                .bind(expected_goal_id)                .bind(expected_goal_id)                .execute(self.pool.as_ref())                .await?            }            (None, None) => {                if let Some(objective) = objective {                    sqlx::query(                        r#"UPDATE thread_goalsSET    objective = ?,    updated_at_ms = ?WHERE thread_id = ?  AND (? IS NULL OR goal_id = ?)            "#,                    )                    .bind(objective)                    .bind(now_ms)                    .bind(thread_id.to_string())                    .bind(expected_goal_id)                    .bind(expected_goal_id)                    .execute(self.pool.as_ref())                    .await?                } else {                    let goal = self.get_thread_goal(thread_id).await?;                    return Ok(match (goal, expected_goal_id) {                        (Some(goal), Some(expected_goal_id))                            if goal.goal_id != expected_goal_id =>                        {                            None                        }                        (goal, _) => goal,                    });                }            }        };        if result.rows_affected() == 0 {            return Ok(None);        }        self.get_thread_goal(thread_id).await    }    pub async fn pause_active_thread_goal(        &self,        thread_id: ThreadId,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        self.update_active_thread_goal_status(thread_id, crate::ThreadGoalStatus::Paused)            .await    }    pub async fn usage_limit_active_thread_goal(        &self,        thread_id: ThreadId,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        self.update_active_thread_goal_status(thread_id, crate::ThreadGoalStatus::UsageLimited)            .await    }    async fn update_active_thread_goal_status(        &self,        thread_id: ThreadId,        status: crate::ThreadGoalStatus,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        let now_ms = datetime_to_epoch_millis(Utc::now());        let result = sqlx::query(            r#"UPDATE thread_goalsSET    status = ?,    updated_at_ms = ?WHERE thread_id = ?  AND (      status = 'active'      OR (          ? = 'usage_limited'          AND status = 'budget_limited'      )  )            "#,        )        .bind(status.as_str())        .bind(now_ms)        .bind(thread_id.to_string())        .bind(status.as_str())        .execute(self.pool.as_ref())        .await?;        if result.rows_affected() == 0 {            return Ok(None);        }        self.get_thread_goal(thread_id).await    }    pub async fn delete_thread_goal(        &self,        thread_id: ThreadId,    ) -> anyhow::Result<Option<crate::ThreadGoal>> {        let row = sqlx::query(            r#"DELETE FROM thread_goalsWHERE thread_id = ?RETURNING    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms            "#,        )        .bind(thread_id.to_string())        .fetch_optional(self.pool.as_ref())        .await?;        row.map(|row| thread_goal_from_row(&row)).transpose()    }    pub async fn account_thread_goal_usage(        &self,        thread_id: ThreadId,        time_delta_seconds: i64,        token_delta: i64,        mode: GoalAccountingMode,        expected_goal_id: Option<&str>,    ) -> anyhow::Result<GoalAccountingOutcome> {        let time_delta_seconds = time_delta_seconds.max(0);        let token_delta = token_delta.max(0);        if time_delta_seconds == 0 && token_delta == 0 {            return Ok(GoalAccountingOutcome::Unchanged(                self.get_thread_goal(thread_id).await?,            ));        }        let now_ms = datetime_to_epoch_millis(Utc::now());        let active_or_stopped_status_filter =            "status IN ('active', 'paused', 'blocked', 'usage_limited', 'budget_limited')";        let status_filter = match mode {            GoalAccountingMode::ActiveStatusOnly => "status = 'active'",            GoalAccountingMode::ActiveOnly => "status IN ('active', 'budget_limited')",            GoalAccountingMode::ActiveOrComplete => {                "status IN ('active', 'budget_limited', 'complete')"            }            GoalAccountingMode::ActiveOrStopped => active_or_stopped_status_filter,        };        let budget_limit_status_filter = match mode {            GoalAccountingMode::ActiveStatusOnly            | GoalAccountingMode::ActiveOnly            | GoalAccountingMode::ActiveOrComplete => "status = 'active'",            GoalAccountingMode::ActiveOrStopped => active_or_stopped_status_filter,        };        let mut builder = QueryBuilder::<Sqlite>::new(            r#"UPDATE thread_goalsSET    time_used_seconds = time_used_seconds +            "#,        );        builder.push_bind(time_delta_seconds);        builder.push(            r#",    tokens_used = tokens_used +            "#,        );        builder.push_bind(token_delta);        builder.push(            r#",    status = CASE        WHEN            "#,        );        builder.push(budget_limit_status_filter);        builder.push(            r#"            AND token_budget IS NOT NULL            AND tokens_used +            "#,        );        builder.push_bind(token_delta);        builder.push(            r#"                >= token_budget            THEN            "#,        );        builder.push_bind(crate::ThreadGoalStatus::BudgetLimited.as_str());        builder.push(            r#"        ELSE status    END,    updated_at_ms =            "#,        );        builder.push_bind(now_ms);        builder.push(            r#"WHERE thread_id =            "#,        );        builder.push_bind(thread_id.to_string());        builder.push(" AND ");        builder.push(status_filter);        if let Some(expected_goal_id) = expected_goal_id {            builder.push(" AND goal_id = ").push_bind(expected_goal_id);        }        builder.push(            r#"RETURNING    thread_id,    goal_id,    objective,    status,    token_budget,    tokens_used,    time_used_seconds,    created_at_ms,    updated_at_ms            "#,        );        let row = builder.build().fetch_optional(self.pool.as_ref()).await?;        let Some(row) = row else {            return Ok(GoalAccountingOutcome::Unchanged(                self.get_thread_goal(thread_id).await?,            ));        };        let updated = thread_goal_from_row(&row)?;        Ok(GoalAccountingOutcome::Updated(updated))    }}fn thread_goal_from_row(row: &sqlx::sqlite::SqliteRow) -> anyhow::Result<crate::ThreadGoal> {    ThreadGoalRow::try_from_row(row).and_then(crate::ThreadGoal::try_from)}fn status_after_budget_limit(    status: crate::ThreadGoalStatus,    tokens_used: i64,    token_budget: Option<i64>,) -> crate::ThreadGoalStatus {    if status == crate::ThreadGoalStatus::Active        && token_budget.is_some_and(|budget| tokens_used >= budget)    {        crate::ThreadGoalStatus::BudgetLimited    } else {        status    }}#[cfg(test)]mod tests {    use super::*;    use crate::runtime::test_support::test_thread_metadata;    use crate::runtime::test_support::unique_temp_dir;    use pretty_assertions::assert_eq;    async fn test_runtime() -> std::sync::Arc<StateRuntime> {        StateRuntime::init(unique_temp_dir(), "test-provider".to_string())            .await            .expect("state db should initialize")    }    fn test_thread_id() -> ThreadId {        ThreadId::from_string("00000000-0000-0000-0000-000000000123").expect("valid thread id")    }    async fn upsert_test_thread(runtime: &StateRuntime, thread_id: ThreadId) {        let metadata = test_thread_metadata(            runtime.codex_home(),            thread_id,            runtime.codex_home().join("workspace"),        );        runtime            .upsert_thread(&metadata)            .await            .expect("test thread should be upserted");    }    #[tokio::test]    async fn replace_update_and_get_thread_goal() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let goal = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "optimize the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100_000),            )            .await            .expect("goal replacement should succeed");        assert_eq!(            Some(goal.clone()),            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .unwrap()        );        let metadata = runtime            .get_thread(thread_id)            .await            .expect("thread metadata should load")            .expect("thread should exist");        assert_eq!(metadata.preview.as_deref(), Some("hello"));        let updated = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Paused),                    token_budget: Some(Some(200_000)),                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        let expected = crate::ThreadGoal {            status: crate::ThreadGoalStatus::Paused,            token_budget: Some(200_000),            updated_at: updated.updated_at,            ..goal.clone()        };        assert_eq!(expected, updated);        let replaced = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "ship the new result",                crate::ThreadGoalStatus::Active,                /*token_budget*/ None,            )            .await            .expect("goal replacement should succeed");        assert_eq!("ship the new result", replaced.objective);        assert_eq!(crate::ThreadGoalStatus::Active, replaced.status);        assert_eq!(None, replaced.token_budget);        assert_eq!(0, replaced.tokens_used);        assert_eq!(0, replaced.time_used_seconds);        assert_eq!(            Some(replaced),            runtime                .thread_goals()                .delete_thread_goal(thread_id)                .await                .unwrap()        );        assert_eq!(            None,            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .unwrap()        );        assert_eq!(            None,            runtime                .thread_goals()                .delete_thread_goal(thread_id)                .await                .unwrap()        );    }    #[tokio::test]    async fn replace_thread_goal_applies_budget_limit_immediately() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let replaced = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(0),            )            .await            .expect("goal replacement should succeed");        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, replaced.status);        assert_eq!(Some(0), replaced.token_budget);        assert_eq!(0, replaced.tokens_used);        assert_eq!(0, replaced.time_used_seconds);    }    #[tokio::test]    async fn insert_thread_goal_does_not_replace_existing_goal() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let inserted = runtime            .thread_goals()            .insert_thread_goal(                thread_id,                "optimize the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100_000),            )            .await            .expect("goal insertion should succeed")            .expect("goal should be inserted");        let duplicate = runtime            .thread_goals()            .insert_thread_goal(                thread_id,                "replace the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(200_000),            )            .await            .expect("duplicate insert should not fail");        assert_eq!(None, duplicate);        assert_eq!(            Some(inserted),            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .unwrap()        );    }    #[tokio::test]    async fn insert_thread_goal_applies_budget_limit_immediately() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let inserted = runtime            .thread_goals()            .insert_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(0),            )            .await            .expect("goal insertion should succeed")            .expect("goal should be inserted");        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, inserted.status);        assert_eq!(Some(0), inserted.token_budget);        assert_eq!(0, inserted.tokens_used);        assert_eq!(0, inserted.time_used_seconds);    }    #[tokio::test]    async fn update_thread_goal_ignores_replaced_goal_version() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let original = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "old objective",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100),            )            .await            .expect("goal replacement should succeed");        let replacement = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "new objective",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(10),            )            .await            .expect("goal replacement should succeed");        let stale_update = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Complete),                    token_budget: None,                    expected_goal_id: Some(original.goal_id),                },            )            .await            .expect("goal update should succeed");        assert_eq!(None, stale_update);        assert_eq!(            Some(replacement.clone()),            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .expect("goal read should succeed")        );        let fresh_update = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Complete),                    token_budget: None,                    expected_goal_id: Some(replacement.goal_id),                },            )            .await            .expect("goal update should succeed")            .expect("fresh update should match the replacement goal");        assert_eq!(crate::ThreadGoalStatus::Complete, fresh_update.status);    }    #[tokio::test]    async fn usage_accounting_ignores_replaced_goal_version() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let original = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "old objective",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100),            )            .await            .expect("goal replacement should succeed");        let replacement = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "new objective",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(10),            )            .await            .expect("goal replacement should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 5,                /*token_delta*/ 5,                GoalAccountingMode::ActiveOnly,                Some(original.goal_id.as_str()),            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Unchanged(Some(goal)) = outcome else {            panic!("stale goal version should not be updated");        };        assert_ne!(replacement.goal_id, original.goal_id);        assert_eq!(replacement.created_at, goal.created_at);        assert_eq!("new objective", goal.objective);        assert_eq!(0, goal.tokens_used);        assert_eq!(0, goal.time_used_seconds);    }    #[tokio::test]    async fn update_thread_goal_objective_preserves_usage_and_created_at() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "draft the report",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100),            )            .await            .expect("goal replacement should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 12,                /*token_delta*/ 30,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(accounted) = outcome else {            panic!("active goal should account usage");        };        let updated = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: Some("draft the report clearly".to_string()),                    status: Some(crate::ThreadGoalStatus::Paused),                    token_budget: Some(Some(200)),                    expected_goal_id: Some(accounted.goal_id.clone()),                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        let expected = crate::ThreadGoal {            objective: "draft the report clearly".to_string(),            status: crate::ThreadGoalStatus::Paused,            token_budget: Some(200),            updated_at: updated.updated_at,            ..accounted        };        assert_eq!(expected, updated);    }    #[tokio::test]    async fn concurrent_partial_updates_preserve_independent_fields() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "optimize the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100_000),            )            .await            .expect("goal replacement should succeed");        let status_update = runtime.thread_goals().update_thread_goal(            thread_id,            GoalUpdate {                objective: None,                status: Some(crate::ThreadGoalStatus::Paused),                token_budget: None,                expected_goal_id: None,            },        );        let budget_update = runtime.thread_goals().update_thread_goal(            thread_id,            GoalUpdate {                objective: None,                status: None,                token_budget: Some(Some(200_000)),                expected_goal_id: None,            },        );        let (status_update, budget_update) = tokio::join!(status_update, budget_update);        status_update.expect("status update should succeed");        budget_update.expect("budget update should succeed");        let goal = runtime            .thread_goals()            .get_thread_goal(thread_id)            .await            .expect("goal read should succeed")            .expect("goal should exist");        assert_eq!(crate::ThreadGoalStatus::Paused, goal.status);        assert_eq!(Some(200_000), goal.token_budget);    }    #[tokio::test]    async fn pause_active_thread_goal_does_not_clobber_terminal_status() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let goal = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "optimize the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100_000),            )            .await            .expect("goal replacement should succeed");        let paused = runtime            .thread_goals()            .pause_active_thread_goal(thread_id)            .await            .expect("active pause should succeed")            .expect("active goal should be paused");        let expected = crate::ThreadGoal {            status: crate::ThreadGoalStatus::Paused,            updated_at: paused.updated_at,            ..goal        };        assert_eq!(expected, paused);        let complete = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Complete),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        let pause_result = runtime            .thread_goals()            .pause_active_thread_goal(thread_id)            .await            .expect("terminal pause attempt should succeed");        assert_eq!(None, pause_result);        assert_eq!(            Some(complete),            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .expect("goal read should succeed")        );    }    #[tokio::test]    async fn usage_limit_active_thread_goal_updates_active_or_budget_limited_goals() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        let goal = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "optimize the benchmark",                crate::ThreadGoalStatus::Active,                /*token_budget*/ None,            )            .await            .expect("goal replacement should succeed");        let usage_limited = runtime            .thread_goals()            .usage_limit_active_thread_goal(thread_id)            .await            .expect("usage limiting should succeed")            .expect("active goal should become usage limited");        let expected = crate::ThreadGoal {            status: crate::ThreadGoalStatus::UsageLimited,            updated_at: usage_limited.updated_at,            ..goal        };        assert_eq!(expected, usage_limited);        let second_update = runtime            .thread_goals()            .usage_limit_active_thread_goal(thread_id)            .await            .expect("repeated usage limiting should succeed");        assert_eq!(None, second_update);        let budget_limited = runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "keep the usage failure visible",                crate::ThreadGoalStatus::BudgetLimited,                /*token_budget*/ Some(1),            )            .await            .expect("goal replacement should succeed");        let usage_limited = runtime            .thread_goals()            .usage_limit_active_thread_goal(thread_id)            .await            .expect("usage limiting should succeed")            .expect("budget-limited goal should become usage limited");        let expected = crate::ThreadGoal {            status: crate::ThreadGoalStatus::UsageLimited,            updated_at: usage_limited.updated_at,            ..budget_limited        };        assert_eq!(expected, usage_limited);    }    #[tokio::test]    async fn usage_accounting_updates_active_goals_and_accounts_budget_limited_in_flight_usage() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(20),            )            .await            .expect("goal replacement should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 7,                /*token_delta*/ 5,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = outcome else {            panic!("active goal should be updated");        };        assert_eq!(crate::ThreadGoalStatus::Active, goal.status);        assert_eq!(5, goal.tokens_used);        assert_eq!(7, goal.time_used_seconds);        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 3,                /*token_delta*/ 15,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = outcome else {            panic!("budget crossing should update the goal");        };        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, goal.status);        assert_eq!(20, goal.tokens_used);        assert_eq!(10, goal.time_used_seconds);        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 5,                /*token_delta*/ 5,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = outcome else {            panic!("budget-limited goal should still account in-flight active usage");        };        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, goal.status);        assert_eq!(25, goal.tokens_used);        assert_eq!(15, goal.time_used_seconds);    }    #[tokio::test]    async fn active_status_only_usage_accounting_does_not_update_budget_limited_goals() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay stopped",                crate::ThreadGoalStatus::BudgetLimited,                /*token_budget*/ Some(20),            )            .await            .expect("goal replacement should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 5,                /*token_delta*/ 5,                GoalAccountingMode::ActiveStatusOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Unchanged(Some(goal)) = outcome else {            panic!("budget-limited goal should not be updated");        };        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, goal.status);        assert_eq!(0, goal.tokens_used);        assert_eq!(0, goal.time_used_seconds);    }    #[tokio::test]    async fn stopped_usage_accounting_promotes_paused_goal_over_budget() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stop before overrun",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(20),            )            .await            .expect("goal replacement should succeed");        runtime            .thread_goals()            .update_thread_goal(                thread_id,                crate::GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Paused),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 3,                /*token_delta*/ 25,                GoalAccountingMode::ActiveOrStopped,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = outcome else {            panic!("stopped goal should account final usage");        };        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, goal.status);        assert_eq!(25, goal.tokens_used);        assert_eq!(3, goal.time_used_seconds);    }    #[tokio::test]    async fn budget_updates_immediately_stop_active_goals_already_over_budget() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(100),            )            .await            .expect("goal replacement should succeed");        runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 1,                /*token_delta*/ 50,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let lowered = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: None,                    token_budget: Some(Some(40)),                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, lowered.status);        assert_eq!(Some(40), lowered.token_budget);        assert_eq!(50, lowered.tokens_used);    }    #[tokio::test]    async fn activating_goal_already_over_budget_keeps_it_budget_limited() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(40),            )            .await            .expect("goal replacement should succeed");        runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 1,                /*token_delta*/ 50,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let reactivated = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: Some("stay within budget, with clearer wording".to_string()),                    status: Some(crate::ThreadGoalStatus::Active),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, reactivated.status);        assert_eq!(            "stay within budget, with clearer wording",            reactivated.objective        );        assert_eq!(Some(40), reactivated.token_budget);        assert_eq!(50, reactivated.tokens_used);    }    #[tokio::test]    async fn pausing_budget_limited_goal_preserves_terminal_status() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(40),            )            .await            .expect("goal replacement should succeed");        runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 1,                /*token_delta*/ 50,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let paused = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Paused),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        assert_eq!(crate::ThreadGoalStatus::BudgetLimited, paused.status);        assert_eq!(Some(40), paused.token_budget);        assert_eq!(50, paused.tokens_used);    }    #[tokio::test]    async fn blocking_budget_limited_goal_preserves_terminal_status() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "stay within budget",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(40),            )            .await            .expect("goal replacement should succeed");        let outcome = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 1,                /*token_delta*/ 50,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(budget_limited) = outcome else {            panic!("budget crossing should update the goal");        };        let blocked = runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Blocked),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        let expected = crate::ThreadGoal {            updated_at: blocked.updated_at,            ..budget_limited        };        assert_eq!(expected, blocked);    }    #[tokio::test]    async fn usage_accounting_can_finalize_completed_goal_for_completing_turn() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "finish the report",                crate::ThreadGoalStatus::Complete,                /*token_budget*/ Some(1_000),            )            .await            .expect("goal replacement should succeed");        let active_only = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 30,                /*token_delta*/ 200,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Unchanged(Some(goal)) = active_only else {            panic!("completed goal should not be updated by active-only accounting");        };        assert_eq!(crate::ThreadGoalStatus::Complete, goal.status);        assert_eq!(0, goal.tokens_used);        assert_eq!(0, goal.time_used_seconds);        let completing_turn = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 30,                /*token_delta*/ 200,                GoalAccountingMode::ActiveOrComplete,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = completing_turn else {            panic!("completed goal should be updated for final accounting");        };        assert_eq!(crate::ThreadGoalStatus::Complete, goal.status);        assert_eq!(200, goal.tokens_used);        assert_eq!(30, goal.time_used_seconds);    }    #[tokio::test]    async fn usage_accounting_can_finalize_stopped_goal_for_in_flight_turn() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "finish the report",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(1_000),            )            .await            .expect("goal replacement should succeed");        runtime            .thread_goals()            .update_thread_goal(                thread_id,                GoalUpdate {                    objective: None,                    status: Some(crate::ThreadGoalStatus::Paused),                    token_budget: None,                    expected_goal_id: None,                },            )            .await            .expect("goal update should succeed")            .expect("goal should exist");        let active_only = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 30,                /*token_delta*/ 200,                GoalAccountingMode::ActiveOnly,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Unchanged(Some(goal)) = active_only else {            panic!("paused goal should not be updated by active-only accounting");        };        assert_eq!(crate::ThreadGoalStatus::Paused, goal.status);        assert_eq!(0, goal.tokens_used);        assert_eq!(0, goal.time_used_seconds);        let in_flight_turn = runtime            .thread_goals()            .account_thread_goal_usage(                thread_id,                /*time_delta_seconds*/ 30,                /*token_delta*/ 200,                GoalAccountingMode::ActiveOrStopped,                /*expected_goal_id*/ None,            )            .await            .expect("usage accounting should succeed");        let GoalAccountingOutcome::Updated(goal) = in_flight_turn else {            panic!("stopped goal should be updated for in-flight accounting");        };        assert_eq!(crate::ThreadGoalStatus::Paused, goal.status);        assert_eq!(200, goal.tokens_used);        assert_eq!(30, goal.time_used_seconds);    }    #[tokio::test]    async fn usage_accounting_adds_concurrent_token_deltas() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "count every token",                crate::ThreadGoalStatus::Active,                /*token_budget*/ Some(1_000),            )            .await            .expect("goal replacement should succeed");        let first = runtime.thread_goals().account_thread_goal_usage(            thread_id,            /*time_delta_seconds*/ 4,            /*token_delta*/ 40,            GoalAccountingMode::ActiveOnly,            /*expected_goal_id*/ None,        );        let second = runtime.thread_goals().account_thread_goal_usage(            thread_id,            /*time_delta_seconds*/ 6,            /*token_delta*/ 60,            GoalAccountingMode::ActiveOnly,            /*expected_goal_id*/ None,        );        let (first, second) = tokio::join!(first, second);        first.expect("first usage accounting should succeed");        second.expect("second usage accounting should succeed");        let goal = runtime            .thread_goals()            .get_thread_goal(thread_id)            .await            .expect("goal read should succeed")            .expect("goal should exist");        assert_eq!(100, goal.tokens_used);        assert_eq!(10, goal.time_used_seconds);    }    #[tokio::test]    async fn deleting_thread_deletes_goal() {        let runtime = test_runtime().await;        let thread_id = test_thread_id();        upsert_test_thread(&runtime, thread_id).await;        runtime            .thread_goals()            .replace_thread_goal(                thread_id,                "clean up with the thread",                crate::ThreadGoalStatus::Active,                /*token_budget*/ None,            )            .await            .expect("goal replacement should succeed");        runtime            .delete_thread(thread_id)            .await            .expect("thread deletion should succeed");        assert_eq!(            None,            runtime                .thread_goals()                .get_thread_goal(thread_id)                .await                .expect("goal read should succeed")        );    }}