Skip to content

refactor(dev): MCP session lifecycles as Effect scoped resources (wave 3.5 stage 3, PR 2) - #159

Merged
ScriptedAlchemy merged 1 commit into
mainfrom
wave35-s3/mcp-session
Sep 1, 2026
Merged

refactor(dev): MCP session lifecycles as Effect scoped resources (wave 3.5 stage 3, PR 2)#159
ScriptedAlchemy merged 1 commit into
mainfrom
wave35-s3/mcp-session

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Subsystem 1 of 4 for #152 stage 3, in the plan's order — MCP sessions first: the lifecycle seam is self-contained behind McpSessionService/McpSession, giving the smallest blast radius of the four.

  • Open chain as scoped resources. McpSessionService.#openEffect acquires the epoch lease and plugin-data directory with Effect.acquireRelease inside the open scope. Releases are infallible (stage-2 lesson): failures are collected, reported through the existing cleanup-failure seam, and the last one re-raises — byte-for-byte the pre-Effect precedence. Once the McpSession is constructed it owns the resources and the scope finalizers disarm; a later failure cleans up via session.close() exactly as before.
  • fix(dev): fail MCP tool calls closed when the pinned epoch vanishes #134 fail-closed contract on the typed error channel. #assertEpochCurrentEffect(): Effect<void, McpSessionStaleEpochError> probes the pinned epoch before each tool call; the mid-flight-vanish path re-probes and substitutes the typed stale-epoch failure for the incidental abort/timeout, then cancels every in-flight request and closes the session (unchanged contract, including the stderr-overflow mirror).
  • Session teardown as one structured Effect. Every release step always runs in order (drain client → rm plugin data → release epoch lease → notify owner); the last failing step's error re-raises — the same last-failure-wins contract the nested finally chain had. The lifecycle serial queue is now an Effect Semaphore(1).
  • Service close settles openings first, then sessions, each phase concurrently via per-element Exit, aggregating into the unchanged McpSessionServiceCloseError failure order.
  • New src/effect/lift.ts: identity-preserving liftPromise/liftTry (typed dev errors and non-Error values must cross the boundary untouched).
  • All Promise edges go through the stage-0/PR-1 boundary; SDK AbortSignal plumbing (session-service close abort, per-request cancel controllers) intentionally stays at the SDK edge.

Parity (all suites unchanged, zero pin flips)

  • mcp-session-service.test.ts + target-mcp-runtime.test.ts (integration pool): 35 passed / 0 failed
  • dev-server.test.ts, mcp-session-routes.test.ts (AB8018/409 contract), boundary tests (unit pool): 62 passed / 0 failed
  • pnpm lint (incl. boundary rule) + pnpm typecheck: green
  • Changeset: patch (internal rewrite).

Refs #152.

@changeset-bot

changeset-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3261b9c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T17:41:19.636818Z 3261b9c PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ScriptedAlchemy
ScriptedAlchemy merged commit 0343e04 into main Sep 1, 2026
4 of 9 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the wave35-s3/mcp-session branch September 3, 2026 05:29
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