fix(windows): preserve deep local and UNC files across the corpus pipeline - #2317
Open
nimide wants to merge 1 commit into
Open
fix(windows): preserve deep local and UNC files across the corpus pipeline#2317nimide wants to merge 1 commit into
nimide wants to merge 1 commit into
Conversation
nimide
marked this pull request as ready for review
July 29, 2026 21:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Graphify 0.9.30 enters recursive corpus enumeration with ordinary Windows drive or UNC paths. A real descendant that crosses the legacy
MAX_PATHboundary can therefore fail before Graphify discovers it, producing a misleading[WinError 3] The system cannot find the path specifiedwarning and an incomplete graph.This change introduces a centralized, cross-platform filesystem I/O boundary in
graphify.pathsand applies it throughout the source-corpus pipeline. Windows filesystem calls use extended-length path spelling internally; Linux and macOS remain pass-through. Graph IDs, manifests, cache keys, ignore matching, diagnostics, and user-visible output continue to use ordinary logical paths.Representative UNC translation:
Problem and root cause
Selected late-stage reads already used a private Windows path helper, but recursive discovery began with an ordinary path:
On Windows,
os.walk()usesos.scandir()for recursive enumeration. When the ordinary path reaches the legacy boundary, enumeration can fail even though the directory exists. A directory just below 260 characters can also fail because native enumeration adds a search suffix.Changing only the first
os.walk()call would not close the defect. A deep file could be discovered and then fail during classification, hashing, cache access, structural extraction, semantic extraction, project resolution, incremental reconciliation, or document/media processing. This migration therefore covers the corpus from discovery through graph production.Design
Separate logical identity from filesystem transport
The implementation maintains two path representations:
Logical/public path
Filesystem I/O path
\\?\C:\...for local Windows paths.\\?\UNC\server\share\...for UNC paths.This prevents the same file from acquiring two Graphify identities and keeps generated artifacts portable.
Centralize the boundary
graphify.pathsnow owns the path translation and filesystem helpers used by the corpus pipeline, including:io_path()andlogical_path();The adapter normalizes and makes a Windows path absolute before adding the extended prefix. Already-extended paths and device paths remain unchanged. Off Windows, the helpers pass paths through unchanged.
Traversal reconstructs returned paths from the caller's logical root, so relative inputs remain relative even though Windows uses an absolute extended path internally.
Keep extended spelling away from external programs
The
\\?\spelling remains an internal filesystem transport detail. External tools receive ordinary absolute paths. Tests cover this rule for Google Workspace export and the C preprocessor.Preserve real errors
The change does not suppress traversal failures. Permission errors, disconnected shares, deletion races, broken links, and genuinely missing paths still flow to existing diagnostics. Only the transport-only prefix is removed before an error reaches user-facing code.
Implementation scope
The migration covers source-corpus filesystem boundaries used by:
collect_files()extraction;The extended prefix is removed immediately when traversal yields a path. It is not persisted in graph output, manifests, cache metadata, or diagnostics.
Graphify 0.9.30 baseline
This proposal is based directly on Graphify 0.9.30 commit:
The port preserves behavior introduced in 0.9.30, including TSX-specific parsing, portable AST cache anchors, fail-closed post-commit graph loading, and protected atomic graph replacement.
Tests and CI
tests/test_windows_long_paths.pyprovides host-neutral contract tests and native Windows integration coverage for:os.walk()receiving extended UNC spelling;walk_errors;\\?\never appears in returned or persisted logical artifacts.The focused GitHub Actions matrix runs the path suite on:
The Windows job creates and extracts a real 300-plus-character local path. UNC behavior is unit-tested at the conversion and traversal boundary because standard hosted runners do not provide a live SMB share.
Native Windows validation
Validation was performed against the 0.9.30 baseline above using Python 3.12 on Windows.
The focused suite validates:
\\?\prefixes;The one skip is the symlink-specific atomic-write test. The test host did not grant Windows symlink creation permission (
WinError 1314); it requires Developer Mode, administrator rights, orSeCreateSymbolicLinkPrivilege.Full-suite baseline comparison
An exploratory full Windows run before the final C-preprocessor follow-up produced:
The exact 42 failed node IDs were then rerun against untouched Graphify 0.9.30:
One shared C-preprocessor failure exposed an extended-path prefix crossing into an external executable. That issue was corrected and the test was added to the focused cross-platform gate.
After that correction, rerunning the cached failed set on the patched tree produced:
The remaining 40 failures reproduce on the untouched 0.9.30 baseline. They are existing Windows portability or test-environment issues, including unavailable symlink privileges, POSIX-only separator assertions, Windows current-directory deletion semantics, default text encoding, output filename limits, and installer/hook behavior outside this corpus-I/O change.
The one earlier non-baseline CodeBuddy directory-rename failure did not reproduce:
This PR therefore does not claim that the complete existing Windows suite is clean. It establishes a passing native gate for the source-corpus long-path pipeline and avoids broadening this change into unrelated Windows portability work.
Why not rely only on Windows policy?
Windows can opt applications into longer ordinary Win32 paths through
LongPathsEnabledand alongPathAwareexecutable manifest. That remains useful defense in depth, but it is not a sufficient Graphify contract:References:
Compatibility and risk
io_path()is a no-op and existing path behavior is retained.The broad call-site migration is intentional. Adapting only initial enumeration would allow a file to be discovered and then fail later during hashing or extraction, recreating the same incomplete-graph defect at another stage.
Scope and non-goals
This PR makes Graphify's source-corpus pipeline long-path-safe and closes a concrete Windows platform-parity gap. It does not claim that every external executable or third-party library accepts every possible path. It cannot prevent failures caused by permissions, share outages, authentication, invalid names, per-component filename limits, or network disconnections.
Unrelated installer, hook, exporter, and user-preference portability issues remain separate work. The watchdog subscription continues to receive the ordinary watch root so event paths retain Graphify's logical identity; a watch root that is itself already beyond the legacy boundary should receive separate native validation.
Reviewer guide
This submission is one commit created from the author-neutral 0.9.30 diff plus native-Windows test follow-ups.
Suggested review order:
graphify/paths.pyfor the logical-path versus filesystem-I/O-path contract.tests/test_windows_long_paths.py, the atomic-write/external-process tests, and the cross-platform CI matrix.Checklist