[GH-ISSUE #3948] [Bug] Timeout partial graphs assign JavaScript analysis to native add-ons #1555

Closed
opened 2026-10-16 21:07:06 +00:00 by bsakaguchi · 1 comment
Owner

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

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

When a JavaScript source times out before a native add-on is visited, the CLI's partial application graph gives the add-on an unavailable analyze-javascript-source scope with ast-static-analysis authority. The add-on also retains its correct inventory metadata. The extra scope incorrectly says a JavaScript analysis operation applies to a file that REA classifies as native-addon with text_status: not-applicable. The same input succeeds without that scope when source analysis completes.

Reproduction

Run this Python script from the baseline checkout with its dependencies and compiled CLI already available and the stated Node.js version on PATH. It creates one JavaScript source and a four-byte add-on, runs the supported CLI with a 1 ms source deadline, inspects the partial result, and runs the same fixture with the default deadline as a control. It cleans up its fixture and HOME afterward.

python3 - <<'PY'
import json
import os
from pathlib import Path
import subprocess
from tempfile import TemporaryDirectory

with TemporaryDirectory(prefix="rea-scope-") as temporary:
    root = Path(temporary)
    fixture = root / "fixture"
    fixture.mkdir()
    (fixture / "a.js").write_text("export const value = 1;\n")
    (fixture / "z.node").write_bytes(bytes([0, 1, 2, 3]))
    home = root / "home"
    home.mkdir()
    environment = dict(os.environ, HOME=str(home))
    for label, options in [
        ("timeout", ["--analysis-timeout-ms", "1"]),
        ("control", []),
    ]:
        result = subprocess.run(
            ["node", "scripts/rea.mjs", "analyze-javascript-application",
             str(fixture), *options, "--format", "json", "--full-output"],
            env=environment, capture_output=True, text=True, timeout=30,
        )
        envelope = json.loads(result.stdout)
        observation = (envelope["data"] if envelope["ok"] else
                       envelope["error"]["details"]["partial_observation"])
        nodes = observation["normalized_result"]["graph"]["nodes"]
        scopes = [o for n in nodes if n["kind"] == "unknown"
                  for o in n["observations"]
                  if o["properties"].get("path") == "z.node"]
        print(label, "exit", result.returncode, "addon unknown scopes", len(scopes))
        for scope in scopes:
            print(json.dumps({
                "properties": scope["properties"],
                "authority": scope["evidence"]["authority"],
                "state": scope["evidence"]["state"],
            }, indent=2))
PY

The executed two-file case produced timeout exit 1 addon unknown scopes 1 and control exit 0 addon unknown scopes 0. It reproduced again when the same fixture also contained a valid package record, an HTML file, and a source map. Those unvisited entries also received the incorrect operation. Across three local timeout runs, the add-on scope appeared in all three, while all three default-deadline controls succeeded. A 1 ms deadline is a supported input but whether a particular run times out depends on the runtime and machine.

Expected behavior

A source timeout should preserve collected partial Evidence and leave unexamined relationships unknown. Native add-ons should keep their documented metadata-only representation without acquiring an inapplicable JavaScript AST-analysis scope. Unknown scopes for unexamined package records, HTML, or source maps should accurately represent their own analysis applicability. The attempted JavaScript source should retain its real timeout evidence.

docs/javascript-artifact-reconstruction.md:178-190 defines retained timeout partial Evidence, and lines 415-416 define native add-ons as metadata-only. The deadline is supported by CLI help and src/domain/javascript/javascriptAnalysisResourceControls.ts:72-81.

Impact and scope

P2. Timeout partial Evidence adds false typed graph nodes, contains edges, and AST-analysis provenance for remaining non-JavaScript entries. Inventory metadata survives, and no severe workflow failure or data loss was observed. The tiny fixtures succeed with the default deadline, but that is not an established remedy for callers needing partial Evidence after a genuine timeout. Workaround status remains unverified.

REA version

rea 6.5.0 at source commit 4692bb3330

Runtime and platform

Node 24.18.0; macOS arm64

Target and artifact context

Disposable directory with inert a.js and a four-byte z.node metadata entry; expanded control also includes package, HTML, and source-map files. No target code, native provider, or external service executed.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

The timeout command exits with code 1 and returns error.code: provider_timeout. In error.details.partial_observation.normalized_result.graph.nodes, an extra unknown node has identity key analyze-javascript-source:z.node. Its observation has these values:

{
  "properties": {
    "path": "z.node",
    "operation": "analyze-javascript-source",
    "limitation": "Source analysis was interrupted: Analysis operation timed out after 1ms: analyze_javascript_application"
  },
  "authority": "ast-static-analysis",
  "state": "unavailable"
}

The graph also attaches the unknown scope to the native-add-on node through a contains edge. This changes the graph and analysis provenance, rather than only the displayed error message. The control exits with code 0, parses its single JavaScript source, and retains the same native-add-on inventory observation without an unknown add-on scope. These are observed CLI results. Cancellation and worker failures were not runtime-tested for this report.

Typed outcome or recovery expected

Run the two-file reproduction and confirm that a real JavaScript timeout still returns its typed error and partial Evidence, with the attempted source's unavailable analysis scope intact. The native-add-on inventory observation must remain present, and the add-on must have no JavaScript AST-analysis failure scope. The default-deadline control must still succeed with its source parsed and the add-on represented by metadata. Repeat with unvisited package, HTML, and source-map entries to check that their unknown coverage preserves the applicable file kind instead of calling them JavaScript sources. No implementation choice is required by this report.

Analysis or suspected cause

Source-derived: src/application/javascript/JavaScriptArtifactAnalysis.ts:268-299 skips analyzed and caller-excluded paths, then attaches the shared interruption failure to each remaining in-scope relevant file regardless of kind. src/application/javascript/JavaScriptArtifactGraphStructure.ts:222-232 treats it as a JavaScript-source failure. src/application/javascript/JavaScriptArtifactGraphContext.ts:209-260 emits the unknown node, contains edge, and unavailable AST evidence.

Additional context

The cited failing code is unchanged on current origin/main at 22ec8bdb2f7d4626587f23b1eed4a207df600386.

Closed #1968 concerns a caller-excluded file being misreported after cancellation; excluded files are already skipped in this reproduction. Open PR #3852 changes skipped-JavaScript parse-status reporting and counters, leaving the non-JavaScript interruption-scope branch unchanged.

Originally created by @coygeek on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3948 ### 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 When a JavaScript source times out before a native add-on is visited, the CLI's partial application graph gives the add-on an unavailable `analyze-javascript-source` scope with `ast-static-analysis` authority. The add-on also retains its correct inventory metadata. The extra scope incorrectly says a JavaScript analysis operation applies to a file that REA classifies as `native-addon` with `text_status: not-applicable`. The same input succeeds without that scope when source analysis completes. ### Reproduction Run this Python script from the baseline checkout with its dependencies and compiled CLI already available and the stated Node.js version on PATH. It creates one JavaScript source and a four-byte add-on, runs the supported CLI with a 1 ms source deadline, inspects the partial result, and runs the same fixture with the default deadline as a control. It cleans up its fixture and HOME afterward. ```sh python3 - <<'PY' import json import os from pathlib import Path import subprocess from tempfile import TemporaryDirectory with TemporaryDirectory(prefix="rea-scope-") as temporary: root = Path(temporary) fixture = root / "fixture" fixture.mkdir() (fixture / "a.js").write_text("export const value = 1;\n") (fixture / "z.node").write_bytes(bytes([0, 1, 2, 3])) home = root / "home" home.mkdir() environment = dict(os.environ, HOME=str(home)) for label, options in [ ("timeout", ["--analysis-timeout-ms", "1"]), ("control", []), ]: result = subprocess.run( ["node", "scripts/rea.mjs", "analyze-javascript-application", str(fixture), *options, "--format", "json", "--full-output"], env=environment, capture_output=True, text=True, timeout=30, ) envelope = json.loads(result.stdout) observation = (envelope["data"] if envelope["ok"] else envelope["error"]["details"]["partial_observation"]) nodes = observation["normalized_result"]["graph"]["nodes"] scopes = [o for n in nodes if n["kind"] == "unknown" for o in n["observations"] if o["properties"].get("path") == "z.node"] print(label, "exit", result.returncode, "addon unknown scopes", len(scopes)) for scope in scopes: print(json.dumps({ "properties": scope["properties"], "authority": scope["evidence"]["authority"], "state": scope["evidence"]["state"], }, indent=2)) PY ``` The executed two-file case produced `timeout exit 1 addon unknown scopes 1` and `control exit 0 addon unknown scopes 0`. It reproduced again when the same fixture also contained a valid package record, an HTML file, and a source map. Those unvisited entries also received the incorrect operation. Across three local timeout runs, the add-on scope appeared in all three, while all three default-deadline controls succeeded. A 1 ms deadline is a supported input but whether a particular run times out depends on the runtime and machine. ### Expected behavior A source timeout should preserve collected partial Evidence and leave unexamined relationships unknown. Native add-ons should keep their documented metadata-only representation without acquiring an inapplicable JavaScript AST-analysis scope. Unknown scopes for unexamined package records, HTML, or source maps should accurately represent their own analysis applicability. The attempted JavaScript source should retain its real timeout evidence. `docs/javascript-artifact-reconstruction.md:178-190` defines retained timeout partial Evidence, and lines 415-416 define native add-ons as metadata-only. The deadline is supported by CLI help and `src/domain/javascript/javascriptAnalysisResourceControls.ts:72-81`. ### Impact and scope P2. Timeout partial Evidence adds false typed graph nodes, contains edges, and AST-analysis provenance for remaining non-JavaScript entries. Inventory metadata survives, and no severe workflow failure or data loss was observed. The tiny fixtures succeed with the default deadline, but that is not an established remedy for callers needing partial Evidence after a genuine timeout. Workaround status remains unverified. ### REA version rea 6.5.0 at source commit 4692bb33300c7cb77b095b6cc0c33da861c1b860 ### Runtime and platform Node 24.18.0; macOS arm64 ### Target and artifact context Disposable directory with inert `a.js` and a four-byte `z.node` metadata entry; expanded control also includes package, HTML, and source-map files. No target code, native provider, or external service executed. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence The timeout command exits with code 1 and returns `error.code: provider_timeout`. In `error.details.partial_observation.normalized_result.graph.nodes`, an extra `unknown` node has identity key `analyze-javascript-source:z.node`. Its observation has these values: ```json { "properties": { "path": "z.node", "operation": "analyze-javascript-source", "limitation": "Source analysis was interrupted: Analysis operation timed out after 1ms: analyze_javascript_application" }, "authority": "ast-static-analysis", "state": "unavailable" } ``` The graph also attaches the unknown scope to the native-add-on node through a `contains` edge. This changes the graph and analysis provenance, rather than only the displayed error message. The control exits with code 0, parses its single JavaScript source, and retains the same native-add-on inventory observation without an unknown add-on scope. These are observed CLI results. Cancellation and worker failures were not runtime-tested for this report. ### Typed outcome or recovery expected Run the two-file reproduction and confirm that a real JavaScript timeout still returns its typed error and partial Evidence, with the attempted source's unavailable analysis scope intact. The native-add-on inventory observation must remain present, and the add-on must have no JavaScript AST-analysis failure scope. The default-deadline control must still succeed with its source parsed and the add-on represented by metadata. Repeat with unvisited package, HTML, and source-map entries to check that their unknown coverage preserves the applicable file kind instead of calling them JavaScript sources. No implementation choice is required by this report. ### Analysis or suspected cause Source-derived: `src/application/javascript/JavaScriptArtifactAnalysis.ts:268-299` skips analyzed and caller-excluded paths, then attaches the shared interruption failure to each remaining in-scope relevant file regardless of kind. `src/application/javascript/JavaScriptArtifactGraphStructure.ts:222-232` treats it as a JavaScript-source failure. `src/application/javascript/JavaScriptArtifactGraphContext.ts:209-260` emits the unknown node, contains edge, and unavailable AST evidence. ### Additional context The cited failing code is unchanged on current `origin/main` at `22ec8bdb2f7d4626587f23b1eed4a207df600386`. Closed #1968 concerns a caller-excluded file being misreported after cancellation; excluded files are already skipped in this reproduction. Open PR #3852 changes skipped-JavaScript parse-status reporting and counters, leaving the non-JavaScript interruption-scope branch unchanged.
Author
Owner

@N0zoM1z0 commented on GitHub (Oct 15, 2026):

Working on this as the next #4027 slice, from fresh main c7f6b8bad1a34d5efb30ff2a017672dea1fcdabb.

Executed static public stdio MCP plus CLI trace parity on the official Joplin v3.7.21 ASAR: selecting ElectronAppWrapper.js, its map, index.html, package.json and keytar's .node, with the supported 1 ms source deadline, reproduces analyze-javascript-source / ast-static-analysis unavailable scopes on keytar and the unvisited structured files. Native content identity/handoff linkage remains correct. The startup code/application and native providers are not executed; supplied native Evidence is explicitly simulated for linkage.

The fix will preserve analysis applicability at the producer and consume it in graph projection, retaining native metadata, caller selection/exclusions, actual JavaScript failure and applicable structured-file unknowns. #3852's skipped-JavaScript reporting remains separate. Public timeout/cancellation controls and real Joplin before/after verification are in progress; no fix or performance improvement is claimed yet.

<!-- gh-comment-id:6198179759 --> @N0zoM1z0 commented on GitHub (Oct 15, 2026): Working on this as the next #4027 slice, from fresh main `c7f6b8bad1a34d5efb30ff2a017672dea1fcdabb`. Executed static public stdio MCP plus CLI trace parity on the official Joplin v3.7.21 ASAR: selecting `ElectronAppWrapper.js`, its map, `index.html`, `package.json` and keytar's `.node`, with the supported 1 ms source deadline, reproduces `analyze-javascript-source` / `ast-static-analysis` unavailable scopes on keytar and the unvisited structured files. Native content identity/handoff linkage remains correct. The startup code/application and native providers are not executed; supplied native Evidence is explicitly simulated for linkage. The fix will preserve analysis applicability at the producer and consume it in graph projection, retaining native metadata, caller selection/exclusions, actual JavaScript failure and applicable structured-file unknowns. #3852's skipped-JavaScript reporting remains separate. Public timeout/cancellation controls and real Joplin before/after verification are in progress; no fix or performance improvement is claimed yet.
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#1555
No description provided.