AI Slop Code Risk Monitor

gtsteffaniak/filebrowser

SlopCodeMonitor badge for gtsteffaniak/filebrowser Adjusted legacy signal; badge bands: 25 / 50 / 75 (different from dashboard bands).

📂 Web File Browser

1.0 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for gtsteffaniak/filebrowser, a Go project with 8,980 GitHub stars. SynthScan examined 288,740 lines of code across 1126 source files, recording 246 pattern matches distributed across 6 syntactic categories. The legacy adjusted pattern signal is 1.0 (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.

1.0
Adjusted Signal
1.0
Raw Pattern Score
100%
Time Factor
2026-10-31
Last Push
9.0K
Stars
Go
Language
288.7K
Lines of Code
1.1K
Files
246
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 4.7/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.2/100 · LOW

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

Agent Over-Engineering Ratio 2.3/100 · LOW

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

PR Review Velocity Impact 4.2/100 · LOW

Which changes need focused human review? 246 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 0MEDIUM 0LOW 246

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 246 distinct pattern matches across 6 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 Identifiers129 hits · 137 pts
SeverityFileLineSnippetContext
LOWfrontend/tests/playwright/playwright-auth.ts17export async function fillPlaywrightAdminPasswordPrompt(CODE
LOWfrontend/tests/playwright/test-setup.ts7export function isExactSettingsApiResponse(CODE
LOWfrontend/tests/playwright/test-setup.ts47export async function expectLockTooltipOnRowHover(CODE
LOWfrontend/tests/playwright/test-setup.ts223export async function getOrCreateShareViaApi(CODE
LOWfrontend/tests/playwright/test-setup.ts330export async function disableAndCloseHalloweenPrompt(page: Page): Promise<void> {CODE
LOWfrontend/tests/playwright/test-setup.ts596export async function openAdvancedProfileSettings(CODE
LOWfrontend/tests/playwright/test-setup.ts724export async function selectExpandDropdownOption(CODE
LOWfrontend/tests/playwright/settings/0-migration.spec.ts85function sourcePermissionsForAllSources(CODE
LOWfrontend/tests/playwright/settings/0-migration.spec.ts92function sourcePermissionsForSources(CODE
LOW⚡frontend/tests/playwright/settings/0-migration.spec.ts269async function expectSourceSidebarLinkWorks(page: Page, sourceName: string) {CODE
LOW⚡frontend/tests/playwright/settings/0-migration.spec.ts278function userRowInSettingsUsersTable(page: Page, username: string): Locator {CODE
LOW⚡frontend/tests/playwright/settings/0-migration.spec.ts284function shareRowInSettingsSharesTable(page: Page, hash: string): Locator {CODE
LOWfrontend/tests/playwright/settings/user-edit-helpers.ts6export function userRowInSettingsUsersTable(page: Page, usernameText: string): Locator {CODE
LOWfrontend/tests/playwright/settings/user-edit-helpers.ts23function globalPermissionContainer(modal: Locator, label: string): Locator {CODE
LOWfrontend/tests/playwright/settings/user-edit-helpers.ts37export async function expandUserEditAccountDefaults(prefsModal: Locator): Promise<void> {CODE
LOW⚡frontend/tests/playwright/settings/user-edit-helpers.ts60export async function expandUserEditSourceScope(modal: Locator, sourceName: string) {CODE
LOW⚡frontend/tests/playwright/settings/user-edit-helpers.ts66export function userEditSourcePermissionCheckbox(CODE
LOW⚡frontend/tests/playwright/settings/user-edit-helpers.ts76export function userEditSourcePermissionToggle(CODE
LOWfrontend/tests/playwright/settings/user-edit-helpers.ts160export async function confirmActorPasswordPrompt(page: Page) {CODE
LOWfrontend/tests/playwright/performance/perf-helpers.ts282export async function runWithOptionalChromeTracing(CODE
LOWfrontend/tests/playwright/performance/perf-frames.ts201export function startFrameWindowOnNextNavigation(page: {CODE
LOWfrontend/src/utils/mimetype.js41export function isRichTextPreviewMimeType(mimeType) {CODE
LOWfrontend/src/utils/playbackQuery.js135export function parsePlaybackTimeFromQuery(query) {CODE
LOWfrontend/src/utils/playbackQuery.js160export function parseTranscodeModeFromQuery(query) {CODE
LOWfrontend/src/utils/playbackQuery.js244export function formatPlaybackTimeQueryValue(seconds) {CODE
LOWfrontend/src/utils/activityDetails.js115export function activityEventTypeBadgeClass(eventType) {CODE
LOWfrontend/src/utils/activityDetails.js200export function defaultActivityOptionalRows() {CODE
LOWfrontend/src/utils/activityDetails.js205export function allActivityOptionalRowsEnabled(rowsState) {CODE
LOWfrontend/src/utils/activityDetails.js217export function optionalColumnsFromRowsState(rowsState) {CODE
LOW⚡frontend/src/utils/activityDetails.js244export function rowsStateFromOptionalColumns(columns) {CODE
LOW⚡frontend/src/utils/activityDetails.js252export function allOptionalColumnsSelected(columns) {CODE
LOW⚡frontend/src/utils/activityDetails.js260export function formatOptionalColumnsParam(columns) {CODE
LOWfrontend/src/utils/activityDetails.js290export function normalizeActivityTableRow(row) {CODE
LOWfrontend/src/utils/activityDetails.js324function formatActivityFieldChange(change, eventType) {CODE
LOWfrontend/src/utils/activityDetails.js465export function buildActivityDetailBadges(row) {CODE
LOWfrontend/src/utils/pdfPreview.js16export function shouldUsePdfPreviewFallback() {CODE
LOWfrontend/src/utils/sidebarCategory.ts28export function isRootOnlySidebarCategory(category?: string): boolean {CODE
LOWfrontend/src/utils/appNotifications.js22export function getNotificationPermission() {CODE
LOWfrontend/src/utils/appNotifications.js29export async function requestNotificationPermission() {CODE
LOWfrontend/src/utils/appNotifications.js42export function isAppNotificationsEnabled() {CODE
LOWfrontend/src/utils/appNotifications.js52export function setAppNotificationsEnabled(enabled) {CODE
LOWfrontend/src/utils/appNotifications.js173export function extractMoveCopyErrorMessage(error, fallback) {CODE
LOWfrontend/src/utils/auth.js37function setSessionExpiresAtFromToken(token) {CODE
LOWfrontend/src/utils/auth.js58export function shouldRefreshBeforeExpiry(expiresAtSeconds, refreshBeforeMs) {CODE
LOWfrontend/src/utils/metadataCache.js51export function invalidateDirMetadataCache(opts = {}) {CODE
LOWfrontend/src/utils/shareDefaultsForm.js3export function emptyShareDefaultsEnforced() {CODE
LOWfrontend/src/utils/shareDefaultsForm.js113export function shareDefaultsToApiPayload(form) {CODE
LOWfrontend/src/utils/shareDefaultsForm.js170export function defaultSidebarLinksForShareType(shareType) {CODE
LOW⚡frontend/src/utils/i18nLabels.js52export function downloadFilesPermissionLabel($t) {CODE
LOW⚡frontend/src/utils/i18nLabels.js60export function createFilesPermissionLabel($t) {CODE
LOW⚡frontend/src/utils/i18nLabels.js64export function deleteFilesPermissionLabel($t) {CODE
LOW⚡frontend/src/utils/i18nLabels.js68export function shareFilesPermissionLabel($t) {CODE
LOWfrontend/src/utils/subtitles.js11export function getSubtitleFormatExtension(filename) {CODE
LOWfrontend/src/utils/notificationActions.js7export function goToItemNotificationButton(label, source, path, isShare) {CODE
LOWfrontend/src/utils/notificationActions.js19export function restoreNotificationButtonAction(button) {CODE
LOWfrontend/src/utils/notificationActions.js33export function resolveHistoryNotificationButtons(buttons, activeButtons) {CODE
LOWfrontend/src/utils/activityChartTime.js71export function clampActivityChartInterval(interval, rangeSecs) {CODE
LOWfrontend/src/utils/activityChartTime.js90export function activityChartIntervalAllowed(rangeSecs) {CODE
LOWfrontend/src/utils/activityChartTime.js106export function resolveActivityChartInterval(from, to, preferred, maxBuckets = DEFAULT_MAX_CHART_BUCKETS) {CODE
LOWfrontend/src/utils/tooltipHelp.js15function ensureGlobalDismissListeners() {CODE
69 more matches not shown…
Over-Commented Block67 hits · 67 pts
SeverityFileLineSnippetContext
LOWfrontend/tests/playwright-files/files/for testing.md1# this is a testCOMMENT
LOWfrontend/src/api/index.js1// Backend route organization:COMMENT
LOWbackend/config.playwright.yaml61COMMENT
LOWbackend/internal/database/sql/tempdb.go61 // Synchronous controls the synchronous mode. OFF is fastest but less safe.COMMENT
LOWbackend/internal/database/sql/tempdb.go81COMMENT
LOWbackend/internal/database/sql/tempdb.go101 // this threshold and cache_size, SQLite will spill dirty pages to disk.COMMENT
LOWbackend/internal/auth/json_timing_test.go1// Package auth_test contains timing attack tests for authentication.COMMENT
LOWbackend/internal/web/users.go101 }COMMENT
LOWbackend/internal/web/users.go341 }COMMENT
LOWbackend/internal/web/media.go21// @Accept jsonCOMMENT
LOWbackend/internal/web/media.go141 }COMMENT
LOWbackend/internal/web/media.go221 }, d.ShareUser)COMMENT
LOWbackend/internal/web/media.go301// @Failure 404 {object} map[string]string "Not found"COMMENT
LOWbackend/internal/web/duplicates.go101 if s.checksumOperations >= maxChecksumOperations {COMMENT
LOWbackend/internal/web/duplicates.go121// 5. Progressive Checksum Verification (2-pass):COMMENT
LOWbackend/internal/web/auth.go201COMMENT
LOWbackend/internal/web/auth.go301 LoginMethod: string(d.User.LoginMethod),COMMENT
LOWbackend/internal/web/totp.go41 }COMMENT
LOWbackend/internal/web/preview.go41// previewHandler handles the preview request for images.COMMENT
LOWbackend/internal/web/oidc.go241 authURL := oauth2Config.AuthCodeURL(state)COMMENT
LOWbackend/internal/web/stream.go181// @Description Mints or extends a source-scoped view token for inline viewing. Authenticated routes require a web sessiCOMMENT
LOWbackend/internal/web/stream.go621// @Description Returns raw file bytes for inline UI viewing in capped byte ranges on a share link. Requires viewToken fCOMMENT
LOWbackend/internal/web/resource.go121 }COMMENT
LOWbackend/internal/web/resource.go201COMMENT
LOWbackend/internal/web/resource.go221 }COMMENT
LOWbackend/internal/web/resource.go361// MoveCopyResponse represents the response from a move/copy operationCOMMENT
LOWbackend/internal/web/resource.go681 pauseCache.Set(pauseUploadCacheKey(source, fullIndexPath), "1")COMMENT
LOWbackend/internal/web/resource.go701 src, ok := settings.Config.Server.SourceMap[d.Share.SourcePath]COMMENT
LOWbackend/internal/web/resource.go1161// @Description Handles file and directory uploads to an upload-only public share. Supports chunked uploads, conflict reCOMMENT
LOWbackend/internal/web/resource.go1201 }COMMENT
LOWbackend/internal/web/resource.go1261 status, err := putResourceWithQuota(w, r, d, source, userScope, fullIndexPath)COMMENT
LOWbackend/internal/web/resource.go1681// @Tags ResourcesCOMMENT
LOWbackend/internal/web/resource.go1841 returnCOMMENT
LOWbackend/internal/web/resource.go1881 }COMMENT
LOWbackend/internal/web/access.go41COMMENT
LOWbackend/internal/web/access.go101 }COMMENT
LOWbackend/internal/web/access.go181 activity.RecordAccessCreate(r, toActor(d), sourceName, parsedPath.String(), activity.AccessRuleCreateChanges(body.AllowCOMMENT
LOWbackend/internal/web/access.go321 resp.Members = state.GetGroupMembers()COMMENT
LOWbackend/internal/web/access.go361 }COMMENT
LOWbackend/internal/web/access.go421 }COMMENT
LOWbackend/internal/web/access.go461// @Summary Replace a user's group membershipsCOMMENT
LOWbackend/internal/web/access.go501 if len(unknown) > 0 {COMMENT
LOWbackend/internal/web/download.go101// @Description **Multiple Files:**COMMENT
LOWbackend/internal/web/download.go141// @Produce octet-streamCOMMENT
LOWbackend/internal/web/search.go41//COMMENT
LOWbackend/internal/web/search.go61// @Description Searches for files matching the provided query. Returns file paths and metadata based on the user's sessCOMMENT
LOWbackend/internal/web/onlyOffice.go121 Users []string `json:"users"`COMMENT
LOWbackend/internal/web/onlyOffice.go741 // complete: retire the document key so it cannot be reused.COMMENT
LOWbackend/internal/web/archive.go181// @Description - **fromSource** (string, required): Source name where the paths to archive live. Example: `"default"`COMMENT
LOWbackend/internal/web/archive.go381 }COMMENT
LOWbackend/internal/web/archive.go401// @Description - **preview** (boolean, optional): Return ZIP encoding candidates and sample filenames without extractinCOMMENT
LOWbackend/internal/web/webdav_uploads.go21 "github.com/gtsteffaniak/filebrowser/backend/internal/adapters/fs/fileutils"COMMENT
LOWbackend/internal/web/share.go221}COMMENT
LOWbackend/internal/web/share.go501 Token: token,COMMENT
LOWbackend/internal/web/share.go721}COMMENT
LOWbackend/internal/web/view.go21 }COMMENT
LOWbackend/internal/web/view.go61COMMENT
LOWbackend/internal/web/api.go21// @Description Create an API token with specified name, duration, and permissions.COMMENT
LOWbackend/internal/web/api.go121 }COMMENT
LOWbackend/internal/web/api.go241COMMENT
7 more matches not shown…
Verbosity Indicators18 hits · 36 pts
SeverityFileLineSnippetContext
LOW⚡frontend/src/components/files/ExtendedImage.vue179 // Step 1: Cache check happens automatically via thumbnailUrl computed propertyCOMMENT
LOW⚡frontend/src/components/files/ExtendedImage.vue181 // Step 2: Always start loading the real imageCOMMENT
LOWfrontend/src/components/files/ExtendedImage.vue278 // Step 3: Real image loaded - hide thumbnail and show imageCOMMENT
LOW⚡backend/internal/database/access/access_test.go771 // Step 1: Add some rulesCOMMENT
LOW⚡backend/internal/database/access/access_test.go779 // Step 2: Call GetAllRules to populate the cacheCOMMENT
LOW⚡backend/internal/database/access/access_test.go807 // Step 4: Delete a ruleCOMMENT
LOW⚡backend/internal/database/access/access_test.go816 // Step 5: Call GetAllRules again - should return fresh data (not cached)COMMENT
LOW⚡backend/internal/database/access/access_test.go833 // Step 6: Delete the remaining ruleCOMMENT
LOW⚡backend/internal/database/access/access_test.go842 // Step 7: Call GetAllRules again - should return empty resultCOMMENT
LOW⚡backend/internal/database/access/access_test.go893 // Step 2: Populate cacheCOMMENT
LOW⚡backend/internal/database/access/access_test.go902 // Step 3: Remove all rules for user1 (bulk operation)COMMENT
LOW⚡backend/internal/database/access/access_test.go908 // Step 4: Verify cache is cleared and rules are goneCOMMENT
LOWbackend/internal/database/access/access_test.go796 // Step 3: Call GetAllRules again - should return cached resultCOMMENT
LOWbackend/internal/database/access/access_test.go882 // Step 1: Add multiple rules for user1COMMENT
LOWbackend/internal/web/duplicates.go274 // Step 1: Query IndexDB for size groups with 2+ files (already sorted by SQL)COMMENT
LOWbackend/internal/web/duplicates.go285 // Step 2: Process sizes in batches using bulk queries to minimize SQL round-tripsCOMMENT
LOW⚡backend/pkg/indexing/iteminfo/mediaMeta.go27 // Step 1: Perform a small initial read to identify file type signature (magic bytes)COMMENT
LOW⚡backend/pkg/indexing/iteminfo/mediaMeta.go35 // Step 2: Fast Path Exit & Format-Specific HandlingCOMMENT
Structural Annotation Overuse18 hits · 36 pts
SeverityFileLineSnippetContext
LOW⚡frontend/src/components/files/ExtendedImage.vue179 // Step 1: Cache check happens automatically via thumbnailUrl computed propertyCOMMENT
LOW⚡frontend/src/components/files/ExtendedImage.vue181 // Step 2: Always start loading the real imageCOMMENT
LOWfrontend/src/components/files/ExtendedImage.vue278 // Step 3: Real image loaded - hide thumbnail and show imageCOMMENT
LOW⚡backend/internal/database/access/access_test.go771 // Step 1: Add some rulesCOMMENT
LOW⚡backend/internal/database/access/access_test.go779 // Step 2: Call GetAllRules to populate the cacheCOMMENT
LOW⚡backend/internal/database/access/access_test.go807 // Step 4: Delete a ruleCOMMENT
LOW⚡backend/internal/database/access/access_test.go816 // Step 5: Call GetAllRules again - should return fresh data (not cached)COMMENT
LOW⚡backend/internal/database/access/access_test.go833 // Step 6: Delete the remaining ruleCOMMENT
LOW⚡backend/internal/database/access/access_test.go842 // Step 7: Call GetAllRules again - should return empty resultCOMMENT
LOW⚡backend/internal/database/access/access_test.go893 // Step 2: Populate cacheCOMMENT
LOW⚡backend/internal/database/access/access_test.go902 // Step 3: Remove all rules for user1 (bulk operation)COMMENT
LOW⚡backend/internal/database/access/access_test.go908 // Step 4: Verify cache is cleared and rules are goneCOMMENT
LOWbackend/internal/database/access/access_test.go796 // Step 3: Call GetAllRules again - should return cached resultCOMMENT
LOWbackend/internal/database/access/access_test.go882 // Step 1: Add multiple rules for user1COMMENT
LOWbackend/internal/web/duplicates.go274 // Step 1: Query IndexDB for size groups with 2+ files (already sorted by SQL)COMMENT
LOWbackend/internal/web/duplicates.go285 // Step 2: Process sizes in batches using bulk queries to minimize SQL round-tripsCOMMENT
LOW⚡backend/pkg/indexing/iteminfo/mediaMeta.go27 // Step 1: Perform a small initial read to identify file type signature (magic bytes)COMMENT
LOW⚡backend/pkg/indexing/iteminfo/mediaMeta.go35 // Step 2: Fast Path Exit & Format-Specific HandlingCOMMENT
Fake / Example Data13 hits · 14 pts
SeverityFileLineSnippetContext
LOW⚡frontend/src/components/LoadingSpinner.vue17 <div v-if="mode === 'placeholder'" class="placeholder-item placeholder-item-1"></div>CODE
LOW⚡frontend/src/components/LoadingSpinner.vue18 <div v-if="mode === 'placeholder'" class="placeholder-item placeholder-item-2"></div>CODE
LOW⚡frontend/src/components/LoadingSpinner.vue19 <div v-if="mode === 'placeholder'" class="placeholder-item placeholder-item-3"></div>CODE
LOWfrontend/src/components/LoadingSpinner.vue30 validator: (value) => ["spinner", "pulse", "bounce", "placeholder"].includes(value),CODE
LOWfrontend/src/components/settings/Table.vue39 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/prompts/Archive.vue4 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/prompts/MoveCopy.vue6 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/prompts/Unarchive.vue4 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/files/FileTree.vue5 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/files/FileTree.vue65 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/files/FileList.vue28 <LoadingSpinner size="small" mode="placeholder" />CODE
LOWfrontend/src/components/files/ListingHeader.vue95 <span v-if="quickDownloadEnabled" class="placeholder"></span>CODE
LOWbackend/internal/database/users/username_test.go31 for _, username := range []string{"alice", "first.last", "j.r.r", "a-b_c", "user@example.com", "José", "李雷", ".alice", CODE
TODO Padding1 hit · 2 pts
SeverityFileLineSnippetContext
LOWbackend/pkg/indexing/indexing_test.go46 // TODO: Add test cases.COMMENT