[PR #3470] [CLOSED] fix(browser): shut down the WebMCP domain before detaching CDP targets #5762

Closed
opened 2026-10-31 01:09:14 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3470
Author: @LuckVd
Created: 10/14/2026
Status: ❌ Closed

Base: main ← Head: fix/3193-webmcp-domain-shutdown


📝 Commits (2)

  • d323390 fix(browser): shut down the WebMCP domain before detaching CDP targets
  • 2873764 test(browser): guard WebMCP cleanup wiring and close ordering

📊 Changes

2 files changed (+98 additions, -1 deletions)

View changed files

📝 src/browser/CdpBrowserProvider.ts (+12 -1)
➕ src/browser/CdpTargetSession.test.ts (+86 -0)

📄 Description

Summary

discover_webmcp_tools enables the WebMCP CDP domain on the target session, but session teardown never sent WebMCP.disable before detaching and closing the socket. closeCdpTargetSession already owns domain shutdown via CLEANUP_DOMAINS; this change adds WebMCP to that list so the domain is shut down by the existing owner. Fixes #3193.

Problem and expected behavior

  • Trigger: run discover_webmcp_tools against a CDP target that supports WebMCP.
  • Violated invariant: a successfully enabled CDP domain is disabled before the session detaches (enable/disable symmetry over the same session).
  • Observed: WebMCP.enable is sent (CdpWebMcpDiscovery.ts), then teardown detaches and closes without WebMCP.disable.
  • Expected: WebMCP.disable is attempted during session cleanup, before Target.detachFromTarget and socket close.

Change and scope

Add "WebMCP" to CLEANUP_DOMAINS in src/browser/CdpBrowserProvider.ts. Domain shutdown stays owned by closeCdpTargetSession, which already sends each ${domain}.disable best-effort with a bounded cleanup signal and swallows rejections, so targets that never enabled WebMCP (or do not support it) are unaffected. The only new upstream command is WebMCP.disable on the already-open session. No provider, contract, or catalog changes; no new capability — this closes down what the existing discovery flow already enables. Contribution scope: not applicable (ordinary fix within existing boundaries).

Contract and boundary impact

  • Semantic owner and earliest changed stage: CDP target-session teardown owner (CLEANUP_DOMAINS consumed by closeCdpTargetSession); unchanged owner, extended domain list.
  • Contribution scope fit and linked maintainer decision: not applicable.
  • CLI and MCP/tool-catalog contract: none.
  • Provider, bridge, target-format, or platform compatibility: targets without a WebMCP domain reject the disable command; the existing best-effort swallow (same as Debugger.disable on non-debuggable targets) keeps teardown unaffected.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Generated metadata: none.

Expected effects:

  • Read existing files or captured data.

No new target interaction beyond one best-effort WebMCP.disable on the session the flow already opened.

Evidence and regression coverage

  • Tests added or updated: src/browser/CdpTargetSession.test.ts (new) — covers: per-domain disable order before detach and close; unsupported-domain rejection swallowed with detach still running; aborted signal skips domain shutdown but still detaches; page-scoped session closes without detach.
  • Base reproduction: source-derived — CLEANUP_DOMAINS lacked WebMCP while discoverWebMcp enables it; the issue reporter additionally verified the omission against the repository's loopback CDP fixture (see #3193).
  • Remaining proof gaps: no live Chrome/Chromium run on this machine; the new tests exercise the teardown owner against a recording connection stub, not a real browser.

Validation performed

  • npm run test:local -- src/browser/CdpTargetSession.test.ts — 4 passed.
  • npm run verify:test-discovery — passed.
  • npm run check:fast (typecheck, lint) — passed (2 tasks, not cached).

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: not exercised here (no browser target on the validation machine); see remaining proof gaps.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: none needed; the command goes to the same user-selected CDP endpoint already in use and is failure-tolerant.

Author readiness

Human owner: @LuckVd

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3470 **Author:** [@LuckVd](https://github.com/LuckVd) **Created:** 10/14/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/3193-webmcp-domain-shutdown` --- ### 📝 Commits (2) - [`d323390`](https://github.com/morluto/rea/commit/d3233903f3f3037bb21365e3ec376dcdaeea6922) fix(browser): shut down the WebMCP domain before detaching CDP targets - [`2873764`](https://github.com/morluto/rea/commit/28737647dd3ceb65d261277a82182250f6dd65e3) test(browser): guard WebMCP cleanup wiring and close ordering ### 📊 Changes **2 files changed** (+98 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/browser/CdpBrowserProvider.ts` (+12 -1) ➕ `src/browser/CdpTargetSession.test.ts` (+86 -0) </details> ### 📄 Description <!-- PR title: type(optional-scope): imperative outcome The title becomes the squash-merge commit subject and generated changelog entry. --> ## Summary `discover_webmcp_tools` enables the WebMCP CDP domain on the target session, but session teardown never sent `WebMCP.disable` before detaching and closing the socket. `closeCdpTargetSession` already owns domain shutdown via `CLEANUP_DOMAINS`; this change adds `WebMCP` to that list so the domain is shut down by the existing owner. Fixes #3193. ## Problem and expected behavior - Trigger: run `discover_webmcp_tools` against a CDP target that supports WebMCP. - Violated invariant: a successfully enabled CDP domain is disabled before the session detaches (enable/disable symmetry over the same session). - Observed: `WebMCP.enable` is sent (`CdpWebMcpDiscovery.ts`), then teardown detaches and closes without `WebMCP.disable`. - Expected: `WebMCP.disable` is attempted during session cleanup, before `Target.detachFromTarget` and socket close. ## Change and scope Add `"WebMCP"` to `CLEANUP_DOMAINS` in `src/browser/CdpBrowserProvider.ts`. Domain shutdown stays owned by `closeCdpTargetSession`, which already sends each `${domain}.disable` best-effort with a bounded cleanup signal and swallows rejections, so targets that never enabled WebMCP (or do not support it) are unaffected. The only new upstream command is `WebMCP.disable` on the already-open session. No provider, contract, or catalog changes; no new capability — this closes down what the existing discovery flow already enables. Contribution scope: not applicable (ordinary fix within existing boundaries). ## Contract and boundary impact - Semantic owner and earliest changed stage: CDP target-session teardown owner (`CLEANUP_DOMAINS` consumed by `closeCdpTargetSession`); unchanged owner, extended domain list. - Contribution scope fit and linked maintainer decision: not applicable. - CLI and MCP/tool-catalog contract: none. - Provider, bridge, target-format, or platform compatibility: targets without a WebMCP domain reject the disable command; the existing best-effort swallow (same as `Debugger.disable` on non-debuggable targets) keeps teardown unaffected. - Evidence, artifact, provenance, or reconstruction contract: none. - Generated metadata: none. Expected effects: - [x] Read existing files or captured data. No new target interaction beyond one best-effort `WebMCP.disable` on the session the flow already opened. ## Evidence and regression coverage - Tests added or updated: `src/browser/CdpTargetSession.test.ts` (new) — covers: per-domain disable order before detach and close; unsupported-domain rejection swallowed with detach still running; aborted signal skips domain shutdown but still detaches; page-scoped session closes without detach. - Base reproduction: source-derived — `CLEANUP_DOMAINS` lacked `WebMCP` while `discoverWebMcp` enables it; the issue reporter additionally verified the omission against the repository's loopback CDP fixture (see #3193). - Remaining proof gaps: no live Chrome/Chromium run on this machine; the new tests exercise the teardown owner against a recording connection stub, not a real browser. ## Validation performed - `npm run test:local -- src/browser/CdpTargetSession.test.ts` — 4 passed. - `npm run verify:test-discovery` — passed. - `npm run check:fast` (typecheck, lint) — passed (2 tasks, not cached). ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: not exercised here (no browser target on the validation machine); see remaining proof gaps. - Package or release metadata impact: none. - Security, privacy, process, or containment review: none needed; the command goes to the same user-selected CDP endpoint already in use and is failure-tolerant. ## Author readiness <!-- The human owner completes these declarations before requesting review. The PR author is the owner by default. A different owner must explicitly accept ownership on this PR. AI agents must leave these declarations to a human to dictate to them or there could be catastrophic consequences for many users of REA. Draft PRs may leave them unchecked. These declarations record initial readiness when opening the PR for review; later pushes do not require a new human sign-off. Keep the description and validation evidence current as the work changes. See CONTRIBUTING.md#pull-request-ownership-and-readiness. --> Human owner: @LuckVd - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge <!-- Draft PRs may leave pending items unchecked. Resolve material scope and authority questions before integration. --> - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:09:14 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5762
No description provided.