[GH-ISSUE #2649] fix(electron): dropped configuration is reported as observed and unavailable preload #949

Closed
opened 2026-10-15 18:29:50 +00:00 by bsakaguchi · 0 comments
Owner

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

Summary

A caller of capture_electron_scenario can receive preload in both observed and unavailable event families when retention discards a main-process preload configuration event. The same result also treats preload-configuration as unavailable when no configuration event was retained. This loses the documented distinction between seeing a configured preload path and observing the preload context. The failure is limited to coverage metadata for dropped events whose process type is browser.

Steps to reproduce

The executed reproduction used the source baseline under Runtime or environment and the production result projector with an inert, typed snapshot. It exercised no Electron process. The small snapshot isolates the dropped-family branch; its empty event list and counters are not claimed to be a complete snapshot emitted by the hook after budget exhaustion.

Create src/browser/preload-coverage-repro.test.ts with this test:

import { expect, it } from "vitest";
import { projectElectronActiveCapture } from "./PlaywrightElectronActiveProjection.js";
import type { ElectronHookSnapshot } from "./PlaywrightElectronActiveActions.js";

it("shows the dropped configuration coverage", () => {
  const hookSnapshot: ElectronHookSnapshot = {
    events: [],
    retention_budget_bytes: 16 * 1024 * 1024,
    estimated_retained_bytes: 0,
    event_serialized_byte_upper_bound: 0,
    retained: 0,
    dropped: 1,
    dropped_ipc: 0,
    dropped_runtime: 1,
    dropped_event_families: [{ family: "preload", count: 1 }],
    dropped_event_roles: [{ role: "browser", count: 1 }],
    observed: 1,
    observed_ipc: 0,
    observed_runtime: 1,
    hook_error: false,
  };
  const result = projectElectronActiveCapture(
    { executable: "/fixture/electron", application: "/fixture/main.js" },
    [],
    { windows: [], metrics: [], electronVersion: "fixture-electron", hookSnapshot },
  );
  expect(result.coverage.observed_event_families).toEqual(["preload"]);
  expect(result.coverage.unavailable_event_families).toContain("preload");
  expect(result.coverage.unavailable_event_families).toContain("preload-configuration");
  expect(result.coverage.observed_roles).toEqual(["browser"]);
});

Run the source test:

npm run test:local -- src/browser/preload-coverage-repro.test.ts

The supported public trigger uses existing absolute Electron executable and application entry-point paths, successful startup and cleanup, no cancellation, and ordinary short window lifecycle events until the hook's finite retention budget fills. A subsequent window exposes a configured preload path. The configured event then drops with the main process's browser role. CLI/MCP reachability was checked from source; the current-source replay below exercised inert hook/parser/projector stand-ins only.

Expected behavior

The Electron observation guide says that preload configuration comes from window metadata and that a configured path does not prove preload execution. Coverage must preserve that distinction when reporting an observation whose detailed event was discarded. For a dropped main-process configuration event, report the observed configuration family and its loss without claiming an observed preload context. Keep the unavailable preload-context claim when that context was not instrumented.

The schema alone does not promise a universal partition of the arrays. The required behavior here is accurate classification of the specific configured event, consistent with its actual observation context.

Actual behavior

The isolated dropped fixture produced:

observed_event_families: ["preload"]
unavailable_event_families: includes "preload" and "preload-configuration"
observed_roles: ["browser"]

The executed retained-event control, with kind: "preload", event: "configured", and process_type: "browser", produced observed preload-configuration, unavailable preload, and no unavailable preload-configuration. The no-observation control left both families unavailable. All three focused source tests passed assertions against the current behavior.

A subsequent current-source replay ran the unchanged hook with an in-memory process whose type was browser, an app emitter, and two window stand-ins. Unrelated hook patch families were no-op stubs. The first window emitted 10,000 fixture-tick events before the second exposed /fixture/preload.js. The actual generated snapshot passed through the production parser and projector. It retained 9,706 events, dropped 299, and recorded one dropped preload family event. Coverage listed preload as observed and both preload and preload-configuration as unavailable. With zero preceding ticks, the configured control observed preload-configuration, made that family available, and kept preload unavailable. With no configured path, neither preload family was observed. These assertions passed. No Electron runtime or public capture command was executed.

Evidence

  • Expected source: docs/electron-observation.md:105-110 distinguishes configured metadata from preload execution; AGENTS.md, Product and Authority and Architecture and Cleanup, requires preserving observation, uncertainty, and source evidence; src/contracts/javascript/electronToolContracts.ts:142 promises observed and unavailable event-family reporting.
  • Failure source: The baseline projector fixture above and current-source inert hook/parser/projector replay returned the conflicting coverage. Relevant locators are scripts/electron-active-hook.cjs:93-119, 137-140, 266-288, 547-566, and 649-673; src/browser/PlaywrightElectronActiveActions.ts:315-343; and src/browser/PlaywrightElectronActiveProjection.ts:71-110.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The supported public entry points are registered in src/cli/electronCommands.ts:38-92 and src/server/registerElectronTools.ts:149-166; their active capture workflow is defined in src/application/javascript/ElectronActiveObservationService.ts:29-126 and src/browser/PlaywrightElectronActiveProvider.ts:99-143. Public workflow applicability remains source-derived.

Electron's versioned process.type documentation defines browser as the main process, matching the runtime version discussed by REA's observation guide. The projector itself states that preload contexts are not instrumented by its main-process hook in src/browser/PlaywrightElectronActiveProjection.ts:168.

Related: #2594 concerns losing an initial snapshot after a failed final capture; #375 tracks broader Electron lifecycle instrumentation. Neither covers the dropped configuration-family classification reported here.

Restoration check

Repeat the supported hook trigger described under Steps to reproduce and inspect its generated snapshot and projected result. The dropped configuration observation must retain the configuration-versus-context distinction: observe preload-configuration, preserve the drop count and browser role, and keep preload unavailable without listing it as observed. The detailed preload path remains unavailable after its event is dropped. Retaining the equivalent configured event must preserve the same distinction. The no-observation control must keep both families unavailable, so restoration cannot invent observations or remove the preload-context limitation. The inline projector fixture records the current hook's incorrect dropped-family label; restoration may change that producer output and does not require reinterpreting arbitrary preclassified snapshots.

Runtime or environment

Source revision a2d8b94dd50dab8d966239dd63ab84718aa8b4b4; Node.js 24.18.0; npm 11.16.0; Vitest 5.0.3. Exactly one source test file ran with three inert projector cases. No compiled CLI, MCP capture, installed package, or Electron process was run. No released REA package was tested. Current upstream source revision 3ae826ceba6f25b08bce50bcb51001209bc16b57 was checked by source inspection and the inert hook/parser/projector replay described above. The replay used the pinned Node.js toolchain with TypeScript transformation and source-module resolution, and did not use Vitest, launch Electron, or execute public CLI/MCP capture. Shared admission and delivery changes do not reclassify this result.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Returned coverage can classify a dropped main-process configuration event as observed preload while also reporting preload unavailable. A caller using these families to assess capture coverage receives inconsistent metadata; retained timeline data and lifecycle ownership are unaffected by this defect.
  • Workaround status: available
  • Workaround basis: A caller can inspect the dropped family together with its browser role, interpret it as lost main-process configuration evidence, and keep preload execution unknown. This avoids trusting the conflicting coverage labels but cannot recover the discarded path.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2649 ## Summary A caller of `capture_electron_scenario` can receive `preload` in both observed and unavailable event families when retention discards a main-process preload configuration event. The same result also treats `preload-configuration` as unavailable when no configuration event was retained. This loses the documented distinction between seeing a configured preload path and observing the preload context. The failure is limited to coverage metadata for dropped events whose process type is `browser`. ## Steps to reproduce The executed reproduction used the source baseline under Runtime or environment and the production result projector with an inert, typed snapshot. It exercised no Electron process. The small snapshot isolates the dropped-family branch; its empty event list and counters are not claimed to be a complete snapshot emitted by the hook after budget exhaustion. Create `src/browser/preload-coverage-repro.test.ts` with this test: ```ts import { expect, it } from "vitest"; import { projectElectronActiveCapture } from "./PlaywrightElectronActiveProjection.js"; import type { ElectronHookSnapshot } from "./PlaywrightElectronActiveActions.js"; it("shows the dropped configuration coverage", () => { const hookSnapshot: ElectronHookSnapshot = { events: [], retention_budget_bytes: 16 * 1024 * 1024, estimated_retained_bytes: 0, event_serialized_byte_upper_bound: 0, retained: 0, dropped: 1, dropped_ipc: 0, dropped_runtime: 1, dropped_event_families: [{ family: "preload", count: 1 }], dropped_event_roles: [{ role: "browser", count: 1 }], observed: 1, observed_ipc: 0, observed_runtime: 1, hook_error: false, }; const result = projectElectronActiveCapture( { executable: "/fixture/electron", application: "/fixture/main.js" }, [], { windows: [], metrics: [], electronVersion: "fixture-electron", hookSnapshot }, ); expect(result.coverage.observed_event_families).toEqual(["preload"]); expect(result.coverage.unavailable_event_families).toContain("preload"); expect(result.coverage.unavailable_event_families).toContain("preload-configuration"); expect(result.coverage.observed_roles).toEqual(["browser"]); }); ``` Run the source test: ```bash npm run test:local -- src/browser/preload-coverage-repro.test.ts ``` The supported public trigger uses existing absolute Electron executable and application entry-point paths, successful startup and cleanup, no cancellation, and ordinary short window lifecycle events until the hook's finite retention budget fills. A subsequent window exposes a configured preload path. The configured event then drops with the main process's `browser` role. CLI/MCP reachability was checked from source; the current-source replay below exercised inert hook/parser/projector stand-ins only. ## Expected behavior The Electron observation guide says that preload configuration comes from window metadata and that a configured path does not prove preload execution. Coverage must preserve that distinction when reporting an observation whose detailed event was discarded. For a dropped main-process configuration event, report the observed configuration family and its loss without claiming an observed preload context. Keep the unavailable preload-context claim when that context was not instrumented. The schema alone does not promise a universal partition of the arrays. The required behavior here is accurate classification of the specific configured event, consistent with its actual observation context. ## Actual behavior The isolated dropped fixture produced: ```text observed_event_families: ["preload"] unavailable_event_families: includes "preload" and "preload-configuration" observed_roles: ["browser"] ``` The executed retained-event control, with `kind: "preload"`, `event: "configured"`, and `process_type: "browser"`, produced observed `preload-configuration`, unavailable `preload`, and no unavailable `preload-configuration`. The no-observation control left both families unavailable. All three focused source tests passed assertions against the current behavior. A subsequent current-source replay ran the unchanged hook with an in-memory process whose type was `browser`, an app emitter, and two window stand-ins. Unrelated hook patch families were no-op stubs. The first window emitted 10,000 `fixture-tick` events before the second exposed `/fixture/preload.js`. The actual generated snapshot passed through the production parser and projector. It retained 9,706 events, dropped 299, and recorded one dropped `preload` family event. Coverage listed `preload` as observed and both `preload` and `preload-configuration` as unavailable. With zero preceding ticks, the configured control observed `preload-configuration`, made that family available, and kept `preload` unavailable. With no configured path, neither preload family was observed. These assertions passed. No Electron runtime or public capture command was executed. ## Evidence - Expected source: `docs/electron-observation.md:105-110` distinguishes configured metadata from preload execution; `AGENTS.md`, Product and Authority and Architecture and Cleanup, requires preserving observation, uncertainty, and source evidence; `src/contracts/javascript/electronToolContracts.ts:142` promises observed and unavailable event-family reporting. - Failure source: The baseline projector fixture above and current-source inert hook/parser/projector replay returned the conflicting coverage. Relevant locators are `scripts/electron-active-hook.cjs:93-119`, `137-140`, `266-288`, `547-566`, and `649-673`; `src/browser/PlaywrightElectronActiveActions.ts:315-343`; and `src/browser/PlaywrightElectronActiveProjection.ts:71-110`. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The supported public entry points are registered in `src/cli/electronCommands.ts:38-92` and `src/server/registerElectronTools.ts:149-166`; their active capture workflow is defined in `src/application/javascript/ElectronActiveObservationService.ts:29-126` and `src/browser/PlaywrightElectronActiveProvider.ts:99-143`. Public workflow applicability remains source-derived. Electron's versioned [`process.type` documentation](https://github.com/electron/electron/blob/v44.7.0/docs/api/process.md#processtype-readonly) defines `browser` as the main process, matching the runtime version discussed by REA's observation guide. The projector itself states that preload contexts are not instrumented by its main-process hook in `src/browser/PlaywrightElectronActiveProjection.ts:168`. Related: #2594 concerns losing an initial snapshot after a failed final capture; #375 tracks broader Electron lifecycle instrumentation. Neither covers the dropped configuration-family classification reported here. ## Restoration check Repeat the supported hook trigger described under Steps to reproduce and inspect its generated snapshot and projected result. The dropped configuration observation must retain the configuration-versus-context distinction: observe `preload-configuration`, preserve the drop count and `browser` role, and keep `preload` unavailable without listing it as observed. The detailed preload path remains unavailable after its event is dropped. Retaining the equivalent configured event must preserve the same distinction. The no-observation control must keep both families unavailable, so restoration cannot invent observations or remove the preload-context limitation. The inline projector fixture records the current hook's incorrect dropped-family label; restoration may change that producer output and does not require reinterpreting arbitrary preclassified snapshots. ## Runtime or environment Source revision `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`; Node.js 24.18.0; npm 11.16.0; Vitest 5.0.3. Exactly one source test file ran with three inert projector cases. No compiled CLI, MCP capture, installed package, or Electron process was run. No released REA package was tested. Current upstream source revision `3ae826ceba6f25b08bce50bcb51001209bc16b57` was checked by source inspection and the inert hook/parser/projector replay described above. The replay used the pinned Node.js toolchain with TypeScript transformation and source-module resolution, and did not use Vitest, launch Electron, or execute public CLI/MCP capture. Shared admission and delivery changes do not reclassify this result. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Returned coverage can classify a dropped main-process configuration event as observed preload while also reporting preload unavailable. A caller using these families to assess capture coverage receives inconsistent metadata; retained timeline data and lifecycle ownership are unaffected by this defect. - Workaround status: available - Workaround basis: A caller can inspect the dropped family together with its browser role, interpret it as lost main-process configuration evidence, and keep preload execution unknown. This avoids trusting the conflicting coverage labels but cannot recover the discarded path.
bsakaguchi 2026-10-15 18:29:50 +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#949
No description provided.