[GH-ISSUE #7299] [Bug] Source-location results misattribute resolved URLs to the upstream codec #4336

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

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

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 public trace-web-source-location CLI succeeds and returns correct, distinct URLs for dir/original.ts and dir//original.ts, but both result limitation arrays say Resolved URLs are derived by the pinned upstream codec. REA derives those URLs with its own WHATWG URL resolver; the locked upstream library returns a different repeated-separator URL for the same map and context. The defect is the explanatory attribution, not the returned URL values.

Reproduction

From the built source checkout with its locked dependencies and Node toolchain, run the following. It creates only synthetic files in a temporary directory and uses isolated HOME/XDG/TMPDIR settings. No capture file, browser, source fetch or target execution is required. The first source is a single-separator control.

node --input-type=module <<'JS'
import {mkdirSync,mkdtempSync,writeFileSync} from 'node:fs';
import {tmpdir} from 'node:os';
import {join,resolve} from 'node:path';
import {createHash} from 'node:crypto';
import {spawnSync} from 'node:child_process';
import {createRequire} from 'node:module';
import {pathToFileURL} from 'node:url';
const packageRoot=resolve(process.env.REA_PACKAGE_ROOT || '.');
const root=mkdtempSync(join(process.env.PROBE_PARENT || tmpdir(),'rea-provenance-'));
mkdirSync(join(root,'files/modules'),{recursive:true});
const source='generated';
const manifest={capture_path:join(root,'capture.json'),capture_sha256:'a'.repeat(64),capture_kind:'browser-scenario',source_evidence_id:null,capture_completeness:{status:'complete',equality_eligible:true,missing_sections:[],truncated_sections:[]},output_directory:root,analysis_input:{input_path:root,format:'directory'},limitations:[],scripts:[{url:'https://example.test/main.js',source:{kind:'scenario-response',transaction_id:'txn',request_sequence:1,response_sequence:2,status:200},content:{state:'exported',relative_path:'modules/main.js',layout:'isolated',layout_reason:'fixture',sha256:createHash('sha256').update(source).digest('hex'),bytes:Buffer.byteLength(source),media_type:'text/javascript',redacted:false,representation:'browser-decoded-response-bytes'}}]};
const map={version:3,sources:['dir/original.ts','dir//original.ts'],sourcesContent:['first','second'],names:[],mappings:'AAAA,ACAA'};
const text=JSON.stringify(map);
const url='https://example.test/maps/app.js.map';
writeFileSync(join(root,'files/modules/main.js'),source,{flag:'wx'});
writeFileSync(join(root,'manifest.json'),JSON.stringify(manifest),{flag:'wx'});
writeFileSync(join(root,'app.js.map'),text,{flag:'wx'});
const env={PATH:process.env.PATH,HOME:join(root,'state/home'),XDG_CONFIG_HOME:join(root,'state/config'),XDG_CACHE_HOME:join(root,'state/cache'),XDG_DATA_HOME:join(root,'state/data'),TMPDIR:join(root,'state/tmp')};
for(const [k,v] of Object.entries(env))if(k!=='PATH')mkdirSync(v,{recursive:true});
const args=[join(packageRoot,'scripts/rea.mjs'),'trace-web-source-location',join(root,'manifest.json'),'0',join(root,'app.js.map'),url,'1','0','--json'];
const r=spawnSync(process.execPath,args,{env,encoding:'utf8',timeout:40000,maxBuffer:4*1024*1024});
writeFileSync(join(root,'cli.stdout.json'),r.stdout||'');
writeFileSync(join(root,'cli.stderr.txt'),r.stderr||'');
console.log(JSON.stringify({kind:'cli',exit:r.status,error:r.error?.message,stderr:r.stderr}));
let cli;try{cli=JSON.parse(r.stdout)}catch{}
if(r.status===0)console.log(JSON.stringify({kind:'cli-result',matches:cli.normalized_result.matches.map(({source_index,resolved_url})=>({source_index,resolved_url})),limitation:cli.limitations.find(x=>x.includes('Resolved URLs')),normalized_limitation:cli.normalized_result.limitations.find(x=>x.includes('Resolved URLs'))}));
else console.log(JSON.stringify({kind:'cli-error',result:cli}));
const {traceSourceMap}=await import(pathToFileURL(join(packageRoot,'dist/javascript/sourceMaps/TraceSourceMap.js')));
const require=createRequire(join(packageRoot,'package.json'));
const {TraceMap}=require('@jridgewell/trace-mapping');
const report=traceSourceMap(text,url,{line:1,column:0});
const upstream=new TraceMap(map,url).resolvedSources;
console.log(JSON.stringify({kind:'module-comparison',engine:report.engine,matches:report.matches.map(({source_index,reported_source,resolved_url})=>({source_index,reported_source,resolved_url})),upstream}));
JS

Two public CLI executions, including a replay of this inline script, exited 0 with empty stderr and the same attribution discrepancy. The direct production-module/upstream comparison also completed in each execution. The script leaves its synthetic files and raw local result available in its temporary directory.

Expected behavior

The explanation should accurately attribute the derived original-source URL facts to their producing implementation. Keep the correct URL identities, raw source declarations, source indices and embedded content. Using the upstream decoder for mappings does not make REA's separate URL derivation upstream-produced.

Impact and scope

P3 wording defect in successful source-location Evidence. The fixed sentence is present in both top-level and normalized-result limitations. The demonstrated URLs, point lookup and embedded contents are correct; no downstream behavioral failure was observed. Consumers can use the returned URLs and retained declarations, and the source-location guide accurately describes the URL parsing rule. MCP shares the service by source inspection but was not executed.

REA version

Source revision 0d1a454e25 with its existing compiled runtime and locked dependencies.

Runtime and platform

Node.js v24.22.1; macOS arm64; locked @jridgewell/trace-mapping 0.3.31.

Target and artifact context

Synthetic export_web_scripts-shaped manifest, retained script containing generated, and the inline regular v3 map. Historical capture metadata is synthetic; only selected manifest/script/map bytes are independently verified.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

  • Expected source: AGENTS.md, Product and Authority, requires preserving Evidence provenance and distinguishing derivations; Architecture and Cleanup requires a clear interpretation owner. docs/web-source-location.md:32-38 documents ECMA-426 URL parsing and significant repeated separators; its Adapter and resource boundaries section distinguishes the upstream library from REA's adapter.
  • Failure source: src/application/WebSourceLocationService.ts:50-56,183-224 publishes the attribution in both arrays; src/javascript/sourceMaps/TraceSourceMap.ts:184-188 populates resolved_url with REA's helper; src/domain/javascript/javascriptSourceMapPaths.ts:48-57 performs URL.parse rather than invoking upstream resolution.
  • Evidence provenance: observed public CLI output and direct locked-library/production-module comparison; source and local history identify the producing implementations separately.
  • Local verification: reproduced; both public CLI executions succeeded without ownership substitutions or cleanup bypasses.
  • Reproduction completeness: complete.

Relevant result fragments and comparison:

CLI exit: 0; stderr: empty
REA source 0: https://example.test/maps/dir/original.ts
REA source 1: https://example.test/maps/dir//original.ts
Upstream source 0: https://example.test/maps/dir/original.ts
Upstream source 1: https://example.test/maps/dir/original.ts
Both limitation arrays: Source names and sourceRoot are reported declarations. Resolved URLs are derived by the pinned upstream codec; no original source is fetched or executed.

History shows that the trace switched from upstream resolvedSources to the shared WHATWG resolver while the limitation sentence remained unchanged. The owned REA worker does produce the report, but calling this specific URL derivation upstream-produced is inaccurate.

Typed outcome or recovery expected

Restoration check: rerun the fixture and retain both distinct REA URLs, separate source indices and embedded texts, while both limitation arrays accurately describe URL derivation. The single-separator control must continue to agree with the upstream comparison. No resolver or source-path identity change is required by this wording defect.

Additional context

The closed repeated-slash URL report concerns incorrect URL values; those values are now correct in this reproduction. The closed pathless-context report explicitly records adoption of the shared WHATWG resolver in its closure comment. Neither report's restoration signal covers this remaining explanatory attribution. Open/closed local-index and live searches covered resolved URLs, upstream codec, provenance and wording; no exact duplicate was found. No implementation change or restoration run was performed.

Triage assessment

  • Impact level: P3
  • Assessment status: supported
  • Impact basis: Successful CLI output inaccurately attributes one derived field to upstream code, while the demonstrated URLs and mapping results remain correct; no consequential behavior change was observed.
  • Workaround status: available
  • Workaround basis: The successful output retains correct resolved URLs and raw declarations, and the documented WHATWG URL rule agrees with the executed comparison; consumers can interpret these facts without relying on the inaccurate ownership sentence.
Originally created by @coygeek on GitHub (Oct 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7299 ## 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 public `trace-web-source-location` CLI succeeds and returns correct, distinct URLs for `dir/original.ts` and `dir//original.ts`, but both result limitation arrays say `Resolved URLs are derived by the pinned upstream codec`. REA derives those URLs with its own WHATWG URL resolver; the locked upstream library returns a different repeated-separator URL for the same map and context. The defect is the explanatory attribution, not the returned URL values. ## Reproduction From the built source checkout with its locked dependencies and Node toolchain, run the following. It creates only synthetic files in a temporary directory and uses isolated HOME/XDG/TMPDIR settings. No capture file, browser, source fetch or target execution is required. The first source is a single-separator control. ```sh node --input-type=module <<'JS' import {mkdirSync,mkdtempSync,writeFileSync} from 'node:fs'; import {tmpdir} from 'node:os'; import {join,resolve} from 'node:path'; import {createHash} from 'node:crypto'; import {spawnSync} from 'node:child_process'; import {createRequire} from 'node:module'; import {pathToFileURL} from 'node:url'; const packageRoot=resolve(process.env.REA_PACKAGE_ROOT || '.'); const root=mkdtempSync(join(process.env.PROBE_PARENT || tmpdir(),'rea-provenance-')); mkdirSync(join(root,'files/modules'),{recursive:true}); const source='generated'; const manifest={capture_path:join(root,'capture.json'),capture_sha256:'a'.repeat(64),capture_kind:'browser-scenario',source_evidence_id:null,capture_completeness:{status:'complete',equality_eligible:true,missing_sections:[],truncated_sections:[]},output_directory:root,analysis_input:{input_path:root,format:'directory'},limitations:[],scripts:[{url:'https://example.test/main.js',source:{kind:'scenario-response',transaction_id:'txn',request_sequence:1,response_sequence:2,status:200},content:{state:'exported',relative_path:'modules/main.js',layout:'isolated',layout_reason:'fixture',sha256:createHash('sha256').update(source).digest('hex'),bytes:Buffer.byteLength(source),media_type:'text/javascript',redacted:false,representation:'browser-decoded-response-bytes'}}]}; const map={version:3,sources:['dir/original.ts','dir//original.ts'],sourcesContent:['first','second'],names:[],mappings:'AAAA,ACAA'}; const text=JSON.stringify(map); const url='https://example.test/maps/app.js.map'; writeFileSync(join(root,'files/modules/main.js'),source,{flag:'wx'}); writeFileSync(join(root,'manifest.json'),JSON.stringify(manifest),{flag:'wx'}); writeFileSync(join(root,'app.js.map'),text,{flag:'wx'}); const env={PATH:process.env.PATH,HOME:join(root,'state/home'),XDG_CONFIG_HOME:join(root,'state/config'),XDG_CACHE_HOME:join(root,'state/cache'),XDG_DATA_HOME:join(root,'state/data'),TMPDIR:join(root,'state/tmp')}; for(const [k,v] of Object.entries(env))if(k!=='PATH')mkdirSync(v,{recursive:true}); const args=[join(packageRoot,'scripts/rea.mjs'),'trace-web-source-location',join(root,'manifest.json'),'0',join(root,'app.js.map'),url,'1','0','--json']; const r=spawnSync(process.execPath,args,{env,encoding:'utf8',timeout:40000,maxBuffer:4*1024*1024}); writeFileSync(join(root,'cli.stdout.json'),r.stdout||''); writeFileSync(join(root,'cli.stderr.txt'),r.stderr||''); console.log(JSON.stringify({kind:'cli',exit:r.status,error:r.error?.message,stderr:r.stderr})); let cli;try{cli=JSON.parse(r.stdout)}catch{} if(r.status===0)console.log(JSON.stringify({kind:'cli-result',matches:cli.normalized_result.matches.map(({source_index,resolved_url})=>({source_index,resolved_url})),limitation:cli.limitations.find(x=>x.includes('Resolved URLs')),normalized_limitation:cli.normalized_result.limitations.find(x=>x.includes('Resolved URLs'))})); else console.log(JSON.stringify({kind:'cli-error',result:cli})); const {traceSourceMap}=await import(pathToFileURL(join(packageRoot,'dist/javascript/sourceMaps/TraceSourceMap.js'))); const require=createRequire(join(packageRoot,'package.json')); const {TraceMap}=require('@jridgewell/trace-mapping'); const report=traceSourceMap(text,url,{line:1,column:0}); const upstream=new TraceMap(map,url).resolvedSources; console.log(JSON.stringify({kind:'module-comparison',engine:report.engine,matches:report.matches.map(({source_index,reported_source,resolved_url})=>({source_index,reported_source,resolved_url})),upstream})); JS ``` Two public CLI executions, including a replay of this inline script, exited 0 with empty stderr and the same attribution discrepancy. The direct production-module/upstream comparison also completed in each execution. The script leaves its synthetic files and raw local result available in its temporary directory. ## Expected behavior The explanation should accurately attribute the derived original-source URL facts to their producing implementation. Keep the correct URL identities, raw source declarations, source indices and embedded content. Using the upstream decoder for mappings does not make REA's separate URL derivation upstream-produced. ## Impact and scope P3 wording defect in successful source-location Evidence. The fixed sentence is present in both top-level and normalized-result limitations. The demonstrated URLs, point lookup and embedded contents are correct; no downstream behavioral failure was observed. Consumers can use the returned URLs and retained declarations, and the source-location guide accurately describes the URL parsing rule. MCP shares the service by source inspection but was not executed. ## REA version Source revision 0d1a454e25db825567782e461da21530bad4b158 with its existing compiled runtime and locked dependencies. ## Runtime and platform Node.js v24.22.1; macOS arm64; locked @jridgewell/trace-mapping 0.3.31. ## Target and artifact context Synthetic export_web_scripts-shaped manifest, retained script containing `generated`, and the inline regular v3 map. Historical capture metadata is synthetic; only selected manifest/script/map bytes are independently verified. ## Interface CLI ## Earliest failure stage Transport or result projection ## Relevant output or evidence - Expected source: `AGENTS.md`, Product and Authority, requires preserving Evidence provenance and distinguishing derivations; Architecture and Cleanup requires a clear interpretation owner. `docs/web-source-location.md:32-38` documents ECMA-426 URL parsing and significant repeated separators; its Adapter and resource boundaries section distinguishes the upstream library from REA's adapter. - Failure source: `src/application/WebSourceLocationService.ts:50-56,183-224` publishes the attribution in both arrays; `src/javascript/sourceMaps/TraceSourceMap.ts:184-188` populates resolved_url with REA's helper; `src/domain/javascript/javascriptSourceMapPaths.ts:48-57` performs URL.parse rather than invoking upstream resolution. - Evidence provenance: observed public CLI output and direct locked-library/production-module comparison; source and local history identify the producing implementations separately. - Local verification: reproduced; both public CLI executions succeeded without ownership substitutions or cleanup bypasses. - Reproduction completeness: complete. Relevant result fragments and comparison: ```text CLI exit: 0; stderr: empty REA source 0: https://example.test/maps/dir/original.ts REA source 1: https://example.test/maps/dir//original.ts Upstream source 0: https://example.test/maps/dir/original.ts Upstream source 1: https://example.test/maps/dir/original.ts Both limitation arrays: Source names and sourceRoot are reported declarations. Resolved URLs are derived by the pinned upstream codec; no original source is fetched or executed. ``` History shows that the trace switched from upstream resolvedSources to the shared WHATWG resolver while the limitation sentence remained unchanged. The owned REA worker does produce the report, but calling this specific URL derivation upstream-produced is inaccurate. ## Typed outcome or recovery expected Restoration check: rerun the fixture and retain both distinct REA URLs, separate source indices and embedded texts, while both limitation arrays accurately describe URL derivation. The single-separator control must continue to agree with the upstream comparison. No resolver or source-path identity change is required by this wording defect. ## Additional context The closed [repeated-slash URL report](https://github.com/morluto/rea/issues/6726) concerns incorrect URL values; those values are now correct in this reproduction. The closed [pathless-context report](https://github.com/morluto/rea/issues/6435) explicitly records adoption of the shared WHATWG resolver in its closure comment. Neither report's restoration signal covers this remaining explanatory attribution. Open/closed local-index and live searches covered resolved URLs, upstream codec, provenance and wording; no exact duplicate was found. No implementation change or restoration run was performed. ## Triage assessment - Impact level: P3 - Assessment status: supported - Impact basis: Successful CLI output inaccurately attributes one derived field to upstream code, while the demonstrated URLs and mapping results remain correct; no consequential behavior change was observed. - Workaround status: available - Workaround basis: The successful output retains correct resolved URLs and raw declarations, and the documented WHATWG URL rule agrees with the executed comparison; consumers can interpret these facts without relying on the inaccurate ownership sentence.
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#4336
No description provided.