[PR #2104] [MERGED] fix(javascript): resolve module-relative Worker URL references #5033

Closed
opened 2026-10-31 00:59:27 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2104
Author: @shoyann
Created: 10/12/2026
Status: ✅ Merged
Merged: 10/12/2026
Merged by: @baron

Base: main ← Head: fix/worker-import-meta-url


📝 Commits (10+)

  • 4943b6a fix(javascript): resolve module-relative Worker URL references
  • 5b97315 fix(javascript): validate Worker URL paths independently of suffixes
  • 6301950 fix(javascript): preserve directory-form Worker URL paths
  • c534ada fix(javascript): unwrap type assertions in Worker URL references
  • 0c2803e fix(javascript): validate Worker bindings before URL resolution
  • 6862b0c fix(javascript): leave drive-letter Worker URLs unresolved
  • bb76ee4 fix(javascript): preserve Worker URL identity boundaries
  • 8d30ba4 fix(javascript): invalidate mutated import.meta URL bases
  • 5d84b26 fix(javascript): close Worker URL identity and pathname gaps
  • 5019ebb fix(javascript): bound alias expansion and classify Worker paths

📊 Changes

20 files changed (+2071 additions, -172 deletions)

View changed files

📝 src/application/javascript/JavaScriptArtifactGraphFindings.ts (+23 -20)
📝 src/application/javascript/JavaScriptArtifactPathResolution.test.ts (+128 -0)
📝 src/application/javascript/JavaScriptArtifactPathResolution.ts (+52 -28)
📝 src/domain/javascript/javascriptElectronMemberWrites.ts (+26 -17)
📝 src/domain/javascript/javascriptIntrinsicInvocation.ts (+45 -5)
📝 src/domain/javascript/javascriptModuleInterop.ts (+59 -51)
➕ src/domain/javascript/javascriptSemanticAmbientWrites.test.ts (+57 -0)
➕ src/domain/javascript/javascriptSemanticAmbientWrites.ts (+301 -0)
📝 src/domain/javascript/javascriptSemanticAnalysis.ts (+21 -5)
➕ src/domain/javascript/javascriptSemanticDependencies.ts (+81 -0)
📝 src/domain/javascript/javascriptSemanticMemberMutations.ts (+3 -3)
📝 src/domain/javascript/javascriptSemanticMutationInitializers.test.ts (+1 -0)
📝 src/domain/javascript/javascriptSemanticState.ts (+8 -1)
➕ src/domain/javascript/javascriptSemanticValues.memo.test.ts (+227 -0)
📝 src/domain/javascript/javascriptSemanticValues.ts (+169 -26)
📝 src/domain/javascript/javascriptStaticAnalysis.ts (+4 -3)
📝 src/domain/javascript/javascriptStaticAnalysisCalls.ts (+99 -3)
📝 src/domain/javascript/javascriptStaticAnalysisHelpers.ts (+16 -9)
➕ tests/acceptance/applications/javascriptWorkerUrlCli.test.ts (+626 -0)
📝 tests/boundary/mcp/targetContentFramingMcp.test.ts (+125 -1)

📄 Description

Summary

Recover the common new Worker(new URL("./worker.js", import.meta.url), { type: "module" }) pattern as a Worker-to-file relationship. Previously the Worker was retained as an unknown expression with no maps_to edge.

Found during a source audit; no existing issue was identified for this pattern.

Problem and expected behavior

A literal URL relative to the current module gives enough static evidence to locate an inventoried Worker script. It must use exact URL resource lookup, including one percent-decoding pass and query/fragment removal before pathname admission, without selecting a similarly named bundled module or applying CommonJS extension/index/package fallbacks.

Representative artifact-graph result, verified through the production source pipeline:

Field Before After
declared_specifier null "./worker.js"
resolved_path null "worker.js"
Worker maps_to absent Worker script file

Change and scope

  • Recognize a new URL argument with a literal string or substitution-free template, an unshadowed global URL, and an import.meta.url base. Reuse the canonical transparent-expression unwrapping for TypeScript assertions, non-null expressions, and satisfies, including wrapped URL callees and module bases. Keep lexical shadow checks and the original Worker evidence node.
  • Require an outer constructor with an unshadowed browser Worker binding, or a runtime ESM named/namespace Worker import from worker_threads/node:worker_threads. The lexical owner distinguishes runtime ESM imports from type-only and import-equals syntax. Keep local classes, parameters, unrelated imports, reassigned bindings, default imports, and CommonJS objects unresolved; mutable module objects do not establish a Worker identity.
  • Reuse the existing module-URL predicate and lexical binding index. Preserve the raw specifier for the owning URL resolver. Existing direct-string Worker detection remains unchanged.
  • Make URL resource lookup exact, and keep Worker references out of bundled module/chunk lookup. Preserve directory-form endings (/, /., /..) before filesystem normalization, and leave repeated URL separators unresolved instead of collapsing distinct URL identities. Reuse the existing HTML directory predicate and confinement handling.
  • Validate only the URL pathname; encoded separators, backslashes, NUL, and other suffix data in query/fragment cannot invalidate an existing script path. Preserve the complete raw specifier, including suffixes.
  • Preserve unsupported or ambiguous inputs as expressions. Empty/query-only and pathnames requiring whitespace/control normalization remain unresolved; dynamic expressions, custom constructors, and shadowed URL are not guessed.

Contract and boundary impact

  • Semantic owner and earliest changed stage: domain static reference production; application artifact URL resolution and graph linking consume that fact.
  • CLI and MCP/tool-catalog contract: no schema or tool changes; shared analysis gains the missing relationship.
  • Provider, target-format, or platform compatibility: static JavaScript only; no new provider requirement.
  • Evidence and provenance: original specifiers, source ranges, and unresolved expressions are retained; no runtime execution is inferred.
  • Process execution, authorization, cleanup, or containment impact: none.
  • Generated metadata, package, or installation impact: none.

Evidence and regression coverage

  • Added three public compiled CLI journeys covering 25 resolved and 34 unresolved cases: relative/parent/template URLs, encoding and query/fragment handling, double-decoding decoy, ordinary string Worker, bundled-module collision, dynamic/shadowed/custom URL cases, missing exact files with extension/index/package decoys, external URLs, and unsupported URL forms.

  • The ordinary Worker URL bug was reproduced before the change through the production analyzer and graph builder.

  • Added resolver regressions for both query and fragment data (%2F, %2E, %5C, %00, %FF, raw backslash, and NUL), while retaining pathname rejection. Both suffix tests failed on 4943b6a and pass after the fix. Six directory/empty-segment regression cases failed on 5b97315 and now pass; interior dot segments, dotfiles, root confinement, and existing HTML behavior remain covered.

  • Added eight TypeScript wrapper scenarios and three wrapped shadow/dynamic negative scenarios. The as URL case reproduced a missing relationship on 6301950; all pass through the production source pipeline after the fix.

  • Added 21 constructor-identity cases (7 resolved, 14 unknown), including browser namespaces, both Node built-in module spellings, local classes/parameters, custom imports, type-only imports, reassignment, mutable namespaces, and calls without new. The local-class case fails against c534ada by creating a false file edge and passes after the fix.

  • Independently executed all 59 new fixture expectations through real file inventory, production source analysis, and graph construction. All passed, including the competing bundled-module assertion.

  • Remaining proof gap: compiled CLI and native-worker boundary tests are blocked locally before worker startup by the installed macOS Command Line Tools SwiftBridging duplicate module definition. No process ownership checks were bypassed.

  • 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

Pinned Node 24.18.0 / npm 11.16.0:

  • npm run check — passed: typecheck, lint (warnings, no errors), formatting, knip, metadata, module boundaries, and architecture guards.
  • Relevant source suites for URL path resolution, static references/source maps/module indexing, Electron identity/options, semantic import structure/require links/builtin defaults, and mutation initializer state — 241 tests passed across 10 files.
  • npm run verify:test-discovery — all 916 test files discovered exactly once.
  • git diff --cached --check — passed before commit.
  • npm run test:focused -- tests/acceptance/applications/javascriptWorkerUrlCli.test.ts — local execution blocked by the Swift toolchain startup failure. Both existing Worker CLI journeys, including TypeScript wrapper, suffix, and directory-form/empty-segment cases, passed in Linux CI on c534ada. The new constructor-identity journey awaits CI on the latest head.
  • Related focused source-map/file-URL boundary suites — 15 native-worker cases blocked by the same environment failure; 123 other tests passed in that run.

The previous PR CI run failed in MCP prompt completion and Darwin package prompt smoke tests. The same failures occur in main's CI at c22111e, following the independent prompt-completion lifecycle change in 07b36c1. Worker acceptance passed; no unrelated MCP change is included here.

Compatibility, safety, and release

  • Breaking changes or migrations: none. False URL extension/directory/module matches are intentionally removed.
  • Real browser/OS coverage: target JavaScript is parsed, not executed. No browser runtime verification claimed.
  • Package/release metadata and security/privacy/process/containment impact: none.

Review checklist

  • Concrete problem and one focused outcome; Conventional Commit title.
  • Reason for no related issue stated above.
  • Regression coverage includes meaningful failure paths and observable graph output.
  • No authored schema/documentation/generated metadata change required.
  • Final diff checked 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/2104 **Author:** [@shoyann](https://github.com/shoyann) **Created:** 10/12/2026 **Status:** ✅ Merged **Merged:** 10/12/2026 **Merged by:** [@baron](https://github.com/baron) **Base:** `main` ← **Head:** `fix/worker-import-meta-url` --- ### 📝 Commits (10+) - [`4943b6a`](https://github.com/morluto/rea/commit/4943b6aaa4ae636f300a6ed7b4b9b8a00b4ddffc) fix(javascript): resolve module-relative Worker URL references - [`5b97315`](https://github.com/morluto/rea/commit/5b97315a04beebda6c3b54e8f6aa0b3bf50fb339) fix(javascript): validate Worker URL paths independently of suffixes - [`6301950`](https://github.com/morluto/rea/commit/63019504648be938e82bc4ce46bad48ffbc4aa8b) fix(javascript): preserve directory-form Worker URL paths - [`c534ada`](https://github.com/morluto/rea/commit/c534adaeaf98556f3fe982d7ff2212f70f51dff7) fix(javascript): unwrap type assertions in Worker URL references - [`0c2803e`](https://github.com/morluto/rea/commit/0c2803e1c7ac8c5d26ab13c5030066f2971fb5ca) fix(javascript): validate Worker bindings before URL resolution - [`6862b0c`](https://github.com/morluto/rea/commit/6862b0c0d554787ef792e7e4f7625feedb1f8ad7) fix(javascript): leave drive-letter Worker URLs unresolved - [`bb76ee4`](https://github.com/morluto/rea/commit/bb76ee4dd30bcdb5438b45a923004cf65a15d817) fix(javascript): preserve Worker URL identity boundaries - [`8d30ba4`](https://github.com/morluto/rea/commit/8d30ba4c0a49ace96f4fe5f73ffa59c68b239c87) fix(javascript): invalidate mutated import.meta URL bases - [`5d84b26`](https://github.com/morluto/rea/commit/5d84b26d7e8c502ef6aa2eaf7a6d918e52a58fb9) fix(javascript): close Worker URL identity and pathname gaps - [`5019ebb`](https://github.com/morluto/rea/commit/5019ebb29294c06a85f249fa9b777b73bded429e) fix(javascript): bound alias expansion and classify Worker paths ### 📊 Changes **20 files changed** (+2071 additions, -172 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/JavaScriptArtifactGraphFindings.ts` (+23 -20) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (+128 -0) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.ts` (+52 -28) 📝 `src/domain/javascript/javascriptElectronMemberWrites.ts` (+26 -17) 📝 `src/domain/javascript/javascriptIntrinsicInvocation.ts` (+45 -5) 📝 `src/domain/javascript/javascriptModuleInterop.ts` (+59 -51) ➕ `src/domain/javascript/javascriptSemanticAmbientWrites.test.ts` (+57 -0) ➕ `src/domain/javascript/javascriptSemanticAmbientWrites.ts` (+301 -0) 📝 `src/domain/javascript/javascriptSemanticAnalysis.ts` (+21 -5) ➕ `src/domain/javascript/javascriptSemanticDependencies.ts` (+81 -0) 📝 `src/domain/javascript/javascriptSemanticMemberMutations.ts` (+3 -3) 📝 `src/domain/javascript/javascriptSemanticMutationInitializers.test.ts` (+1 -0) 📝 `src/domain/javascript/javascriptSemanticState.ts` (+8 -1) ➕ `src/domain/javascript/javascriptSemanticValues.memo.test.ts` (+227 -0) 📝 `src/domain/javascript/javascriptSemanticValues.ts` (+169 -26) 📝 `src/domain/javascript/javascriptStaticAnalysis.ts` (+4 -3) 📝 `src/domain/javascript/javascriptStaticAnalysisCalls.ts` (+99 -3) 📝 `src/domain/javascript/javascriptStaticAnalysisHelpers.ts` (+16 -9) ➕ `tests/acceptance/applications/javascriptWorkerUrlCli.test.ts` (+626 -0) 📝 `tests/boundary/mcp/targetContentFramingMcp.test.ts` (+125 -1) </details> ### 📄 Description ## Summary Recover the common `new Worker(new URL("./worker.js", import.meta.url), { type: "module" })` pattern as a Worker-to-file relationship. Previously the Worker was retained as an unknown expression with no `maps_to` edge. Found during a source audit; no existing issue was identified for this pattern. ## Problem and expected behavior A literal URL relative to the current module gives enough static evidence to locate an inventoried Worker script. It must use exact URL resource lookup, including one percent-decoding pass and query/fragment removal before pathname admission, without selecting a similarly named bundled module or applying CommonJS extension/index/package fallbacks. Representative artifact-graph result, verified through the production source pipeline: | Field | Before | After | | --- | --- | --- | | `declared_specifier` | `null` | `"./worker.js"` | | `resolved_path` | `null` | `"worker.js"` | | Worker `maps_to` | absent | Worker script file | ## Change and scope - Recognize a `new URL` argument with a literal string or substitution-free template, an unshadowed global `URL`, and an `import.meta.url` base. Reuse the canonical transparent-expression unwrapping for TypeScript assertions, non-null expressions, and `satisfies`, including wrapped URL callees and module bases. Keep lexical shadow checks and the original Worker evidence node. - Require an outer constructor with an unshadowed browser Worker binding, or a runtime ESM named/namespace Worker import from `worker_threads`/`node:worker_threads`. The lexical owner distinguishes runtime ESM imports from type-only and import-equals syntax. Keep local classes, parameters, unrelated imports, reassigned bindings, default imports, and CommonJS objects unresolved; mutable module objects do not establish a Worker identity. - Reuse the existing module-URL predicate and lexical binding index. Preserve the raw specifier for the owning URL resolver. Existing direct-string Worker detection remains unchanged. - Make URL resource lookup exact, and keep Worker references out of bundled module/chunk lookup. Preserve directory-form endings (`/`, `/.`, `/..`) before filesystem normalization, and leave repeated URL separators unresolved instead of collapsing distinct URL identities. Reuse the existing HTML directory predicate and confinement handling. - Validate only the URL pathname; encoded separators, backslashes, NUL, and other suffix data in query/fragment cannot invalidate an existing script path. Preserve the complete raw specifier, including suffixes. - Preserve unsupported or ambiguous inputs as expressions. Empty/query-only and pathnames requiring whitespace/control normalization remain unresolved; dynamic expressions, custom constructors, and shadowed `URL` are not guessed. ## Contract and boundary impact - Semantic owner and earliest changed stage: domain static reference production; application artifact URL resolution and graph linking consume that fact. - CLI and MCP/tool-catalog contract: no schema or tool changes; shared analysis gains the missing relationship. - Provider, target-format, or platform compatibility: static JavaScript only; no new provider requirement. - Evidence and provenance: original specifiers, source ranges, and unresolved expressions are retained; no runtime execution is inferred. - Process execution, authorization, cleanup, or containment impact: none. - Generated metadata, package, or installation impact: none. ## Evidence and regression coverage - Added three public compiled CLI journeys covering 25 resolved and 34 unresolved cases: relative/parent/template URLs, encoding and query/fragment handling, double-decoding decoy, ordinary string Worker, bundled-module collision, dynamic/shadowed/custom URL cases, missing exact files with extension/index/package decoys, external URLs, and unsupported URL forms. - The ordinary Worker URL bug was reproduced before the change through the production analyzer and graph builder. - Added resolver regressions for both query and fragment data (`%2F`, `%2E`, `%5C`, `%00`, `%FF`, raw backslash, and NUL), while retaining pathname rejection. Both suffix tests failed on `4943b6a` and pass after the fix. Six directory/empty-segment regression cases failed on `5b97315` and now pass; interior dot segments, dotfiles, root confinement, and existing HTML behavior remain covered. - Added eight TypeScript wrapper scenarios and three wrapped shadow/dynamic negative scenarios. The `as URL` case reproduced a missing relationship on `6301950`; all pass through the production source pipeline after the fix. - Added 21 constructor-identity cases (7 resolved, 14 unknown), including browser namespaces, both Node built-in module spellings, local classes/parameters, custom imports, type-only imports, reassignment, mutable namespaces, and calls without `new`. The local-class case fails against `c534ada` by creating a false file edge and passes after the fix. - Independently executed all 59 new fixture expectations through real file inventory, production source analysis, and graph construction. All passed, including the competing bundled-module assertion. - Remaining proof gap: compiled CLI and native-worker boundary tests are blocked locally before worker startup by the installed macOS Command Line Tools `SwiftBridging` duplicate module definition. No process ownership checks were bypassed. - [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 Pinned Node 24.18.0 / npm 11.16.0: - `npm run check` — passed: typecheck, lint (warnings, no errors), formatting, knip, metadata, module boundaries, and architecture guards. - Relevant source suites for URL path resolution, static references/source maps/module indexing, Electron identity/options, semantic import structure/require links/builtin defaults, and mutation initializer state — 241 tests passed across 10 files. - `npm run verify:test-discovery` — all 916 test files discovered exactly once. - `git diff --cached --check` — passed before commit. - `npm run test:focused -- tests/acceptance/applications/javascriptWorkerUrlCli.test.ts` — local execution blocked by the Swift toolchain startup failure. Both existing Worker CLI journeys, including TypeScript wrapper, suffix, and directory-form/empty-segment cases, passed in Linux CI on `c534ada`. The new constructor-identity journey awaits CI on the latest head. - Related focused source-map/file-URL boundary suites — 15 native-worker cases blocked by the same environment failure; 123 other tests passed in that run. The previous [PR CI run](https://github.com/morluto/rea/actions/runs/38229449003) failed in MCP prompt completion and Darwin package prompt smoke tests. The same failures occur in [main's CI](https://github.com/morluto/rea/actions/runs/38224038323) at `c22111e`, following the independent prompt-completion lifecycle change in `07b36c1`. Worker acceptance passed; no unrelated MCP change is included here. ## Compatibility, safety, and release - Breaking changes or migrations: none. False URL extension/directory/module matches are intentionally removed. - Real browser/OS coverage: target JavaScript is parsed, not executed. No browser runtime verification claimed. - Package/release metadata and security/privacy/process/containment impact: none. ## Review checklist - [x] Concrete problem and one focused outcome; Conventional Commit title. - [x] Reason for no related issue stated above. - [x] Regression coverage includes meaningful failure paths and observable graph output. - [x] No authored schema/documentation/generated metadata change required. - [x] Final diff checked 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 00:59:27 +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#5033
No description provided.