Repository Analysis

nicotine-plus/nicotine-plus

Graphical client for the Soulseek peer-to-peer network

10.1 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 3,060 GitHub stars. SynthScan v2.0 examined 73,365 lines of code across 209 source files, recording 676 pattern matches distributed across 13 syntactic categories. The overall adjusted score of 10.1 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.1
Adjusted Score
10.1
Raw Score
100%
Time Factor
2026-08-28
Last Push
3.1K
Stars
Python
Language
73.4K
Lines of Code
209
Files
676
Pattern Hits
2026-08-29
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 654

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 676 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 Identifiers427 hits · 443 pts
SeverityFileLineSnippetContext
LOWpynicotine/chatrooms.py227 def request_add_room_operator(self, room, username):CODE
LOWpynicotine/chatrooms.py230 def request_remove_room_member(self, room, username):CODE
LOWpynicotine/chatrooms.py233 def request_remove_room_operator(self, room, username):CODE
LOWpynicotine/chatrooms.py250 def request_cancel_room_ownership(self, room):CODE
LOWpynicotine/chatrooms.py257 def request_cancel_room_membership(self, room):CODE
LOWpynicotine/chatrooms.py264 def request_enable_room_invitations(self, enabled):CODE
LOWpynicotine/chatrooms.py315 def _room_invitation_rejected(self, username):CODE
LOWpynicotine/chatrooms.py467 def _room_operatorship_granted(self, msg):CODE
LOWpynicotine/chatrooms.py480 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.py151 def _private_message_queue_add(self, msg):CODE
LOWpynicotine/core.py300 def send_message_to_network_thread(self, message: InternalMessage):CODE
LOWpynicotine/downloads.py686 def get_default_download_folder(self, username=None):CODE
LOWpynicotine/downloads.py696 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.py392 def _enqueue_limited_transfers(self, username):CODE
LOWpynicotine/downloads.py452 def _folder_downloaded_actions(self, username, folder_path):CODE
LOWpynicotine/downloads.py557 def _delete_stale_incomplete_downloads(self):CODE
LOWpynicotine/downloads.py609 def _retry_failed_connection_downloads(self):CODE
LOWpynicotine/downloads.py624 def _retry_failed_io_downloads(self):CODE
LOWpynicotine/downloads.py743 def get_complete_download_file_path(self, username, virtual_path, size, download_folder_path=None):CODE
LOWpynicotine/downloads.py767 def get_incomplete_download_file_path(self, username, virtual_path):CODE
LOWpynicotine/downloads.py789 def get_current_download_file_path(self, transfer):CODE
LOWpynicotine/downloads.py1015 def _requested_folder_timeout(self, requested_folder, is_offline=False):CODE
LOWpynicotine/downloads.py1042 def _folder_contents_response(self, msg):CODE
LOWpynicotine/downloads.py1097 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
367 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.py728 except Exception:CODE
LOWpynicotine/config.py758 except Exception:CODE
LOWpynicotine/config.py849 except Exception as error:CODE
LOWpynicotine/events.py275 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.py446 except Exception as error:CODE
LOWpynicotine/downloads.py487 except Exception as error:CODE
LOWpynicotine/pluginsystem.py347 except Exception:CODE
LOWpynicotine/pluginsystem.py519 except Exception as error:CODE
LOWpynicotine/pluginsystem.py544 except Exception as error:CODE
LOWpynicotine/pluginsystem.py615 except Exception:CODE
LOWpynicotine/pluginsystem.py725 except Exception:CODE
LOWpynicotine/pluginsystem.py769 except Exception:CODE
LOWpynicotine/pluginsystem.py872 except Exception:CODE
LOWpynicotine/pluginsystem.py1083 except Exception as error:CODE
LOWpynicotine/pluginsystem.py1112 except Exception as error:CODE
LOWpynicotine/userinfo.py79 except Exception:CODE
LOWpynicotine/userinfo.py159 except Exception as error:CODE
MEDIUMpynicotine/userinfo.py151def 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.py516 except Exception:CODE
LOWpynicotine/utils.py601 except Exception as error:CODE
LOWpynicotine/utils.py647 except Exception as error:CODE
LOWpynicotine/utils.py672 except Exception as error:CODE
LOWpynicotine/utils.py700 except Exception as error:CODE
LOWpynicotine/utils.py720 except Exception as error:CODE
LOWpynicotine/utils.py731 except Exception as second_error:CODE
MEDIUMpynicotine/utils.py654def load_file(file_path, load_func, use_old_file=False):CODE
LOWpynicotine/slskmessages.py3310 except Exception as error:CODE
MEDIUMpynicotine/slskmessages.py3294def _make_shares_list(self, share_groups):CODE
MEDIUMpynicotine/slskproto.py694def _pack_network_message(msg):CODE
LOWpynicotine/slskproto.py699 except Exception:CODE
LOWpynicotine/slskproto.py729 except Exception as error:CODE
31 more matches not shown…
Deep Nesting99 hits · 82 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.py618CODE
LOWpynicotine/config.py700CODE
LOWpynicotine/users.py340CODE
LOWpynicotine/nowplaying.py49CODE
LOWpynicotine/privatechat.py161CODE
LOWpynicotine/privatechat.py383CODE
LOWpynicotine/downloads.py557CODE
LOWpynicotine/downloads.py933CODE
LOWpynicotine/pluginsystem.py328CODE
LOWpynicotine/pluginsystem.py473CODE
LOWpynicotine/pluginsystem.py558CODE
LOWpynicotine/pluginsystem.py655CODE
LOWpynicotine/pluginsystem.py730CODE
LOWpynicotine/pluginsystem.py848CODE
LOWpynicotine/pluginsystem.py993CODE
LOWpynicotine/utils.py526CODE
LOWpynicotine/utils.py654CODE
LOWpynicotine/slskmessages.py3228CODE
LOWpynicotine/search.py258CODE
LOWpynicotine/search.py393CODE
LOWpynicotine/search.py465CODE
LOWpynicotine/search.py832CODE
LOWpynicotine/slskproto.py835CODE
LOWpynicotine/slskproto.py1129CODE
LOWpynicotine/slskproto.py1352CODE
LOWpynicotine/slskproto.py1902CODE
LOWpynicotine/slskproto.py2413CODE
LOWpynicotine/slskproto.py2600CODE
LOWpynicotine/slskproto.py2783CODE
LOWpynicotine/i18n.py39CODE
LOWpynicotine/uploads.py561CODE
LOWpynicotine/uploads.py1274CODE
LOWpynicotine/userbrowse.py203CODE
LOWpynicotine/userbrowse.py299CODE
LOWpynicotine/shares.py553CODE
LOWpynicotine/shares.py842CODE
LOWpynicotine/shares.py928CODE
LOWpynicotine/shares.py1253CODE
LOWpynicotine/plugins/core_commands/__init__.py600CODE
LOWpynicotine/external/tinytag.py336CODE
LOWpynicotine/external/tinytag.py401CODE
LOWpynicotine/external/tinytag.py451CODE
LOWpynicotine/external/tinytag.py652CODE
LOWpynicotine/external/tinytag.py785CODE
LOWpynicotine/external/tinytag.py1295CODE
LOWpynicotine/external/tinytag.py1440CODE
LOWpynicotine/external/tinytag.py1529CODE
LOWpynicotine/external/tinytag.py1727CODE
LOWpynicotine/external/tinytag.py1838CODE
LOWpynicotine/external/tinytag.py1994CODE
LOWpynicotine/external/tinytag.py2096CODE
LOWpynicotine/external/tinytag.py2280CODE
LOWpynicotine/external/tinytag.py2468CODE
39 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.py608 # Check if we have specified a username or passwordCOMMENT
LOWpynicotine/config.py709 # Check if config section exists in defaultsCOMMENT
LOWpynicotine/config.py713 # Check if config option exists in defaultsCOMMENT
LOWpynicotine/config.py780 # Check if server value is validCOMMENT
LOWpynicotine/config.py786 # Check if port range value is validCOMMENT
LOWpynicotine/downloads.py679 # Check if a custom download location was specifiedCOMMENT
LOWpynicotine/downloads.py690 # Check if username subfolders should be created for downloadsCOMMENT
LOWpynicotine/downloads.py1142 # Check if download exists in our default download folderCOMMENT
LOWpynicotine/cli.py88 # Check if custom prompt is activeCOMMENT
LOWpynicotine/search.py669 # Check if file path contains phrase excluded from the search networkCOMMENT
LOWpynicotine/slskproto.py324 # Set IP_BIND_ADDRESS_NO_PORT to avoid reserving an ephemeral port in bind(),COMMENT
LOWpynicotine/slskproto.py807 # Check if there's already a connection for the specified usernameCOMMENT
LOWpynicotine/slskproto.py812 # 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.py1032 # Check if virtual share name is already in useCOMMENT
LOWpynicotine/gtkgui/application.py963 # 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.py441 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.py25# This module contains message classes, that networking and UI threadCOMMENT
MEDIUMpynicotine/slskproto.py665 # Create a UDP socketCOMMENT
MEDIUMpynicotine/gtkgui/widgets/popupmenu.py239 """This function is called before a menu model needs to be manipulatedSTRING
Modern Structural Boilerplate8 hits · 9 pts
SeverityFileLineSnippetContext
LOWpynicotine/core.py47__all__ = ["Core", "UpdateChecker", "core"]CODE
LOWpynicotine/external/tinytag.py1188 def _set_custom_field(self, custom_field_name: str, value: str) -> None:CODE
LOWpynicotine/external/tinytag.py1195 def _set_grouping_work_fields(self) -> None:CODE
LOWpynicotine/external/tinytag.py303 def _set_field(self, fieldname: str, value: str | float) -> None:CODE
LOWpynicotine/external/tinytag.py322 def _set_other_field(self, fieldname: str, value: str) -> None:CODE
LOWpynicotine/external/tinytag.py431 def _set_field(self, fieldname: str, value: Image) -> None:CODE
LOWpynicotine/external/tinytag.py444 def _set_other_field(self, fieldname: str, value: Image) -> None:CODE
LOWpynicotine/external/tinytag.py1885 def _set_vorbis_comment_fields(self, fh: BinaryIO) -> None:CODE
AI Structural Patterns9 hits · 9 pts
SeverityFileLineSnippetContext
LOWpynicotine/slskmessages.py523CODE
LOWpynicotine/slskmessages.py3450CODE
LOWpynicotine/search.py49CODE
LOWpynicotine/search.py317CODE
LOWpynicotine/external/tinytag.py129CODE
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.py35CODE
LOWpynicotine/gtkgui/__init__.py84CODE
LOWpynicotine/gtkgui/__init__.py89CODE
Decorative Section Separators1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUMpynicotine/external/tinytag.py2116 # ----------------------------------------------COMMENT
Over-Commented Block2 hits · 2 pts
SeverityFileLineSnippetContext
LOWpynicotine/downloads.py1# SPDX-FileCopyrightText: 2020-2026 Nicotine+ ContributorsCOMMENT
LOWpynicotine/external/tinytag.py1# SPDX-FileCopyrightText: 2020-2026 Nicotine+ ContributorsCOMMENT
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