Skip to content

🤖 refactor: make turn cancellation and session disposal awaitable - #4118

Merged
ThomasK33 merged 1 commit into
mainfrom
codex/phase5-awaitable-disposal
Sep 7, 2026
Merged

🤖 refactor: make turn cancellation and session disposal awaitable#4118
ThomasK33 merged 1 commit into
mainfrom
codex/phase5-awaitable-disposal

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Cancellation now finishes the captured stream attempt's partial persistence and terminal delivery before a replacement starts. Session and workspace disposal await in-flight work, while application and CLI shutdown keep their existing bounded teardown budget.

Abort persistence moves from AIService event forwarding into StreamManager and its mock counterpart. The first cancellation owns its reason and completion; identity checks prevent old cleanup from touching a replacement, and failed commits retain recoverable partial data. Startup cancellation joins the same completion barrier without waiting on an envelope callback that may itself await stop.

AgentSession separates synchronous closing from awaitable disposal. WorkspaceService tracks destructive cleanup outside continuation callbacks to avoid joining the callback that requested removal, keeps subscriptions through captured terminal delivery, and joins cleanup within the app scope. Closing cancels idle and queue waits separately from physical cleanup. Empty service-graph rollback remains synchronous so constructor failures retain their original error.

Test fixtures now await teardown. Policy-only fake handles retire on their own session's closing signal; lifecycle tests retain independent completion barriers.

Validation: 512 session/coordinator/queue/hooks tests, 421 engine/history/AI/mock tests, 1,162 workspace/task/container tests, and 20 CLI/edit tests passed. The full static check and main-process build passed. Isolated UI suites passed for interruption (1 test) and send-mode/queue behavior (5 tests). Deterministic regressions hold disk writes, envelope callbacks, session work and task-tree locks to exercise concurrent stop, replacement, cleanup errors, reentrant disposal, and shutdown bounds.

Risk: incorrect cleanup ordering could stall interruption or workspace removal, or lose interrupted output. Raw engine events retain their role, and session policy settlement stays separate from engine completion to avoid circular waits. Compaction policy and retry ownership remain for later phases.


Generated with xum • Model: unavailable • Thinking: unavailable • Cost: $unavailable

Keep cancellation bound to its captured stream until partial persistence,
resource cleanup, and raw terminal delivery finish. Session disposal now
closes admission synchronously and returns one stable Promise that joins
engine cleanup, background work, and original execution leases.

Keep workspace bridges attached through disposal and transfer destructive
continuation-failure cleanup outside held callbacks and locks. A sibling
app-scope guardian owns deferred cleanup within the existing shutdown
budget; CLI teardown initiates disposal without adding a second unbounded
join. Empty guardian rollback stays synchronous to preserve constructor
failure reporting.

Validation: full static checks pass, alongside 512 session/coordinator/queue/
hook tests, 421 engine/history/AI tests, 1162 workspace/task/container tests,
and 20 CLI/updated-edit-fixture tests. Main build and isolated real-backend
Electron interruption (1 test) and send-mode (5 tests) workflows also pass.

Signed-off-by: Thomas Kosiewski <tk@coder.com>

---

_Generated with `xum` • Model: `unavailable` • Thinking: `unavailable` • Cost: `$unavailable`_

<!-- mux-attribution: model=unavailable thinking=unavailable costs=unavailable -->

Change-Id: Ic9f04b6d889877c85c694cad127f61b9dfc5e858
@chatgpt-codex-connector

This comment has been minimized.

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: ed08e6076f

ℹ️ 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".

@chatgpt-codex-connector

This comment has been minimized.

@ThomasK33
ThomasK33 added this pull request to the merge queue Sep 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 7, 2026
@ThomasK33
ThomasK33 added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit 42863ff Sep 7, 2026
35 of 38 checks passed
@ThomasK33
ThomasK33 deleted the codex/phase5-awaitable-disposal branch September 7, 2026 09:27
ibetitsmike added a commit that referenced this pull request Sep 7, 2026
Adopt main's serialized auto-retry preference writes (#4120), awaitable session disposal and closing-signal turn handles (#4118) while keeping this branch's unrecorded-write tracking, idle-wake predicates, and pricing-identity tests.
ibetitsmike added a commit that referenced this pull request Sep 7, 2026
When an accepted wake's consumption I/O keeps failing until the app exits, the
durable transcript row is the only record of delivery: on the next run the
signal derives as outstanding again and the in-memory owed acceptance is gone.
The reconciler now asks the owner's history for wake records before dispatching
and treats a signal whose (processId, wakeUpdatedAt) key is already in the
transcript as delivered, advancing its watermark and acknowledging it with no
new row. The lookup scans full history backward, compaction archive included,
stopping once a chunk predates every process being checked, and is memoized per
outstanding key so an unchanged frontier reconciles without another read. A
failed history read rejects so dispatch stays held in the retry backoff.

Also retires the wake-wiring test harness's never-completed stream handles on
session close, which #4118's awaitable dispose otherwise drains forever.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant