[PR #3144] [CLOSED] fix(javascript): admit candidate endpoint interpretations at the worker boundary #5641

Closed
opened 2026-10-31 01:08:12 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3144
Author: @thanvi007
Created: 10/14/2026
Status: ❌ Closed

Base: main ← Head: fix/javascript-candidate-endpoints


📝 Commits (1)

  • 293bbf2 fix(javascript): admit candidate endpoint interpretations at the worker boundary

📊 Changes

3 files changed (+60 additions, -1 deletions)

View changed files

📝 src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts (+15 -0)
📝 src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.ts (+5 -1)
➕ tests/acceptance/applications/javascriptEndpointCandidateCli.test.ts (+40 -0)

📄 Description

Summary

Closes #3128.

analyze_javascript_application failed with unreadable_output on any source containing a call that the endpoint helper classifies as a candidate, for example client.post("session");. The analyzer emits interpretation: "candidate" on such endpoints, but the worker's strict endpoint schema did not declare that key. The analyzer's own output was therefore rejected at the worker boundary, and the whole analysis failed instead of reporting a low-confidence candidate.

Problem and expected behavior

  • Trigger: printf 'client.post("session");\n' > app/main.js && rea analyze-javascript-application ./app --json
  • Before: exit 1, code: "unreadable_output", with the reason unrecognized_keys: ["interpretation"] at ["endpoints", 0].
  • After: exit 0. The endpoint node carries properties.interpretation: "candidate" with static-relationship-inference evidence at state: "inferred", confidence: "low" and the existing "only a candidate" limitation. Its edge carries the same interpretation.

The domain types (javascriptStaticAnalysisTypes.ts, javascriptStaticAnalysisState.ts), the producer (javascriptStaticAnalysisCalls.ts) and the artifact graph projection (JavaScriptArtifactGraphFindings.ts) already support the field. Only the worker boundary schema was out of step.

Change and scope

  • JavaScriptAnalysisWorkerSchemas.ts: declare interpretation: z.literal("candidate").optional() on endpoints. The transform keeps the key absent, rather than undefined, for observed literals, matching how module_runtime is handled through withRuntime.
  • Not changed: candidate classification itself, the graph projection, and any public contract. The graph already projects the field.

Contribution scope: an ordinary fix within existing boundaries, so not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: the JavaScript analysis worker boundary schema (src/javascript/analysis).

  • Contribution scope fit and linked maintainer decision: not applicable.

  • CLI and MCP/tool-catalog contract: no schema change. Inputs that previously failed now return the candidate the graph already describes.

  • Provider, bridge, target-format, or platform compatibility: none.

  • Evidence, artifact, provenance, or reconstruction contract: unchanged. Candidates keep their inferred, low-confidence evidence.

  • Target selection, authority, upstream behavior, and cleanup details: not applicable.

  • Generated metadata, package, or installation impact: none.

  • Read existing files or captured data.

  • Launch or attach to a process.

  • Inject instrumentation or run scripts/code.

  • Change process memory, registers, files, or configuration.

  • Contact network services.

  • Recover protected code or work around protections.

  • Documentation or usability only; no target interaction.

  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts: the analyzer's output for client.post("session"); fetch("/literal"); round-trips through the worker schema. The candidate keeps interpretation: "candidate" and the literal has no interpretation key.
    • tests/acceptance/applications/javascriptEndpointCandidateCli.test.ts: the issue's reproduction through scripts/rea.mjs analyze-javascript-application. It asserts the endpoint node's properties and its inferred, low-confidence evidence, and the edge's interpretation.
  • Base reproduction: on main (5830088), both new tests fail with the reported unrecognized_keys error, and the built CLI reproduces the issue output exactly. With this change both pass.
  • Why the existing coverage missed it: javascriptArtifactGraphEndpoints.test.ts already covers candidates, but it calls analyzeJavaScriptArtifactFiles in process, so it never crosses the worker schema.
  • Remaining proof gaps: none known for this path.

Validation performed

  • npx tsc -p tsconfig.json --noEmit: passed.
  • npm run test:focused -- on the two new tests: 3 passed with the change, and 2 failed without it (unrecognized_keys).
  • npm run test:focused -- on the 22 related files (src/javascript/analysis/*, tests/boundary/filesystem/javascript-applications/*, and the JavaScript CLI acceptance tests applicationWorkflowCli, javascriptAnalysisLimits, javascriptFunctionNameCli, javascriptEndpointCandidateCli): 223 passed and 6 failed.
    • The same 6 also fail on unmodified main on this host (macOS arm64, Node 24.13). They are 3 in javascriptApplicationEmptyLiterals.test.ts (identity keys) and 3 in applicationWorkflowCli.test.ts (evidence locations). They look unrelated to this change, and I left them alone.
    • On main, a 7th test, "retains empty literal evidence across the application boundary surfaces", also fails. This change makes it pass.
  • npx oxfmt --check and npx oxlint on the changed files: passed. The only lint output is the existing max-lines warning on JavaScriptAnalysisWorkerSchemas.ts, which is already 668 lines on main.

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable. This is static JavaScript analysis, verified through the built CLI on macOS arm64.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no new process, file or network effects.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3144 **Author:** [@thanvi007](https://github.com/thanvi007) **Created:** 10/14/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/javascript-candidate-endpoints` --- ### 📝 Commits (1) - [`293bbf2`](https://github.com/morluto/rea/commit/293bbf2244e343d3f0aa43460a264607ffd45bac) fix(javascript): admit candidate endpoint interpretations at the worker boundary ### 📊 Changes **3 files changed** (+60 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts` (+15 -0) 📝 `src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.ts` (+5 -1) ➕ `tests/acceptance/applications/javascriptEndpointCandidateCli.test.ts` (+40 -0) </details> ### 📄 Description ## Summary Closes #3128. `analyze_javascript_application` failed with `unreadable_output` on any source containing a call that the endpoint helper classifies as a candidate, for example `client.post("session");`. The analyzer emits `interpretation: "candidate"` on such endpoints, but the worker's strict endpoint schema did not declare that key. The analyzer's own output was therefore rejected at the worker boundary, and the whole analysis failed instead of reporting a low-confidence candidate. ## Problem and expected behavior - **Trigger:** `printf 'client.post("session");\n' > app/main.js && rea analyze-javascript-application ./app --json` - **Before:** exit 1, `code: "unreadable_output"`, with the reason `unrecognized_keys: ["interpretation"]` at `["endpoints", 0]`. - **After:** exit 0. The endpoint node carries `properties.interpretation: "candidate"` with `static-relationship-inference` evidence at `state: "inferred"`, `confidence: "low"` and the existing "only a candidate" limitation. Its edge carries the same interpretation. The domain types (`javascriptStaticAnalysisTypes.ts`, `javascriptStaticAnalysisState.ts`), the producer (`javascriptStaticAnalysisCalls.ts`) and the artifact graph projection (`JavaScriptArtifactGraphFindings.ts`) already support the field. Only the worker boundary schema was out of step. ## Change and scope - `JavaScriptAnalysisWorkerSchemas.ts`: declare `interpretation: z.literal("candidate").optional()` on endpoints. The transform keeps the key absent, rather than `undefined`, for observed literals, matching how `module_runtime` is handled through `withRuntime`. - Not changed: candidate classification itself, the graph projection, and any public contract. The graph already projects the field. Contribution scope: an ordinary fix within existing boundaries, so not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: the JavaScript analysis worker boundary schema (`src/javascript/analysis`). - Contribution scope fit and linked maintainer decision: not applicable. - CLI and MCP/tool-catalog contract: no schema change. Inputs that previously failed now return the candidate the graph already describes. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: unchanged. Candidates keep their inferred, low-confidence evidence. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts`: the analyzer's output for `client.post("session"); fetch("/literal");` round-trips through the worker schema. The candidate keeps `interpretation: "candidate"` and the literal has no `interpretation` key. - `tests/acceptance/applications/javascriptEndpointCandidateCli.test.ts`: the issue's reproduction through `scripts/rea.mjs analyze-javascript-application`. It asserts the endpoint node's properties and its inferred, low-confidence evidence, and the edge's interpretation. - Base reproduction: on `main` (`5830088`), both new tests fail with the reported `unrecognized_keys` error, and the built CLI reproduces the issue output exactly. With this change both pass. - Why the existing coverage missed it: `javascriptArtifactGraphEndpoints.test.ts` already covers candidates, but it calls `analyzeJavaScriptArtifactFiles` in process, so it never crosses the worker schema. - Remaining proof gaps: none known for this path. ## Validation performed - `npx tsc -p tsconfig.json --noEmit`: passed. - `npm run test:focused --` on the two new tests: 3 passed with the change, and 2 failed without it (`unrecognized_keys`). - `npm run test:focused --` on the 22 related files (`src/javascript/analysis/*`, `tests/boundary/filesystem/javascript-applications/*`, and the JavaScript CLI acceptance tests `applicationWorkflowCli`, `javascriptAnalysisLimits`, `javascriptFunctionNameCli`, `javascriptEndpointCandidateCli`): 223 passed and 6 failed. - The same 6 also fail on unmodified `main` on this host (macOS arm64, Node 24.13). They are 3 in `javascriptApplicationEmptyLiterals.test.ts` (identity keys) and 3 in `applicationWorkflowCli.test.ts` (evidence locations). They look unrelated to this change, and I left them alone. - On `main`, a 7th test, "retains empty literal evidence across the application boundary surfaces", also fails. This change makes it pass. - `npx oxfmt --check` and `npx oxlint` on the changed files: passed. The only lint output is the existing `max-lines` warning on `JavaScriptAnalysisWorkerSchemas.ts`, which is already 668 lines on `main`. ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. This is static JavaScript analysis, verified through the built CLI on macOS arm64. - Package or release metadata impact: none. - Security, privacy, process, or containment review: no new process, file or network effects. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:08:12 +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#5641
No description provided.