Repository Analysis

permissionlesstech/bitchat-android

decentralized mesh chat

23.7 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of permissionlesstech/bitchat-android, a Kotlin project with 7,240 GitHub stars. SynthScan v2.0 examined 144,230 lines of code across 597 source files, recording 349 pattern matches distributed across 10 syntactic categories. The overall adjusted score of 23.7 places this repository in the Moderate 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).

23.7
Adjusted Score
23.7
Raw Score
100%
Time Factor
2026-08-02
Last Push
7.2K
Stars
Kotlin
Language
144.2K
Lines of Code
597
Files
349
Pattern Hits
2026-08-02
Scan Date
0.49
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

Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.

No multi-scan history yet — run the scanner again to build trend data.

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 289HIGH 1MEDIUM 9LOW 50

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 349 distinct pattern matches across 10 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.

Hallucination Indicators289 hits · 3335 pts
SeverityFileLineSnippetContext
CRITICAL…rc/test/java/com/bitchat/android/ui/ChatUIUtilsTest.kt180 private fun androidx.compose.ui.graphics.Color.isSpecified() =CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt115 com.bitchat.android.service.AppShutdownCoordinator.cancelPendingShutdown()CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt124 meshService = com.bitchat.android.service.MeshServiceHolder.getOrCreate(applicationContext)CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt125 unifiedMeshService = com.bitchat.android.service.MeshServiceHolder.getUnifiedOrCreate(applicationContext)CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt397 val bleRequired = try { com.bitchat.android.ui.debug.DebugPreferenceManager.getBleEnabled(true) } catch (_: ExceCODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt436 !com.bitchat.android.onboarding.BackgroundLocationPreferenceManager.isSkipped(this@MainActivity)CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt499 com.bitchat.android.wifiaware.WifiAwareController.startIfPossible()CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt564 val bleRequired2 = try { com.bitchat.android.ui.debug.DebugPreferenceManager.getBleEnabled(true) } catch (_: ExcCODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt606 com.bitchat.android.service.MeshForegroundService.start(applicationContext)CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt690 com.bitchat.android.nostr.LocationNotesInitializer.initialize(this@MainActivity)CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt731 com.bitchat.android.service.AppShutdownCoordinator.cancelPendingShutdown()CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt759 val bleRequired = try { com.bitchat.android.ui.debug.DebugPreferenceManager.getBleEnabled(true) } catch (_: CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt777 com.bitchat.android.wifiaware.WifiAwareController.startIfPossible()CODE
CRITICALapp/src/main/java/com/bitchat/android/MainActivity.kt838 val channelId = com.bitchat.android.geohash.ChannelID.Location(geohashChannel)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt17 com.bitchat.android.mesh.PowerManager.getInstance(this).start()CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt29 try { com.bitchat.android.nostr.LocationNotesInitializer.initialize(this) } catch (_: Exception) { }CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt33 com.bitchat.android.favorites.FavoritesPersistenceService.initialize(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt40 com.bitchat.android.services.AppStateStore.initializeConversationPersistence(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt45 com.bitchat.android.nostr.NostrIdentityBridge.getCurrentNostrIdentity(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt52 com.bitchat.android.ui.theme.ChatUiModeManager.init(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt55 try { com.bitchat.android.ui.debug.DebugPreferenceManager.init(this) } catch (_: Exception) { }CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt59 val enabled = com.bitchat.android.ui.debug.DebugPreferenceManager.getWifiAwareEnabled(false)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt60 com.bitchat.android.wifiaware.WifiAwareController.initialize(this, enabled)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt65 com.bitchat.android.nostr.GeohashAliasRegistry.initialize(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt66 com.bitchat.android.nostr.GeohashConversationRegistry.initialize(this)CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt71 try { com.bitchat.android.nostr.NostrBackgroundRuntime.initialize(this) } catch (_: Exception) { }CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt74 try { com.bitchat.android.service.MeshServicePreferences.init(this) } catch (_: Exception) { }CODE
CRITICAL…rc/main/java/com/bitchat/android/BitchatApplication.kt77 try { com.bitchat.android.service.MeshForegroundService.start(this) } catch (_: Exception) { }CODE
CRITICAL…/main/java/com/bitchat/android/mesh/PacketProcessor.kt19 private val debugManager by lazy { try { com.bitchat.android.ui.debug.DebugSettingsManager.getInstance() } catch (e:CODE
CRITICAL…com/bitchat/android/mesh/BluetoothPacketBroadcaster.kt85 val manager = com.bitchat.android.ui.debug.DebugSettingsManager.getInstance()CODE
CRITICAL…com/bitchat/android/mesh/BluetoothGattServerManager.kt57 com.bitchat.android.ui.debug.DebugSettingsManager.getInstance().bleEnabled.valueCODE
CRITICAL…com/bitchat/android/mesh/BluetoothGattServerManager.kt59 try { com.bitchat.android.ui.debug.DebugPreferenceManager.getBleEnabled(true) } catch (_: Exception) { true CODE
CRITICAL…com/bitchat/android/mesh/BluetoothGattServerManager.kt65 (try { com.bitchat.android.ui.debug.DebugSettingsManager.getInstance().gattServerEnabled.value } catch (_: ECODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt219 try { com.bitchat.android.services.AppStateStore.setTransportPeers(transport.id, peerIDs) } catch (_: ExCODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt415 com.bitchat.android.services.AppStateStore.updatePrivateMessageStatus(CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt417 com.bitchat.android.model.DeliveryStatus.Delivered(peerID, java.util.Date())CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt425 com.bitchat.android.services.AppStateStore.updatePrivateMessageStatus(CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt427 com.bitchat.android.model.DeliveryStatus.Read(peerID, java.util.Date())CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt787 data = com.bitchat.android.services.VerificationService.buildVerifyChallenge(noiseKeyHex, nonceA)CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt793 val tlv = com.bitchat.android.services.VerificationService.buildVerifyResponse(noiseKeyHex, nonceA) ?: returnCODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt875 tlvPayload += com.bitchat.android.services.meshgraph.GossipTLV.encodeNeighbors(directPeersForGossip)CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt877 com.bitchat.android.services.meshgraph.MeshGraphService.getInstance()CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt891 try { com.bitchat.android.services.AppStateStore.setTransportDirectPeers(transport.id, localDirect) } catch CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt893 com.bitchat.android.services.AppStateStore.getDirectPeers().ifEmpty { localDirect }CODE
CRITICALapp/src/main/java/com/bitchat/android/mesh/MeshCore.kt1049 val path = com.bitchat.android.services.meshgraph.RoutePlanner.shortestPath(CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt84 val noisePayload = com.bitchat.android.model.NoisePayload.decode(decryptedData)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt93 val privateMessage = com.bitchat.android.model.PrivateMessagePacket.decode(noisePayload.data)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt128 val file = com.bitchat.android.model.BitchatFilePacket.decode(noisePayload.data)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt132 val savedPath = com.bitchat.android.features.file.FileUtils.saveIncomingFile(appContext, file)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt137 type = com.bitchat.android.features.file.FileUtils.messageTypeForMime(file.mimeType),CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt353 val neighborsOrNull = com.bitchat.android.services.meshgraph.GossipTLV.decodeNeighborsFromAnnouncementPayloaCODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt354 com.bitchat.android.services.meshgraph.MeshGraphService.getInstance()CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt466 val isFileTransfer = com.bitchat.android.protocol.MessageType.fromValue(packet.type) == com.bitchat.android.CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt467 val file = com.bitchat.android.model.BitchatFilePacket.decode(packet.payload)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt470 val savedPath = com.bitchat.android.features.file.FileUtils.saveIncomingFile(appContext, file)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt475 type = com.bitchat.android.features.file.FileUtils.messageTypeForMime(file.mimeType),CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt506 val isFileTransfer = com.bitchat.android.protocol.MessageType.fromValue(packet.type) ==CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt526 val file = com.bitchat.android.model.BitchatFilePacket.decode(packet.payload)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt529 val savedPath = com.bitchat.android.features.file.FileUtils.saveIncomingFile(appContext, file)CODE
CRITICAL…c/main/java/com/bitchat/android/mesh/MessageHandler.kt534 type = com.bitchat.android.features.file.FileUtils.messageTypeForMime(file.mimeType),CODE
229 more matches not shown…
Hyper-Verbose Identifiers21 hits · 22 pts
SeverityFileLineSnippetContext
LOWtools/release_gate/test_release_gate.py102 def test_manifest_covers_every_release_category(self):CODE
LOWtools/release_gate/test_release_gate.py116 def test_documented_matrix_template_is_schema_valid_but_not_runnable(self):CODE
LOWtools/release_gate/test_release_gate.py122 def test_matrix_enforces_distinct_api_manufacturer_and_counterpart_clients(self):CODE
LOWtools/release_gate/test_release_gate.py132 def test_privacy_policy_rejects_identifiers_paths_addresses_and_long_ids(self):CODE
LOWtools/release_gate/test_release_gate.py146 def test_initialize_creates_disposable_fixtures_and_pending_results(self):CODE
LOWtools/release_gate/test_release_gate.py174 def test_record_requires_structured_evidence_and_rejects_pii(self):CODE
LOWtools/release_gate/test_release_gate.py206 def test_complete_run_requires_all_evidence_traces_and_endurance_bounds(self):CODE
LOWtools/release_gate/test_release_gate.py258 def test_manifest_tampering_after_initialization_is_detected(self):CODE
LOWtools/release_gate/test_release_gate.py268 def test_trace_accepts_only_aggregate_metrics(self):CODE
LOWtools/release_gate/test_release_gate.py283 def test_evidence_parser_is_typed_and_privacy_checked(self):CODE
LOWtools/release_gate/test_release_gate.py292 def test_adb_device_count_never_returns_selectors(self, _find_adb):CODE
LOWtools/release_gate/test_release_gate.py303 def test_adb_probe_emits_only_logical_device_metadata(self, run_adb):CODE
LOWtools/release_gate/test_release_gate.py316 def test_disposable_cleanup_targets_the_real_application_id(self, run_adb):CODE
LOWtools/release_gate/test_release_gate.py336 def test_resource_snapshot_returns_only_aggregate_metrics(self, run_adb):CODE
LOWtools/release_gate/mesh_lab.py320def make_private_media_fixtures(directory: Path, seed: int = 7331) -> dict[str, dict]:CODE
LOWtools/release_gate/mesh_lab.py384def wait_for_mutual_discovery(a: Device, b: Device) -> None:CODE
LOWtools/release_gate/mesh_lab.py427def scenario_favorite_verification(a: Device, b: Device) -> dict:CODE
LOWtools/release_gate/mesh_lab.py764def scenario_session_recovery(a: Device, b: Device) -> dict:CODE
LOWtools/release_gate/android_lab.py109def prepare_disposable_device(serial: str, confirmed: bool) -> None:CODE
LOWtools/release_gate/android_lab.py118def collect_resource_snapshot(serial: str) -> dict[str, int | bool]:CODE
LOWapp/src/main/java/com/bitchat/android/ui/DataManager.kt13class DataManager(private val context: Context) {CODE
Decorative Section Separators6 hits · 21 pts
SeverityFileLineSnippetContext
MEDIUMtools/arti-build/build-arti.sh22# ==============================================================================COMMENT
MEDIUMtools/arti-build/build-arti.sh24# ==============================================================================COMMENT
MEDIUMtools/arti-build/build-arti.sh138# ==============================================================================COMMENT
MEDIUMtools/arti-build/build-arti.sh140# ==============================================================================COMMENT
MEDIUMtools/arti-build/build-arti.sh606# ==============================================================================COMMENT
MEDIUMtools/arti-build/build-arti.sh608# ==============================================================================COMMENT
Over-Commented Block15 hits · 15 pts
SeverityFileLineSnippetContext
LOWtools/arti-build/build-arti.sh1#!/usr/bin/env bashCOMMENT
LOWapp/src/test/kotlin/com/bitchat/FileTransferTest.kt321 // Additional assertions would test different file typesCOMMENT
LOW…com/bitchat/android/mesh/BluetoothConnectionManager.kt241 // try {COMMENT
LOW…itchat/android/noise/southernstorm/crypto/NewHope.java721 1036095,929607,995151,962391,896859,1027935,946023,1011567,COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt1//package com.bitchat.android.servicesCOMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt21// companion object {COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt41// retentionDir.mkdirs()COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt61// prefs.edit().putStringSet(KEY_FAVORITE_CHANNELS, currentFavorites).apply()COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt81//COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt101// return@withContextCOMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt121// if (!isChannelBookmarked(channel)) {COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt141// channelFile.delete()COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt161//COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt181// }COMMENT
LOW…om/bitchat/android/services/MessageRetentionService.kt201//COMMENT
AI Slop Vocabulary3 hits · 9 pts
SeverityFileLineSnippetContext
MEDIUM…in/java/com/bitchat/android/ui/MessageSpecialParser.kt62 // 1) Use Android's WEB_URL for robust detection of http(s) and www.*COMMENT
MEDIUM…in/java/com/bitchat/android/protocol/BinaryProtocol.kt349 // Try decode as-is first (robust when padding wasn't applied) - iOS fixCOMMENT
MEDIUM…in/java/com/bitchat/android/nostr/NostrRelayManager.kt97 // Persistent subscription tracking for robust reconnectionCOMMENT
Unused Imports6 hits · 6 pts
SeverityFileLineSnippetContext
LOWtools/release_gate/mesh_lab.py20CODE
LOWtools/release_gate/release_gate.py10CODE
LOWtools/release_gate/android_lab.py8CODE
LOW…reenshot-studio/scripts/validate_readme_screenshots.py4CODE
LOW…-ui-visual-review/scripts/validate_capture_manifest.py4CODE
LOW…s/android-ui-visual-review/scripts/upload_pr_images.py4CODE
Synthetic Comment Markers1 hit · 5 pts
SeverityFileLineSnippetContext
HIGH…in/java/com/bitchat/android/model/BitchatFilePacket.kt63 val contentLenFieldLen = 4 // UInt32 for CONTENT TLV as requestedCODE
Deep Nesting4 hits · 4 pts
SeverityFileLineSnippetContext
LOWtools/release_gate/mesh_lab.py912CODE
LOWtools/release_gate/mesh_lab.py985CODE
LOWtools/release_gate/release_gate.py685CODE
LOWtools/release_gate/android_lab.py178CODE
Excessive Try-Catch Wrapping3 hits · 3 pts
SeverityFileLineSnippetContext
LOWtools/release_gate/mesh_lab.py143 except Exception:CODE
LOWtools/release_gate/mesh_lab.py241 except Exception as error:CODE
LOWtools/release_gate/mesh_lab.py252 except Exception:CODE
Example Usage Blocks1 hit · 2 pts
SeverityFileLineSnippetContext
LOWtools/arti-build/build-arti.sh14# Usage:COMMENT