[GH-ISSUE #5440] [Bug] Web runtime partial Evidence reports confirmed cleanup after cleanup commands fail #3300

Closed
opened 2026-10-31 00:38:55 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5440

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

inspect-web-event-listeners and observe-web-execution return cleanup_incomplete after rejected CDP cleanup commands, but their retained details.partial_observation Evidence still asserts cleanup was "confirmed". The enclosing error correctly reports cleanup uncertainty; the partial record contradicts it.

Reproduction

An independent verifier ran these steps three times against the source revision below, using the locked dependencies/build:

  1. Start a synthetic loopback page in real Playwright Chromium, with a button and a timer incrementing a counter. Click the button and verify its text changes. Put a loopback HTTP/WebSocket CDP proxy in front of the browser. Forward discovery and capture requests unchanged, rewriting discovery WebSocket URLs to the proxy.
  2. Run the two public commands below with the proxy forwarding everything. Both exit 0 and report confirmed cleanup.
  3. Configure the proxy to reject only DOM.disable and Page.disable, returning CDP error -32000 with message verifier injected cleanup rejection, preserving the request ID and session ID. Repeat both commands against the same page. Both exit 1 with the contradictory fields below.
  4. Confirm the page remains open and its button still has the changed text, then close the fixture. Isolate HOME and XDG config/data/cache/state for REA throughout.
node scripts/rea.mjs inspect-web-event-listeners ENDPOINT TARGET '#missing' --json
node scripts/rea.mjs observe-web-execution ENDPOINT TARGET --observation-ms 30 --json

ENDPOINT is the loopback proxy endpoint; TARGET is the real page ID from Chromium discovery. The missing selector is intentional and yields an explicit not_found selection with empty listeners. Chromium supplies actual capture responses; only the cleanup rejections are injected.

Expected behavior

Preserve useful completed observations and return the cleanup failure without claiming confirmed cleanup inside the retained partial Evidence. Passing cleanup should continue to report confirmed cleanup.

At the tested revision, docs/web-runtime.md:14-16,35 requires cleanup acknowledgement and reports unconfirmed cleanup as an error; docs/cli.md:200-202 defines cleanup_incomplete; docs/tool-design.md:119-134 distinguishes completed observations from owner-confirmed release.

Impact and scope

Bounded evidence-integrity defect after successful capture followed by cleanup failure, reproduced in all three runs per command with injected rejection. Consumers retaining the partial record alone can retain an unsupported cleanup assertion. A practical workaround is to honor the enclosing cleanup_incomplete, details.cleanup, and failed-command diagnostics.

No physical instrumentation leak, data loss, or security boundary crossing was established. The page survived all four calls in the final run. Natural cleanup failures and MCP execution were not tested.

REA version

rea-agents 6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

Node v26.12.0; macOS arm64; locked playwright-core 1.58.2; HeadlessChrome/145.0.7632.6. NOT_ENOUGH_INFO: the exact macOS release was not recorded.

Target and artifact context

One synthetic page and CDP proxy on 127.0.0.1; a 30 ms execution window; no external sites or APIs. Retained JSON Evidence from public CLI calls.

Interface

CLI

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

Selected fields from the independently reproduced CLI JSON:

Command / proxy mode Exit code details.cleanup Retained Evidence cleanup
Listener inspection / pass 0 — — normalized_result.cleanup = "confirmed"
Execution observation / pass 0 — — normalized_result.instrumentation.cleanup = "confirmed"
Listener inspection / reject 1 cleanup_incomplete incomplete details.partial_observation.normalized_result.cleanup = "confirmed"
Execution observation / reject 1 cleanup_incomplete incomplete details.partial_observation.normalized_result.instrumentation.cleanup = "confirmed"

Both rejecting results retain an Evidence ID and confidence: "observed". Listener diagnostics identify rejected DOM.disable and Page.disable; execution diagnostics identify rejected Page.disable. Execution coverage and one source record remain available. These outputs establish contradictory confirmation claims, not that instrumentation remained active after detach/transport closure.

Typed outcome or recovery expected

Keep cleanup_incomplete, the selected target, failed-command diagnostics, and useful partial capture data. Represent cleanup as unconfirmed throughout the retained record. Keep successful controls and preservation of the externally owned page working.

Analysis or suspected cause

Source-derived corroboration: src/browser/execution/CdpEventListeners.ts:95 and CdpExecutionCapture.ts:143 construct the confirmed assertion before CdpWebRuntimeProvider.ts:95-124 awaits cleanup and retains the unchanged capture on failure. src/application/WebRuntimeService.ts:42-56,104-118,150-188 projects it as observed Evidence. The successful capture schemas require the confirmed state (src/domain/webEventListeners.ts:41, src/domain/webExecution.ts:88). This is supporting reasoning, not a prescribed fix.

Additional context

Prepared with AI assistance and independently reproduced through real Chromium and the public CLI. The submitter fetched current main and found no post-baseline changes in the cited contract or implementation files. Related #4467 and PR #4571 concern stale cleanup errors after successful transport retries, rather than a partial capture claiming confirmation when cleanup fails.

NOT_ENOUGH_INFO: no last-known-good version or regression range was established.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5440 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `inspect-web-event-listeners` and `observe-web-execution` return `cleanup_incomplete` after rejected CDP cleanup commands, but their retained `details.partial_observation` Evidence still asserts cleanup was `"confirmed"`. The enclosing error correctly reports cleanup uncertainty; the partial record contradicts it. ### Reproduction An independent verifier ran these steps three times against the source revision below, using the locked dependencies/build: 1. Start a synthetic loopback page in real Playwright Chromium, with a button and a timer incrementing a counter. Click the button and verify its text changes. Put a loopback HTTP/WebSocket CDP proxy in front of the browser. Forward discovery and capture requests unchanged, rewriting discovery WebSocket URLs to the proxy. 2. Run the two public commands below with the proxy forwarding everything. Both exit 0 and report confirmed cleanup. 3. Configure the proxy to reject only `DOM.disable` and `Page.disable`, returning CDP error `-32000` with message `verifier injected cleanup rejection`, preserving the request ID and session ID. Repeat both commands against the same page. Both exit 1 with the contradictory fields below. 4. Confirm the page remains open and its button still has the changed text, then close the fixture. Isolate HOME and XDG config/data/cache/state for REA throughout. ```bash node scripts/rea.mjs inspect-web-event-listeners ENDPOINT TARGET '#missing' --json node scripts/rea.mjs observe-web-execution ENDPOINT TARGET --observation-ms 30 --json ``` `ENDPOINT` is the loopback proxy endpoint; `TARGET` is the real page ID from Chromium discovery. The missing selector is intentional and yields an explicit `not_found` selection with empty listeners. Chromium supplies actual capture responses; only the cleanup rejections are injected. ### Expected behavior Preserve useful completed observations and return the cleanup failure without claiming confirmed cleanup inside the retained partial Evidence. Passing cleanup should continue to report confirmed cleanup. At the tested revision, `docs/web-runtime.md:14-16,35` requires cleanup acknowledgement and reports unconfirmed cleanup as an error; `docs/cli.md:200-202` defines `cleanup_incomplete`; `docs/tool-design.md:119-134` distinguishes completed observations from owner-confirmed release. ### Impact and scope Bounded evidence-integrity defect after successful capture followed by cleanup failure, reproduced in all three runs per command with injected rejection. Consumers retaining the partial record alone can retain an unsupported cleanup assertion. A practical workaround is to honor the enclosing `cleanup_incomplete`, `details.cleanup`, and failed-command diagnostics. No physical instrumentation leak, data loss, or security boundary crossing was established. The page survived all four calls in the final run. Natural cleanup failures and MCP execution were not tested. ### REA version `rea-agents` 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform Node v26.12.0; macOS arm64; locked `playwright-core` 1.58.2; HeadlessChrome/145.0.7632.6. NOT_ENOUGH_INFO: the exact macOS release was not recorded. ### Target and artifact context One synthetic page and CDP proxy on `127.0.0.1`; a 30 ms execution window; no external sites or APIs. Retained JSON Evidence from public CLI calls. ### Interface CLI ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence Selected fields from the independently reproduced CLI JSON: | Command / proxy mode | Exit | `code` | `details.cleanup` | Retained Evidence cleanup | | --- | --- | --- | --- | --- | | Listener inspection / pass | 0 | — | — | `normalized_result.cleanup = "confirmed"` | | Execution observation / pass | 0 | — | — | `normalized_result.instrumentation.cleanup = "confirmed"` | | Listener inspection / reject | 1 | `cleanup_incomplete` | `incomplete` | `details.partial_observation.normalized_result.cleanup = "confirmed"` | | Execution observation / reject | 1 | `cleanup_incomplete` | `incomplete` | `details.partial_observation.normalized_result.instrumentation.cleanup = "confirmed"` | Both rejecting results retain an Evidence ID and `confidence: "observed"`. Listener diagnostics identify rejected `DOM.disable` and `Page.disable`; execution diagnostics identify rejected `Page.disable`. Execution coverage and one source record remain available. These outputs establish contradictory confirmation claims, not that instrumentation remained active after detach/transport closure. ### Typed outcome or recovery expected Keep `cleanup_incomplete`, the selected target, failed-command diagnostics, and useful partial capture data. Represent cleanup as unconfirmed throughout the retained record. Keep successful controls and preservation of the externally owned page working. ### Analysis or suspected cause Source-derived corroboration: `src/browser/execution/CdpEventListeners.ts:95` and `CdpExecutionCapture.ts:143` construct the confirmed assertion before `CdpWebRuntimeProvider.ts:95-124` awaits cleanup and retains the unchanged capture on failure. `src/application/WebRuntimeService.ts:42-56,104-118,150-188` projects it as observed Evidence. The successful capture schemas require the confirmed state (`src/domain/webEventListeners.ts:41`, `src/domain/webExecution.ts:88`). This is supporting reasoning, not a prescribed fix. ### Additional context Prepared with AI assistance and independently reproduced through real Chromium and the public CLI. The submitter fetched current `main` and found no post-baseline changes in the cited contract or implementation files. Related #4467 and PR #4571 concern stale cleanup errors after successful transport retries, rather than a partial capture claiming confirmation when cleanup fails. NOT_ENOUGH_INFO: no last-known-good version or regression range was established.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Checked the reported fix on main at d87e73f2db.

Capture projections initially mark cleanup unconfirmed; CdpWebRuntimeProvider upgrades to confirmed only through the successful completion projector. A rejected Page.disable test runs both observe and inspect with a healthy control, asserts partial Evidence unconfirmed plus retained target/facts, and checks successful-result schema rejects it. No CDP runtime test was executed here.

Implementation: CdpEventListeners.ts, CdpExecutionCapture.ts.

The relevant regression checks in browserLifecycleFollowup.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380761982 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. Capture projections initially mark cleanup unconfirmed; CdpWebRuntimeProvider upgrades to confirmed only through the successful completion projector. A rejected Page.disable test runs both observe and inspect with a healthy control, asserts partial Evidence unconfirmed plus retained target/facts, and checks successful-result schema rejects it. No CDP runtime test was executed here. Implementation: [CdpEventListeners.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/browser/execution/CdpEventListeners.ts#L95), [CdpExecutionCapture.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/browser/execution/CdpExecutionCapture.ts#L154). The relevant regression checks in [browserLifecycleFollowup.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/browser/browserLifecycleFollowup.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3300
No description provided.