AI Slop Code Risk Monitor

Leantime/leantime

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

Leantime is a goals focused project management system for non-project managers. Building with ADHD, Autism, and dyslexia in mind.

0.8 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for Leantime/leantime, a PHP project with 11,942 GitHub stars. SynthScan examined 549,218 lines of code across 1756 source files, recording 383 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 0.8 (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.8
Adjusted Signal
0.8
Raw Pattern Score
100%
Time Factor
2026-10-31
Last Push
11.9K
Stars
PHP
Language
549.2K
Lines of Code
1.8K
Files
383
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 3.2/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.3/100 · LOW

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

Agent Over-Engineering Ratio 2.8/100 · LOW

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

PR Review Velocity Impact 3.8/100 · LOW

Which changes need focused human review? 383 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 1HIGH 0MEDIUM 16LOW 366

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 383 distinct pattern matches across 10 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 Identifiers291 hits · 273 pts
SeverityFileLineSnippetContext
LOWapp/Core/Application.php67 protected function registerBaseServiceProviders()CODE
LOWapp/Core/UI/Template.php615 public function displayInlineNotification(): stringCODE
LOWapp/Core/UI/Template.php1009 public function patchDownloadUrlToFilenameOrAwsUrl(string $textHtml): stringCODE
LOWapp/Core/UI/ViewsServiceProvider.php317 private function discoverPluginComposerFiles(): ?\Illuminate\Support\CollectionCODE
LOWapp/Core/Middleware/AuthCheck.php280 protected function tooManyFailedAuthAttempts(IncomingRequest $request): boolCODE
LOWapp/Core/Middleware/StartSession.php493 protected function getSessionLifetimeInSeconds()CODE
LOWapp/Core/Domains/BaseService.php47 public function setPermissionServiceResolver(\Closure $resolver): voidCODE
LOWapp/Core/Auth/AuthenticationServiceProvider.php81 protected function registerRequestRebindHandler()CODE
LOWapp/Core/Auth/AuthenticationServiceProvider.php95 protected function registerEventRebindHandler()CODE
LOWapp/Core/Auth/Permissions/PermissionSeeder.php39 public function syncDiscoveredPermissions(): arrayCODE
LOWapp/Core/Auth/Permissions/PermissionSeeder.php73 private function grantNewPermissionsToRoles(array $newPermissionKeys): voidCODE
LOWapp/Core/Auth/Permissions/PermissionServiceProvider.php48 protected function forgetRolesBetweenQueuedJobs(): voidCODE
LOWapp/Core/Auth/Permissions/PermissionServiceProvider.php107 protected function injectBaseServiceDependencies(): voidCODE
LOWapp/Core/Plugins/PluginCompatibility.php98 private function lastLeantimeVersionForBrokenRelease(string $packageName, string $pluginVersion): ?stringCODE
LOWapp/Core/Exceptions/ExceptionHandler.php415 protected function convertExceptionToResponse(Throwable $e)CODE
LOWapp/Core/Exceptions/ExceptionHandler.php445 protected function renderExceptionWithWhoops(Throwable $e)CODE
LOWapp/Core/Exceptions/ExceptionHandler.php476 protected function renderExceptionWithSymfony(Throwable $e, $debug)CODE
LOWapp/Core/Exceptions/HandleExceptions.php117 protected function shouldIgnoreDeprecationErrors()CODE
LOWapp/Core/Exceptions/HandleExceptions.php129 protected function ensureDeprecationLoggerIsConfigured()CODE
LOWapp/Core/Exceptions/HandleExceptions.php153 protected function ensureNullLogDriverIsConfigured()CODE
LOWapp/Core/Controller/Frontcontroller.php398 private function assertVerbSegmentMatchesRequestMethod(string $methodName): voidCODE
LOWapp/Core/Support/RoutingFormatter.php131 protected function formatRecentHistoryAsPrompt(array $recentHistory): stringCODE
LOWapp/Core/Support/Build.php205 public function getAndTap(string $key = '', ?callable $callback = null): mixedCODE
LOWapp/Core/Shims/McpServiceProvider.php49 private function flushStalePackageManifest(): voidCODE
LOWapp/Core/Db/DatabaseHelper.php131 private function convertDateFormatToPostgres(string $mysqlFormat): stringCODE
LOWapp/Core/Events/EventDispatcher.php215 private static function executeClassEventHandlers(LeantimeEvent $event): voidCODE
LOWapp/Core/Events/EventDispatcher.php570 public static function loadEnabledPluginRegisterFiles(bool $failOnDatabaseError = false): voidCODE
LOWapp/Core/Modules/ProjectModules.php117 public function withoutSwitchedOffProjects(string $moduleId, array $rows, string $projectKey = 'projectId'): arrayCODE
LOWapp/Core/Modules/Contracts/StoresProjectModules.php32 public function getModuleOverridesForProjects(array $projectIds): array;CODE
LOWapp/Core/Console/Application.php52 protected function getDefaultInputDefinition(): InputDefinitionCODE
LOWapp/Core/Console/CliServiceProvider.php269 protected function registerCacheClearCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php281 protected function registerCacheForgetCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php293 protected function registerCacheTableCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php317 protected function registerChannelMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php329 protected function registerComponentMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php341 protected function registerConfigCacheCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php353 protected function registerConfigClearCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php365 protected function registerConsoleMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php377 protected function registerControllerMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php401 protected function registerExceptionMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php413 protected function registerFactoryMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php425 protected function registerEventClearCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php449 protected function registerListenerMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php473 protected function registerMiddlewareMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php497 protected function registerNotificationMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php509 protected function registerNotificationTableCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php521 protected function registerObserverMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php533 protected function registerPolicyMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php545 protected function registerProviderMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php557 protected function registerQueueForgetCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php567 protected function registerQueueListenCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php579 protected function registerQueueMonitorCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php591 protected function registerQueuePruneBatchesCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php603 protected function registerQueuePruneFailedJobsCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php615 protected function registerQueueRestartCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php639 protected function registerQueueFailedTableCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php651 protected function registerQueueTableCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php663 protected function registerQueueBatchesTableCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php675 protected function registerRequestMakeCommand()CODE
LOWapp/Core/Console/CliServiceProvider.php687 protected function registerResourceMakeCommand()CODE
231 more matches not shown…
Decorative Section Separators12 hits · 36 pts
SeverityFileLineSnippetContext
MEDIUM…WorkStructure/Repositories/WorkStructureRepository.php32 // ─── Structures ──────────────────────────────────────────────────COMMENT
MEDIUM…WorkStructure/Repositories/WorkStructureRepository.php114 // ─── Elements ────────────────────────────────────────────────────COMMENT
MEDIUM…WorkStructure/Repositories/WorkStructureRepository.php168 // ─── Relationships ───────────────────────────────────────────────COMMENT
MEDIUM…WorkStructure/Repositories/WorkStructureRepository.php203 // ─── Mappings ────────────────────────────────────────────────────COMMENT
MEDIUM…WorkStructure/Repositories/WorkStructureRepository.php272 // ─── Hydrators ───────────────────────────────────────────────────COMMENT
MEDIUMapp/Domain/Goalcanvas/Repositories/Goalcanvas.php409 // ─── Goal↔milestone edges (tracked_by on zp_entity_relationship) ──────COMMENT
MEDIUM…in/Resources/Services/ResourceStructureServiceTest.php308 // ─── Test doubles ────────────────────────────────────────────────COMMENT
MEDIUM…ts/Unit/app/Domain/Users/EditUserAuthorizationTest.php40 // ─── Attribute presence on every write surface ────────────────────COMMENT
MEDIUM…ts/Unit/app/Domain/Users/EditUserAuthorizationTest.php90 // ─── Default-grant hierarchy — who has users.edit ─────────────────COMMENT
MEDIUM…ts/Unit/app/Domain/Users/EditUserAuthorizationTest.php123 // ─── Helpers ──────────────────────────────────────────────────────COMMENT
MEDIUM…p/Domain/Goalcanvas/Services/GoalcanvasServiceTest.php870 // ─── Milestone rollup / mobile Progress (many-to-many) ────────────────COMMENT
MEDIUM…t/app/Domain/Reports/Services/CapacityAnalyzerTest.php259 // ─── Program rollup: supply is capacity, not booked hours ────────COMMENT
Over-Commented Block28 hits · 26 pts
SeverityFileLineSnippetContext
LOWbootstrap/app.php61return $app;COMMENT
LOWapp/Core/Auth/Permissions/DefaultRolePermissions.php61 ['scope' => 'project', 'keys' => ['comments.create']],COMMENT
LOWapp/Core/Controller/Frontcontroller.php281 $enabledPlugins = app()->make(\Leantime\Domain\Plugins\Services\Plugins::class)->getEnabledPlugins();COMMENT
LOWapp/Core/Http/HttpKernel.php161 }COMMENT
LOWapp/Core/Events/EventDispatcher.php441 // // Handle Laravel style eventsCOMMENT
LOWapp/Core/Events/EventDispatcher.php461 // }COMMENT
LOW…/Views/Templates/components/forms/text-input.blade.php1@props([COMMENT
LOWapp/Views/Templates/components/forms/select.blade.php1@props([COMMENT
LOWapp/Domain/Tickets/Services/Tickets.php2461 */COMMENT
LOWapp/Domain/Tickets/Services/Tickets.php5241COMMENT
LOWapp/Domain/Tickets/Services/Tickets.php5841 // if (! empty($ticket['milestoneid']) && $ticket['milestoneid'] == $milestoneId)COMMENT
LOWapp/Domain/Tickets/Services/Tickets.php6241 // this day on the user's calendar", no time, no TZ. Running itCOMMENT
LOWapp/Domain/Calendar/Js/calendarController.js481COMMENT
LOWapp/Domain/Calendar/Js/calendarController.js501 // enitityType: "ticket",COMMENT
LOWapp/Domain/Auth/Services/Auth.php641 {COMMENT
LOWapp/Domain/Projects/Services/Projects.php2741 return false;COMMENT
LOWapp/Domain/Oidc/Controllers/Mobile.php81 // so — unlike getToken, which lives in the plugin and is gated by absence —COMMENT
LOWapp/Domain/Wiki/Templates/templates.blade.php21COMMENT
LOWapp/Domain/Status/Controllers/Index.php101 'ssoProviders' => [],COMMENT
LOW…tes/partials/stakeholder/page-impact-journey.blade.php141 // ── STARTED bookend text.COMMENT
LOWapp/Domain/Reports/Services/CapacityAnalyzer.php261 // made the two halves of the report disagree: the headline tileCOMMENT
LOWpublic/assets/css/libs/jquery.alerts.css81#popup_container.alert-warning #popup_title { background-color: #FCB904; }COMMENT
LOWpublic/assets/css/libs/jquery.alerts.css101#popup_container.alert-inverse #popup_ok,COMMENT
LOWpublic/assets/js/libs/simpleGantt/snap.svg-min.js1// Snap.svg 0.4.0COMMENT
LOW.github/workflows/update-latest-tag.yml21 COMMENT
LOWhelm/Chart.yaml1apiVersion: v2COMMENT
LOWhelm/values.yaml21COMMENT
LOWhelm/values.yaml61 # -- S3 regionCOMMENT
Fake / Example Data23 hits · 25 pts
SeverityFileLineSnippetContext
LOW⚡accessibility-mockup.html785 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labCODE
LOW⚡accessibility-mockup.html785 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labCODE
LOW⚡accessibility-mockup.html794 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labCODE
LOW⚡accessibility-mockup.html794 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labCODE
LOWapp/Views/Templates/components/emojiinput.blade.php5 'placeholder' => '',CODE
LOWapp/Views/Templates/components/forms/tags.blade.php25 'placeholder' => null,CODE
LOWtests/Unit/app/Core/Support/AvatarcreatorTest.php67 $this->avatarCreator->setInitials('John Doe');CODE
LOWtests/Unit/app/Core/Support/AvatarcreatorTest.php100 $result = $this->avatarCreator->getAvatar('John Doe');CODE
LOWtests/Unit/app/Core/Support/AvatarcreatorTest.php112 $result = $this->avatarCreator->getAvatar('John Doe');CODE
LOW…nit/app/Domain/Tickets/Services/TicketsServiceTest.php374 'get' => fn () => ['id' => 5, 'name' => 'Acme Inc'],CODE
LOW…nit/app/Domain/Tickets/Services/TicketsServiceTest.php378 $this->assertEquals('Acme Inc', $service->getClientNameById(5));CODE
LOW…p/Domain/Tickets/Services/TicketHistoryServiceTest.php98 $this->assertSame('Jane Doe', $entries[0]->userName);CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php43 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php76 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php93 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php110 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php286 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Install/Services/InstallServiceTest.php302 'email' => 'admin@example.com',CODE
LOW…nit/app/Domain/Auth/Services/OnboardingServiceTest.php57 'Jane Doe',CODE
LOW…nit/app/Domain/Auth/Services/OnboardingServiceTest.php80 'Jane Doe',CODE
LOW…nit/app/Domain/Auth/Services/OnboardingServiceTest.php129 'Jane Doe',CODE
LOW…sts/Unit/app/Domain/Users/Services/BackgroundsTest.php181 'user' => ['name' => 'Jane Doe', 'links' => ['html' => 'https://unsplash.com/@jane']],CODE
LOW…sts/Unit/app/Domain/Users/Services/BackgroundsTest.php212 'photographerName' => 'Jane Doe',CODE
Structural Annotation Overuse12 hits · 24 pts
SeverityFileLineSnippetContext
LOW⚡app/Core/Support/String/AlphaNumeric.php24 // Step 2: Replace multiple spaces with a single spaceCOMMENT
LOW⚡app/Core/Support/String/AlphaNumeric.php28 // Step 3: Trim leading and trailing spacesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php24 // Step 1: Replace line breaks with spaceCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php27 // Step 2: Escape JSON special characters except newlinesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php34 // Step 3: Replace problematic characters with safe alternativesCOMMENT
LOWapp/Core/Support/String/SanitizeForLLM.php52 // Step 4: Remove any remaining potentially problematic charactersCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php75 // Step 5: Handle potential JSON serialization issuesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php81 // Step 6: Additional sanitization for special patternsCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php89 // Step 7: Remove consecutive spaces (which can occur after other replacements)COMMENT
LOW.claude/docs/google-calendar-plugin.md281### Step 1: Connect ControllerCOMMENT
LOW.claude/docs/google-calendar-plugin.md307### Step 2: Callback ControllerCOMMENT
LOW.claude/docs/google-calendar-plugin.md367### Step 3: GoogleAuth ServiceCOMMENT
Verbosity Indicators9 hits · 20 pts
SeverityFileLineSnippetContext
LOW⚡app/Core/Support/String/AlphaNumeric.php24 // Step 2: Replace multiple spaces with a single spaceCOMMENT
LOW⚡app/Core/Support/String/AlphaNumeric.php28 // Step 3: Trim leading and trailing spacesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php24 // Step 1: Replace line breaks with spaceCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php27 // Step 2: Escape JSON special characters except newlinesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php34 // Step 3: Replace problematic characters with safe alternativesCOMMENT
LOWapp/Core/Support/String/SanitizeForLLM.php52 // Step 4: Remove any remaining potentially problematic charactersCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php75 // Step 5: Handle potential JSON serialization issuesCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php81 // Step 6: Additional sanitization for special patternsCOMMENT
LOW⚡app/Core/Support/String/SanitizeForLLM.php89 // Step 7: Remove consecutive spaces (which can occur after other replacements)COMMENT
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICALpublic/assets/js/app/core/tiptap/extensions/columns.js31 nodes = [props.editor.schema.nodes.paragraph.create()];CODE
Slop Phrases5 hits · 8 pts
SeverityFileLineSnippetContext
MEDIUMapp/Language/en-GB.ini4002text.onboarding_default_project_details="Welcome to your first project in Leantime!<br />This is your space to organize CODE
MEDIUMapp/Language/en-US.ini4194text.onboarding_default_project_details = "Welcome to your first project in Leantime!<br />This is your space to organizCODE
LOW⚡public/assets/js/libs/uppy/uppy.js7Uppy plugins must have unique \`id\` options. See https://uppy.io/docs/plugins/#id.`;throw new Error(a)}return e.VERSIONCODE
LOW⚡public/assets/js/libs/uppy/uppy.js16 `,t={width:this.opts.width,height:this.opts.height};return u("button",{type:"button",className:e,style:t,onClick:()=CODE
LOW⚡public/assets/js/libs/uppy/uppy.js18See https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`)}n(hS,"validateParameters");CODE
Modern AI Meta-Vocabulary1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUMapp/Core/Middleware/RequestRateLimiter.php130 // MCP endpoint gets its own (higher) budget: agentic LLM clients legitimately burstCOMMENT
AI Slop Vocabulary1 hit · 2 pts
SeverityFileLineSnippetContext
MEDIUMpackage-lock.json14062 "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",CODE