fix(server): canonicalise media paths the same way their callers do#9575

merged1
windows-tests/antigravity-host
windows-tests/media-realpath
openedSep 4, 2026byJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 3d ago

openMediaFile rejected a file whenever fs/promises.realpath disagreed with the path it was handed. Callers canonicalise through Effect's FileSystem.realPath, which is Node's JS realpath; the promises variant is the native binding, and on Windows it also expands 8.3 short names, so every media file under a short-named temp or profile directory was refused as a symlink swap. Use the same realpath as the callers, so the check still catches a planted link but agrees with a path that is already canonical.

The favicon and asset tests now build their relative-path expectations with Path.join rather than a literal '/'.

Part of the Windows test-suite stack rooted at #9564; the manual Windows lane comes from #9538.

Model: Claude Fable 5 in Claude Code.

πŸ€– Generated with Claude Code


Note

Medium Risk Touches security-sensitive media open acceptance logic; behavior can differ only where the two Node realpath APIs disagree (notably Windows short paths).

Overview openMediaFile no longer uses fs/promises.realpath for its β€œpath must already be canonical” guard. It now calls callback fs.realpath via realpathLikeFileSystem, matching how upstream code canonicalises with Effect FileSystem.realPath. That fixes false rejections on Windows when the promises API expands 8.3 short names while the caller’s path is already canonical; symlink-swap protection is unchanged in intent.

AssetAccess and ProjectFaviconResolver tests now assert sourcePath / resolved favicon paths with Path.join instead of hard-coded / segments, so expectations match platform-native separators.

Reviewed by Cursor Bugbot for commit 2c64068e10a194c8d8732a046147b9f240a4104a. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Use callback-based Node realpath in openMediaFile descriptor checks

  • Adds realpathLikeFileSystem, a Promise wrapper around the callback-based Node fs.realpath, and replaces the fs/promises.realpath call in openMediaFile's acceptance checks with it.
  • This aligns the canonicalization with how callers produce paths, fixing mismatches where the two Node realpath APIs return different representations (e.g. Windows 8.3 short names).
  • Updates AssetAccess and ProjectFaviconResolver tests to assert exact platform-native joined paths instead of slash-separated substring checks.
  • Behavioral Change: openMediaFile may now accept or reject files differently for paths whose fs/promises.realpath and callback-based fs.realpath disagree; reviewers should check the descriptor acceptance logic in MediaFile.ts.

Macroscope summarized 2c64068.

Synced from GitHub

Thread transfer impact

βœ… Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wireβ€”13.6 KiBβ€”15.1 KiBβœ…
CodexThread snapshot wireβ€”7.0 KiBβ€”7.3 KiBβœ…
CodexLive turn WebSocket wireβ€”6.5 KiBβ€”7.8 KiBβœ…
CodexLive turn WebSocket decodedβ€”57.0 KiBβ€”66.4 KiBβœ…
CodexLive turn messagesβ€”9β€”21βœ…
ClaudeTotal thread wireβ€”13.6 KiBβ€”15.1 KiBβœ…
ClaudeThread snapshot wireβ€”7.0 KiBβ€”7.3 KiBβœ…
ClaudeLive turn WebSocket wireβ€”6.5 KiBβ€”7.8 KiBβœ…
ClaudeLive turn WebSocket decodedβ€”57.8 KiBβ€”66.4 KiBβœ…
ClaudeLive turn messagesβ€”9β€”21βœ…

Baseline: unavailable Β· PR result: 2c64068 Β· Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Approvability

Verdict: Approved at 529f71e

Macroscope's review found this PR approvable β€” This is a small, self-contained server bug fix that aligns media-path validation with the canonicalization already used by callers, primarily correcting Windows path handling. Existing file identity and replacement protections remain in place, and the other changes are platform-portable test assertions.

No code changes detected at 2c64068. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

Added 1 commit

  • fix(server): canonicalise media paths the same way their callers do2c64068