Repository navigation
mcpx: give tasks honest cancellation and error endings (#2499) - #3699
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 43 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e0c4363614
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| t.cancelTimer = time.AfterFunc(grace, func() { | ||
| s.expireCancellation(t, reason) | ||
| }) |
There was a problem hiding this comment.
Preserve immediate cancellation for legacy MCP clients
For clients negotiated to 2025-11-25, mcpserver/tasks.go still handles tasks/cancel by calling this shared store method and returning its snapshot. Replacing the immediate terminal transition with a grace timer now returns working or input_required, and cooperative work can subsequently become completed or failed. That violates the legacy requirements recorded in internal/conformance/requirements.json (tasks-cancel-transition-before-response and tasks-cancelled-sticky): cancellation must transition to cancelled before replying and remain cancelled. Keep the cooperative behavior for the modern extension while preserving the legacy cancellation semantics.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in f75de20: the legacy 2025-11-25 tasks/cancel handler now calls the new tasks.Store.CancelImmediate, which records Cancelled under the store lock before the reply (grace timer stopped, StatusMessage set) and returns the terminal snapshot; the work is still notified but its later finish cannot change the ending (finish() drops results for terminal tasks). The cooperative grace window remains only on CancelWithReason (modern extension + daemon paths). Regression test TestCancelImmediateIsTerminalAndSticky covers terminal-and-sticky with a grace window configured; internal/tasks, mcpserver Task|Cancel, and conformance Cancel|Stateful tests pass on the laptop.
|
🤖 Agent note · parked (task 5601, lane E resume)
|
…ment-honest-task-endings # Conflicts: # pkgs/mcpx/internal/settings/effect.go
|
Fix-forward for the Codex P1 (finding 4435807111), in f75de20 + merge 7f37ee0:
Verification on the laptop: @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f37ee033b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sections: prototasks | ||
| kind: Added | ||
| summary: protoTasks.cancelGrace setting (5s) — cooperative task work may finish inside the cancel grace window instead of being recorded cancelled (#2499) |
There was a problem hiding this comment.
Register the new change fragment in the compendium manifest
This newly added Markdown file has no entry in docs/compendium.manifest.json. TestEveryDocumentHasAChapter in internal/settings/compendium_test.go scans all Markdown files, including docs/changes, and fails for each unregistered file. Although main already has unrelated manifest drift, this fragment introduces an additional failure that will remain after those baseline issues are fixed. Add a manifest entry, using the existing change fragment's not-compendium role if appropriate.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed: docs/changes/prototasks-cancel-grace.md is now registered in docs/compendium.manifest.json as a not-compendium docs-history fragment (same shape as the artifact-copy-semantics entry). Re-running TestEveryDocumentHasAChapter, our file no longer appears; the 3 remaining unregistered files (TESTING.md, docs/changes/docs-history-tool.md, docs/changes/research-and-findings-chapter.md) are pre-existing on clean main and tracked by #2846.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d81a702983
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| if moved { | ||
| if transitioned { | ||
| s.changed(id) |
There was a problem hiding this comment.
Cancel the worker before notifying terminal-state watchers
When a legacy client cancels an ownerless modern task with an active task subscription, this synchronous notification can deadlock before reaching cancel(). The production watcher in mcpserver/listen.go calls detailedNow, which calls Store.Result for terminal tasks and waits for t.done. If the worker is waiting on ctx.Done(), neither side can proceed: the watcher waits for the worker, while cancellation waits for the watcher. Previously, the worker context was cancelled before notifying watchers. Move this notification after the cancellation hooks and context cancellation so the cancellation request and subscribed stream can finish.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in f847036: CancelImmediate now invokes the OnCancel hook, the store hook, and the worker context cancellation before s.changed(id) notifies watchers, so a watcher waiting on Store.Result/done cannot deadlock against the pending cancellation. internal/tasks tests pass.
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
isErrorresults now carry the first text block asstatusMessage(512-rune limit), or the specified fallback. AddsprotoTasks.cancelGrace(default5s), store/settings wiring, docs, tests, and retires both conformance gaps. Closes #2499.Evidence
CancelWithReasonpersistedcancelledbefore invoking cancellation hooks;finishdiscarded any later result. TheisErrorbranch setfailedwithout a message.go test ./internal/tasks -count=1passes; changed task tests pass with-race -shuffle=on -count=5; focused setting/docs tests pass;internal/mcpserver,internal/daemon, andinternal/clicompile.internal/conformancetest package currently does not compile on this base because existing test backends implement the olderCompletesignature; CI should confirm whether that baseline has since been repaired.Merge Danger
Door: two-way
Blast Radius: tasks
Only task-store terminal-state behavior and its daemon setting change; the existing wire status enum and
OnCancelcontract remain unchanged.Need help on this PR? Tag
@codesmith-botwith what you need.