Skip to content

Windows: canonicalize UNC and extended-length paths in semantic cache lookup #629

Closed

Description

@sdinaro

Summary

On Windows, check_semantic_cache() should canonicalize equivalent drive/UNC/extended-length paths before cache lookup. Right now it passes each incoming string straight to Path(fpath), so semantically equivalent paths can hash to different cache keys if one caller supplies a normal drive path and another supplies a UNC or extended-length form.

Current behavior

check_semantic_cache() does no normalization itself:

# cache.py:163-170
for fpath in files:
    result = load_cached(Path(fpath), root, kind="semantic")
    if result is not None:
        ...
    else:
        uncached.append(fpath)

The cache key is eventually built by file_hash():

# cache.py:39-42
try:
    rel = p.resolve().relative_to(Path(root).resolve())
    h.update(rel.as_posix().encode())
except ValueError:
    h.update(str(p.resolve()).encode())

If the same physical file arrives as different Windows spellings, the fallback absolute-path branch can produce distinct strings and therefore distinct hashes. Examples of forms that can refer to the same file:

C:\repo\docs\a.md
\\?\C:\repo\docs\a.md
\\localhost\C$\repo\docs\a.md

The practical symptom is a false semantic-cache miss: the semantic cache entry exists, but check_semantic_cache() reports the file as uncached and queues it for extraction again.

Why this matters

The cache is intended to be stable across graphify entry points. On Windows, tools commonly disagree about whether they hand back drive-letter paths, extended-length paths, UNC paths, or slash-normalized variants. A cache key that depends on the spelling rather than the canonical file identity causes avoidable re-extraction and can make --update look nondeterministic.

Suggested fix

Introduce a single path canonicalization helper used by file_hash(), check_semantic_cache(), and save_semantic_cache() before hashing or grouping by source_file.

Possible behavior on Windows:

  • strip the \\?\ extended-length prefix for local drive paths before hashing;
  • normalize slashes;
  • apply os.path.normcase();
  • resolve relative to the same normalized root;
  • keep POSIX behavior unchanged except for existing .resolve() semantics.

Add a regression test that writes one semantic cache entry, then checks it using an equivalent alternate Windows path form and expects a cache hit.

Environment

  • Package: graphifyy 0.5.4
  • Platform: Windows + Python 3.13

Activity

  1. added a commit that references this issue on May 1, 2026
  2. safishamsi commented on May 1, 2026

    @safishamsi
    Member

    Fixed in e73b606: added _normalize_path() in cache.py that strips the \\?\\ extended-length prefix and applies os.path.normcase() on Windows before hashing. POSIX behavior is unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions