[PR #2074] [MERGED] fix(browser): isolate script URLs with empty query or fragment #5008

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

📋 Pull Request Information

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

Base: main ← Head: fix/empty-url-delimiters


📝 Commits (1)

  • 9224115 fix(browser): isolate script URLs with empty query or fragment

📊 Changes

3 files changed (+46 additions, -2 deletions)

View changed files

📝 src/domain/webScriptExportPlan.test.ts (+3 -0)
📝 src/domain/webScriptExportPlan.ts (+3 -2)
📝 tests/boundary/filesystem/webScriptExport.test.ts (+40 -0)

📄 Description

Summary

Keep script URLs ending in an empty ? or # in isolated export layouts. URL.search and URL.hash return "" for both absent and explicitly empty components, so these variants currently receive a canonical url-path layout even though the exporter explicitly excludes query/fragment identities from that layout.

Problem and expected behavior

A capture containing only https://fixture.test/query.js? currently exports it under origins/<origin-hash>/query.js. This can make the captured variant appear to be the canonical local target for ./query.js. Empty components remain part of serialized URL identity and should follow the same isolation policy as nonempty query/fragment variants. Found in the export planner; no separate issue exists.

Change and scope

Detect component delimiters in the parsed URL's serialized href, which preserves empty components. Keep the original reported URL, source bytes, origin handling, and collision policy. Add empty ?, #, and ?# cases to the existing planner matrix and verify persisted export output through the real filesystem publication service.

Contract and boundary impact

  • Semantic owner and earliest changed stage: candidatePath in webScriptExportPlan.
  • CLI and MCP/tool-catalog contract: exported variants now report layout: isolated; schemas unchanged.
  • Provider, bridge, target-format, or platform compatibility: no capture/browser provider changes.
  • Evidence, artifact, provenance, or reconstruction contract: exact URL and bytes are retained; empty URL components no longer establish a canonical local module layout.
  • Process execution, authorization, cleanup, or containment impact: none.
  • Generated metadata, package, or installation impact: none.

Evidence and regression coverage

The filesystem regression reads a saved capture, publishes scripts, reads back bytes and manifest, and verifies an ordinary URL remains url-path while separate empty-query and empty-fragment URLs are isolated. The regression fails against the original owner (url-path received instead of isolated). Existing source/capture/provenance tests continue to pass.

  • 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

Node 24.18.0 / npm 11.16.0, macOS arm64:

  • npm run test:focused -- src/domain/webScriptExportPlan.test.ts tests/boundary/filesystem/webScriptExport.test.ts — 45 passed.
  • npm run check — passed.
  • npm run docs:check — passed after integrating upstream's translation-link correction.
  • git diff --check — passed.

Compatibility, safety, and release

No schema, package, migration, or authority changes. Export paths for the affected URL variants intentionally change to the existing isolated layout. No live browser, separate CLI/MCP transport, or full suite run; this change consumes already-retained captures and is verified at the filesystem export boundary.

Review checklist

  • Concrete bug and one focused conventional title; no separate issue as explained above.
  • Changed output, preserved source bytes, ordinary controls, and manifest persistence covered.
  • Relevant checks run; generated outputs remain ignored.
  • Final diff inspected for secrets, unrelated changes, and unsupported claims.

AI-assisted with Codex.


🔄 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/2074 **Author:** [@1052326311](https://github.com/1052326311) **Created:** 10/12/2026 **Status:** ✅ Merged **Merged:** 10/12/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/empty-url-delimiters` --- ### 📝 Commits (1) - [`9224115`](https://github.com/morluto/rea/commit/922411564f8ecc7ae44bb23ade83713a8f3444ba) fix(browser): isolate script URLs with empty query or fragment ### 📊 Changes **3 files changed** (+46 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/webScriptExportPlan.test.ts` (+3 -0) 📝 `src/domain/webScriptExportPlan.ts` (+3 -2) 📝 `tests/boundary/filesystem/webScriptExport.test.ts` (+40 -0) </details> ### 📄 Description ## Summary Keep script URLs ending in an empty `?` or `#` in isolated export layouts. `URL.search` and `URL.hash` return `""` for both absent and explicitly empty components, so these variants currently receive a canonical `url-path` layout even though the exporter explicitly excludes query/fragment identities from that layout. ## Problem and expected behavior A capture containing only `https://fixture.test/query.js?` currently exports it under `origins/<origin-hash>/query.js`. This can make the captured variant appear to be the canonical local target for `./query.js`. Empty components remain part of serialized URL identity and should follow the same isolation policy as nonempty query/fragment variants. Found in the export planner; no separate issue exists. ## Change and scope Detect component delimiters in the parsed URL's serialized `href`, which preserves empty components. Keep the original reported URL, source bytes, origin handling, and collision policy. Add empty `?`, `#`, and `?#` cases to the existing planner matrix and verify persisted export output through the real filesystem publication service. ## Contract and boundary impact - Semantic owner and earliest changed stage: `candidatePath` in `webScriptExportPlan`. - CLI and MCP/tool-catalog contract: exported variants now report `layout: isolated`; schemas unchanged. - Provider, bridge, target-format, or platform compatibility: no capture/browser provider changes. - Evidence, artifact, provenance, or reconstruction contract: exact URL and bytes are retained; empty URL components no longer establish a canonical local module layout. - Process execution, authorization, cleanup, or containment impact: none. - Generated metadata, package, or installation impact: none. ## Evidence and regression coverage The filesystem regression reads a saved capture, publishes scripts, reads back bytes and manifest, and verifies an ordinary URL remains `url-path` while separate empty-query and empty-fragment URLs are `isolated`. The regression fails against the original owner (`url-path` received instead of `isolated`). Existing source/capture/provenance tests continue to pass. - [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 Node 24.18.0 / npm 11.16.0, macOS arm64: - `npm run test:focused -- src/domain/webScriptExportPlan.test.ts tests/boundary/filesystem/webScriptExport.test.ts` — 45 passed. - `npm run check` — passed. - `npm run docs:check` — passed after integrating upstream's translation-link correction. - `git diff --check` — passed. ## Compatibility, safety, and release No schema, package, migration, or authority changes. Export paths for the affected URL variants intentionally change to the existing isolated layout. No live browser, separate CLI/MCP transport, or full suite run; this change consumes already-retained captures and is verified at the filesystem export boundary. ## Review checklist - [x] Concrete bug and one focused conventional title; no separate issue as explained above. - [x] Changed output, preserved source bytes, ordinary controls, and manifest persistence covered. - [x] Relevant checks run; generated outputs remain ignored. - [x] Final diff inspected for secrets, unrelated changes, and unsupported claims. AI-assisted with Codex. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:57:57 +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#5008
No description provided.