[GH-ISSUE #7500] [Bug] trace_javascript_semantics forward influence stops at operands of + and template literals, and reports found with no unknowns #4464

Closed
opened 2026-10-31 00:50:03 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @Rinkia on GitHub (Oct 27, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/7500

Before submitting

  • I searched the open and closed issues for a related report (forward-influence, concatenation, binary expression, template literal). Related: #6193 (closed, links assignment right-hand sides to their target) and #6192 (properties assigned after declaration). Neither covers a value that flows through an operator.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

A forward-influence trace from a string literal follows a plain alias and a compound assignment into a fetch argument. It stops at the literal's read when the value goes through + or a template literal. In the + case the result is status: "found" with no unknowns, so nothing tells the caller the trace is incomplete.

Fixture app.js (with {"type":"module"} in package.json):

const A = "https://alias.example.test";
const A2 = A;
export async function f1() { return fetch(A2); }
const B = "https://binary.example.test";
const B2 = B + "/x";
export async function f2() { return fetch(B2); }
const C = "https://reassign.example.test";
let C2;
C2 = C + "/y";
export async function f3() { return fetch(C2); }
const D = "https://compound.example.test";
let D2 = "";
D2 += D;
export async function f4() { return fetch(D2); }
const E = "https://callarg.example.test";
export async function f5() { return fetch(E + "/z"); }
const T = "https://template.example.test";
export async function f6(id) { return fetch(`${T}/c/${id}`); }
const G = "https://plusassign.example.test";
let G2 = "";
G2 = G2 + G;
export async function f7() { return fetch(G2); }

Forward influence from each literal (seed: {kind: "literal", value: …}):

Literal flows through Nodes reached Reaches the fetch argument status
const A2 = A A, A2, read of A2, argument 0, f1 yes ambiguous
D2 += D D, D2, read of D2, argument 0, f4 yes ambiguous
const B2 = B + "/x" B, read of B no (B2 not reached) found
C2 = C + "/y" C, read of C no ambiguous
fetch(E + "/z") E, read of E, f5 no ambiguous
fetch(`${T}/c/${id}`) T, read of T, f6 no ambiguous
G2 = G2 + G G, read of G no ambiguous

The compound case shows the influence edge exists for D2 += D, which is also arithmetic on a string. The same write spelled G2 = G2 + G loses it.

Building a URL from a base constant with + or a template literal is the usual way requests are written, so a trace from an API base URL misses most of its requests.

A related gap: a literal that only appears as an operand or call argument ("/x", fetch("https://inline.example.test/f"), return "nothing") produces no seed match (total_seed_matches: 0, status: "partial").

Reproduction

MCP, same session:

{"name": "analyze_javascript_application", "arguments": {"input_path": "/abs/path/to/fixture"}}
{"name": "trace_javascript_semantics", "arguments": {
  "application": {"kind": "retained-evidence", "evidence_id": "<evidence_id from the analysis>"},
  "query": {"seed": {"kind": "literal", "value": "https://binary.example.test"}, "direction": "forward-influence"}}}

Same result on rea-agents@6.8.0 and on main at 570abe95f built from source (Linux x64 container, Node 24.22.1).

Expected behavior

  • The trace continues from an operand of + (and other binary operators) and from a template-literal expression to the value they produce, then to the binding, argument or return that receives it. Values stay unknown, as #4342 and #6193 already do for compound assignments; only the dependency edge is needed.
  • If an operator is deliberately not followed, the trace reports that as an unknown or a limitation, so status isn't found for a path that was cut.

Impact and scope

Forward traces through string building are incomplete, and in the declaration case the result looks complete. Static analysis only; no execution involved.

Originally created by @Rinkia on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7500 ### Before submitting - [x] I searched the open and closed issues for a related report (forward-influence, concatenation, binary expression, template literal). Related: #6193 (closed, links assignment right-hand sides to their target) and #6192 (properties assigned after declaration). Neither covers a value that flows through an operator. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior A forward-influence trace from a string literal follows a plain alias and a compound assignment into a `fetch` argument. It stops at the literal's read when the value goes through `+` or a template literal. In the `+` case the result is `status: "found"` with no unknowns, so nothing tells the caller the trace is incomplete. Fixture `app.js` (with `{"type":"module"}` in `package.json`): ```js const A = "https://alias.example.test"; const A2 = A; export async function f1() { return fetch(A2); } const B = "https://binary.example.test"; const B2 = B + "/x"; export async function f2() { return fetch(B2); } const C = "https://reassign.example.test"; let C2; C2 = C + "/y"; export async function f3() { return fetch(C2); } const D = "https://compound.example.test"; let D2 = ""; D2 += D; export async function f4() { return fetch(D2); } const E = "https://callarg.example.test"; export async function f5() { return fetch(E + "/z"); } const T = "https://template.example.test"; export async function f6(id) { return fetch(`${T}/c/${id}`); } const G = "https://plusassign.example.test"; let G2 = ""; G2 = G2 + G; export async function f7() { return fetch(G2); } ``` Forward influence from each literal (`seed: {kind: "literal", value: …}`): | Literal flows through | Nodes reached | Reaches the `fetch` argument | `status` | |---|---|---|---| | `const A2 = A` | `A`, `A2`, read of `A2`, `argument 0`, `f1` | yes | ambiguous | | `D2 += D` | `D`, `D2`, read of `D2`, `argument 0`, `f4` | yes | ambiguous | | `const B2 = B + "/x"` | `B`, read of `B` | **no** (`B2` not reached) | **found** | | `C2 = C + "/y"` | `C`, read of `C` | **no** | ambiguous | | `fetch(E + "/z")` | `E`, read of `E`, `f5` | **no** | ambiguous | | `` fetch(`${T}/c/${id}`) `` | `T`, read of `T`, `f6` | **no** | ambiguous | | `G2 = G2 + G` | `G`, read of `G` | **no** | ambiguous | The compound case shows the influence edge exists for `D2 += D`, which is also arithmetic on a string. The same write spelled `G2 = G2 + G` loses it. Building a URL from a base constant with `+` or a template literal is the usual way requests are written, so a trace from an API base URL misses most of its requests. A related gap: a literal that only appears as an operand or call argument (`"/x"`, `fetch("https://inline.example.test/f")`, `return "nothing"`) produces no seed match (`total_seed_matches: 0`, `status: "partial"`). ### Reproduction MCP, same session: ```json {"name": "analyze_javascript_application", "arguments": {"input_path": "/abs/path/to/fixture"}} {"name": "trace_javascript_semantics", "arguments": { "application": {"kind": "retained-evidence", "evidence_id": "<evidence_id from the analysis>"}, "query": {"seed": {"kind": "literal", "value": "https://binary.example.test"}, "direction": "forward-influence"}}} ``` Same result on `rea-agents@6.8.0` and on `main` at `570abe95f` built from source (Linux x64 container, Node 24.22.1). ### Expected behavior - The trace continues from an operand of `+` (and other binary operators) and from a template-literal expression to the value they produce, then to the binding, argument or return that receives it. Values stay unknown, as #4342 and #6193 already do for compound assignments; only the dependency edge is needed. - If an operator is deliberately not followed, the trace reports that as an unknown or a limitation, so `status` isn't `found` for a path that was cut. ### Impact and scope Forward traces through string building are incomplete, and in the declaration case the result looks complete. Static analysis only; no execution involved.
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#4464
No description provided.