Found in a read-only audit of v2.3.8. Verified against current main.
What happens
_WatchSupervisor._schedule catches OSError from observer.schedule(), logs a warning and returns (code_review_graph/incremental.py:1847). _adopt_directory then returns True regardless of whether any watch was actually installed (:1914), so the caller counts the directory as adopted, health keeps reporting the watcher as alive, and nothing records which paths ended up unwatched.
Reproduction
With a permanently failing schedule (inotify ENOSPC is the realistic case — it is #811's own trigger):
adoption returned: True
watched_paths: []
degraded: False
Why it matters
Additions under the unwatched directory may still be picked up by the periodic scan, but deletions will not: watch-mode updates run with reconcile_stale=False, so rows for deleted files stay in the graph indefinitely. That is the stale-row divergence of #812/#817, arriving silently.
Note the liveness path already handles the same failure honestly — a reschedule that fails is reported as a death rather than a repair (check_liveness). Adoption should match it.
Suggested fix
Have _schedule report failure, _adopt_directory return False when nothing was scheduled, and set degraded = True (with the failed paths in the health payload) so crg-daemon status can say the watcher is running with reduced coverage.
Found in a read-only audit of v2.3.8. Verified against current
main.What happens
_WatchSupervisor._schedulecatchesOSErrorfromobserver.schedule(), logs a warning and returns (code_review_graph/incremental.py:1847)._adopt_directorythen returnsTrueregardless of whether any watch was actually installed (:1914), so the caller counts the directory as adopted, health keeps reporting the watcher as alive, and nothing records which paths ended up unwatched.Reproduction
With a permanently failing
schedule(inotifyENOSPCis the realistic case — it is #811's own trigger):Why it matters
Additions under the unwatched directory may still be picked up by the periodic scan, but deletions will not: watch-mode updates run with
reconcile_stale=False, so rows for deleted files stay in the graph indefinitely. That is the stale-row divergence of #812/#817, arriving silently.Note the liveness path already handles the same failure honestly — a reschedule that fails is reported as a death rather than a repair (
check_liveness). Adoption should match it.Suggested fix
Have
_schedulereport failure,_adopt_directoryreturnFalsewhen nothing was scheduled, and setdegraded = True(with the failed paths in the health payload) socrg-daemon statuscan say the watcher is running with reduced coverage.