[GH-ISSUE #2594] fix(electron): failed final capture loses the initial snapshot #910

Closed
opened 2026-10-15 18:29:30 +00:00 by bsakaguchi · 1 comment
Owner

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

Summary

An Electron scenario that reads its initial state successfully and then fails to read its final state returns an error without the collected snapshot. Analysts lose the known application version and any initial observations even though that state remains available inside the provider. The failure should retain those facts and identify their pre-action timing.

Runtime or environment

Source revision 8b181716ac, Node v26.10.0, npm 11.19.1, and locked dependencies. This was a mocked provider-boundary test; no Electron process was launched or signaled.

Steps to reproduce

  1. Create a focused Vitest test beside the Electron provider. Instantiate PlaywrightElectronActiveProvider with an empty selected environment and a launcher returning an application whose process method returns pid 12345, windows returns an empty array, and close resolves.
  2. Mock prepareProcessOwnershipInspection to resolve and observeOwnedProcessLineage to return verified lineage with launcher PID and process group 12345, parent PID 1, and no descendants. Mock cleanupOwnedProcessGroup to return cleaned true and signaled false, and verifyNoTokenOwnedProcesses to return cleaned true. Provide a mock ownership host using the test platform and a no-op signalGroup. These mocks prevent real process inspection or cleanup from affecting the case.
  3. Mock readApplicationState to resolve once with electronVersion 44.0.0, empty windows and metrics, and an empty hookSnapshot. Set every numeric hook counter and budget to zero, its events and dropped-family/role arrays to empty, and hook_error to false. Make the second read reject with Error("application closed before the final state read"). Mock runElectronActions to return an empty action list.
  4. Parse the scenario input through electronActiveObservationInputSchema using process.execPath for executable_path and application_path, and dirname(process.execPath) for application_root. The executed fixture used synthetic canonical paths; these runtime-derived paths exercise the same branch because the mocked provider performs no filesystem reads. Call provider.capture without an aborted signal. This tests the provider directly; the public service additionally requires existing canonicalizable paths.
  5. Run npm run test:focused -- src/browser/electron-final-read.test.ts for the created test. Require result.ok to be false and result.error.partialObservation to include kind electron-active-observation and capture.application.electron_version 44.0.0.

Expected behavior

A failed final read preserves the successfully collected initial snapshot on the failure result. Its limitations identify that the snapshot predates actions and cannot establish their final effects. The operation remains a failure.

Actual behavior

The executed test returned a failure with undefined partialObservation. The version marker 44.0.0 was absent from the error even though the first state read returned it. The test used empty observation collections, so it establishes snapshot loss rather than real-world loss of populated rows.

Evidence

  • Expected source: AGENTS.md, Architecture and Cleanup, requires preserved partial facts; src/browser/PlaywrightElectronActiveProvider.ts:144-162 already retains the initial snapshot when the final read fails after cancellation.
  • Failure source: src/browser/PlaywrightElectronActiveProvider.ts:125-176 collects initialState but skips its projection on a non-cancelled final-read exception; src/application/javascript/ElectronActiveObservationService.ts:107-119 propagates provider errors unchanged.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The fixture passed the positive-PID and successful-cleanup branches and used no cancellation. Runtime application evaluation can reject when the process becomes unavailable, and the provider has no guard that makes the final read infallible. No matching existing issue was found in read-only searches.

Restoration check

Repeat the same successful initial read followed by a rejected final read. Require an error that retains the version marker and initial snapshot with an explicit pre-action limitation. A failed initial read must not fabricate a snapshot. Successful final reads and existing cancellation behavior must keep their current success or failure semantics.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A bounded failed capture discards previously observed evidence while correctly reporting the operation failure. The simulation establishes this return path, not its real-world frequency or lost row count.
  • Workaround status: none
  • Workaround basis: The returned error does not expose the initial snapshot. Starting another scenario cannot recover that exact past observation.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2594 ## Summary An Electron scenario that reads its initial state successfully and then fails to read its final state returns an error without the collected snapshot. Analysts lose the known application version and any initial observations even though that state remains available inside the provider. The failure should retain those facts and identify their pre-action timing. ## Runtime or environment Source revision 8b181716aca2cb467be499cba226abfb5ae19141, Node v26.10.0, npm 11.19.1, and locked dependencies. This was a mocked provider-boundary test; no Electron process was launched or signaled. ## Steps to reproduce 1. Create a focused Vitest test beside the Electron provider. Instantiate PlaywrightElectronActiveProvider with an empty selected environment and a launcher returning an application whose process method returns pid 12345, windows returns an empty array, and close resolves. 2. Mock prepareProcessOwnershipInspection to resolve and observeOwnedProcessLineage to return verified lineage with launcher PID and process group 12345, parent PID 1, and no descendants. Mock cleanupOwnedProcessGroup to return cleaned true and signaled false, and verifyNoTokenOwnedProcesses to return cleaned true. Provide a mock ownership host using the test platform and a no-op signalGroup. These mocks prevent real process inspection or cleanup from affecting the case. 3. Mock readApplicationState to resolve once with electronVersion 44.0.0, empty windows and metrics, and an empty hookSnapshot. Set every numeric hook counter and budget to zero, its events and dropped-family/role arrays to empty, and hook_error to false. Make the second read reject with Error("application closed before the final state read"). Mock runElectronActions to return an empty action list. 4. Parse the scenario input through electronActiveObservationInputSchema using process.execPath for executable_path and application_path, and dirname(process.execPath) for application_root. The executed fixture used synthetic canonical paths; these runtime-derived paths exercise the same branch because the mocked provider performs no filesystem reads. Call provider.capture without an aborted signal. This tests the provider directly; the public service additionally requires existing canonicalizable paths. 5. Run npm run test:focused -- src/browser/electron-final-read.test.ts for the created test. Require result.ok to be false and result.error.partialObservation to include kind electron-active-observation and capture.application.electron_version 44.0.0. ## Expected behavior A failed final read preserves the successfully collected initial snapshot on the failure result. Its limitations identify that the snapshot predates actions and cannot establish their final effects. The operation remains a failure. ## Actual behavior The executed test returned a failure with undefined partialObservation. The version marker 44.0.0 was absent from the error even though the first state read returned it. The test used empty observation collections, so it establishes snapshot loss rather than real-world loss of populated rows. ## Evidence - Expected source: AGENTS.md, Architecture and Cleanup, requires preserved partial facts; src/browser/PlaywrightElectronActiveProvider.ts:144-162 already retains the initial snapshot when the final read fails after cancellation. - Failure source: src/browser/PlaywrightElectronActiveProvider.ts:125-176 collects initialState but skips its projection on a non-cancelled final-read exception; src/application/javascript/ElectronActiveObservationService.ts:107-119 propagates provider errors unchanged. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The fixture passed the positive-PID and successful-cleanup branches and used no cancellation. Runtime application evaluation can reject when the process becomes unavailable, and the provider has no guard that makes the final read infallible. No matching existing issue was found in read-only searches. ## Restoration check Repeat the same successful initial read followed by a rejected final read. Require an error that retains the version marker and initial snapshot with an explicit pre-action limitation. A failed initial read must not fabricate a snapshot. Successful final reads and existing cancellation behavior must keep their current success or failure semantics. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A bounded failed capture discards previously observed evidence while correctly reporting the operation failure. The simulation establishes this return path, not its real-world frequency or lost row count. - Workaround status: none - Workaround basis: The returned error does not expose the initial snapshot. Starting another scenario cannot recover that exact past observation.
bsakaguchi 2026-10-15 18:29:30 +00:00
Author
Owner

@morluto commented on GitHub (Oct 14, 2026):

Addressed on main in bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c.

A failed final Electron snapshot retains the initial observed snapshot and cleanup facts.

Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit.

Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.

<!-- gh-comment-id:6159212488 --> @morluto commented on GitHub (Oct 14, 2026): Addressed on main in [bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c](https://github.com/morluto/rea/commit/bffdd91053fb5d076b762cf1b325e8dcb5ab2d8c). A failed final Electron snapshot retains the initial observed snapshot and cleanup facts. Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit. Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.
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#910
No description provided.