Description
SyncSignature uses (mtime, size) to detect external file changes. A file rewrite that produces the same size within the filesystem's mtime tick granularity (1 second on ext4/HFS+) generates an identical signature. The stat→read→re-stat pattern introduced in #103 does not close this window: if the write completed before the first stat, both stats return the same mtime and size.
Common triggers:
- A formatter that reorders imports or comments without changing file size
- A macro-expansion tool that produces same-length output
- Any atomic
rename(2) replacement within the same mtime tick
Reproduction Steps
- Open a Rust file via an MCP tool call (triggers
ensure_open)
- Replace the file with same-byte-count content within the same second
- Call
get_hover or another tool on the modified file
- Observe: mcpls sends the old content to the LSP server (stale
textDocument/didOpen)
Expected Behavior
mcpls should detect the content change and resync the document.
Actual Behavior
SyncSignature comparison returns equal; resync is skipped.
Affected Code
crates/mcpls-core/src/bridge/state.rs — SyncSignature and ensure_open
Fix Direction
Include a content hash (e.g. xxhash or blake3 of first N bytes) in SyncSignature as a tie-breaker when (mtime, size) is identical to the cached value.
Environment
- Filesystem: ext4 (1 s mtime resolution), HFS+ (1 s), APFS (1 ns — significantly less likely)
- Severity: low in practice, but silent data corruption for affected cases
Description
SyncSignatureuses(mtime, size)to detect external file changes. A file rewrite that produces the same size within the filesystem's mtime tick granularity (1 second on ext4/HFS+) generates an identical signature. The stat→read→re-stat pattern introduced in #103 does not close this window: if the write completed before the first stat, both stats return the same mtime and size.Common triggers:
rename(2)replacement within the same mtime tickReproduction Steps
ensure_open)get_hoveror another tool on the modified filetextDocument/didOpen)Expected Behavior
mcpls should detect the content change and resync the document.
Actual Behavior
SyncSignaturecomparison returns equal; resync is skipped.Affected Code
crates/mcpls-core/src/bridge/state.rs—SyncSignatureandensure_openFix Direction
Include a content hash (e.g.
xxhashorblake3of first N bytes) inSyncSignatureas a tie-breaker when(mtime, size)is identical to the cached value.Environment