AI Slop Code RIsk Monitor

gorakhargosh/watchdog

Python library and shell utilities to monitor filesystem events.

16.2 Elevated pattern signal View on GitHub

Maintenance and Governance Review

This report summarizes scanner evidence for gorakhargosh/watchdog, a Python project with 7,419 GitHub stars. SynthScan examined 16,018 lines of code across 81 source files, recording 222 pattern matches distributed across 11 syntactic categories. The legacy adjusted pattern signal is 16.2 (Elevated pattern signal); it is not an authorship estimate.

Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.

16.2
Adjusted Signal
16.2
Raw Pattern Score
100%
Time Factor
2026-10-10
Last Push
7.4K
Stars
Python
Language
16.0K
Lines of Code
81
Files
222
Pattern Hits
2026-10-12
Scan Date
0.10
HC Hit Rate

Risk Review · v3

Use each vector to guide manual verification of the underlying findings.

Cognitive Ownership Risk 37.3/100 · MEDIUM

Can maintainers explain intent, assumptions, and trade-offs? 147 finding(s).

Hallucinated Dependency & Supply Chain Risk 14.2/100 · LOW

Are imports declared and package/API names verified? 49 finding(s).

Agent Over-Engineering Ratio 39.0/100 · MEDIUM

Are wrappers, guards, and repeated structures necessary? 128 finding(s).

PR Review Velocity Impact 57.0/100 · HIGH

Which changes need focused human review? 222 finding(s).

What These Metrics Mean

Adjusted Signal
Legacy pattern score normalized per 1,000 scanned lines and multiplied by the repository-level time factor. It is not an estimate of AI authorship.
Raw Pattern Score
Sum of severity- and context-weighted pattern findings before applying the time factor.
Time Factor
A coarse multiplier based on repository last-push metadata. It does not identify when individual code was written.
Pattern Hits
Count of configured pattern findings. Review each location and surrounding code before acting.
HC Hit Rate
High- and critical-severity findings per scanned file. Severity is a configured detector weight, not proof of a vulnerability or authorship.
Lines / Files
Scan coverage denominators used by the legacy normalized score.

Pattern-Signal History

This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.

Severity Breakdown

Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.

CRITICAL 0HIGH 8MEDIUM 4LOW 210

Directory Score Breakdown

This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.

Pattern Findings

The scanner identified 222 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.

