You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observation-class finding, recorded while reading chokidar's event normalization for #7369 (PR #12695). Not fixed there: it is a separate question from that card's defect, and answering it changes watcher behaviour on a path that card deliberately left alone.
What I found
FileSystemRepository.startWatcher() (packages/metadata-fs/src/repository.ts) constructs its watcher with usePolling: true. chokidar intends atomic to default OFF in exactly that case, and says so in a comment:
// Editor atomic write normalization enabled by default with fs.watchif(opts.atomic===undefined)opts.atomic=!opts.usePolling;
That correction never runs. A few lines earlier the defaults literal already assigns a value, before the user options are spread in:
constopts={// Defaults
...
atomic: true,// NOTE: overwritten later (depends on usePolling)
..._opts,
...
};
Since metadata-fs does not pass atomic, opts.atomic is true, never undefined, so the === undefined branch is dead and the polling watcher runs with editor-atomic-write normalization ON — the opposite of chokidar's stated intent. (chokidar 5.0.0, node_modules/chokidar/index.js.)
Why it is worth a look rather than a shrug
Two behaviours ride on that flag, and this repository chose neither:
Every unlink is deferred by 100 ms. In _emit, an unlink with atomic on is parked in _pendingUnlinks and flushed on a 100 ms timer, and an add for the same path arriving inside that window rewrites the event to change and cancels the removal. That is a wall-clock coalescing window in the delivery path of a package whose test file already carries a standing prohibition on wall-clock budgets, and it stretches with runner load exactly like every other budget that has ejected this package from the merge queue.
Neither is a defect today — no measurement here says either one has bitten. The finding is that the value is unchosen: it reads as "chokidar defaults to off under polling" and is in fact on.
Suggested disposition (for triage to grade and size)
A — pass atomic explicitly, whichever way the maintainers want it, so the value is declared at the call site instead of inherited from an upstream branch that cannot execute. Cheapest and makes the intent checkable. If false is chosen, the 100 ms deferral and the DOT_RE rule both go away, and that is a behaviour change to the delivery path which owes its own reverse verification.
B — leave it and document it next to the other watcher options, so the next reader of startWatcher does not have to re-derive chokidar's option merge to know what is on.
No measurement that either behaviour has ever affected a run. I read the option merge while tracing chokidar's removal path; I did not instrument the 100 ms window or find a path DOT_RE matches in this tree.
I did not check whether upstream chokidar considers the dead branch a bug worth reporting there as well.
Observation-class finding, recorded while reading chokidar's event normalization for #7369 (PR #12695). Not fixed there: it is a separate question from that card's defect, and answering it changes watcher behaviour on a path that card deliberately left alone.
What I found
FileSystemRepository.startWatcher()(packages/metadata-fs/src/repository.ts) constructs its watcher withusePolling: true. chokidar intendsatomicto default OFF in exactly that case, and says so in a comment:That correction never runs. A few lines earlier the defaults literal already assigns a value, before the user options are spread in:
Since
metadata-fsdoes not passatomic,opts.atomicistrue, neverundefined, so the=== undefinedbranch is dead and the polling watcher runs with editor-atomic-write normalization ON — the opposite of chokidar's stated intent. (chokidar 5.0.0,node_modules/chokidar/index.js.)Why it is worth a look rather than a shrug
Two behaviours ride on that flag, and this repository chose neither:
unlinkis deferred by 100 ms. In_emit, an unlink withatomicon is parked in_pendingUnlinksand flushed on a 100 ms timer, and anaddfor the same path arriving inside that window rewrites the event tochangeand cancels the removal. That is a wall-clock coalescing window in the delivery path of a package whose test file already carries a standing prohibition on wall-clock budgets, and it stretches with runner load exactly like every other budget that has ejected this package from the merge queue._isIgnoredgains a rule nobody chose.if (this.options.atomic && DOT_RE.test(path)) return true;adds an editor-temp-file matcher (vim swap files, trailing~, sublime tmp) on top ofisIgnoredWatchPath, which is the matcher metadata-fs: the FileSystemRepository chokidar watcher is inert in the production layout — its ownignoreddotfile regex matches the.objectstacksegment of the root path #7150 was fought over. The repository's boot scan (scanHeads), its watcher matcher and its reconciliation sweep are deliberately kept in agreement about what the repository contains; this is a fourth opinion none of them knows about.Neither is a defect today — no measurement here says either one has bitten. The finding is that the value is unchosen: it reads as "chokidar defaults to off under polling" and is in fact on.
Suggested disposition (for triage to grade and size)
atomicexplicitly, whichever way the maintainers want it, so the value is declared at the call site instead of inherited from an upstream branch that cannot execute. Cheapest and makes the intent checkable. Iffalseis chosen, the 100 ms deferral and the DOT_RE rule both go away, and that is a behaviour change to the delivery path which owes its own reverse verification.startWatcherdoes not have to re-derive chokidar's option merge to know what is on.watch-dot-root.test.tscase 1 is wall-clock-timed and ejected an unrelated PR from the merge queue — the queue's full-suite load is where it bites #7369's fix, which is keyed to the disk check and holds whateveratomicis set to.What I did NOT establish
Generated by Claude Code