AI Slop Code RIsk Monitor

jsvine/pdfplumber

Plumb a PDF for detailed information about each char, rectangle, line, et cetera — and easily extract text and tables.

9.8 Moderate pattern signal View on GitHub

Maintenance and Governance Review

This report summarizes scanner evidence for jsvine/pdfplumber, a Python project with 10,803 GitHub stars. SynthScan examined 10,104 lines of code across 55 source files, recording 106 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 9.8 (Moderate 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.

9.8
Adjusted Signal
9.8
Raw Pattern Score
100%
Time Factor
2026-08-06
Last Push
10.8K
Stars
Python
Language
10.1K
Lines of Code
55
Files
106
Pattern Hits
2026-10-12
Scan Date
0.00
HC Hit Rate

Risk Review · v3

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

Cognitive Ownership Risk 21.1/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 18.6/100 · LOW

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

Agent Over-Engineering Ratio 16.1/100 · LOW

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

PR Review Velocity Impact 40.8/100 · MEDIUM

Which changes need focused human review? 106 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 106

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 106 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.

Unused Imports51 hits · 42 pts
SeverityFileLineSnippetContext
LOWpdfplumber/__init__.py10CODE
LOWpdfplumber/__init__.py11CODE
LOWpdfplumber/__init__.py13CODE
LOWpdfplumber/__init__.py14CODE
LOWpdfplumber/__init__.py16CODE
LOWpdfplumber/page.py79CODE
LOWpdfplumber/display.py15CODE
LOWpdfplumber/display.py17CODE
LOWpdfplumber/structure.py32CODE
LOWpdfplumber/structure.py33CODE
LOWpdfplumber/table.py18CODE
LOWpdfplumber/utils/generic.py7CODE
LOWpdfplumber/utils/__init__.py1CODE
LOWpdfplumber/utils/__init__.py1CODE
LOWpdfplumber/utils/__init__.py1CODE
LOWpdfplumber/utils/__init__.py2CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py3CODE
LOWpdfplumber/utils/__init__.py25CODE
LOWpdfplumber/utils/__init__.py25CODE
LOWpdfplumber/utils/__init__.py25CODE
LOWpdfplumber/utils/__init__.py25CODE
LOWpdfplumber/utils/__init__.py25CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
LOWpdfplumber/utils/__init__.py32CODE
Hyper-Verbose Identifiers20 hits · 22 pts
SeverityFileLineSnippetContext
LOWtests/test_structure.py860 def test_structure_tree_class(self):CODE
LOWtests/test_utils.py102 def test_extract_words_return_chars(self):CODE
LOWtests/test_utils.py147 def test_text_rotation_layout(self):CODE
LOWtests/test_utils.py184 def test_text_render_directions(self):CODE
LOWtests/test_utils.py243 def test_extract_words_punctuation(self):CODE
LOWtests/test_utils.py290 def test_extract_text_punctuation(self):CODE
LOWtests/test_utils.py323 def test_text_flow_overlapping(self):CODE
LOWtests/test_utils.py339 def test_text_flow_words_mixed_lines(self):CODE
LOWtests/test_utils.py400 def test_extract_text_layout_cropped(self):CODE
LOW⚡tests/test_utils.py411 def test_extract_text_layout_widths(self):CODE
LOW⚡tests/test_utils.py420 def test_extract_text_nochars(self):CODE
LOW⚡tests/test_utils.py425 def test_search_regex_compiled(self):CODE
LOWtests/test_utils.py440 def test_search_regex_uncompiled(self):CODE
LOWtests/test_utils.py497 def test_handle_empty_and_whitespace_search_results(self):CODE
LOWtests/test_basics.py195 def test_unicode_normalization(self):CODE
LOWtests/test_basics.py216 def test_load_with_custom_laparams(self):CODE
LOWtests/test_table.py30 def test_table_settings_errors(self):CODE
LOWtests/test_table.py102 def test_explicit_desc_decimalization(self):CODE
LOWtests/test_display.py64 def test_bytes_stream_to_image(self):CODE
LOWtests/test_convert.py170 def test_additional_attr_types(self):CODE
Deep Nesting18 hits · 18 pts
SeverityFileLineSnippetContext
LOWpdfplumber/convert.py33CODE
LOWpdfplumber/page.py273CODE
LOWpdfplumber/page.py282CODE
LOWpdfplumber/cli.py95CODE
LOWpdfplumber/structure.py351CODE
LOWpdfplumber/structure.py419CODE
LOWpdfplumber/structure.py466CODE
LOWpdfplumber/structure.py391CODE
LOWpdfplumber/table.py207CODE
LOWpdfplumber/table.py297CODE
LOWpdfplumber/table.py421CODE
LOWpdfplumber/table.py558CODE
LOWpdfplumber/table.py602CODE
LOWpdfplumber/utils/text.py241CODE
LOWpdfplumber/utils/text.py593CODE
LOWpdfplumber/utils/geometry.py163CODE
LOWpdfplumber/utils/pdfinternals.py24CODE
LOWtests/test_dedupe_chars.py85CODE
Excessive Try-Catch Wrapping6 hits · 6 pts
SeverityFileLineSnippetContext
LOWpdfplumber/page.py267 except Exception as e:CODE
LOWpdfplumber/pdf.py51 except Exception as e:CODE
LOWpdfplumber/pdf.py61 except Exception as e: # pragma: nocoverCODE
LOWpdfplumber/pdf.py160 except Exception as e: # pragma: nocoverCODE
LOWtests/test_oss_fuzz.py26 except Exception as e:CODE
LOWtests/test_oss_fuzz.py38 except Exception as e:CODE
AI Slop Vocabulary3 hits · 4 pts
SeverityFileLineSnippetContext
LOWpdfplumber/convert.py90 # Otherwise, just use the string-representationCOMMENT
LOWpdfplumber/page.py137 # Even if pdfminer.six's API would just return the objects itCOMMENT
LOWpdfplumber/display.py191 # Otherwise, just use ((x0, top), (x1, bottom))COMMENT
Modern Structural Boilerplate4 hits · 4 pts
SeverityFileLineSnippetContext
LOWpdfplumber/__init__.py1__all__ = [CODE
LOWpdfplumber/pdf.py22logger = logging.getLogger(__name__)CODE
LOWpdfplumber/structure.py28logger = logging.getLogger(__name__)CODE
LOWpdfplumber/utils/text.py25logger = logging.getLogger(__name__)CODE
AI Structural Patterns4 hits · 4 pts
SeverityFileLineSnippetContext
LOWpdfplumber/pdf.py28CODE
LOWpdfplumber/pdf.py73CODE
LOWpdfplumber/utils/text.py241CODE
LOWpdfplumber/utils/text.py424CODE