[GH-ISSUE #2589] fix(analysisView): capture views let inline accessor errors escape #904

Closed
opened 2026-10-15 18:29:27 +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/2589

Summary

Summary and capture views invoke a getter in malformed inline Evidence and throw its exception out of the analysis-view service. The service accepts unknown input and promises a typed Result; the API-surface view already rejects the same input without invoking the getter.

Steps to reproduce

  1. On the source baseline below, call inspectAnalysisView directly with the following local JavaScript fixture, once for summary and once for capture.
let accessed = false;
const evidence = {
  get normalized_result() {
    accessed = true;
    throw new Error("test accessor");
  },
};
inspectAnalysisView({
  source: { kind: "inline", evidence },
  view: { kind: "summary" },
});
  1. Observe the escaped exception and accessed. Repeat with view.kind set to api-surface as a control, resetting the flag first.
  2. Use analysisViewCaptureEvidence() from the existing analysis-view fixtures as an ordinary small input and confirm all three views succeed.

Expected behavior

Malformed inline Evidence must return a typed input failure through the service's Result contract. The existing API-surface control rejects this input without invoking its getter.

Actual behavior

The focused test observed Error: test accessor escaping both summary and capture calls, with accessed set to true. API-surface returned AnalysisInputError and left the flag false. Ordinary small capture Evidence succeeded for all three views.

Evidence

  • Expected source: AGENTS.md requires unknown boundary values to produce tagged errors and Result; src/application/analysisView/AnalysisViewService.ts:28 declares the unknown-input service contract. src/application/analysisView/AnalysisViewService.test.ts:436 requires inline accessor rejection without invocation.
  • Failure source: src/application/analysisView/AnalysisViewService.ts:50 limits pre-parse admission to API-surface; line 160 parses unadmitted Evidence for other views and line 181 rethrows an ordinary getter exception.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Two focused tests passed and directly checked the escaped exception, getter invocation, protected-view control, and small valid captures. The accessor input is an in-process JavaScript object; it is not a JSON value transmitted through MCP or CLI. A separate dense-capture observation confirmed view-dependent resource admission, but the documented API-surface representation budget was not established as a contract for other views.

Runtime or environment

Source revision 8b181716ac, Node.js v26.10.0, npm 11.19.1, installed locked dependencies, and Vitest 5.0.3.

Restoration check

Repeat the fixture for summary and capture. Both must return a typed input error without an escaped exception. API-surface must retain its current rejection without invoking the getter, and small ordinary capture Evidence must still produce successful summary and capture views.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Malformed inline Evidence escapes the documented error channel for two supported view kinds, so local callers expecting Result can fail unexpectedly. No process crash or security boundary crossing was observed.
  • Workaround status: unverified
  • Workaround basis: No supported summary or capture option was verified to return a typed failure for this input instead of letting the getter exception escape. Supplying ordinary data avoids the trigger but does not restore malformed-input handling.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2589 ## Summary Summary and capture views invoke a getter in malformed inline Evidence and throw its exception out of the analysis-view service. The service accepts unknown input and promises a typed `Result`; the API-surface view already rejects the same input without invoking the getter. ## Steps to reproduce 1. On the source baseline below, call `inspectAnalysisView` directly with the following local JavaScript fixture, once for `summary` and once for `capture`. ```ts let accessed = false; const evidence = { get normalized_result() { accessed = true; throw new Error("test accessor"); }, }; inspectAnalysisView({ source: { kind: "inline", evidence }, view: { kind: "summary" }, }); ``` 2. Observe the escaped exception and `accessed`. Repeat with `view.kind` set to `api-surface` as a control, resetting the flag first. 3. Use `analysisViewCaptureEvidence()` from the existing analysis-view fixtures as an ordinary small input and confirm all three views succeed. ## Expected behavior Malformed inline Evidence must return a typed input failure through the service's `Result` contract. The existing API-surface control rejects this input without invoking its getter. ## Actual behavior The focused test observed `Error: test accessor` escaping both summary and capture calls, with `accessed` set to true. API-surface returned `AnalysisInputError` and left the flag false. Ordinary small capture Evidence succeeded for all three views. ## Evidence - Expected source: `AGENTS.md` requires unknown boundary values to produce tagged errors and `Result`; `src/application/analysisView/AnalysisViewService.ts:28` declares the unknown-input service contract. `src/application/analysisView/AnalysisViewService.test.ts:436` requires inline accessor rejection without invocation. - Failure source: `src/application/analysisView/AnalysisViewService.ts:50` limits pre-parse admission to API-surface; line 160 parses unadmitted Evidence for other views and line 181 rethrows an ordinary getter exception. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Two focused tests passed and directly checked the escaped exception, getter invocation, protected-view control, and small valid captures. The accessor input is an in-process JavaScript object; it is not a JSON value transmitted through MCP or CLI. A separate dense-capture observation confirmed view-dependent resource admission, but the documented API-surface representation budget was not established as a contract for other views. ## Runtime or environment Source revision 8b181716aca2cb467be499cba226abfb5ae19141, Node.js v26.10.0, npm 11.19.1, installed locked dependencies, and Vitest 5.0.3. ## Restoration check Repeat the fixture for summary and capture. Both must return a typed input error without an escaped exception. API-surface must retain its current rejection without invoking the getter, and small ordinary capture Evidence must still produce successful summary and capture views. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Malformed inline Evidence escapes the documented error channel for two supported view kinds, so local callers expecting Result can fail unexpectedly. No process crash or security boundary crossing was observed. - Workaround status: unverified - Workaround basis: No supported summary or capture option was verified to return a typed failure for this input instead of letting the getter exception escape. Supplying ordinary data avoids the trigger but does not restore malformed-input handling.
bsakaguchi 2026-10-15 18:29:27 +00:00
Author
Owner

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

Addressed on main in 278d7fb28.

Inline Evidence parsing rejects accessor-backed, cyclic, and non-plain data before view projection, returning typed input failure without invoking the getter. Summary, capture, and API-surface paths share this boundary.

Validation: AnalysisViewService: 17 passed, plus shared runtime fixture cleanup: 2 passed; full static and architecture checks pass.

Verification scope: Controlled local boundary verification; unexpected programmer/parser failures remain visible.

<!-- gh-comment-id:6159231528 --> @morluto commented on GitHub (Oct 14, 2026): Addressed on main in [278d7fb28](https://github.com/morluto/rea/commit/278d7fb28). Inline Evidence parsing rejects accessor-backed, cyclic, and non-plain data before view projection, returning typed input failure without invoking the getter. Summary, capture, and API-surface paths share this boundary. Validation: AnalysisViewService: 17 passed, plus shared runtime fixture cleanup: 2 passed; full static and architecture checks pass. Verification scope: Controlled local boundary verification; unexpected programmer/parser failures remain visible.
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#904
No description provided.