AI Slop Code RIsk Monitor

andreafrancia/trash-cli

Command line interface to the freedesktop.org trashcan.

47.4 High pattern signal View on GitHub

Maintenance and Governance Review

This report summarizes scanner evidence for andreafrancia/trash-cli, a Python project with 4,601 GitHub stars. SynthScan examined 19,900 lines of code across 568 source files, recording 825 pattern matches distributed across 6 syntactic categories. The legacy adjusted pattern signal is 47.4 (High 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.

47.4
Adjusted Signal
47.4
Raw Pattern Score
100%
Time Factor
2026-10-03
Last Push
4.6K
Stars
Python
Language
19.9K
Lines of Code
568
Files
825
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 76.4/100 · CRITICAL

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

Hallucinated Dependency & Supply Chain Risk 59.4/100 · HIGH

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

Agent Over-Engineering Ratio 76.4/100 · CRITICAL

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

PR Review Velocity Impact 87.6/100 · CRITICAL

Which changes need focused human review? 825 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 1MEDIUM 1LOW 823

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 825 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 Identifiers450 hits · 562 pts
SeverityFileLineSnippetContext
LOWtests/test_empty/cmd/test_empty_cmd_fs_fake.py40 def test_trash_empty_will_skip_unreadable_dir(self):CODE
LOWtests/test_empty/cmd/test_empty_cmd_fs_real.py42 def test_trash_empty_will_skip_unreadable_dir(self):CODE
LOW…ty/cmd/test_empty_cmd_with_multiple_volumes_fs_real.py58 def test_it_removes_trashinfo_from_specified_trash_dir(self):CODE
LOW…ty/cmd/test_empty_cmd_with_multiple_volumes_fs_fake.py57 def test_it_removes_trashinfo_from_specified_trash_dir(self):CODE
LOW…mpty/components/test_empty_end_to_end_with_argument.py50 def test_it_should_kept_files_with_invalid_deletion_date(self):CODE
LOWtests/test_empty/components/test_guard.py28 def test_it_just_calls_the_emptier(self):CODE
LOWtests/test_empty/components/test_empty_end_to_end.py77 def test_on_trash_date_not_parsable(self):STRING
LOW⚡tests/test_empty/components/test_make_parser.py16 def test_non_interactive_default_is_non_interactive(self):CODE
LOW⚡tests/test_empty/components/test_make_parser.py22 def test_interactive_default_is_interactive(self):CODE
LOW⚡tests/test_empty/components/test_make_parser.py28 def test_interactive_made_non_interactive(self):CODE
LOW…ts/test_empty/components/test_existing_file_remover.py9 def test_remove_file_if_exists_fails_when_file_does_not_exists(self):CODE
LOW…pty/components/test_empty_end_to_end_with_trash_dir.py46 def test_non_trash_info_is_not_deleted(self):CODE
LOWtests/test_empty/components/test_clock.py27 def test_return_true_now_whe_fake_time_is_invalid(self):CODE
LOW…ools/test_make_scripts/test_list_of_created_scripts.py11 def test_is_empty_on_start_up(self):CODE
LOW…ools/test_make_scripts/test_list_of_created_scripts.py14 def test_collect_added_script(self):CODE
LOW⚡…s/test_dev_tools/test_make_scripts/test_make_script.py28 def test_should_set_executable_permission(self):CODE
LOW⚡…s/test_dev_tools/test_make_scripts/test_make_script.py31 def test_should_write_the_script(self):CODE
LOW⚡…s/test_dev_tools/test_make_scripts/test_make_script.py35 def test_the_script_should_call_the_right_function_from_the_right_module(self):CODE
LOWtests/test_dev_tools/cmds/test_bump_cmd.py39 def test_when_clean_and_dry_run(self):CODE
LOWtests/test_dev_tools/cmds/test_set_dev_version_cmd.py41 def test_ref_with_hyphens_is_sanitized(self, capsys):CODE
LOW⚡…ts/test_dev_tools/components/test_version_from_date.py17 def test_replaces_hyphens_with_dots(self):CODE
LOW⚡…ts/test_dev_tools/components/test_version_from_date.py21 def test_collapses_consecutive_separators_into_one_dot(self):CODE
LOW⚡…ts/test_dev_tools/components/test_version_from_date.py26 def test_sanitizes_hyphens_in_ref(self):CODE
LOW…test_fs/test_what_python_raise_on_non_existent_file.py11 def test_reading_an_existing_file(self):CODE
LOWtests/test_list/cmd/test_version.py9 def test_should_output_the_version(self, user):CODE
LOWtests/test_list/cmd/test_debug_volumes.py7 def test_prints_physical_and_virtual_partitions_and_df_output(self, user):CODE
LOWtests/test_list/cmd/test_debug_volumes.py25 def test_when_there_are_no_partitions(self, user):CODE
LOWtests/test_list/cmd/test_list_trash_dirs.py13 def test_lists_the_home_trash_dir(self, user):CODE
LOWtests/test_list/cmd/test_list_trash_dirs.py18 def test_lists_the_trash_dirs_of_a_volume(self, user):CODE
LOW⚡tests/test_list/cmd/test_list_trash_dirs.py30 def test_does_not_list_the_trash_dirs_that_does_not_exist(self, user):CODE
LOW⚡tests/test_list/cmd/test_list_trash_dirs.py38 def test_reports_when_the_parent_is_not_sticky(self, user):CODE
LOW⚡tests/test_list/cmd/test_list_trash_dirs.py48 def test_reports_when_the_parent_is_a_symlink_to_a_sticky_dir(self, user):CODE
LOWtests/test_list/cmd/test_list_trash_dirs.py59 def test_lists_only_the_trash_dirs_specified_by_the_user(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py9 def test_should_output_nothing_when_trashcan_is_empty(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py14 def test_should_output_deletion_date_and_path(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py22 def test_should_output_info_for_multiple_files(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py33 def test_should_output_unknown_dates_with_question_marks(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py40 def test_should_output_invalid_dates_using_question_marks(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py49 def test_should_warn_about_empty_trashinfos(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py58 def test_should_warn_about_unreadable_trashinfo(self, user):CODE
LOW⚡tests/test_list/cmd/test_trash_list.py68 def test_should_warn_about_unexistent_path_entry(self, user):CODE
LOW⚡tests/test_list/cmd/test_with_a_top_trash_dir.py15 def test_should_list_its_contents_if_parent_is_sticky(self, user):CODE
LOW⚡tests/test_list/cmd/test_with_a_top_trash_dir.py23 def test_and_should_warn_if_parent_is_not_sticky(self, user):CODE
LOW⚡tests/test_list/cmd/test_with_a_top_trash_dir.py32 def test_but_it_should_not_warn_when_the_parent_is_unsticky_but_there_is_no_trashdir(CODE
LOW⚡tests/test_list/cmd/test_with_a_top_trash_dir.py41 def test_should_ignore_trash_from_a_unsticky_topdir(self, user):CODE
LOW⚡tests/test_list/cmd/test_with_a_top_trash_dir.py50 def test_it_should_skip_a_symlink(self, user):CODE
LOW…st_list/cmd/test_trash_list_sanitizes_control_chars.py16def test_on_a_terminal_the_name_is_shell_escaped(trash_list_user):CODE
LOW…st_list/cmd/test_trash_list_sanitizes_control_chars.py29def test_when_piped_the_name_is_printed_raw(trash_list_user):CODE
LOW…s/test_list/components/test_deletion_date_extractor.py11 def test_extract_attribute_default(self):CODE
LOW…s/test_list/components/test_deletion_date_extractor.py15 def test_extract_attribute_value(self):CODE
LOWtests/test_list/components/test_trash_list_parser.py18 def test_trash_dir_not_specified(self):CODE
LOWtests/test_rm/cmd/test_trash_rm.py33 def test_without_pattern_argument(self):CODE
LOWtests/test_rm/components/test_file_remover.py14 def test_remove_file_fails_when_file_does_not_exists(self):CODE
LOWtests/test_rm/components/test_filter.py20 def test_example_with_star_dot_o(self):CODE
LOW…s/test_put/cmd/test_put_undeletable_file_is_refused.py17 def test_a_file_that_cannot_be_deleted_is_not_trashed_or_copied(self):CODE
LOW⚡tests/test_put/cmd/test_put_option_shaped_filename.py15 def test_it_refuses_an_existing_file_that_looks_like_an_option(self):CODE
LOW⚡tests/test_put/cmd/test_put_option_shaped_filename.py23 def test_the_double_dash_separator_still_lets_you_trash_such_a_file(self):CODE
LOW⚡tests/test_put/cmd/test_put_option_shaped_filename.py32 def test_a_real_option_is_unaffected_when_no_such_file_exists(self):CODE
LOW⚡tests/test_put/cmd/test_put.py31 def test_when_needs_a_different_suffix(self):CODE
LOW⚡tests/test_put/cmd/test_put.py39 def test_when_needs_a_random_suffix(self):CODE
390 more matches not shown…
Unused Imports359 hits · 359 pts
SeverityFileLineSnippetContext
LOWtests/test_empty/components/test_make_parser.py2CODE
LOWtests/test_dev_tools/support/run_set_dev_version.py6CODE
LOWtests/test_list/cmd/support/trash_list_user.py13CODE
LOWtests/test_put/cmd/test_put.py1CODE
LOWtests/test_put/cmd/test_put.py2CODE
LOWtests/test_put/cmd/test_put.py13CODE
LOWtests/test_put/cmd/e2e/test_on_symbolic_links.py6CODE
LOWtests/test_put/cmd/e2e/test_on_symbolic_links.py9CODE
LOWtests/test_put/cmd/e2e/run_trash_put/put_result.py3CODE
LOW…sts/test_put/cmd/e2e/run_trash_put/directory_layout.py1CODE
LOW…sts/test_put/cmd/e2e/run_trash_put/directory_layout.py3CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py1CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py2CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py5CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py6CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py8CODE
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py9CODE
LOWtests/test_put/components/test_move_file.py3CODE
LOW…ts/test_put/components/test_restore_fs_like_real_fs.py6CODE
LOWtests/test_put/support/result.py1CODE
LOWtests/test_put/support/result.py2CODE
LOWtests/test_put/support/result.py4CODE
LOWtests/test_put/support/result.py5CODE
LOWtests/test_put/support/logs.py5CODE
LOWtests/test_put/support/recording_backend.py1CODE
LOWtests/test_put/support/recording_backend.py3CODE
LOWtests/test_put/support/recording_backend.py7CODE
LOWtests/test_put/support/recording_backend.py8CODE
LOW…i_lib/test_invalid_utf8_path/test_format_trash_info.py6CODE
LOWtests/support/make_scripts.py3CODE
LOWtests/support/py2mock.py5CODE
LOWtests/support/py2mock.py5CODE
LOWtests/support/py2mock.py5CODE
LOWtests/support/py2mock.py5CODE
LOWtests/support/py2mock.py7CODE
LOWtests/support/py2mock.py7CODE
LOWtests/support/py2mock.py7CODE
LOWtests/support/py2mock.py7CODE
LOWtests/support/cmd/capture_exit_code2.py1CODE
LOWtests/support/cmd/capture_exit_code2.py1CODE
LOWtests/support/tools/version_from_date.py1CODE
LOWtests/support/tools/set_dev_version.py1CODE
LOWtests/support/tools/bump_main.py1CODE
LOWtests/support/put/fake_random.py1CODE
LOWtests/support/put/fake_fs/inode.py3CODE
LOWtests/support/put/fake_fs/directory.py2CODE
LOWtests/support/put/fake_fs/directory.py3CODE
LOWtests/support/put/fake_fs/fake_fs.py3CODE
LOWtests/support/put/fake_fs/fake_fs.py8CODE
LOWtests/support/put/fake_fs/fake_fs.py10CODE
LOWtests/support/fakes/fake_is_mount.py2CODE
LOWtests/support/fakes/fake_volume_of.py1CODE
LOWtests/support/fakes/fake_disk_partitions_fs.py1CODE
LOWtests/support/fakes/fake_disk_partitions_fs.py1CODE
LOWtests/support/fakes/fake_trash_dir.py4CODE
LOWtests/support/fakes/fake_trash_dir.py4CODE
LOWtests/support/fakes/fake_trash_dir.py7CODE
LOWtests/support/trash_dirs/given_trash.py3CODE
LOWtests/support/trash_dirs/given_trash.py5CODE
LOWtests/support/dirs/my_path.py3CODE
299 more matches not shown…
Deep Nesting9 hits · 9 pts
SeverityFileLineSnippetContext
LOWtrashcli/trash_dirs_scanner.py86CODE
LOWtrashcli/put/describer.py8CODE
LOWtrashcli/put/janitor_tools/info_file_persister.py77CODE
LOWtrashcli/list/list_trash_action.py98CODE
LOWtrashcli/list/minor_actions/list_trash_dirs.py26CODE
LOWtrashcli/restore/trashed_files.py29CODE
LOWtrashcli/restore/trashed_files.py46CODE
LOWtrashcli/restore/real_output.py30CODE
LOWtrashcli/rm/rm_cmd.py39CODE
Empty Error Handlers1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHtrashcli/restore/info_files.py23except OSError: # when directory does not existCODE
Excessive Try-Catch Wrapping3 hits · 4 pts
SeverityFileLineSnippetContext
LOWtests/support/capture_error.py4 except Exception as e:CODE
MEDIUMtests/support/capture_error.py1def capture_error(callable):CODE
LOWtrashcli/lib/sanitize.py51 except Exception:CODE
AI Structural Patterns3 hits · 3 pts
SeverityFileLineSnippetContext
LOWtests/test_put/cmd/e2e/run_trash_put/__init__.py55CODE
LOWtests/support/put/fake_fs/failing_fake_fs.py39CODE
LOWtrashcli/lib/printable.py9CODE