Repository Analysis

nicotine-plus/nicotine-plus

Graphical client for the Soulseek peer-to-peer network

10.2 Low AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of nicotine-plus/nicotine-plus, a Python project with 2,984 GitHub stars. SynthScan v2.0 examined 72,344 lines of code across 209 source files, recording 667 pattern matches distributed across 13 syntactic categories. The overall adjusted score of 10.2 places this repository in the Low AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

10.2
Adjusted Score
10.2
Raw Score
100%
Time Factor
2026-07-14
Last Push
3.0K
Stars
Python
Language
72.3K
Lines of Code
209
Files
667
Pattern Hits
2026-07-14
Scan Date
0.03
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 3HIGH 3MEDIUM 16LOW 645

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 667 distinct pattern matches across 13 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. 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 diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Hyper-Verbose Identifiers425 hits · 442 pts
SeverityFileLineSnippetContext
LOWpynicotine/chatrooms.py222 def request_add_room_operator(self, room, username):CODE
LOWpynicotine/chatrooms.py225 def request_remove_room_member(self, room, username):CODE
LOWpynicotine/chatrooms.py228 def request_remove_room_operator(self, room, username):CODE
LOWpynicotine/chatrooms.py245 def request_cancel_room_ownership(self, room):CODE
LOWpynicotine/chatrooms.py252 def request_cancel_room_membership(self, room):CODE
LOWpynicotine/chatrooms.py259 def request_enable_room_invitations(self, enabled):CODE
LOWpynicotine/chatrooms.py459 def _room_operatorship_granted(self, msg):CODE
LOWpynicotine/chatrooms.py472 def _room_operatorship_revoked(self, msg):CODE
LOWpynicotine/logfacility.py188 def _close_inactive_log_files(self):CODE
LOWpynicotine/transfers.py183 def _load_legacy_transfers_file(transfers_file):CODE
LOWpynicotine/transfers.py436 def _update_transfer_progress(self, transfer, stat_id, current_byte_offset=None, speed=None):CODE
LOWpynicotine/transfers.py500 def _enqueue_limited_transfers(self, username):CODE
LOWpynicotine/interests.py121 def request_global_recommendations(self):CODE
LOWpynicotine/interests.py124 def request_item_recommendations(self, item):CODE
LOWpynicotine/interests.py127 def request_item_similar_users(self, item):CODE
LOWpynicotine/nowplaying.py115 def _parse_audioscrobbler_response(self, response_body):CODE
LOWpynicotine/privatechat.py153 def _private_message_queue_add(self, msg):CODE
LOWpynicotine/core.py300 def send_message_to_network_thread(self, message: InternalMessage):CODE
LOWpynicotine/downloads.py682 def get_default_download_folder(self, username=None):CODE
LOWpynicotine/downloads.py692 def get_incomplete_download_folder(self):CODE
LOWpynicotine/downloads.py158 def _get_transfer_list_file_path(self):CODE
LOWpynicotine/downloads.py195 def _open_incomplete_transfer(self, transfer):CODE
LOWpynicotine/downloads.py388 def _enqueue_limited_transfers(self, username):CODE
LOWpynicotine/downloads.py448 def _folder_downloaded_actions(self, username, folder_path):CODE
LOWpynicotine/downloads.py553 def _delete_stale_incomplete_downloads(self):CODE
LOWpynicotine/downloads.py605 def _retry_failed_connection_downloads(self):CODE
LOWpynicotine/downloads.py620 def _retry_failed_io_downloads(self):CODE
LOWpynicotine/downloads.py739 def get_complete_download_file_path(self, username, virtual_path, size, download_folder_path=None):CODE
LOWpynicotine/downloads.py763 def get_incomplete_download_file_path(self, username, virtual_path):CODE
LOWpynicotine/downloads.py785 def get_current_download_file_path(self, transfer):CODE
LOWpynicotine/downloads.py1007 def _requested_folder_timeout(self, requested_folder):CODE
LOWpynicotine/downloads.py1034 def _folder_contents_response(self, msg):CODE
LOWpynicotine/downloads.py1089 def _transfer_request_downloads(self, msg):CODE
LOWpynicotine/pluginsystem.py72 def public_room_message_notification(self, room, user, line):CODE
LOWpynicotine/pluginsystem.py76 def search_request_notification(self, searchterm, user, token):CODE
LOWpynicotine/pluginsystem.py80 def distrib_search_notification(self, searchterm, user, token):CODE
LOWpynicotine/pluginsystem.py84 def incoming_private_chat_event(self, user, line):CODE
LOWpynicotine/pluginsystem.py88 def incoming_private_chat_notification(self, user, line):CODE
LOWpynicotine/pluginsystem.py92 def incoming_public_chat_event(self, room, user, line):CODE
LOWpynicotine/pluginsystem.py96 def incoming_public_chat_notification(self, room, user, line):CODE
LOWpynicotine/pluginsystem.py100 def outgoing_private_chat_event(self, user, line):CODE
LOWpynicotine/pluginsystem.py104 def outgoing_private_chat_notification(self, user, line):CODE
LOWpynicotine/pluginsystem.py108 def outgoing_public_chat_event(self, room, line):CODE
LOWpynicotine/pluginsystem.py112 def outgoing_public_chat_notification(self, room, line):CODE
LOWpynicotine/pluginsystem.py116 def outgoing_global_search_event(self, text):CODE
LOWpynicotine/pluginsystem.py120 def outgoing_room_search_event(self, rooms, text):CODE
LOWpynicotine/pluginsystem.py124 def outgoing_buddy_search_event(self, text):CODE
LOWpynicotine/pluginsystem.py128 def outgoing_user_search_event(self, users, text):CODE
LOWpynicotine/pluginsystem.py132 def outgoing_wishlist_search_event(self, text):CODE
LOWpynicotine/pluginsystem.py136 def user_resolve_notification(self, user, ip_address, port, country):CODE
LOWpynicotine/pluginsystem.py140 def server_connect_notification(self):CODE
LOWpynicotine/pluginsystem.py144 def server_disconnect_notification(self, userchoice):CODE
LOWpynicotine/pluginsystem.py148 def join_chatroom_notification(self, room):CODE
LOWpynicotine/pluginsystem.py152 def leave_chatroom_notification(self, room):CODE
LOWpynicotine/pluginsystem.py156 def user_join_chatroom_notification(self, room, user):CODE
LOWpynicotine/pluginsystem.py160 def user_leave_chatroom_notification(self, room, user):CODE
LOWpynicotine/pluginsystem.py164 def private_room_membership_granted_notification(self, room):CODE
LOWpynicotine/pluginsystem.py168 def private_room_membership_revoked_notification(self, room):CODE
LOWpynicotine/pluginsystem.py172 def private_room_member_added_notification(self, room, user):CODE
LOWpynicotine/pluginsystem.py176 def private_room_member_removed_notification(self, room, user):CODE
365 more matches not shown…
Excessive Try-Catch Wrapping91 hits · 98 pts
SeverityFileLineSnippetContext
LOWpynicotine/portmapper.py332 except Exception as error:CODE
LOWpynicotine/portmapper.py630 except Exception as natpmp_error:CODE
LOWpynicotine/portmapper.py637 except Exception as upnp_error:CODE
LOWpynicotine/portmapper.py673 except Exception as error:CODE
LOWpynicotine/logfacility.py162 except Exception as error:CODE
LOWpynicotine/logfacility.py251 except Exception as error:CODE
LOWpynicotine/logfacility.py276 except Exception as error:CODE
LOWpynicotine/logfacility.py322 except Exception as error:CODE
MEDIUMpynicotine/logfacility.py171def _close_log_file(self, log_file):CODE
LOWpynicotine/transfers.py364 except Exception as error:CODE
LOWpynicotine/config.py721 except Exception:CODE
LOWpynicotine/config.py751 except Exception:CODE
LOWpynicotine/config.py842 except Exception as error:CODE
LOWpynicotine/events.py270 except Exception as error:CODE
LOWpynicotine/nowplaying.py156 except Exception as error:CODE
LOWpynicotine/nowplaying.py164 except Exception as error:CODE
LOWpynicotine/nowplaying.py180 except Exception as error:CODE
LOWpynicotine/nowplaying.py188 except Exception as error:CODE
LOWpynicotine/nowplaying.py245 except Exception as error:CODE
LOWpynicotine/nowplaying.py301 except Exception as error:CODE
LOWpynicotine/nowplaying.py323 except Exception as error:CODE
LOWpynicotine/nowplaying.py338 except Exception as error:CODE
LOWpynicotine/__init__.py148 except Exception as error:CODE
LOWpynicotine/__init__.py158 except Exception as second_error:CODE
LOWpynicotine/__init__.py207 except Exception as error:CODE
LOWpynicotine/core.py337 except Exception as error:CODE
MEDIUMpynicotine/core.py329def _check(self):CODE
LOWpynicotine/downloads.py442 except Exception as error:CODE
LOWpynicotine/downloads.py483 except Exception as error:CODE
LOWpynicotine/pluginsystem.py347 except Exception:CODE
LOWpynicotine/pluginsystem.py517 except Exception as error:CODE
LOWpynicotine/pluginsystem.py542 except Exception as error:CODE
LOWpynicotine/pluginsystem.py613 except Exception:CODE
LOWpynicotine/pluginsystem.py723 except Exception:CODE
LOWpynicotine/pluginsystem.py767 except Exception:CODE
LOWpynicotine/pluginsystem.py863 except Exception:CODE
LOWpynicotine/pluginsystem.py1075 except Exception as error:CODE
LOWpynicotine/pluginsystem.py1104 except Exception as error:CODE
LOWpynicotine/userinfo.py78 except Exception:CODE
LOWpynicotine/userinfo.py153 except Exception as error:CODE
MEDIUMpynicotine/userinfo.py145def save_user_picture(file_path, picture_bytes):CODE
LOWpynicotine/portchecker.py30 except Exception as error:CODE
MEDIUMpynicotine/portchecker.py25def _check_status(self, port):CODE
LOWpynicotine/cli.py10 except Exception as curses_error:CODE
LOWpynicotine/cli.py47 except Exception:CODE
LOWpynicotine/cli.py124 except Exception:CODE
LOWpynicotine/utils.py490 except Exception as error:CODE
LOWpynicotine/utils.py512 except Exception:CODE
LOWpynicotine/utils.py597 except Exception as error:CODE
LOWpynicotine/utils.py643 except Exception as error:CODE
LOWpynicotine/utils.py668 except Exception as error:CODE
LOWpynicotine/utils.py696 except Exception as error:CODE
LOWpynicotine/utils.py716 except Exception as error:CODE
LOWpynicotine/utils.py727 except Exception as second_error:CODE
MEDIUMpynicotine/utils.py650def load_file(file_path, load_func, use_old_file=False):CODE
LOWpynicotine/slskmessages.py3304 except Exception as error:CODE
MEDIUMpynicotine/slskmessages.py3288def _make_shares_list(self, share_groups):CODE
MEDIUMpynicotine/slskproto.py685def _pack_network_message(msg):CODE
LOWpynicotine/slskproto.py690 except Exception:CODE
LOWpynicotine/slskproto.py720 except Exception as error:CODE
31 more matches not shown…
Deep Nesting98 hits · 84 pts
SeverityFileLineSnippetContext
LOWsetup.py11CODE
LOWbuild-aux/macos/setup.py143CODE
LOWbuild-aux/appimage/setup.py143CODE
LOWbuild-aux/windows/setup.py143CODE
LOWpynicotine/portmapper.py111CODE
LOWpynicotine/portmapper.py281CODE
LOWpynicotine/transfers.py262CODE
LOWpynicotine/config.py615CODE
LOWpynicotine/config.py693CODE
LOWpynicotine/users.py329CODE
LOWpynicotine/nowplaying.py49CODE
LOWpynicotine/privatechat.py242CODE
LOWpynicotine/downloads.py553CODE
LOWpynicotine/downloads.py925CODE
LOWpynicotine/pluginsystem.py328CODE
LOWpynicotine/pluginsystem.py473CODE
LOWpynicotine/pluginsystem.py556CODE
LOWpynicotine/pluginsystem.py653CODE
LOWpynicotine/pluginsystem.py731CODE
LOWpynicotine/pluginsystem.py839CODE
LOWpynicotine/pluginsystem.py985CODE
LOWpynicotine/utils.py522CODE
LOWpynicotine/utils.py650CODE
LOWpynicotine/slskmessages.py3222CODE
LOWpynicotine/search.py257CODE
LOWpynicotine/search.py388CODE
LOWpynicotine/search.py460CODE
LOWpynicotine/search.py827CODE
LOWpynicotine/slskproto.py826CODE
LOWpynicotine/slskproto.py1114CODE
LOWpynicotine/slskproto.py1335CODE
LOWpynicotine/slskproto.py2367CODE
LOWpynicotine/slskproto.py2554CODE
LOWpynicotine/slskproto.py2738CODE
LOWpynicotine/i18n.py39CODE
LOWpynicotine/uploads.py561CODE
LOWpynicotine/uploads.py1274CODE
LOWpynicotine/userbrowse.py197CODE
LOWpynicotine/userbrowse.py293CODE
LOWpynicotine/shares.py553CODE
LOWpynicotine/shares.py847CODE
LOWpynicotine/shares.py933CODE
LOWpynicotine/shares.py1258CODE
LOWpynicotine/plugins/core_commands/__init__.py600CODE
LOWpynicotine/external/tinytag.py310CODE
LOWpynicotine/external/tinytag.py373CODE
LOWpynicotine/external/tinytag.py416CODE
LOWpynicotine/external/tinytag.py544CODE
LOWpynicotine/external/tinytag.py658CODE
LOWpynicotine/external/tinytag.py923CODE
LOWpynicotine/external/tinytag.py1127CODE
LOWpynicotine/external/tinytag.py1241CODE
LOWpynicotine/external/tinytag.py1349CODE
LOWpynicotine/external/tinytag.py1427CODE
LOWpynicotine/external/tinytag.py1556CODE
LOWpynicotine/external/tinytag.py1633CODE
LOWpynicotine/external/tinytag.py1770CODE
LOWpynicotine/external/tinytag.py1885CODE
LOWpynicotine/gtkgui/transfers.py410CODE
LOWpynicotine/gtkgui/transfers.py536CODE
38 more matches not shown…
Redundant / Tautological Comments22 hits · 34 pts
SeverityFileLineSnippetContext
LOWpynicotine/portmapper.py695 # Check if we want to do a port mappingCOMMENT
LOWpynicotine/transfers.py212 # Check if a dictionary is represented in string formatCOMMENT
LOWpynicotine/config.py605 # Check if we have specified a username or passwordCOMMENT
LOWpynicotine/config.py702 # Check if config section exists in defaultsCOMMENT
LOWpynicotine/config.py706 # Check if config option exists in defaultsCOMMENT
LOWpynicotine/config.py773 # Check if server value is validCOMMENT
LOWpynicotine/config.py779 # Check if port range value is validCOMMENT
LOWpynicotine/downloads.py675 # Check if a custom download location was specifiedCOMMENT
LOWpynicotine/downloads.py686 # Check if username subfolders should be created for downloadsCOMMENT
LOWpynicotine/downloads.py1134 # Check if download exists in our default download folderCOMMENT
LOWpynicotine/cli.py88 # Check if custom prompt is activeCOMMENT
LOWpynicotine/search.py664 # Check if file path contains phrase excluded from the search networkCOMMENT
LOWpynicotine/slskproto.py316 # Set IP_BIND_ADDRESS_NO_PORT to avoid reserving an ephemeral port in bind(),COMMENT
LOWpynicotine/slskproto.py798 # Check if there's already a connection for the specified usernameCOMMENT
LOWpynicotine/slskproto.py803 # Check if we have a pending PeerInit message (currently requesting user IP address)COMMENT
LOWpynicotine/uploads.py111 # Check if queued uploads can be started every 10 secondsCOMMENT
LOWpynicotine/shares.py535 # Check if file is marked as hidden on WindowsCOMMENT
LOWpynicotine/shares.py1037 # Check if virtual share name is already in useCOMMENT
LOWpynicotine/gtkgui/application.py930 # Check if exception occurred in a pluginCOMMENT
LOWpynicotine/gtkgui/widgets/trayicon.py564 # Check if custom icons existCOMMENT
LOWpynicotine/gtkgui/widgets/trayicon.py569 # Check if local icons existCOMMENT
LOWpynicotine/gtkgui/widgets/iconnotebook.py711 # Check if tab was removed before timer expiredCOMMENT
Hallucination Indicators3 hits · 30 pts
SeverityFileLineSnippetContext
CRITICALpynicotine/gtkgui/privatechat.py466 self.chats.window.application.chat_history.remove_user(self.user)CODE
CRITICALpynicotine/gtkgui/privatechat.py567 self.chats.window.application.chat_history.update_user(username, message)CODE
CRITICALpynicotine/gtkgui/dialogs/wishlist.py433 for tab in self.application.window.search.pages.values():CODE
Cross-File Repetition3 hits · 15 pts
SeverityFileLineSnippetContext
HIGHbuild-aux/macos/testrun.py0verify the packaged application starts and keeps running.STRING
HIGHbuild-aux/appimage/testrun.py0verify the packaged application starts and keeps running.STRING
HIGHbuild-aux/windows/testrun.py0verify the packaged application starts and keeps running.STRING
Self-Referential Comments4 hits · 10 pts
SeverityFileLineSnippetContext
MEDIUMpynicotine/portmapper.py377 # Create a UDP socket and set its timeoutCOMMENT
MEDIUMpynicotine/slskmessages.py26# This module contains message classes, that networking and UI threadCOMMENT
MEDIUMpynicotine/slskproto.py656 # Create a UDP socketCOMMENT
MEDIUMpynicotine/gtkgui/widgets/popupmenu.py235 """This function is called before a menu model needs to be manipulatedSTRING
AI Structural Patterns8 hits · 8 pts
SeverityFileLineSnippetContext
LOWpynicotine/slskmessages.py524CODE
LOWpynicotine/slskmessages.py3444CODE
LOWpynicotine/search.py48CODE
LOWpynicotine/search.py312CODE
LOWpynicotine/gtkgui/widgets/combobox.py17CODE
LOWpynicotine/gtkgui/widgets/treeview.py33CODE
LOWpynicotine/gtkgui/widgets/dialogs.py22CODE
LOWpynicotine/gtkgui/widgets/dialogs.py524CODE
Unused Imports5 hits · 5 pts
SeverityFileLineSnippetContext
LOWpynicotine/core.py3CODE
LOWpynicotine/plugins/auto_buddy_rooms/__init__.py4CODE
LOWpynicotine/external/tinytag.py29CODE
LOWpynicotine/gtkgui/__init__.py84CODE
LOWpynicotine/gtkgui/__init__.py89CODE
Decorative Section Separators1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUMpynicotine/external/tinytag.py1660 # ----------------------------------------------COMMENT
Over-Commented Block3 hits · 2 pts
SeverityFileLineSnippetContext
LOWpynicotine/downloads.py1# SPDX-FileCopyrightText: 2020-2026 Nicotine+ ContributorsCOMMENT
LOWpynicotine/external/tinytag.py1# tinytag - an audio file metadata readerCOMMENT
LOWpynicotine/external/tinytag.py1661 # H | <16> The minimum block size (in samples)COMMENT
Modern Structural Boilerplate2 hits · 2 pts
SeverityFileLineSnippetContext
LOWpynicotine/core.py47__all__ = ["Core", "UpdateChecker", "core"]CODE
LOWpynicotine/external/tinytag.py402 def _set_field(self, fieldname: str, value: Image) -> None:CODE
Fake / Example Data2 hits · 2 pts
SeverityFileLineSnippetContext
LOWpynicotine/utils.py392 If the 'replacement' argument is given, every occurrence of 'placeholder'STRING
LOWpynicotine/gtkgui/widgets/trayicon.py69 self.show_hide_item = self._create_item("placeholder", self.application.on_window_hide_unhide)CODE