The SQL IDE for Your Terminal.
This report presents the forensic synthetic code analysis of tconbeer/harlequin, a Python project with 6,315 GitHub stars. SynthScan v2.0 examined 22,224 lines of code across 143 source files, recording 312 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 14.7 places this repository in the Low AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 312 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. 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 diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 1 | CODE | |
| LOW | tests/unit_tests/test_statements.py | 8 | CODE | |
| LOW | tests/unit_tests/conftest.py | 1 | CODE | |
| LOW | tests/unit_tests/test_plugins.py | 1 | CODE | |
| LOW | tests/unit_tests/test_import_hygiene.py | 9 | CODE | |
| LOW | tests/unit_tests/test_s3_tree.py | 1 | CODE | |
| LOW | tests/unit_tests/test_exception.py | 1 | CODE | |
| LOW | tests/unit_tests/test_config.py | 1 | CODE | |
| LOW | tests/unit_tests/test_query.py | 1 | CODE | |
| LOW | tests/functional_tests/test_keys_app.py | 1 | CODE | |
| LOW | tests/functional_tests/test_results_viewer.py | 1 | CODE | |
| LOW | tests/functional_tests/test_keymap_vscode.py | 1 | CODE | |
| LOW | tests/functional_tests/test_run_query_bar.py | 1 | CODE | |
| LOW | tests/functional_tests/test_query_editor.py | 1 | CODE | |
| LOW | tests/functional_tests/test_history_screen.py | 1 | CODE | |
| LOW | tests/functional_tests/test_app.py | 1 | CODE | |
| LOW | tests/functional_tests/test_keymap_from_config.py | 1 | CODE | |
| LOW | tests/adapter_tests/test_duckdb.py | 1 | CODE | |
| LOW | tests/adapter_tests/test_sqlite.py | 1 | CODE | |
| LOW | scripts/catalog_lag.py | 14 | CODE | |
| LOW | scripts/cold_start.py | 18 | CODE | |
| LOW | src/harlequin_sqlite/catalog.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/catalog.py | 17 | CODE | |
| LOW | src/harlequin_sqlite/adapter.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/__init__.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/__init__.py | 2 | CODE | |
| LOW | src/harlequin_sqlite/completions.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/cli_options.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/interactions.py | 1 | CODE | |
| LOW | src/harlequin_sqlite/interactions.py | 6 | CODE | |
| LOW | src/harlequin_sqlite/interactions.py | 10 | CODE | |
| LOW | src/harlequin_sqlite/interactions.py | 11 | CODE | |
| LOW | src/harlequin_sqlite/interactions.py | 11 | CODE | |
| LOW | src/harlequin/catalog.py | 1 | CODE | |
| LOW | src/harlequin/catalog.py | 7 | CODE | |
| LOW | src/harlequin/catalog.py | 8 | CODE | |
| LOW | src/harlequin/keys_app.py | 1 | CODE | |
| LOW | src/harlequin/options.py | 1 | CODE | |
| LOW | src/harlequin/plugins.py | 1 | CODE | |
| LOW | src/harlequin/catalog_cache.py | 1 | CODE | |
| LOW | src/harlequin/config.py | 1 | CODE | |
| LOW | src/harlequin/query.py | 15 | CODE | |
| LOW | src/harlequin/config_wizard.py | 1 | CODE | |
| LOW | src/harlequin/adapter.py | 1 | CODE | |
| LOW | src/harlequin/copy_formats.py | 1 | CODE | |
| LOW | src/harlequin/cache.py | 7 | CODE | |
| LOW | src/harlequin/cache.py | 7 | CODE | |
| LOW | src/harlequin/actions.py | 1 | CODE | |
| LOW | src/harlequin/__init__.py | 15 | CODE | |
| LOW | src/harlequin/__init__.py | 15 | CODE | |
| LOW | src/harlequin/__init__.py | 15 | CODE | |
| LOW | src/harlequin/__init__.py | 20 | CODE | |
| LOW | src/harlequin/__init__.py | 21 | CODE | |
| LOW | src/harlequin/__init__.py | 22 | CODE | |
| LOW | src/harlequin/__init__.py | 22 | CODE | |
| LOW | src/harlequin/__init__.py | 23 | CODE | |
| LOW | src/harlequin/__init__.py | 24 | CODE | |
| LOW | src/harlequin/__init__.py | 24 | CODE | |
| LOW | src/harlequin/__init__.py | 25 | CODE | |
| LOW | src/harlequin/copy_widgets.py | 1 | CODE | |
| 70 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 165 | def app_all_adapters_small_db( | CODE |
| LOW | tests/conftest.py | 186 | def _create_sqlite_db_from_data_dir(data_dir: Path, db_path: Path) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 22 | def test_completer_fixed_first(iris_completer: WordCompleter) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 27 | def test_completer_fuzzy_match(iris_completer: WordCompleter) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 54 | def test_extend_catalog_merges_by_default(parent_item: CatalogItem) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 60 | def test_extend_catalog_defer_merge(parent_item: CatalogItem) -> None: | CODE |
| LOW | tests/unit_tests/test_statements.py | 119 | def test_find_separators_agrees_with_split(script: str, expected: list[str]) -> None: | CODE |
| LOW | tests/unit_tests/test_statements.py | 141 | def test_find_separators_returns_character_columns() -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_statements.py | 152 | def test_find_separators_on_multiple_lines() -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_statements.py | 157 | def test_find_separators_are_sorted() -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_statements.py | 165 | def test_statements_are_indexed_in_order() -> None: | CODE |
| LOW | tests/unit_tests/test_statements.py | 178 | def test_dollar_quoted_body_is_not_split() -> None: | CODE |
| LOW | tests/unit_tests/test_plugins.py | 22 | def test_do_not_load_keymaps_that_duplicate_plugin_names() -> None: | CODE |
| LOW | tests/unit_tests/test_plugins.py | 29 | def test_plugin_load_failure_goes_to_stderr( | CODE |
| LOW | tests/unit_tests/test_import_hygiene.py | 40 | def test_headless_imports_do_not_load_the_tui( | CODE |
| LOW | tests/unit_tests/test_import_hygiene.py | 52 | def test_public_names_still_resolve() -> None: | CODE |
| LOW | tests/unit_tests/test_import_hygiene.py | 93 | def test_unknown_attribute_still_raises_attribute_error() -> None: | CODE |
| LOW | tests/unit_tests/test_exception.py | 7 | def test_pretty_print_warning_goes_to_stderr( | CODE |
| LOW | tests/unit_tests/test_config.py | 64 | def test_load_bad_keymap_raises( | CODE |
| LOW | tests/unit_tests/test_config.py | 90 | def test_load_default_profile(data_dir: Path, filename: str) -> None: | CODE |
| LOW | tests/unit_tests/test_config.py | 126 | def test_config_file_discovery( | CODE |
| LOW⚡ | tests/unit_tests/test_query.py | 24 | def test_unlimited_asks_for_everything(self) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_query.py | 28 | def test_plain_limit_asks_for_exactly_that_many(self) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_query.py | 31 | def test_overflow_detection_asks_for_one_more(self) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_query.py | 37 | def test_yields_one_result_per_statement( | CODE |
| LOW⚡ | tests/unit_tests/test_query.py | 45 | def test_ddl_yields_no_cursor(self, connection: HarlequinConnection) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 61 | def test_stops_at_the_first_error_by_default( | CODE |
| LOW | tests/unit_tests/test_query.py | 71 | def test_continues_past_an_error_when_asked( | CODE |
| LOW | tests/unit_tests/test_query.py | 82 | def test_applies_the_fetch_limit(self, connection: HarlequinConnection) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 90 | def test_overflow_detection_fetches_one_extra_row( | CODE |
| LOW | tests/unit_tests/test_query.py | 103 | def test_returns_columns_and_rows(self, connection: HarlequinConnection) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 113 | def test_a_query_that_matches_nothing_returns_zero_rows( | CODE |
| LOW | tests/unit_tests/test_query.py | 125 | def test_a_cursor_that_returns_none_has_no_backend(self) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 150 | def test_rejects_a_statement_with_no_cursor( | CODE |
| LOW | tests/unit_tests/test_query.py | 157 | def test_the_row_cap_is_not_the_fetch_limit( | CODE |
| LOW | tests/unit_tests/test_query.py | 175 | def test_truncation_is_detected_from_one_extra_row( | CODE |
| LOW | tests/unit_tests/test_query.py | 191 | def test_an_unlimited_fetch_is_never_truncated( | CODE |
| LOW | tests/unit_tests/test_query.py | 207 | def test_a_raw_driver_exception_does_not_escape(self) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 221 | def test_keyboard_interrupt_propagates(self) -> None: | CODE |
| LOW | tests/unit_tests/test_query.py | 249 | def test_every_shape_a_cursor_may_return_is_normalized(returned: Any) -> None: | CODE |
| LOW | tests/unit_tests/test_cli.py | 323 | def test_config_path_fron_env( | CODE |
| LOW | tests/unit_tests/test_cli.py | 380 | def test_sqlite_extension_not_supported( | CODE |
| LOW | tests/functional_tests/conftest.py | 183 | async def wait_for_filtered_workers(app: Harlequin) -> None: | CODE |
| LOW | tests/functional_tests/conftest.py | 218 | def transaction_button_visible() -> Callable[[Harlequin], bool]: | CODE |
| LOW | tests/functional_tests/test_results_viewer.py | 87 | async def test_data_truncated_with_tooltip( | CODE |
| LOW | tests/functional_tests/test_keymap_vscode.py | 171 | async def test_results_viewer_bindings( | CODE |
| LOW | tests/functional_tests/test_query_editor.py | 355 | async def test_selected_queries_split_on_character_columns( | CODE |
| LOW | tests/functional_tests/test_history_screen.py | 65 | async def test_history_screen_crash( | CODE |
| LOW | tests/functional_tests/test_cache.py | 62 | async def test_harlequin_loads_cache(cache: Cache, app: Harlequin) -> None: | CODE |
| LOW | tests/functional_tests/test_cache.py | 77 | async def test_harlequin_writes_cache(app: Harlequin) -> None: | CODE |
| LOW | tests/functional_tests/test_app.py | 76 | async def test_queries_do_not_crash_all_adapters( | CODE |
| LOW | tests/functional_tests/test_app.py | 134 | async def test_queries_do_not_crash( | CODE |
| LOW | tests/functional_tests/test_app.py | 227 | async def test_single_query_terminated_with_semicolon( | CODE |
| LOW | tests/functional_tests/test_app.py | 345 | async def test_adapter_raises_unexpected_error( | CODE |
| LOW | tests/functional_tests/test_data_catalog.py | 154 | async def test_double_click_inserts_node_into_editor( | CODE |
| LOW | tests/functional_tests/test_data_catalog.py | 349 | async def test_file_tree_refreshes_after_editor_save( | CODE |
| LOW | tests/functional_tests/test_data_catalog.py | 385 | async def test_file_tree_refreshes_after_export( | CODE |
| LOW | tests/functional_tests/test_data_catalog.py | 439 | async def test_reload_while_loader_is_fetching( | CODE |
| LOW | tests/functional_tests/test_keymap_from_config.py | 31 | async def test_results_viewer_bindings( | CODE |
| LOW | tests/adapter_tests/test_duckdb.py | 283 | def test_initialize_adapter_ignores_extra_kwargs() -> None: | CODE |
| 59 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 63 | def set_locale_to_enUS() -> None: | CODE |
| LOW | tests/functional_tests/conftest.py | 172 | def set_paste(x: str) -> None: | CODE |
| LOW | src/harlequin/keys_app.py | 396 | def update_binding(new_binding: HarlequinKeyBinding | None) -> None: | CODE |
| LOW | src/harlequin/keys_app.py | 427 | def update_keymap_name(self, message: ActiveKeymapFound) -> None: | CODE |
| LOW | src/harlequin/locale_manager.py | 6 | def set_locale(locale_config: str) -> None: | CODE |
| LOW | src/harlequin/cache.py | 9 | __all__ = ["BufferState", "Cache"] | CODE |
| LOW | src/harlequin/__init__.py | 27 | __all__ = [ | CODE |
| LOW | src/harlequin/app.py | 514 | def update_limit_tooltip(self, message: Input.Changed) -> None: | CODE |
| LOW | src/harlequin/app.py | 778 | def update_transaction_button_label(self, message: TransactionModeChanged) -> None: | CODE |
| LOW | src/harlequin/app.py | 799 | def update_editor_completers(self, message: CompletersReady) -> None: | CODE |
| LOW | src/harlequin/app.py | 1210 | def update_completers(self, catalog: Catalog) -> None: | CODE |
| LOW | src/harlequin/app.py | 1251 | def update_schema_data(self) -> None: | CODE |
| LOW | src/harlequin/autocomplete/__init__.py | 8 | __all__ = [ | CODE |
| LOW | src/harlequin/autocomplete/completers.py | 61 | def update_catalog(self, catalog: Catalog) -> None: | CODE |
| LOW | src/harlequin/components/__init__.py | 11 | __all__ = [ | CODE |
| LOW | src/harlequin/components/run_query_bar.py | 93 | def set_not_responsive(self) -> None: | CODE |
| LOW | src/harlequin/components/run_query_bar.py | 100 | def set_responsive(self) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 190 | def update_database_tree(self, catalog: Catalog) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 193 | def update_file_tree(self) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 197 | def update_s3_tree(self) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/harlequin/adapter.py | 84 | Executes query and returns a cursor (for a select stmt) or None. Raises HarlequinQueryError if the data | STRING |
| HIGH | src/harlequin/adapter.py | 132 | Exports data returned by query to a file or directory at path, using options. Args: | STRING |
| HIGH | src/harlequin/adapter.py | 150 | Parses text as one or more queries; returns text if parsing does not result in an error; otherwise retu | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 186 | CODE | |
| LOW | scripts/export_screenshots.py | 34 | CODE | |
| LOW | src/harlequin_sqlite/adapter.py | 189 | CODE | |
| LOW | src/harlequin_sqlite/adapter.py | 308 | CODE | |
| LOW | src/harlequin/config.py | 200 | CODE | |
| LOW | src/harlequin/windows_timezone.py | 17 | CODE | |
| LOW | src/harlequin/cli.py | 158 | CODE | |
| LOW | src/harlequin/app.py | 708 | CODE | |
| LOW | src/harlequin/app.py | 809 | CODE | |
| LOW | src/harlequin/components/help_screen.py | 40 | CODE | |
| LOW | src/harlequin/components/debug_info.py | 229 | CODE | |
| LOW | src/harlequin/components/debug_info.py | 239 | CODE | |
| LOW | src/harlequin/components/data_catalog/s3_tree.py | 96 | CODE | |
| LOW | src/harlequin_duckdb/adapter.py | 301 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin/options.py | 177 | except Exception as e: | CODE |
| LOW | src/harlequin/query.py | 134 | except Exception as e: | CODE |
| LOW | src/harlequin/windows_timezone.py | 58 | except Exception as e: | CODE |
| LOW | src/harlequin/copy_widgets.py | 36 | except Exception as e: | CODE |
| LOW | src/harlequin/bindings.py | 34 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1115 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1233 | except Exception: | CODE |
| LOW | src/harlequin/app.py | 1301 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1327 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1353 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1375 | except Exception as e: | CODE |
| LOW | src/harlequin/components/debug_info.py | 66 | except Exception: | CODE |
| LOW | src/harlequin/components/debug_info.py | 70 | except Exception: | CODE |
| MEDIUM | src/harlequin/components/debug_info.py | 63 | def parse_info(self) -> List[DebugWidget]: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin_sqlite/adapter.py | 248 | CODE | |
| LOW | src/harlequin/options.py | 301 | CODE | |
| LOW | src/harlequin/export.py | 128 | CODE | |
| LOW | src/harlequin/cli.py | 132 | CODE | |
| LOW | src/harlequin/app.py | 187 | CODE | |
| LOW | src/harlequin/components/results_viewer.py | 36 | CODE | |
| LOW | src/harlequin_duckdb/adapter.py | 256 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/harlequin/query.py | 11 | null, how a nested struct comes out) in two places, and the disagreement would | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin/options.py | 138 | placeholder = self.placeholder or getattr(other, "placeholder", None) | CODE |
| LOW | src/harlequin/options.py | 353 | placeholder = self.placeholder or getattr(other, "placeholder", None) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin/catalog_cache.py | 30 | # Never raise a TypeError, just use the repr | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin/components/data_catalog/database_tree.py | 461 | except WorkerCancelled: | COMMENT |