Hyper-Verbose Identifiers102 hits · 98 pts
SeverityFileLineSnippetContext
LOWtests/test_inotify_c.py44def test_late_double_deletion(helper: Helper, p: P, event_queue: TestEventQueue, start_watching: StartWatching) -> None:CODE
LOWtests/test_kqueue.py19def test_register_kevent_ignores_permission_errors(tmpdir, err):CODE
LOWtests/test_logging_event_handler.py63def test_logging_event_handler_dispatch():CODE
LOWtests/test_isolated.py13def test_observer_stops_in_eventlet():CODE
LOWtests/test_isolated.py21def test_eventlet_skip_repeat_queue():CODE
LOWtests/test_snapshot_diff.py44def test_move_to_with_context_manager(p):CODE
LOWtests/test_snapshot_diff.py93def test_dir_modify_on_create(p):CODE
LOWtests/test_snapshot_diff.py112def test_detect_modify_for_moved_files(p):CODE
LOWtests/test_snapshot_diff.py123def test_replace_dir_with_file(p):CODE
LOW⚡tests/test_observer.py35def test_schedule_should_start_emitter_if_running(observer):CODE
LOW⚡tests/test_observer.py42def test_schedule_should_not_start_emitter_if_not_running(observer):CODE
LOW⚡tests/test_observer.py48def test_start_should_start_emitter(observer):CODE
LOW⚡tests/test_observer.py55def test_stop_should_stop_emitter(observer):CODE
LOWtests/test_observer.py88def test_schedule_after_unschedule_all(observer):CODE
LOWtests/test_observer.py110def test_start_failure_should_not_prevent_further_try(observer):CODE
LOWtests/test_observer.py135def test_schedule_failure_should_not_prevent_future_schedules(observer):CODE
LOWtests/test_observer.py152def test_context_manager_starts_observer():CODE
LOWtests/test_observer.py168def test_context_manager_with_already_started_observer():CODE
LOWtests/test_observer.py186def test_context_manager_stops_on_exit():CODE
LOWtests/test_observer.py202def test_context_manager_handles_exceptions():CODE
LOWtests/test_observer.py222def test_context_manager_with_scheduled_watches():CODE
LOWtests/test_fsevents.py78def test_coalesced_event_check(event, expectation):CODE
LOWtests/test_fsevents.py82def test_native_event_owns_path() -> None:CODE
LOWtests/test_fsevents.py99def test_native_event_cycles_are_collected() -> None:CODE
LOWtests/test_fsevents.py111def test_native_event_allocations_are_released() -> None:CODE
LOWtests/test_fsevents.py292def test_stopping_unstarted_observer_releases_emitter(p: P) -> None:CODE
LOWtests/test_fsevents.py302def test_stream_stop_racing_run(p: P) -> None:CODE
LOWtests/test_fsevents.py313def test_two_streams_same_path(p: P) -> None:CODE
LOWtests/test_fsevents.py326def test_stream_concurrent_run_race(p: P) -> None:CODE
LOWtests/test_fsevents.py367def test_stream_concurrent_stop_calls(p: P) -> None:CODE
LOWtests/test_fsevents.py387def test_stream_stop_from_inside_callback(p: P) -> None:CODE
LOWtests/test_fsevents.py411def test_stream_callback_failure_terminates_stream(p: P) -> None:CODE
LOWtests/test_fsevents.py447def test_observer_stop_racing_start(p: P, start_watching: StartWatching, expect_event: ExpectEvent) -> None:CODE
LOWtests/test_fsevents.py467def test_rapid_observer_start_stop(p: P) -> None:CODE
LOWtests/test_fsevents.py477def test_module_keeps_gil_disabled() -> None:CODE
LOWtests/test_fsevents.py598def test_unschedule_removed_folder(observer: BaseObserver, p: P) -> None:CODE
LOWtests/test_fsevents.py620def test_converting_cfstring_to_pyunicode(p: P, start_watching: StartWatching, events_checker: EventsChecker) -> None:CODE
LOWtests/test_fsevents.py636def test_recursive_check_accepts_relative_paths(p: P) -> None:CODE
LOW⚡tests/test_fsevents.py131def test_native_event_requires_arguments() -> None:STRING
LOW⚡tests/test_fsevents.py136def test_native_event_unsigned_id() -> None:STRING
LOW⚡tests/test_fsevents.py141def test_stream_does_not_retain_paths_list(p: P) -> None:STRING
LOWtests/test_fsevents.py184def test_observer_propagates_stream_startup_failure(p: P, *, already_running: bool) -> None:STRING
LOWtests/test_fsevents.py207def test_stream_stop_before_run(p: P) -> None:STRING
LOWtests/test_fsevents.py228def test_stream_stop_after_start(p: P) -> None:STRING
LOWtests/test_fsevents.py243def test_stream_can_retry_after_startup_callback_failure(p: P) -> None:STRING
LOWtests/test_fsevents.py257def test_emitter_start_waits_for_stream(p: P) -> None:STRING
LOWtests/test_observers_winapi.py142def test_drop_case_only_rename_deletions():STRING
LOWtests/test_observers_winapi.py174def test_drop_case_only_rename_deletions_keeps_real_deletions(events):CODE
LOWtests/test_observers_winapi.py189def test_parse_event_buffer_reads_the_whole_file_name(file_name):CODE
LOWtests/utils.py217 def _check_events_without_order(self, found_events: list[FileSystemEvent]) -> None:CODE
LOWtests/test_0_watchmedo.py102def test_auto_restart_stop_signal_is_delivered(tmpdir, capfd):CODE
LOWtests/test_0_watchmedo.py132def test_shell_command_wait_for_completion(tmpdir, capfd):CODE
LOWtests/test_0_watchmedo.py144def test_shell_command_subprocess_termination_nowait(tmpdir):CODE
LOWtests/test_0_watchmedo.py155def test_shell_command_subprocess_termination_not_happening_on_file_opened_event(CODE
LOWtests/test_0_watchmedo.py169def test_auto_restart_not_happening_on_file_opened_event(tmpdir, capfd):CODE
LOWtests/test_0_watchmedo.py185def test_auto_restart_on_file_change(tmpdir, capfd):CODE
LOWtests/test_0_watchmedo.py204def test_auto_restart_on_file_change_debounce(tmpdir, capfd):CODE
LOWtests/test_0_watchmedo.py251def test_auto_restart_subprocess_termination(tmpdir, capfd, restart_on_command_exit):CODE
LOWtests/test_0_watchmedo.py270def test_auto_restart_arg_parsing_basic():CODE
LOWtests/test_0_watchmedo.py279def test_auto_restart_arg_parsing():CODE
42 more matches not shown…
Unused Imports49 hits · 49 pts
SeverityFileLineSnippetContext
LOWtests/test_inotify_c.py1CODE
LOWtests/conftest.py1CODE
LOWtests/test_pattern_matching_event_handler.py1CODE
LOWtests/test_kqueue.py1CODE
LOWtests/test_logging_event_handler.py1CODE
LOWtests/test_snapshot_diff.py1CODE
LOWtests/test_delayed_queue.py1CODE
LOWtests/test_observer.py1CODE
LOWtests/test_fsevents.py1CODE
LOWtests/shell.py8CODE
LOWtests/test_patterns.py1CODE
LOWtests/test_observers_winapi.py1CODE
LOWtests/utils.py1CODE
LOWtests/test_0_watchmedo.py1CODE
LOWtests/test_skip_repeats_queue.py1CODE
LOWtests/test_observers_polling.py1CODE
LOWtests/test_observers_api.py1CODE
LOWtests/test_events.py1CODE
LOWtests/test_regex_matching_event_handler.py1CODE
LOWtests/test_examples.py1CODE
LOWtests/test_inotify_watch_group.py1CODE
LOWtests/test_emitter.py1CODE
LOWdocs/source/examples/debounced.py1CODE
LOWdocs/source/examples/simple.py1CODE
LOWdocs/source/examples/file_organizer.py14CODE
LOWsrc/watchdog/watchmedo.py7CODE
LOWsrc/watchdog/version.py1CODE
LOWsrc/watchdog/events.py82CODE
LOWsrc/watchdog/utils/patterns.py8CODE
LOWsrc/watchdog/utils/__init__.py15CODE
LOWsrc/watchdog/utils/event_debouncer.py1CODE
LOWsrc/watchdog/utils/dirsnapshot.py32CODE
LOWsrc/watchdog/utils/delayed_queue.py6CODE
LOWsrc/watchdog/utils/platform.py1CODE
LOWsrc/watchdog/utils/process_watcher.py1CODE
LOWsrc/watchdog/utils/bricks.py20CODE
LOWsrc/watchdog/utils/echo.py26CODE
LOWsrc/watchdog/observers/fsevents.py8CODE
LOWsrc/watchdog/observers/inotify_move_event_grouper.py9CODE
LOWsrc/watchdog/observers/inotify.py69CODE
LOWsrc/watchdog/observers/__init__.py37CODE
LOWsrc/watchdog/observers/api.py1CODE
LOWsrc/watchdog/observers/winapi.py12CODE
LOWsrc/watchdog/observers/read_directory_changes.py1CODE
LOWsrc/watchdog/observers/kqueue.py58CODE
LOWsrc/watchdog/observers/inotify_c.py1CODE
LOWsrc/watchdog/observers/polling.py22CODE
LOWsrc/watchdog/observers/fsevents2.py8CODE
LOWsrc/watchdog/tricks/__init__.py26CODE
Cross-File Repetition6 hits · 30 pts
SeverityFileLineSnippetContext
HIGHtests/conftest.py0convenience function to join the temporary directory path with the provided arguments.STRING
HIGHtests/test_observers_winapi.py0convenience function to join the temporary directory path with the provided arguments.STRING
HIGHtests/test_observers_polling.py0convenience function to join the temporary directory path with the provided arguments.STRING
HIGHsrc/watchdog/observers/inotify.py0observer thread that schedules watching directories and dispatches calls to event handlers.STRING
HIGHsrc/watchdog/observers/read_directory_changes.py0observer thread that schedules watching directories and dispatches calls to event handlers.STRING
HIGHsrc/watchdog/observers/kqueue.py0observer thread that schedules watching directories and dispatches calls to event handlers.STRING
Deep Nesting24 hits · 24 pts
SeverityFileLineSnippetContext
LOWtests/test_inotify_c.py44CODE
LOWtests/test_fsevents.py184CODE
LOWtests/utils.py217CODE
LOWtests/test_emitter.py383CODE
LOWtests/test_emitter.py424CODE
LOWsrc/watchdog/watchmedo.py269CODE
LOWsrc/watchdog/watchmedo.py463CODE
LOWsrc/watchdog/utils/backwards_compat.py24CODE
LOWsrc/watchdog/utils/backwards_compat.py96CODE
LOWsrc/watchdog/utils/event_debouncer.py58CODE
LOWsrc/watchdog/utils/dirsnapshot.py321CODE
LOWsrc/watchdog/observers/fsevents.py164CODE
LOWsrc/watchdog/observers/inotify.py210CODE
LOWsrc/watchdog/observers/inotify.py319CODE
LOWsrc/watchdog/observers/inotify.py442CODE
LOWsrc/watchdog/observers/inotify.py502CODE
LOWsrc/watchdog/observers/__init__.py53CODE
LOWsrc/watchdog/observers/read_directory_changes.py67CODE
LOWsrc/watchdog/observers/kqueue.py424CODE
LOWsrc/watchdog/observers/kqueue.py494CODE
LOWsrc/watchdog/observers/kqueue.py610CODE
LOWsrc/watchdog/observers/inotify_c.py376CODE
LOWsrc/watchdog/observers/fsevents2.py200CODE
LOWsrc/watchdog/tricks/__init__.py275CODE
Over-Commented Block15 hits · 15 pts
SeverityFileLineSnippetContext
LOWdocs/source/conf.py1# watchdog documentation build configuration file, created byCOMMENT
LOWdocs/source/conf.py41]COMMENT
LOW.github/workflows/build-and-publish.yml1# Because this library provides extension modules for macOS, but not for otherCOMMENT
LOWsrc/pythoncapi_compat.h1// Header file providing new C API functions to old Python versions.COMMENT
LOWsrc/pythoncapi_compat.h21#include <Python.h>COMMENT
LOWsrc/pythoncapi_compat.h41# if (defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L) \COMMENT
LOWsrc/pythoncapi_compat.h121# define Py_IsNone(x) Py_Is(x, Py_None)COMMENT
LOWsrc/pythoncapi_compat.h481COMMENT
LOWsrc/pythoncapi_compat.h541#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION)COMMENT
LOWsrc/pythoncapi_compat.h1221# define PyHASH_IMAG _PyHASH_IMAGCOMMENT
LOWsrc/pythoncapi_compat.h1921#if PY_VERSION_HEX < 0x030C00A3COMMENT
LOWsrc/pythoncapi_compat.h1941COMMENT
LOWsrc/watchdog/observers/fsevents.py181 stat = os.stat(src_path)COMMENT
LOWsrc/watchdog/observers/inotify.py221 if event.is_moved_from:COMMENT
LOWsrc/watchdog/observers/kqueue.py441 # of created and deleted events for the path.COMMENT
Modern Structural Boilerplate11 hits · 11 pts
SeverityFileLineSnippetContext
LOWtests/test_inotify_c.py28logger = logging.getLogger(__name__)CODE
LOWtests/test_fsevents.py42logger = logging.getLogger(__name__)CODE
LOWtests/test_emitter.py33logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/utils/event_debouncer.py14logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/utils/process_watcher.py12logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/observers/inotify_move_event_grouper.py21logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/observers/inotify.py114logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/observers/__init__.py91__all__ = ["Observer"]CODE
LOWsrc/watchdog/observers/inotify_c.py22logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/observers/fsevents2.py65logger = logging.getLogger(__name__)CODE
LOWsrc/watchdog/tricks/__init__.py42logger = logging.getLogger(__name__)CODE
Empty Error Handlers2 hits · 10 pts
SeverityFileLineSnippetContext
HIGHsrc/watchdog/watchmedo.py768except WatchdogShutdownError:CODE
HIGHsrc/watchdog/tricks/__init__.py290except OSError:CODE
Excessive Try-Catch Wrapping7 hits · 10 pts
SeverityFileLineSnippetContext
MEDIUMsrc/watchdog/watchmedo.py799 print(f"Error: {exc.args[0]}", file=sys.stderr) # noqa:T201CODE
LOWsrc/watchdog/utils/process_watcher.py29 except Exception:CODE
LOWsrc/watchdog/observers/fsevents.py305 except Exception:CODE
LOW⚡src/watchdog/observers/__init__.py62 except Exception:CODE
LOW⚡src/watchdog/observers/__init__.py65 except Exception:CODE
LOW⚡src/watchdog/observers/__init__.py75 except Exception:CODE
LOWsrc/watchdog/observers/api.py308 except Exception:CODE
Self-Referential Comments3 hits · 9 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_snapshot_diff.py169 # Create a file and take a snapshot.COMMENT
MEDIUMtests/test_snapshot_diff.py206 # Create a file and declare a DirectorySnapshot and a EmptyDirectorySnapshot.COMMENT
MEDIUMdocs/source/conf.py4# This file is execfile()d with the current directory set to its containing dir.COMMENT
Redundant / Tautological Comments2 hits · 3 pts
SeverityFileLineSnippetContext
LOWsrc/watchdog/observers/fsevents.py231 # Check if we have a corresponding destination event in the watched path.COMMENT
LOWsrc/watchdog/observers/inotify_move_event_grouper.py73 # Check if move_from is in delayqueue alreadyCOMMENT
Overly Generic Function Names1 hit · 0 pts
SeverityFileLineSnippetContext
LOWsrc/watchdog/utils/echo.py21 def my_function(args):STRING