AI-Powered Dark Web OSINT Tool
This report summarizes scanner evidence for apurvsinghgautam/robin, a Python project with 7,506 GitHub stars. SynthScan examined 14,600 lines of code across 45 source files, recording 379 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 28.5 (Elevated 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.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 328 finding(s).
Are imports declared and package/API names verified? 1 finding(s).
Are wrappers, guards, and repeated structures necessary? 358 finding(s).
Which changes need focused human review? 379 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
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.
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.
The scanner identified 379 distinct pattern matches across 8 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.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | ui.py | 443 | def _render_investigation_body(inv): | CODE |
| LOW | ui.py | 472 | def _followup_history_messages(chat_history, max_turns=5): | CODE |
| LOW | search.py | 164 | def fetch_search_results_detailed(endpoint, query): | CODE |
| LOW | search.py | 342 | def get_search_results_detailed(refined_query, max_workers=5, per_host_limit=None): | CODE |
| LOW | mcp_server.py | 911 | def _read_saved_investigation(directory: Path, filename: str) -> Optional[str]: | CODE |
| LOW | mcp_server.py | 1661 | async def robin_list_investigations(limit: Annotated[int, Field(ge=1, le=200)] = 20) -> str: | CODE |
| LOW⚡ | tests/test_model_smoke.py | 26 | def test_real_stages_pass_the_grounded_fixture(self): | CODE |
| LOW⚡ | tests/test_model_smoke.py | 32 | def test_invented_artifacts_and_padded_selections_fail_the_fixture(self): | CODE |
| LOW⚡ | tests/test_model_smoke.py | 38 | def test_repeating_identifiers_in_the_query_is_not_artifact_extraction(self): | CODE |
| LOW | tests/test_model_compatibility.py | 50 | def test_openai_and_gateway_requests_omit_sampling(self): | CODE |
| LOW | tests/test_model_compatibility.py | 65 | def test_claude_requests_omit_sampling(self): | CODE |
| LOW | tests/test_model_compatibility.py | 78 | def test_gemini_requests_omit_sampling_for_current_models(self): | CODE |
| LOW | tests/test_model_compatibility.py | 92 | def test_mistral_retains_the_clients_documented_sampling_default(self): | CODE |
| LOW | tests/test_model_compatibility.py | 100 | def test_local_and_custom_requests_preserve_server_defaults(self): | CODE |
| LOW | tests/test_model_compatibility.py | 136 | def test_modern_content_blocks_and_local_thinking_prefixes(self): | CODE |
| LOW | tests/test_model_compatibility.py | 152 | def test_health_checks_accept_answer_blocks_but_reject_reasoning_only(self): | CODE |
| LOW | tests/test_model_compatibility.py | 165 | def test_streams_exclude_reasoning_even_when_tags_span_tokens(self): | CODE |
| LOW | tests/test_packaging.py | 56 | def test_secrets_and_case_data_stay_out_and_the_example_env_and_logo_ship(self): | CODE |
| LOW | tests/test_packaging.py | 67 | def test_the_dockerfile_labels_the_server_and_pre_creates_robin_owned_directories(self): | CODE |
| LOW | tests/test_packaging.py | 82 | def test_every_echo_goes_to_stderr(self): | CODE |
| LOW | tests/test_packaging.py | 90 | def test_tor_and_the_model_warm_up_write_to_stderr_in_the_background(self): | CODE |
| LOW | tests/test_packaging.py | 102 | def test_requirements_pins_mcp_to_an_exact_version(self): | CODE |
| LOW | tests/test_packaging.py | 105 | def test_server_json_is_publishable_and_mounts_the_volume(self): | CODE |
| LOW | tests/test_llm.py | 30 | def test_a_label_is_dropped_before_the_indices_are_read(self): | CODE |
| LOW | tests/test_llm.py | 42 | def test_list_markers_are_not_indices_and_real_ranges_expand(self): | CODE |
| LOW | tests/test_llm.py | 58 | def test_llm_uses_the_prompt_modules_own_objects(self): | CODE |
| LOW | tests/test_llm.py | 66 | def test_every_preset_has_a_prompt_a_persona_and_a_sidebar_label(self): | CODE |
| LOW | tests/test_llm.py | 78 | def test_each_prompt_keeps_its_substitution_points_and_grounding_rule(self): | CODE |
| LOW | tests/test_llm.py | 107 | def test_the_streaming_handler_hands_every_chunk_to_the_ui_and_none_to_stdout(self): | CODE |
| LOW | tests/test_llm.py | 122 | def test_the_filters_rate_limit_retry_logs_rather_than_prints(self): | CODE |
| LOW | tests/test_llm.py | 146 | def test_a_verbose_registry_refresh_reports_on_stderr_only(self): | CODE |
| LOW | tests/test_llm.py | 177 | def test_the_ui_filter_is_the_detailed_selection(self): | CODE |
| LOW | tests/test_llm.py | 190 | def test_the_detailed_variant_reports_the_reply_and_reads_long_ranges(self): | CODE |
| LOW | tests/test_llm.py | 204 | def test_a_lost_identifier_or_empty_answer_keeps_the_original_query(self): | CODE |
| LOW | tests/test_llm.py | 220 | def test_an_answer_that_keeps_identifiers_is_used_verbatim(self): | CODE |
| LOW | tests/test_llm.py | 240 | def test_every_stage_preserves_the_final_answer(self): | CODE |
| LOW | tests/test_search.py | 54 | def test_each_host_keeps_only_its_first_three_results(self): | CODE |
| LOW⚡ | tests/test_search.py | 66 | def test_a_tracker_tagged_duplicate_does_not_use_up_the_cap(self): | CODE |
| LOW⚡ | tests/test_search.py | 72 | def test_results_are_link_and_title_dicts(self): | CODE |
| LOW⚡ | tests/test_search.py | 80 | def test_each_engine_reports_whether_it_answered_came_back_empty_or_failed(self): | CODE |
| LOW | tests/test_search.py | 98 | def test_result_counts_show_what_dedup_and_the_cap_removed(self): | CODE |
| LOW | tests/test_search.py | 116 | def test_abuse_results_are_dropped_before_anything_else_and_counted(self): | CODE |
| LOW | tests/test_search.py | 138 | def test_plus_and_ampersand_reach_the_engine_verbatim(self): | CODE |
| LOW | tests/test_search.py | 154 | def test_redirect_wrappers_are_unwrapped_and_engine_navigation_dropped(self): | CODE |
| LOW | tests/test_search.py | 171 | def test_anchor_text_is_scrubbed_and_navigation_dropped(self): | CODE |
| LOW | tests/test_search.py | 237 | def test_a_dead_engine_costs_one_attempt(self): | CODE |
| LOW | tests/test_search.py | 253 | def test_the_slowest_engine_still_counts(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 40 | def test_a_host_that_samples_runs_it_on_its_own_model(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 48 | def test_the_sampling_client_reaches_the_host(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 61 | def test_without_sampling_a_configured_model_runs_it(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 75 | def test_with_no_model_it_points_at_the_tools_path(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 85 | def test_a_failed_run_is_a_status_with_the_providers_words_fenced(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 105 | def test_each_unfinished_status_is_reported_as_itself(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 122 | def test_an_engine_outage_in_the_real_pipeline_is_reported_as_one(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 135 | def test_every_pipeline_status_is_allowed_through(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 148 | def test_the_report_and_pivots_are_fenced_as_model_output(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 164 | def test_run_details_and_model_names_are_fenced_on_every_status(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 176 | def test_nothing_readable_hands_back_the_kept_links_fenced(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 184 | def test_a_long_report_is_trimmed_for_a_capped_client(self): | CODE |
| LOW | tests/test_mcp_investigate.py | 212 | def test_a_finished_run_is_saved_once_with_what_robin_measured(self): | CODE |
| 245 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | health.py | 25 | except Exception as e: | CODE |
| LOW | health.py | 91 | except Exception as e: | CODE |
| LOW | health.py | 125 | except Exception as e: | CODE |
| LOW | ui.py | 173 | except Exception: | CODE |
| LOW | ui.py | 548 | except Exception as e: | CODE |
| LOW | llm.py | 454 | except Exception as e: | CODE |
| LOW | llm.py | 467 | except Exception: | CODE |
| LOW | llm_utils.py | 175 | except Exception as exc: # noqa: BLE001 - never let the picker hard-fail | CODE |
| LOW | pipeline.py | 71 | except Exception: | CODE |
| LOW | pipeline.py | 192 | except Exception as exc: | CODE |
| LOW | pipeline.py | 199 | except Exception as exc: | CODE |
| LOW | pipeline.py | 210 | except Exception as exc: | CODE |
| LOW | pipeline.py | 226 | except Exception as exc: | CODE |
| LOW | pipeline.py | 245 | except Exception as exc: | CODE |
| LOW | pipeline.py | 266 | except Exception as exc: | CODE |
| LOW | pipeline.py | 283 | except Exception as exc: | CODE |
| LOW | search.py | 208 | except Exception: | CODE |
| LOW | search.py | 212 | except Exception as exc: | CODE |
| LOW | search.py | 246 | except Exception: | CODE |
| LOW | search.py | 305 | except Exception: | CODE |
| LOW | search.py | 360 | except Exception as exc: # A worker that died is a failed engine. | CODE |
| MEDIUM | search.py | 243 | def _result_host(link): | CODE |
| LOW | model_registry.py | 513 | except Exception as exc: # noqa: BLE001 - any failure falls back a layer | CODE |
| LOW | scrape.py | 138 | except Exception: | CODE |
| LOW | scrape.py | 627 | except Exception as exc: | CODE |
| LOW | scrape.py | 680 | except Exception as exc: | CODE |
| MEDIUM | scrape.py | 220 | def _codec(name): | CODE |
| LOW | mcp_server.py | 812 | except Exception: | CODE |
| LOW | mcp_server.py | 829 | except Exception: | CODE |
| LOW | mcp_server.py | 1162 | except Exception as exc: # a missing key or an unknown model name | CODE |
| LOW | mcp_server.py | 1177 | except Exception as exc: | CODE |
| LOW | mcp_server.py | 1227 | except Exception as exc: | CODE |
| LOW | mcp_server.py | 1771 | except Exception as exc: | CODE |
| LOW | mcp_server.py | 1829 | except Exception as exc: | CODE |
| LOW | tests/test_mcp_saving.py | 357 | except Exception as exc: | CODE |
| LOW | tests/model_smoke.py | 100 | except Exception as exc: | CODE |
| LOW | tests/test_store.py | 122 | except Exception as exc: # surfaced below, never swallowed | CODE |
| MEDIUM | tests/test_store.py | 118 | def worker(inv): | CODE |
| MEDIUM | tests/test_models.py | 539 | def write(providers): | CODE |
| LOW | tests/test_models.py | 542 | except Exception as exc: # surfaced below | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | model_registry.py | 272 | except ValueError: | CODE |
| HIGH | model_registry.py | 464 | except OSError: | CODE |
| HIGH | scrape.py | 245 | except UnicodeDecodeError: | CODE |
| HIGH | scrape.py | 533 | except ValueError: | CODE |
| HIGH | mcp_server.py | 573 | except ValueError: | CODE |
| HIGH | tests/stubs.py | 150 | except OSError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | health.py | 33 | CODE | |
| LOW | ui.py | 29 | CODE | |
| LOW | ui.py | 484 | CODE | |
| LOW | llm.py | 59 | CODE | |
| LOW | llm_utils.py | 416 | CODE | |
| LOW | search.py | 90 | CODE | |
| LOW | search.py | 164 | CODE | |
| LOW | model_registry.py | 468 | CODE | |
| LOW | scrape.py | 644 | CODE | |
| LOW | tests/test_model_compatibility.py | 100 | CODE | |
| LOW | tests/test_llm.py | 107 | CODE | |
| LOW | tests/test_llm.py | 122 | CODE | |
| LOW | tests/test_llm.py | 146 | CODE | |
| LOW | tests/test_mcp_investigate.py | 386 | CODE | |
| LOW | tests/test_mcp_tools.py | 872 | CODE | |
| LOW | tests/test_mcp_tools.py | 940 | CODE | |
| LOW | tests/test_mcp_saving.py | 77 | CODE | |
| LOW | tests/test_config.py | 117 | CODE | |
| LOW | tests/test_config.py | 199 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | tests/test_config.py | 41 | for raw in ("your_ollama_url", "YOUR_API_KEY", '"your_key"', "", " ", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | store.py | 11 | logger = logging.getLogger(__name__) | CODE |
| LOW | pipeline.py | 29 | logger = logging.getLogger(__name__) | CODE |
| LOW | model_registry.py | 19 | logger = logging.getLogger(__name__) | CODE |
| LOW | mcp_server.py | 47 | logger = logging.getLogger(__name__) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | config.py | 20 | # Ollama applies its own context window rather than the model's full capability, | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pipeline.py | 151 | CODE | |
| LOW | mcp_server.py | 1010 | CODE | |
| LOW | mcp_server.py | 1411 | CODE |