[GH-ISSUE #3189] [Bug] Node-ID feature seeds ignore substring and case-insensitive matching options #1126

Closed
opened 2026-10-15 18:31:18 +00:00 by bsakaguchi · 2 comments
Owner

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

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

The CLI accepts a node-id feature seed with match: "contains" and case_sensitive: false, then returns an empty trace when the value is a prefix of an existing graph node ID. A full ID converted to uppercase also returns no matches when case sensitivity is disabled or omitted. Supplying the complete, exactly cased ID succeeds against the same authenticated application Evidence.

All six trace requests in the reproduction exited with status zero. The failing requests reported zero traced nodes and empty seed_matches despite complete source-graph coverage. The successful controls reported one match with basis: "node-id" and field: "node_id". Inspection of the default-case request confirmed that the returned parameters normalized omitted case_sensitive to false.

Reproduction

  1. Start with a clean checkout at the verified source revision and install the repository's pinned Node toolchain, Node 24.18.0. Prepare the CLI from the checkout root:
git clone https://github.com/morluto/rea.git rea-node-seed-repro
cd rea-node-seed-repro
git checkout 58300885207133422af235e0f2b10658cf958b03
npm ci
npm run build:cached

These install and build commands are clean-checkout preparation. Verification used already-installed lockfile dependencies and the prepared baseline runtime rather than rerunning preparation.

  1. With Python 3 available, run this driver from the checkout root. It creates a two-file application inline, isolates REA's home/config/cache/data directories, obtains an actual graph node ID through the CLI, and submits six file-backed trace requests. It removes the fixture when it exits.
python3 - <<'PY'
import json
import os
from pathlib import Path
import subprocess
import tempfile

with tempfile.TemporaryDirectory(prefix="rea-node-seed-") as directory:
    work = Path(directory)
    environment = os.environ.copy()
    for key, child in [("HOME", "home"), ("XDG_CONFIG_HOME", "config"),
                       ("XDG_CACHE_HOME", "cache"), ("XDG_DATA_HOME", "data")]:
        target = work / child
        target.mkdir()
        environment[key] = str(target)

    app = work / "app"
    app.mkdir()
    (app / "package.json").write_text(
        '{"name":"sample-app","version":"1.0.0","main":"index.js"}\n')
    (app / "index.js").write_text(
        'module.exports = function greet() { return "hello"; };\n')

    def rea(*arguments):
        result = subprocess.run(
            ["node", "scripts/rea.mjs", *arguments, "--format", "json"],
            env=environment, capture_output=True, text=True, check=True)
        return json.loads(result.stdout)

    application = rea("analyze-javascript-application", str(app))
    node_id = application["normalized_result"]["graph"]["nodes"][0]["node_id"]
    cases = [
        ("prefix-contains", node_id[:24], "contains", False),
        ("full-contains", node_id, "contains", False),
        ("upper-exact-false", node_id.upper(), "exact", False),
        ("upper-exact-default", node_id.upper(), "exact", None),
        ("full-exact", node_id, "exact", True),
        ("upper-exact-true", node_id.upper(), "exact", True),
    ]
    for name, value, mode, case_sensitive in cases:
        seed = {"kind": "node-id", "value": value, "match": mode}
        if case_sensitive is not None:
            seed["case_sensitive"] = case_sensitive
        request = work / (name + ".json")
        request.write_text(json.dumps({"application": application,
                                      "direction": "both", "seed": seed}))
        result = rea("trace-application-feature", str(request))["normalized_result"]
        print(name, result["summary"]["matched_seeds"],
              result["coverage"]["status"])
PY
  1. Read each output line as the case name, matched seed count, and coverage status. Compare the prefix and uppercase case-insensitive requests with the full-ID controls and the uppercase case-sensitive negative control.

Expected behavior

docs/javascript-application-workflows.md:43-48 lists node ID among the literal feature seeds and offers exact or literal substring matching. src/domain/javascript/javascriptFeatureTraceSchemas.ts:57-70 accepts node-ID seeds with these modes and defaults case_sensitive to false.

The prefix request should include the selected node in its matches. Both uppercase full-ID requests with case sensitivity disabled or omitted should match that node once. The complete, exactly cased ID should continue to match once in both modes, and the uppercase request with case_sensitive: true should continue to return no matches.

Impact and scope

Accepted substring and case-insensitive node-ID queries silently return empty feature traces for nodes present in the graph. The reproduced defect is bounded to these seed comparisons and produces incorrect caller-visible results. Copying the complete, exactly cased node ID from the application graph is an observed practical workaround.

Runtime verification exercised CLI requests only. The fixture was analyzed statically; no target application executed, and no native provider or external API was involved. No security boundary was crossed.

REA version

6.4.0 (main at 5830088520)

Runtime and platform

Node v26.10.0 and Node v24.21.0; Darwin 27.0.0 arm64. Both runtimes produced the same six matching results. The complete fresh-fixture driver ran on Node v24.21.0. The repository's exact Node 24.18.0 patch was not installed or exercised during verification.

Target and artifact context

A generated CommonJS application directory containing package.json and index.js. The CLI's analyze-javascript-application command produced authenticated application Evidence with complete graph coverage. The same Evidence was supplied to every trace-application-feature request.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

prefix-contains 0 no-match
full-contains 1 complete-within-source
upper-exact-false 0 no-match
upper-exact-default 0 no-match
full-exact 1 complete-within-source
upper-exact-true 0 no-match

Typed outcome or recovery expected

The prefix request must include the selected node, and both uppercase case-insensitive requests must return that exact node as a seed match. The full-ID controls must keep returning one match, and the uppercase case-sensitive negative control must keep returning no matches. A no-match result should represent absence under the requested literal-matching options.

Analysis or suspected cause

Source-derived reasoning at the reported baseline: src/cli/applicationCommands.ts:29-40 binds the accepted trace schema to the CLI command. src/domain/javascript/javascriptFeatureSeed.ts:43-53 handles node-ID seeds with strict node.node_id === seed.value equality and returns before the shared mode and case-normalization logic at src/domain/javascript/javascriptFeatureSeed.ts:72-78. src/domain/javascript/javascriptFeatureTrace.ts:40-52 invokes this matcher and emits no-match when it returns no seeds. These branches account for the reproduced substring and case failures.

Additional context

Related closed report #2669 concerns missing nested Electron API call paths; this report instead concerns substring and case options when matching node IDs already present in the graph.

P2 impact is supported by bounded incorrect feature-trace results and an observed workaround using the complete, exactly cased ID.

Related: #3190 reports a separate failure in the same area; the two have independent fixes.

Originally created by @coygeek on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3189 ### 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 The CLI accepts a `node-id` feature seed with `match: "contains"` and `case_sensitive: false`, then returns an empty trace when the value is a prefix of an existing graph node ID. A full ID converted to uppercase also returns no matches when case sensitivity is disabled or omitted. Supplying the complete, exactly cased ID succeeds against the same authenticated application Evidence. All six trace requests in the reproduction exited with status zero. The failing requests reported zero traced nodes and empty `seed_matches` despite complete source-graph coverage. The successful controls reported one match with `basis: "node-id"` and `field: "node_id"`. Inspection of the default-case request confirmed that the returned parameters normalized omitted `case_sensitive` to false. ### Reproduction 1. Start with a clean checkout at the verified source revision and install the repository's pinned Node toolchain, Node 24.18.0. Prepare the CLI from the checkout root: ```sh git clone https://github.com/morluto/rea.git rea-node-seed-repro cd rea-node-seed-repro git checkout 58300885207133422af235e0f2b10658cf958b03 npm ci npm run build:cached ``` These install and build commands are clean-checkout preparation. Verification used already-installed lockfile dependencies and the prepared baseline runtime rather than rerunning preparation. 2. With Python 3 available, run this driver from the checkout root. It creates a two-file application inline, isolates REA's home/config/cache/data directories, obtains an actual graph node ID through the CLI, and submits six file-backed trace requests. It removes the fixture when it exits. ```sh python3 - <<'PY' import json import os from pathlib import Path import subprocess import tempfile with tempfile.TemporaryDirectory(prefix="rea-node-seed-") as directory: work = Path(directory) environment = os.environ.copy() for key, child in [("HOME", "home"), ("XDG_CONFIG_HOME", "config"), ("XDG_CACHE_HOME", "cache"), ("XDG_DATA_HOME", "data")]: target = work / child target.mkdir() environment[key] = str(target) app = work / "app" app.mkdir() (app / "package.json").write_text( '{"name":"sample-app","version":"1.0.0","main":"index.js"}\n') (app / "index.js").write_text( 'module.exports = function greet() { return "hello"; };\n') def rea(*arguments): result = subprocess.run( ["node", "scripts/rea.mjs", *arguments, "--format", "json"], env=environment, capture_output=True, text=True, check=True) return json.loads(result.stdout) application = rea("analyze-javascript-application", str(app)) node_id = application["normalized_result"]["graph"]["nodes"][0]["node_id"] cases = [ ("prefix-contains", node_id[:24], "contains", False), ("full-contains", node_id, "contains", False), ("upper-exact-false", node_id.upper(), "exact", False), ("upper-exact-default", node_id.upper(), "exact", None), ("full-exact", node_id, "exact", True), ("upper-exact-true", node_id.upper(), "exact", True), ] for name, value, mode, case_sensitive in cases: seed = {"kind": "node-id", "value": value, "match": mode} if case_sensitive is not None: seed["case_sensitive"] = case_sensitive request = work / (name + ".json") request.write_text(json.dumps({"application": application, "direction": "both", "seed": seed})) result = rea("trace-application-feature", str(request))["normalized_result"] print(name, result["summary"]["matched_seeds"], result["coverage"]["status"]) PY ``` 3. Read each output line as the case name, matched seed count, and coverage status. Compare the prefix and uppercase case-insensitive requests with the full-ID controls and the uppercase case-sensitive negative control. ### Expected behavior `docs/javascript-application-workflows.md:43-48` lists node ID among the literal feature seeds and offers exact or literal substring matching. `src/domain/javascript/javascriptFeatureTraceSchemas.ts:57-70` accepts node-ID seeds with these modes and defaults `case_sensitive` to false. The prefix request should include the selected node in its matches. Both uppercase full-ID requests with case sensitivity disabled or omitted should match that node once. The complete, exactly cased ID should continue to match once in both modes, and the uppercase request with `case_sensitive: true` should continue to return no matches. ### Impact and scope Accepted substring and case-insensitive node-ID queries silently return empty feature traces for nodes present in the graph. The reproduced defect is bounded to these seed comparisons and produces incorrect caller-visible results. Copying the complete, exactly cased node ID from the application graph is an observed practical workaround. Runtime verification exercised CLI requests only. The fixture was analyzed statically; no target application executed, and no native provider or external API was involved. No security boundary was crossed. ### REA version 6.4.0 (main at 58300885207133422af235e0f2b10658cf958b03) ### Runtime and platform Node v26.10.0 and Node v24.21.0; Darwin 27.0.0 arm64. Both runtimes produced the same six matching results. The complete fresh-fixture driver ran on Node v24.21.0. The repository's exact Node 24.18.0 patch was not installed or exercised during verification. ### Target and artifact context A generated CommonJS application directory containing `package.json` and `index.js`. The CLI's `analyze-javascript-application` command produced authenticated application Evidence with complete graph coverage. The same Evidence was supplied to every `trace-application-feature` request. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence ```text prefix-contains 0 no-match full-contains 1 complete-within-source upper-exact-false 0 no-match upper-exact-default 0 no-match full-exact 1 complete-within-source upper-exact-true 0 no-match ``` ### Typed outcome or recovery expected The prefix request must include the selected node, and both uppercase case-insensitive requests must return that exact node as a seed match. The full-ID controls must keep returning one match, and the uppercase case-sensitive negative control must keep returning no matches. A `no-match` result should represent absence under the requested literal-matching options. ### Analysis or suspected cause Source-derived reasoning at the reported baseline: `src/cli/applicationCommands.ts:29-40` binds the accepted trace schema to the CLI command. `src/domain/javascript/javascriptFeatureSeed.ts:43-53` handles node-ID seeds with strict `node.node_id === seed.value` equality and returns before the shared mode and case-normalization logic at `src/domain/javascript/javascriptFeatureSeed.ts:72-78`. `src/domain/javascript/javascriptFeatureTrace.ts:40-52` invokes this matcher and emits `no-match` when it returns no seeds. These branches account for the reproduced substring and case failures. ### Additional context Related closed report #2669 concerns missing nested Electron API call paths; this report instead concerns substring and case options when matching node IDs already present in the graph. P2 impact is supported by bounded incorrect feature-trace results and an observed workaround using the complete, exactly cased ID. Related: #3190 reports a separate failure in the same area; the two have independent fixes.
bsakaguchi 2026-10-15 18:31:18 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

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

Heads up: this looks fixed on main in 44c9d2924. The change is in src/domain/javascript/javascriptFeatureSeed.ts, and matches feature seeds against node IDs and preserved route values through CLI and MCP covers it. It is listed on tracker #3582. If it still happens on main, please say so here and I'll take it off the list.

🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊

<!-- gh-comment-id:6174981281 --> @CassieFox23 commented on GitHub (Oct 14, 2026): Heads up: this looks fixed on main in 44c9d2924. The change is in `src/domain/javascript/javascriptFeatureSeed.ts`, and `matches feature seeds against node IDs and preserved route values through CLI and MCP` covers it. It is listed on tracker #3582. If it still happens on main, please say so here and I'll take it off the list. 🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
Author
Owner

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

Resolved on main by 44c9d2924.

Node-ID seeds now honor the same substring/exact and case-sensitive/insensitive options as other seeds.

Rechecked on main b8510ee00 in the current focused run: 17 test files passed, 485 tests passed and one platform-dependent test skipped. Relevant regression coverage: tests/acceptance/applications/javascriptFeatureTraceSeedSelectionCli.test.ts.

<!-- gh-comment-id:6175071565 --> @morluto commented on GitHub (Oct 14, 2026): Resolved on main by 44c9d2924. Node-ID seeds now honor the same substring/exact and case-sensitive/insensitive options as other seeds. Rechecked on main b8510ee00 in the current focused run: 17 test files passed, 485 tests passed and one platform-dependent test skipped. Relevant regression coverage: tests/acceptance/applications/javascriptFeatureTraceSeedSelectionCli.test.ts.
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#1126
No description provided.