Repository navigation
Milestone 25: deterministic run effort estimates and size-oriented queue filters - #47
Merged
Merged
Conversation
Co-authored-by: anschmieg <6830368+anschmieg@users.noreply.github.com>
Copilot stopped work on behalf of
anschmieg due to an error
March 18, 2026 08:49
- Add effort field to test helper in run_set_dependencies.rs - Fix redundant closure clippy warnings in handlers.rs - Merge main and resolve conflicts
anschmieg
marked this pull request as ready for review
March 18, 2026 09:50
There was a problem hiding this comment.
Pull request overview
Adds deterministic “effort bucket” metadata to runs (small/medium/large) and exposes it through the protocol, persistence, and daemon listing/inspection surfaces to enable size-oriented queue filtering and sorting.
Changes:
- Introduces
RunEffort+run.set_effortprotocol DTOs and threadseffortthroughRunState/RunSummary/RunGetResult/RunsListParams. - Persists
effortin SQLite and surfaces it viaget_run/list_runs, plus adds handler-side filtering/sorting. - Adds deterministic core logic + tests for setting/clearing effort; updates numerous test helpers/constructors to include the new field.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| codex-rs/deterministic-protocol/src/types.rs | Adds RunEffort, run.set_effort params/results, and effort fields + list filter/sort params. |
| codex-rs/deterministic-protocol/src/methods.rs | Adds Method::RunSetEffort and wire name mapping. |
| codex-rs/deterministic-daemon/src/persistence.rs | Adds SQLite effort column migration and persists/loads effort in save/get/list paths. |
| codex-rs/deterministic-daemon/src/handlers.rs | Wires dispatch for run.set_effort, adds effort to run.get, and adds effort filter/sort to runs.list. |
| codex-rs/deterministic-core/src/run_set_effort.rs | Implements deterministic set/clear effort logic with unit tests. |
| codex-rs/deterministic-core/src/lib.rs | Exports run_set_effort module. |
| codex-rs/deterministic-core/src/run_prepare.rs | Initializes new runs with effort: None. |
| codex-rs/deterministic-core/src/run_supersede.rs | Ensures superseded/successor state initialization includes effort: None. |
| codex-rs/deterministic-core/src/run_archive.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_unarchive.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_pin.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_unpin.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_snooze.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_unsnooze.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_finalize.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_reopen.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_replan.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_refresh.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_set_due_date.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_set_dependencies.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_set_priority.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/run_assign_owner.rs | Updates test helper state construction to include effort. |
| codex-rs/deterministic-core/src/approval.rs | Updates test helper state construction to include effort. |
You can also share your feedback on Copilot code review. Take the survey.
| let blocked_by_count_val = blocked_by_run_ids.len(); | ||
| let is_blocked_val = !blocked_by_run_ids.is_empty(); | ||
| // Milestone 24: effort — optional TEXT, default None. | ||
| let effort_str: Option<String> = row.get(22).unwrap_or(None); |
Comment on lines
261
to
266
| // Milestone 21: persist blocked_by_run_ids as JSON array. | ||
| let blocked_by_run_ids_json = serde_json::to_string(&state.blocked_by_run_ids) | ||
| .context("failed to serialise blocked_by_run_ids")?; | ||
| // Milestone 24: persist effort as optional string. | ||
| let effort_str: Option<&str> = state.effort.as_ref().map(|e| e.as_str()); | ||
| conn.execute( |
Comment on lines
55
to
60
| RunSetDependencies, | ||
| // Milestone 24: deterministic queue overview | ||
| RunsQueueOverview, | ||
| // Milestone 25: deterministic run effort estimates | ||
| RunSetEffort, | ||
| } |
| /// | ||
| /// - `Some(Some(effort))` → set effort to this value | ||
| /// - `Some(None)` → clear the effort estimate | ||
| /// - `None` → no-op (absent from JSON; treated as no change) |
Comment on lines
+1790
to
+1798
| // --------------------------------------------------------------------------- | ||
| // run.set_effort (Milestone 24) | ||
| // --------------------------------------------------------------------------- | ||
|
|
||
| /// Deterministic run effort bucket. | ||
| /// | ||
| /// Three levels from smallest to largest: `small < medium < large`. | ||
| /// The default for all new and existing runs is `None` (no estimate set). | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] |
Comment on lines
+543
to
+551
| // effort sort last. Uses a stable sort to preserve the existing pin / updated_at | ||
| // ordering within each bucket. | ||
| if p.sort_by_effort.unwrap_or(false) { | ||
| runs.sort_by(|a, b| match (a.effort, b.effort) { | ||
| (Some(ea), Some(eb)) => ea.cmp(&eb), | ||
| (Some(_), None) => std::cmp::Ordering::Less, | ||
| (None, Some(_)) => std::cmp::Ordering::Greater, | ||
| (None, None) => std::cmp::Ordering::Equal, | ||
| }); |
| &serde_json::json!({ | ||
| "previous_effort": result.previous_effort.map(deterministic_protocol::RunEffort::as_str), | ||
| "effort": result.effort.map(deterministic_protocol::RunEffort::as_str), | ||
| "updated_at": result.updated_at, |
Comment on lines
62
to
+66
| Method::RunSetDependencies => handle_run_set_dependencies(params, store), | ||
| // Milestone 24: deterministic queue overview | ||
| Method::RunsQueueOverview => handle_runs_queue_overview(params, store), | ||
| // Milestone 25: deterministic run effort estimates | ||
| Method::RunSetEffort => handle_run_set_effort(params, store), |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RunEffortenum todeterministic-protocol/src/types.rswith variantssmall | medium | largeRunSetEffortParamsandRunSetEffortResultprotocol typesRunSetEfforttoMethodenum indeterministic-protocol/src/methods.rseffortfield toRunState,RunSummary,RunGetResult, andRunsListParamscodex-rs/deterministic-core/src/run_set_effort.rswith deterministic logic and testsrun_set_efforttodeterministic-core/src/lib.rsRunSetEfforthandler indeterministic-daemon/src/handlers.rseffortcolumn migration todeterministic-daemon/src/persistence.rssave_run,get_run, andlist_runsin persistence to include efforthandle_runs_listRunGetResultinhandle_run_getRunStatemake_run_state test helper in persistence.rsset_run_effortMCP tool to TypeScript gateway (schemas.ts, tools.ts)invariants.test.tswith Milestone 24 entriesOriginal prompt
This section details on the original issue you should resolve
<issue_title>Milestone 24: deterministic run effort estimates and size-oriented queue filters</issue_title>
<issue_description>Implement Milestone 24 for ChatCodex: add deterministic run effort estimates and size-oriented queue filters so ChatGPT can explicitly classify runs by expected execution size without introducing backend autonomy.
Summary
The control plane can now represent blockers, readiness, priority, due dates, ownership, and blocker impact, but it still lacks a compact way to express how large or small a run is.
ChatGPT should be able to say things like:
run.get,run.refresh, andruns.listThis milestone is about deterministic planning metadata and queue visibility, not automation.
In scope
1. Deterministic effort metadata
Add compact structured effort metadata to runs.
Conservative first version:
small | medium | large2. Dedicated explicit update operation
Add a tightly scoped metadata operation such as:
set_run_effortrun.set_effortThis operation should:
3. Authoritative inspection support
Expose effort metadata in:
run.getrun.refreshwhere appropriateruns.listRunSummaryshould carry concise effort fields if practical.4. Deterministic list behavior
Extend run listing in a tightly scoped way.
At minimum support:
5. Audit trail integration
Append a deterministic audit entry such as:
run_effort_setIf helpful, include concise metadata such as previous and next effort value.
6. TypeScript MCP gateway updates
Keep TypeScript thin:
Do not move effort logic into TypeScript.
7. SQLite persistence updates
Persist effort metadata with safe, idempotent migration support.
New databases must work immediately.
Older databases must migrate safely and deterministically.
8. Tests and CI
Add milestone-scoped tests for:
Out of scope
Do not implement:
Acceptance criteria
<agent_instructions>Implement Milestone 24 for ChatCodex: add deterministic run effort estimates and size-oriented queue filters so ChatGPT can explicitly classify runs by expected size without introducing backend autonomy.
This milestone builds on the current system, which already includes:
📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.