AI Slop Code Risk Monitor

thunderbird/thunderbird-android

SlopCodeMonitor badge for thunderbird/thunderbird-android Adjusted legacy signal; badge bands: 25 / 50 / 75 (different from dashboard bands).

Thunderbird for Android – Open Source Email App for Android (fka K-9 Mail)

0.6 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for thunderbird/thunderbird-android, a Kotlin project with 14,166 GitHub stars. SynthScan examined 508,833 lines of code across 7988 source files, recording 221 pattern matches distributed across 15 syntactic categories. The legacy adjusted pattern signal is 0.6 (Low 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.

0.6
Adjusted Signal
0.6
Raw Pattern Score
100%
Time Factor
2026-10-30
Last Push
14.2K
Stars
Kotlin
Language
508.8K
Lines of Code
8.0K
Files
221
Pattern Hits
2026-10-31
Scan Date
0.00
HC Hit Rate

Risk Review · Payload v1

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

Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.

Cognitive Ownership Risk 0.6/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 2.2/100 · LOW

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

Agent Over-Engineering Ratio 0.3/100 · LOW

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

PR Review Velocity Impact 2.8/100 · LOW

Which changes need focused human review? 221 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 4HIGH 3MEDIUM 7LOW 207

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 221 distinct pattern matches across 15 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.

Fake / Example Data168 hits · 192 pts
SeverityFileLineSnippetContext
LOW…p/k9mail/core/android/common/contact/ContactFixture.kt9val CONTACT_EMAIL_ADDRESS = "user@example.com".toEmailAddressOrThrow()CODE
LOWquality/e2e/README.md28./launch_tfa_debug.sh --real --email "user@example.com" --account-name "Work" --user-name "User42" test tests/init_with_CODE
LOWquality/e2e/tests/mail_compose_simple_message.yml17 BODY: "Lorem ipsum dolor sit amet."CODE
LOWquality/e2e/tests/mail_compose_simple_message.yml17 BODY: "Lorem ipsum dolor sit amet."CODE
LOW⚡…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt122 "\"()<>[]:,;@\\\\\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org",CODE
LOW⚡…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt123 "\" \"@example.org",CODE
LOW⚡…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt126 "#!$%&'*+-/=?^_`{}|~@example.org",CODE
LOW…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt228 val address = "alice@example.org"CODE
LOW…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt241 val address = parse("alice@example.org")[0]CODE
LOW…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt242 val address2: Address = parse("alice@example.org")[0]CODE
LOW…l/common/src/test/java/com/fsck/k9/mail/AddressTest.kt255 val address = parse("alice@example.org")[0]CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java45 checkAddresses(msg.getFrom(), "adam@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java46 checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java74 checkAddresses(msg.getFrom(), "adam@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java75 checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java93 checkAddresses(msg.getFrom(), "adam@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java94 checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java122 checkAddresses(msg.getFrom(), "x@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java123 checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java177 checkAddresses(msg.getFrom(), "x@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java178 checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java221 checkAddresses(msg.getFrom(), "x@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MimeMessageParseTest.java222 checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");CODE
LOW…va/com/fsck/k9/mail/internet/MessageIdGeneratorTest.kt18 setFrom(Address("alice@example.org"))CODE
LOW⚡…in/net/thunderbird/app/common/feature/mail/FakeData.kt18 name = "user@example.com",CODE
LOW⚡…in/net/thunderbird/app/common/feature/mail/FakeData.kt21 name = "user@example.com",CODE
LOW⚡…in/net/thunderbird/app/common/feature/mail/FakeData.kt31 identities = listOf(Identity(email = "user@example.com")),CODE
LOW⚡…in/net/thunderbird/app/common/feature/mail/FakeData.kt32 email = "user@example.com",CODE
LOW…t/thunderbird/app/common/account/AccountCreatorTest.kt78 emailAddress = "user@example.com",CODE
LOW…t/thunderbird/app/common/account/AccountCreatorTest.kt99 assertThat(result.email).isEqualTo("user@example.com")CODE
LOW…t/thunderbird/app/common/account/AccountCreatorTest.kt108 assertThat(result.identities.single().email).isEqualTo("user@example.com")CODE
LOW…t/thunderbird/app/common/account/AccountCreatorTest.kt127 emailAddress = "user@example.com",CODE
LOW…t/thunderbird/app/common/account/AccountCreatorTest.kt158 emailAddress = "user@example.com",CODE
LOW…p/common/account/DefaultAccountDefaultsProviderTest.kt257 email = "user@example.com",CODE
LOW…ccount/data/LegacyAccountLocalDataSourceStorageTest.kt136 email = "user@example.com",CODE
LOW…common/account/data/DefaultLegacyAccountManagerTest.kt382 email = "user@example.com",CODE
LOW…ommon/account/data/LegacyAccountLocalDataSourceTest.kt144 email = "user@example.com",CODE
LOW…/common/account/data/LegacyInMemoryAccountCacheTest.kt120 email = "user@example.com",CODE
LOW…ava/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java216 assertEquals("test@example.org", capturedApiIntent.getStringExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS));CODE
LOW…ava/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java284 assertEquals("test@example.org", capturedApiIntent.getStringExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS));CODE
LOW…fsck/k9/ui/messagedetails/AddToContactsLauncherTest.kt19 val result = testSubject.launch(context, name = "John Doe", email = "john@example.com")CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt458 recipientAddresses = listOf("alice@example.org", "bob@example.org"),CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt475 verify(autocryptOpenPgpApiInteractor).getKeyMaterialForUserId(same(openPgpApi), eq("alice@example.org"))CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt476 verify(autocryptOpenPgpApiInteractor).getKeyMaterialForUserId(same(openPgpApi), eq("bob@example.org"))CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt484 recipientAddresses = listOf("alice@example.org", "bob@example.org", "carol@example.org"),CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt487 pgpMessageBuilder.setBcc(listOf(Address("carol@example.org")))CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt507 verify(autocryptOpenPgpApiInteractor).getKeyMaterialForUserId(same(openPgpApi), eq("alice@example.org"))CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt508 verify(autocryptOpenPgpApiInteractor).getKeyMaterialForUserId(same(openPgpApi), eq("bob@example.org"))CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt517 recipientAddresses = listOf("alice@example.org", "carol@example.org"),CODE
LOW⚡…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt520 pgpMessageBuilder.setBcc(listOf(Address("carol@example.org")))CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt548 recipientAddresses = listOf("test@example.org"),CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt610 recipientAddresses = listOf("test@example.org"),CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt658 recipientAddresses = listOf("test@example.org"),CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt733 val cryptoStatus = defaultCryptoStatus.copy(recipientAddresses = listOf("test@example.org"))CODE
LOW…test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt789 private const val SENDER_EMAIL = "test@example.org"CODE
LOW…ui/legacy/src/main/res/layout/recipient_token_item.xml34 tools:text="Jane Doe"CODE
LOW…cy/ui/legacy/src/main/res/layout/account_list_item.xml63 tools:text="test@example.org"CODE
LOW…ui/legacy/src/main/res/layout/account_spinner_item.xml30 tools:text="test@example.org"CODE
LOW…/src/main/res/layout/account_spinner_dropdown_item.xml33 tools:text="test@example.org"CODE
LOW…ck/k9/activity/setup/AccountSetupCompositionPreview.kt16 senderName = "John Doe",CODE
108 more matches not shown…
Hallucination Indicators4 hits · 40 pts
SeverityFileLineSnippetContext
CRITICAL…c/main/java/com/fsck/k9/mail/internet/EncoderUtil.java84 return prefix + org.apache.james.mime4j.codec.EncoderUtil.encodeB(bytes) + ENC_WORD_SUFFIX;CODE
CRITICAL…c/main/java/com/fsck/k9/mail/internet/EncoderUtil.java114 return prefix + org.apache.james.mime4j.codec.EncoderUtil.encodeQ(bytes, org.apache.james.mime4j.codec.EncodCODE
CRITICAL…mpl/ui/sendingMail/SendingMailSettingsViewModelTest.kt100 profile = net.thunderbird.feature.account.storage.profile.ProfileDto(CODE
CRITICAL…mpl/ui/sendingMail/SendingMailSettingsViewModelTest.kt104 avatar = net.thunderbird.feature.account.storage.profile.AvatarDto(CODE
Structural Annotation Overuse10 hits · 15 pts
SeverityFileLineSnippetContext
LOWdocs/developer/db-migration-checklist.md91#### Step 1: Renumber Your MigrationCOMMENT
LOWdocs/developer/db-migration-checklist.md101#### Step 2: Verify Your Renumbered MigrationCOMMENT
LOW…cs/user-guide/troubleshooting/collecting-debug-logs.md14## Step 1: Enable debug loggingCOMMENT
LOW…cs/user-guide/troubleshooting/collecting-debug-logs.md23## Step 2: Reproduce the problemCOMMENT
LOW…cs/user-guide/troubleshooting/collecting-debug-logs.md34## Step 3: Collect the debug logCOMMENT
LOW…cs/user-guide/troubleshooting/collecting-debug-logs.md116## Step 4: Check Logs for Sensitive InformationCOMMENT
LOW…cs/user-guide/troubleshooting/collecting-debug-logs.md136## Step 5: Report the Issue and Attach LogsCOMMENT
LOWfeature/notification/README.md12### Step 1: Inject the `NotificationSender`COMMENT
LOWfeature/notification/README.md33### Step 2: Create a Notification instanceCOMMENT
LOWfeature/notification/README.md47### Step 3: Send and handle the outcomeCOMMENT
Cross-File Repetition3 hits · 15 pts
SeverityFileLineSnippetContext
HIGH…k/k9/preferences/migration/StorageMigrationTo25Test.kt0{ "type": "smtp", "host": "irrelevant.invalid", "port": 465, "connectionsecurity": "starttls_required", "authenticationtSTRING
HIGH…k/k9/preferences/migration/StorageMigrationTo24Test.kt0{ "type": "smtp", "host": "irrelevant.invalid", "port": 465, "connectionsecurity": "starttls_required", "authenticationtSTRING
HIGH…k/k9/preferences/migration/StorageMigrationTo22Test.kt0{ "type": "smtp", "host": "irrelevant.invalid", "port": 465, "connectionsecurity": "starttls_required", "authenticationtSTRING
Over-Commented Block12 hits · 12 pts
SeverityFileLineSnippetContext
LOW…Main/kotlin/net/thunderbird/core/common/mail/Tokens.kt21 get() = this in '0'..'9'COMMENT
LOWquality/e2e/launch_tfa_debug.sh1#!/usr/bin/env bashCOMMENT
LOWquality/e2e/tests/mail_compose.yml1appId: ${MAESTRO_APP_ID}COMMENT
LOWconfig/detekt/detekt.yml1config:COMMENT
LOW…java/com/fsck/k9/ui/messagelist/MessageListFragment.kt1361 }COMMENT
LOWgradle/libs.versions.toml1# Judging the impact of newer library versions on the app requires being intimately familiar with the code base.COMMENT
LOWscripts/extract-eml.sh1#!/usr/bin/env bashCOMMENT
LOWscripts/merged-pr-report.sh1#!/usr/bin/env bashCOMMENT
LOWscripts/merged-pr-report.sh21#COMMENT
LOWscripts/requirements.txt1# Python dependencies for scripts in this directoryCOMMENT
LOWscripts/changelog/migrate_changelog_to_json.py1#!/usr/bin/env python3COMMENT
LOWscripts/changelog/generate_changelog_json.py1#!/usr/bin/env python3COMMENT
Example Usage Blocks6 hits · 9 pts
SeverityFileLineSnippetContext
LOWscripts/extract-eml.sh16# Usage:COMMENT
LOWscripts/merged-pr-report.sh8# Usage:COMMENT
LOWscripts/changelog/migrate_changelog_to_json.py12# Usage:COMMENT
LOWscripts/changelog/generate_changelog_json.py16# Usage:COMMENT
LOWscripts/ci/validate-pr-report-labels.sh8# Usage:COMMENT
LOWscripts/ci/manage-pr-comment.sh6# Usage:COMMENT
Decorative Section Separators2 hits · 6 pts
SeverityFileLineSnippetContext
MEDIUMscripts/app_cycler.sh3# ==============================================================================COMMENT
MEDIUMscripts/app_cycler.sh6# ==============================================================================COMMENT
Hyper-Verbose Identifiers6 hits · 6 pts
SeverityFileLineSnippetContext
LOWscripts/changelog/test_changelog.py15 def test_migration_preserves_beta_history_and_normalizes_date(self):CODE
LOWscripts/changelog/test_changelog.py47 def test_generation_orders_versions_not_dates(self):CODE
LOWscripts/changelog/test_changelog.py58 def test_generation_places_final_after_release_candidates_and_orders_beta_numbers(self):CODE
LOWscripts/changelog/test_changelog.py66 def test_beta_generation_filters_groups_and_preserves_other_index_entries(self):CODE
LOWscripts/changelog/test_changelog.py107 def test_main_generates_only_requested_beta_release(self):CODE
LOWscripts/ci/contributor_list.py101def generate_contributor_list(CODE
Modern AI Meta-Vocabulary2 hits · 6 pts
SeverityFileLineSnippetContext
MEDIUMscripts/ci/pr-sentinel/lib.sh4# Shared PR Sentinel helpers for comment + label + close orchestration.COMMENT
MEDIUM…ification/api/ui/layout/InAppNotificationHostLayout.kt64 // Measuring Body content, applying scaffold paddingsCOMMENT
Redundant / Tautological Comments3 hits · 4 pts
SeverityFileLineSnippetContext
LOWdocs/install.sh19# Check if the script was run with "force" argumentCOMMENT
LOWscripts/test_python_scripts.sh32# Check if Python is availableCOMMENT
LOWscripts/ci/run-fluidattacks-scanners.sh8# Check if tools are installedCOMMENT
AI Slop Vocabulary1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUM…ava/com/fsck/k9/ui/messageview/ViewIntentFinderTest.kt43 // set. The most robust way to accomplish this is to properly initialize the content provider.COMMENT
Slop Phrases1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUM…p/k9mail/ui/utils/itemtouchhelper/ItemTouchHelper.java1294 * {@link #makeMovementFlags(int, int)} to easily construct it. Alternatively, you can use {@link SimpleCallback}.COMMENT
Excessive Try-Catch Wrapping1 hit · 2 pts
SeverityFileLineSnippetContext
MEDIUMscripts/ci/render-notes.py58 print("Error: Unsupported applicationid")CODE
TODO Padding1 hit · 2 pts
SeverityFileLineSnippetContext
LOW…/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.kt91 // TODO: Fix tests to not use open() directlyCOMMENT
Deep Nesting1 hit · 1 pts
SeverityFileLineSnippetContext
LOWscripts/ci/render-notes.py27CODE