Skip to content

File reads flagged as edits on Windows (NTFS atime) #1451

Description

@radeilic

Env: codegraph 1.4.1 (win32-x64), same code at main (v1.5.0). Windows 11, NTFS with last-access updates enabled (fsutil behavior query disablelastaccess2, ENABLED; the Windows default since 10 1803).

Symptom

Nearly every codegraph_explore response flags the files it just rendered:

⚠️ Some files referenced below were edited since the last index sync ...
  - src/.../ServiceAccountPermissionAssignment.cs (edited 13ms ago, pending sync)

The files were never edited: LastWriteTime weeks old, git clean. Only their LastAccessTime changed, to the moment the daemon read them to serve the query.

Repro

With the daemon watching, read indexed files from any other process without modifying them:

for f in $(find src -name '*.cs' | head -40); do cat "$f" > /dev/null; sleep 0.3; done

Run any explore while the loop runs. The merely-read files appear as pending, with ages matching the read cadence:

(Note: 12 file(s) elsewhere in this project are pending index sync ...
  - src/.../AddCustomerSettingsTests.cs (edited 4706ms ago)
  - src/.../AssignResourceToCustomerTests.cs (edited 4274ms ago)
  - src/.../AssignServiceRegionToCustomerTests.cs (edited 3799ms ago)
  ...)

Root cause

handleChange (src/sync/watcher.ts#L573-L592) marks every watcher event as a pending edit, with no mtime/size/hash check. On Windows, libuv's ReadDirectoryChangesW filter includes FILE_NOTIFY_CHANGE_LAST_ACCESS, so with atime updates enabled a mere read emits a 'change' event identical to an edit. The daemon's own render-time reads then flag the files of the very response being built. (NTFS re-updates atime only when >1h stale, which is why each query flags a fresh batch. macOS FSEvents and Linux inotify don't report reads, so only Windows is affected.)

The debounced sync that follows is a harmless no-op (the size+mtime pre-filter rejects it); the damage is the chronic false "read these files directly" advice, which wastes agent calls and drowns out real pending edits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions