[PR #2642] [CLOSED] fix(javascript): report present non-JavaScript require targets as unavailable #5303

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2642
Author: @cyberpunk47
Created: 10/13/2026
Status: ❌ Closed

Base: main ← Head: fix/javascript-present-non-js-targets


📝 Commits (8)

  • 822e466 fix(javascript): report present non-JavaScript require targets as unavailable
  • d404bbd fix(javascript): preserve opaque target identity through shared resolution
  • 10746e3 fix(javascript): index opaque identities and preserve resolution policy
  • 73534cf fix(javascript): retain partial opaque launch resolution evidence
  • b5ed98b fix(javascript): retain opaque package role candidates
  • 9834235 fix(javascript): retain exact expanded ASAR candidates
  • 97a79c0 Merge branch 'main' into fix/javascript-present-non-js-targets
  • 1366b77 Merge branch 'main' into fix/javascript-present-non-js-targets

📊 Changes

13 files changed (+703 additions, -65 deletions)

View changed files

📝 src/application/javascript/ElectronBoundaryGraphWindows.ts (+40 -8)
📝 src/application/javascript/JavaScriptArtifactGraphBuilder.ts (+1 -0)
📝 src/application/javascript/JavaScriptArtifactGraphContext.ts (+5 -0)
📝 src/application/javascript/JavaScriptArtifactGraphDocuments.ts (+1 -0)
📝 src/application/javascript/JavaScriptArtifactGraphFindings.ts (+40 -19)
📝 src/application/javascript/JavaScriptArtifactGraphStructure.ts (+6 -1)
📝 src/application/javascript/JavaScriptArtifactPathResolution.test.ts (+102 -1)
📝 src/application/javascript/JavaScriptArtifactPathResolution.ts (+66 -33)
📝 src/application/javascript/JavaScriptModuleRelationships.ts (+1 -0)
📝 src/artifacts/javascript/JavaScriptArtifactFiles.ts (+118 -0)
📝 src/domain/artifactInventorySnapshot.ts (+2 -0)
📝 src/domain/javascript/javascriptArtifactFiles.ts (+22 -0)
📝 tests/boundary/filesystem/javascriptRequireLiteralPaths.test.ts (+299 -3)

📄 Description

Summary

Fixes #2641

analyze-javascript-application reported resolution_status: "not-found" for a module target that exists in the analysed artifact when the file is outside the JavaScript-relevant kinds (for example a bytenode .jsc module). The output was identical to a really missing file, and the edge evidence stated that no candidate exists in the inventoried container. This change keeps the inventory identity of such files and reports them as unavailable, with a limitation naming their sha256 and size. Missing files still report not-found.

Problem and expected behavior

Smallest trigger: a directory with main.js containing const core = require("./core.jsc") and a core.jsc file next to it.

  • Before: resolution_status: "not-found", with the limitation "No extension, directory package, or index candidate exists in the inventoried artifact container."
  • After: resolution_status: "unavailable", with the limitation "core.jsc exists in the inventoried artifact container (sha256 …, N bytes) but is not a JavaScript, JSON, HTML, source map, or native add-on file; its contents were not analyzed."

Violated invariant (AGENTS.md): "Unresolved identity or applicability must remain unknown rather than be treated as absent, foreign, or aligned."

Change and scope

  • Producing boundary: src/artifacts/javascript/JavaScriptArtifactFiles.ts skipped inventoried regular files with no relevant kind (if (kind === undefined) continue;) and left no record. It now records them as unanalyzed_files (path, container sha256, sha256, bytes, inventory artifact id) on JavaScriptArtifactFileSet. Their bytes are still never read.
  • JavaScriptArtifactPathResolution.resolveFileCandidates checks those records in the same candidate order as before, keeping the same-container rule. A match returns unavailable instead of falling through to not-found.
  • The graph context carries unanalyzedFilesByPath, and every resolveArtifactPathByContext call built from the context passes it.
  • Not included: no new status value, no contract or schema change, no change to graph-level coverage, and no reading or decoding of bytecode.

Contribution scope: not applicable (routine fix within existing boundaries).

Contract and boundary impact

  • Semantic owner and earliest changed stage: JavaScript artifact file projection (JavaScriptArtifactFiles), then path resolution
  • Contribution scope fit and linked maintainer decision: routine evidence-correctness fix; not applicable
  • CLI and MCP/tool-catalog contract: no schema change; the existing unavailable status is now used for this case
  • Provider, bridge, target-format, or platform compatibility: none
  • Evidence, artifact, provenance, or reconstruction contract: present-but-unanalysed targets keep their inventory identity in the limitation instead of being reported absent
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none

Expected effects:

  • 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/application/javascript/JavaScriptArtifactPathResolution.test.ts: require and import targets present outside the projection give unavailable; a target in another container stays not-found; a missing target stays not-found.
    • tests/boundary/filesystem/javascriptRequireLiteralPaths.test.ts: real directory analysis; a present .jsc gives unavailable with its sha256 and size, and the same layout without the file gives not-found.
  • Base reproduction or other evidence: with only the test changes applied to the base revision, the boundary test and both unavailable unit tests fail; the two not-found guard tests pass.
  • User-visible CLI/MCP output (if applicable): see the before/after limitation text above.
  • Remaining proof gaps: graph-level coverage.status remains complete; whether it should change is left to maintainer preference (asked in the issue).

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npx vitest run src/application/javascript src/artifacts src/domain/javascript: 76 files, 1547 tests passed
  • npm run test:focused -- <43 JavaScript boundary test files>: 565 passed, 1 skipped, 1 failed. The failure (packageImportAliases.test.ts, "matches literal imports keys containing path-like bytes in both Node loaders") fails identically on the unmodified base under Node 22.22 (Node returns ERR_INVALID_MODULE_SPECIFIER) and is unrelated to this change.
  • npm run check:fast: typecheck and lint passed
  • oxfmt --check on changed files: passed
  • Manual CLI run on the issue's sample: ./core.jsc reports unavailable; with the file deleted it reports not-found.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Consumers that treat every non-resolved status as unresolved are unaffected; consumers matching not-found specifically will now see unavailable for present, unanalysed targets.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable (static JavaScript analysis only); verified on Linux x64 with Node.js 22.22 and 22.23.
  • Package or release metadata impact: none
  • Security, privacy, process, or containment review: no new reads of file contents and no execution; only inventory metadata the artifact inventory already holds (path, sha256, size) is reported.

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/2642 **Author:** [@cyberpunk47](https://github.com/cyberpunk47) **Created:** 10/13/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/javascript-present-non-js-targets` --- ### 📝 Commits (8) - [`822e466`](https://github.com/morluto/rea/commit/822e46606615195881b01542bd99502e25d70f3c) fix(javascript): report present non-JavaScript require targets as unavailable - [`d404bbd`](https://github.com/morluto/rea/commit/d404bbdfac78b1e4172a9ad098b49955a94aafc0) fix(javascript): preserve opaque target identity through shared resolution - [`10746e3`](https://github.com/morluto/rea/commit/10746e3c3fe8a571bb3757cd3d1d350a9951f767) fix(javascript): index opaque identities and preserve resolution policy - [`73534cf`](https://github.com/morluto/rea/commit/73534cf2d4b831f02b298cedbb37339c40813303) fix(javascript): retain partial opaque launch resolution evidence - [`b5ed98b`](https://github.com/morluto/rea/commit/b5ed98b02922ac595a4a027606f088959871ef55) fix(javascript): retain opaque package role candidates - [`9834235`](https://github.com/morluto/rea/commit/9834235c1c981e933d4556bfd89f7eec8d0c548a) fix(javascript): retain exact expanded ASAR candidates - [`97a79c0`](https://github.com/morluto/rea/commit/97a79c05d1b6d2a73756e0135a40f9f33f91fd21) Merge branch 'main' into fix/javascript-present-non-js-targets - [`1366b77`](https://github.com/morluto/rea/commit/1366b773809f7b7c5c66717845d805b4162b89b2) Merge branch 'main' into fix/javascript-present-non-js-targets ### 📊 Changes **13 files changed** (+703 additions, -65 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/ElectronBoundaryGraphWindows.ts` (+40 -8) 📝 `src/application/javascript/JavaScriptArtifactGraphBuilder.ts` (+1 -0) 📝 `src/application/javascript/JavaScriptArtifactGraphContext.ts` (+5 -0) 📝 `src/application/javascript/JavaScriptArtifactGraphDocuments.ts` (+1 -0) 📝 `src/application/javascript/JavaScriptArtifactGraphFindings.ts` (+40 -19) 📝 `src/application/javascript/JavaScriptArtifactGraphStructure.ts` (+6 -1) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (+102 -1) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.ts` (+66 -33) 📝 `src/application/javascript/JavaScriptModuleRelationships.ts` (+1 -0) 📝 `src/artifacts/javascript/JavaScriptArtifactFiles.ts` (+118 -0) 📝 `src/domain/artifactInventorySnapshot.ts` (+2 -0) 📝 `src/domain/javascript/javascriptArtifactFiles.ts` (+22 -0) 📝 `tests/boundary/filesystem/javascriptRequireLiteralPaths.test.ts` (+299 -3) </details> ### 📄 Description ## Summary Fixes #2641 `analyze-javascript-application` reported `resolution_status: "not-found"` for a module target that exists in the analysed artifact when the file is outside the JavaScript-relevant kinds (for example a bytenode `.jsc` module). The output was identical to a really missing file, and the edge evidence stated that no candidate exists in the inventoried container. This change keeps the inventory identity of such files and reports them as `unavailable`, with a limitation naming their sha256 and size. Missing files still report `not-found`. ## Problem and expected behavior Smallest trigger: a directory with `main.js` containing `const core = require("./core.jsc")` and a `core.jsc` file next to it. - Before: `resolution_status: "not-found"`, with the limitation "No extension, directory package, or index candidate exists in the inventoried artifact container." - After: `resolution_status: "unavailable"`, with the limitation "core.jsc exists in the inventoried artifact container (sha256 …, N bytes) but is not a JavaScript, JSON, HTML, source map, or native add-on file; its contents were not analyzed." Violated invariant (AGENTS.md): "Unresolved identity or applicability must remain unknown rather than be treated as absent, foreign, or aligned." ## Change and scope - Producing boundary: `src/artifacts/javascript/JavaScriptArtifactFiles.ts` skipped inventoried regular files with no relevant kind (`if (kind === undefined) continue;`) and left no record. It now records them as `unanalyzed_files` (path, container sha256, sha256, bytes, inventory artifact id) on `JavaScriptArtifactFileSet`. Their bytes are still never read. - `JavaScriptArtifactPathResolution.resolveFileCandidates` checks those records in the same candidate order as before, keeping the same-container rule. A match returns `unavailable` instead of falling through to `not-found`. - The graph context carries `unanalyzedFilesByPath`, and every `resolveArtifactPathByContext` call built from the context passes it. - Not included: no new status value, no contract or schema change, no change to graph-level coverage, and no reading or decoding of bytecode. Contribution scope: not applicable (routine fix within existing boundaries). ## Contract and boundary impact - Semantic owner and earliest changed stage: JavaScript artifact file projection (`JavaScriptArtifactFiles`), then path resolution - Contribution scope fit and linked maintainer decision: routine evidence-correctness fix; not applicable - CLI and MCP/tool-catalog contract: no schema change; the existing `unavailable` status is now used for this case - Provider, bridge, target-format, or platform compatibility: none - Evidence, artifact, provenance, or reconstruction contract: present-but-unanalysed targets keep their inventory identity in the limitation instead of being reported absent - Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none Expected effects: - [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/application/javascript/JavaScriptArtifactPathResolution.test.ts`: require and import targets present outside the projection give `unavailable`; a target in another container stays `not-found`; a missing target stays `not-found`. - `tests/boundary/filesystem/javascriptRequireLiteralPaths.test.ts`: real directory analysis; a present `.jsc` gives `unavailable` with its sha256 and size, and the same layout without the file gives `not-found`. - Base reproduction or other evidence: with only the test changes applied to the base revision, the boundary test and both `unavailable` unit tests fail; the two `not-found` guard tests pass. - User-visible CLI/MCP output (if applicable): see the before/after limitation text above. - Remaining proof gaps: graph-level `coverage.status` remains `complete`; whether it should change is left to maintainer preference (asked in the issue). For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npx vitest run src/application/javascript src/artifacts src/domain/javascript`: 76 files, 1547 tests passed - `npm run test:focused -- <43 JavaScript boundary test files>`: 565 passed, 1 skipped, 1 failed. The failure (`packageImportAliases.test.ts`, "matches literal imports keys containing path-like bytes in both Node loaders") fails identically on the unmodified base under Node 22.22 (Node returns `ERR_INVALID_MODULE_SPECIFIER`) and is unrelated to this change. - `npm run check:fast`: typecheck and lint passed - `oxfmt --check` on changed files: passed - Manual CLI run on the issue's sample: `./core.jsc` reports `unavailable`; with the file deleted it reports `not-found`. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Consumers that treat every non-`resolved` status as unresolved are unaffected; consumers matching `not-found` specifically will now see `unavailable` for present, unanalysed targets. - Real Hopper/Ghidra, browser, or OS coverage: not applicable (static JavaScript analysis only); verified on Linux x64 with Node.js 22.22 and 22.23. - Package or release metadata impact: none - Security, privacy, process, or containment review: no new reads of file contents and no execution; only inventory metadata the artifact inventory already holds (path, sha256, size) is reported. ## 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:05:34 +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#5303
No description provided.