AI Slop Code Risk Monitor

binwiederhier/ntfy

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

Send push notifications to your phone or desktop using PUT/POST

0.9 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for binwiederhier/ntfy, a Go project with 35,194 GitHub stars. SynthScan examined 179,483 lines of code across 497 source files, recording 144 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 0.9 (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.9
Adjusted Signal
0.9
Raw Pattern Score
100%
Time Factor
2026-10-31
Last Push
35.2K
Stars
Go
Language
179.5K
Lines of Code
497
Files
144
Pattern Hits
2026-10-31
Scan Date
0.01
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.2/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.3/100 · LOW

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

Agent Over-Engineering Ratio 0.0/100 · LOW

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

PR Review Velocity Impact 4.5/100 · LOW

Which changes need focused human review? 144 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 2MEDIUM 1LOW 140

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

Over-Commented Block129 hits · 124 pts
SeverityFileLineSnippetContext
LOWcluster/cluster_mesh.go61COMMENT
LOWcluster/types.go41// prevention). Access changes do not need this, since peers reload their access cache and endCOMMENT
LOWcluster/cluster.go21const (COMMENT
LOWcluster/cluster.go101// Local delivery to a node's own subscribers still happens inline in the server; the clusterCOMMENT
LOWcluster/cluster.go121 // enough (within NodeTTL) that peers still forward messages to it. Health checkers mustCOMMENT
LOWcluster/registry/registry.go41 RolePassive Role = "passive"COMMENT
LOWcluster/registry/registry.go201}COMMENT
LOWcluster/registry/registry.go221// that cannot reach the database stops believing within the lease, and it stops before anyCOMMENT
LOWcluster/registry/registry_test.go241 require.Len(t, r1.Peers(), 1) // Snapshot replacedCOMMENT
LOWs3/client.go21const (COMMENT
LOWs3/client.go41// },COMMENT
LOWs3/client.go81// single PUT request without buffering. The read is limited to untrustedLength bytes;COMMENT
LOWtools/loadtest/main.go1// Load test program for ntfy staging server.COMMENT
LOWtools/s3cli/main.go1// Command s3cli is a minimal CLI for testing the s3 package. It supports put, get, rm, and ls.COMMENT
LOWutil/linger_queue.go1package utilCOMMENT
LOWutil/lookup_cache.go1package utilCOMMENT
LOWutil/batching_queue.go1package utilCOMMENT
LOWutil/sprig/defaults.go21func defaultValue(d any, given ...any) any {COMMENT
LOWutil/sprig/defaults.go121// This function ignores any errors that occur during decoding.COMMENT
LOWutil/sprig/defaults.go141// - any: The decoded valueCOMMENT
LOWutil/sprig/defaults.go181// This function ignores any errors that occur during encoding.COMMENT
LOWutil/sprig/defaults.go201// - string: The indented JSON string representation of the valueCOMMENT
LOWutil/sprig/defaults.go241 enc.SetEscapeHTML(false)COMMENT
LOWutil/sprig/numeric.go61// Returns:COMMENT
LOWutil/sprig/numeric.go121// add sums all the provided values.COMMENT
LOWutil/sprig/numeric.go141// - a: The value to subtract fromCOMMENT
LOWutil/sprig/numeric.go161// Panics:COMMENT
LOWutil/sprig/numeric.go201//COMMENT
LOWutil/sprig/numeric.go241//COMMENT
LOWutil/sprig/numeric.go301 }COMMENT
LOWutil/sprig/numeric.go361// ceil returns the least integer value greater than or equal to the input.COMMENT
LOWutil/sprig/numeric.go421}COMMENT
LOWutil/sprig/reflect.go21// typeIsLike returns true if the src is the type named in target or a pointer to that type.COMMENT
LOWutil/sprig/reflect.go41// Returns:COMMENT
LOWutil/sprig/reflect.go61// The kind represents the specific Go type category (e.g., "string", "int", "map", "slice").COMMENT
LOWutil/sprig/regex.go21// mustRegexMatch checks if a string matches a regular expression pattern.COMMENT
LOWutil/sprig/regex.go41// - n: The maximum number of matches to return (negative means all matches)COMMENT
LOWutil/sprig/regex.go101// regexReplaceAll replaces all matches of a regular expression with a replacement string.COMMENT
LOWutil/sprig/regex.go121// Parameters:COMMENT
LOWutil/sprig/regex.go141// Parameters:COMMENT
LOWutil/sprig/regex.go161//COMMENT
LOWutil/sprig/regex.go181// Returns:COMMENT
LOWutil/sprig/strings.go41// base32encode encodes a string to base32 using standard encoding.COMMENT
LOWutil/sprig/strings.go101 return strings.Join(out, " ")COMMENT
LOWutil/sprig/strings.go121// Parameters:COMMENT
LOWutil/sprig/strings.go141// Parameters:COMMENT
LOWutil/sprig/strings.go181// strslice converts a value to a slice of strings.COMMENT
LOWutil/sprig/strings.go241 newSlice = append(newSlice, i)COMMENT
LOWutil/sprig/strings.go301//COMMENT
LOWutil/sprig/strings.go321// split splits a string by a separator and returns a map.COMMENT
LOWutil/sprig/strings.go341//COMMENT
LOWutil/sprig/strings.go361// Returns:COMMENT
LOWutil/sprig/strings.go401// - count: The number of times to repeat the stringCOMMENT
LOWutil/sprig/strings.go421//COMMENT
LOWutil/sprig/strings.go441// - string: The string with the prefix removed, or the original string if it doesn't start with the prefixCOMMENT
LOWutil/sprig/strings.go461//COMMENT
LOWutil/sprig/strings.go481 return strings.HasPrefix(str, substr)COMMENT
LOWutil/sprig/date.go21COMMENT
LOWutil/sprig/date.go41// If the timezone is invalid, UTC is used.COMMENT
LOWutil/sprig/date.go81COMMENT
69 more matches not shown…
Synthetic Comment Markers2 hits · 12 pts
SeverityFileLineSnippetContext
HIGHdocs/releases.md559if things are working (or not working). There is a [one-off migration tool](https://github.com/binwiederhier/ntfy/tree/mCODE
HIGHdocs/static/js/config-generator.js5// This code is entirely AI generated, but this very comment is not. Phil wrote this. Hi!COMMENT
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICALweb/public/sw.js316 const action = event.notification.data.message.actions.find(({ label }) => event.action === label);CODE
Structural Annotation Overuse5 hits · 9 pts
SeverityFileLineSnippetContext
LOW⚡s3/client_multipart.go99 // Step 1: Initiate multipart uploadCOMMENT
LOW⚡s3/client_multipart.go105 // Step 2: Upload partsCOMMENT
LOWs3/client_multipart.go131 // Step 3: Complete multipart uploadCOMMENT
LOWdocs/index.md5## Step 1: Get the appCOMMENT
LOWdocs/index.md24## Step 2: Send a messageCOMMENT
Verbosity Indicators3 hits · 6 pts
SeverityFileLineSnippetContext
LOW⚡s3/client_multipart.go99 // Step 1: Initiate multipart uploadCOMMENT
LOW⚡s3/client_multipart.go105 // Step 2: Upload partsCOMMENT
LOWs3/client_multipart.go131 // Step 3: Complete multipart uploadCOMMENT
Slop Phrases2 hits · 4 pts
SeverityFileLineSnippetContext
MEDIUMtemplate/gotext/doc.go463constant. Here is a simple example:CODE
LOWserver/server.go96 // If changed, don't forget to update Android App and auth_sqlite.goCOMMENT
Fake / Example Data2 hits · 2 pts
SeverityFileLineSnippetContext
LOWdocs/config.md325<input type="text" data-key="web-push-email-address" placeholder="admin@example.com">CODE
LOWdocs/static/js/config-generator.js858 prefill(modal, "web-push-email-address", "admin@example.com");CODE