Skip to content

fix(watcher): Linux swallows Create events (debounce replaces instead of merges) - #5

Closed
NestorCanales wants to merge 1 commit into
mainfrom
fix/watcher-create-swallowed-linux
Closed

fix(watcher): Linux swallows Create events (debounce replaces instead of merges)#5
NestorCanales wants to merge 1 commit into
mainfrom
fix/watcher-create-swallowed-linux

Conversation

@NestorCanales

Copy link
Copy Markdown
Collaborator

Bug

On Linux, creating a file emits CREATE then WRITE as two rapid inotify events. The watcher's per-path debouncer replaced the pending event, so the CREATE was swallowed and new files were reported as modifications — TestOnCreate fails 3/3 on Linux, passes on macOS (whose event coalescing masked this since day one).

Found during the local-embeddings epic's Phase 5 Linux work — first time the suite ever ran on Linux. Full report: Documentation/Bugs/fswatcher-create-event-swallowed-linux.md (lands in #4). Independent of the epic — based on main, mergeable anytime.

Impact

None user-visible today (engine.OnCreate/OnModify both index the file), but any future create/modify divergence would silently break Linux.

Fix

The debouncer accumulates fsnotify ops per path (OR) and classifies the merged set when the timer fires: Remove/Rename > Create > Write/Chmod. Single-event behavior identical to before.

Verification

  • Linux arm64 (Docker golang:1.26-bookworm): watcher suite 3/3 pass (was 3/3 fail)
  • macOS: watcher suite 3/3 pass + full go test ./... green

🤖 Generated with Claude Code

…wallowed

On Linux, writing a new file emits CREATE then WRITE as separate inotify
events within milliseconds. The per-path debouncer replaced the pending
callback on each event, so the WRITE cancelled the CREATE and the handler
reported a modification — OnCreate never fired for any newly created file
(TestOnCreate failed deterministically on Linux; macOS's event coalescing
masked the bug). No user impact today because engine.OnCreate and OnModify
both index the file, but any future divergence would break Linux silently.

The debouncer now accumulates fsnotify ops per path (OR) and classifies
the merged set when the timer fires, with precedence
Remove/Rename > Create > Write/Chmod. Single-event behavior is unchanged.

Verified: watcher suite passes 3/3 on macOS and 3/3 on Linux arm64
(golang:1.26-bookworm container); previously 3/3 FAIL on Linux.
Found during local-embeddings Phase 5 (first test run on Linux); report in
Documentation/Bugs/fswatcher-create-event-swallowed-linux.md (PR #4).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
NestorCanales added a commit that referenced this pull request Jul 17, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NestorCanales

Copy link
Copy Markdown
Collaborator Author

Windows verification added (2026-07-17, native Windows x64 on the dev PC):

  • Without this fix (feat/xplat-windows, which doesn't include it): TestOnCreate fails deterministically — Windows delivers the same CREATE+WRITE double-event as Linux inotify, so the replace-not-merge debouncer swallows the Create there too.
  • With this fix (this branch): watcher suite passes 3/3 runs.

So the fix is now verified on all three OS families: macOS 3/3, Linux arm64 3/3, Windows x64 3/3 (each failing without it on Linux + Windows). Also: the full untagged go test ./... ran on Windows for the first time — every other package is green there.

🤖 Generated with Claude Code

@NestorCanales

Copy link
Copy Markdown
Collaborator Author

Consolidated into #2 (single reviewable branch per Bo's review-workflow preference) — all commits from this PR are now in feat/local-embeddings.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant