AI Slop Code Risk Monitor

crmne/ruby_llm

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

The Ruby AI framework.

3.6 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for crmne/ruby_llm, a Ruby project with 4,490 GitHub stars. SynthScan examined 221,907 lines of code across 1235 source files, recording 734 pattern matches distributed across 11 syntactic categories. The legacy adjusted pattern signal is 3.6 (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.

3.6
Adjusted Signal
3.6
Raw Pattern Score
100%
Time Factor
2026-10-28
Last Push
4.5K
Stars
Ruby
Language
221.9K
Lines of Code
1.2K
Files
734
Pattern Hits
2026-10-31
Scan Date
0.00
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 15.6/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.4/100 · LOW

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

Agent Over-Engineering Ratio 8.1/100 · LOW

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

PR Review Velocity Impact 16.9/100 · LOW

Which changes need focused human review? 734 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 1MEDIUM 38LOW 694

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 734 distinct pattern matches across 11 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 Identifiers350 hits · 360 pts
SeverityFileLineSnippetContext
LOWspec/ruby_llm/chat_tools_spec.rb6 def skip_unless_supports_functions(provider, model)CODE
LOWspec/ruby_llm/chat_tools_spec.rb194 def assistant_tool_call_messages(chat)CODE
LOWspec/ruby_llm/uploaded_file_spec.rb151 def stub_default_model_provider(provider, config: RubyLLM.config)CODE
LOWspec/ruby_llm/chat_tool_attachments_spec.rb66 def messages_with_tool_attachment(path)CODE
LOWspec/ruby_llm/chat_tool_attachments_spec.rb74 def chat_with_tool_attachment(model, provider, protocol: nil, attachment: image_path)CODE
LOWspec/ruby_llm/chat_streaming_spec.rb13 def visible_output_token_count(message)CODE
LOWspec/ruby_llm/open_telemetry_spec.rb356 def complete_standalone_operation(operation, reported: true)CODE
LOWspec/ruby_llm/active_record/acts_as_action_text_spec.rb72 def attachable_plain_text_representation(caption)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb23 def expect_messages_helper_content(path)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb36 def expect_generated_view_set( # rubocop:disable Metrics/AbcSizeCODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb148 def expect_queued_message_views(base_path, path_helper)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb169 def expect_broadcasting_model(path:, acts_as_message_lines:)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb198 def run_rails_runner_outside_executor(script)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb208 def give_chat_agent_an_approval_tool(agent_path)CODE
LOWspec/ruby_llm/generators/chat_ui_generator_spec.rb394 def expect_chat_script_to_succeed(script)CODE
LOW…y_llm/protocols/invoke_model/embedding_batches_spec.rb72 def cleanup_live_embedding_batch(batch)CODE
LOW…y_llm/protocols/invoke_model/embedding_batches_spec.rb89 def wait_for_live_embedding_batch(batch)CODE
LOWspec/support/websocket_cassette.rb82 def ensure_websocket_recording_allowed(path, key)CODE
LOWspec/support/models_to_test.rb16def filter_unrecorded_providers(models)CODE
LOWspec/support/models_to_test.rb36def skip_without_cassette_or_key(env_key)CODE
LOW⚡benchmarks/support/payloads.rb115 def chat_completions_text_stream(count)CODE
LOW⚡benchmarks/support/payloads.rb121 def chat_completions_large_event(bytes, piece:)CODE
LOW⚡benchmarks/support/payloads.rb127 def openrouter_reasoning_stream(count)CODE
LOWbenchmarks/support/payloads.rb173 def converse_reasoning_stream(count)CODE
LOWlib/ruby_llm/tool.rb561 def validate_keyword_arguments(arguments) # :nodoc:CODE
LOWlib/ruby_llm/cost.rb91 def missing_recorded_components(amounts, tokens, total)CODE
LOWlib/ruby_llm/agent.rb732 def validate_thinking_options(enabled, options)CODE
LOWlib/ruby_llm/agent.rb844 def apply_passthrough_options(chat)CODE
LOWlib/ruby_llm/agent.rb938 def apply_assume_model_exists(chat_object)CODE
LOWlib/ruby_llm/agent.rb958 def resolved_instruction_value(declaration, chat_object, runtime, inputs:)CODE
LOWlib/ruby_llm/model.rb210 def pricing_data_with_long_context(pricing)CODE
LOWlib/ruby_llm/model.rb234 def normalize_reasoning_options(options)CODE
LOW⚡lib/ruby_llm/chat.rb2157 def handle_concurrent_tool_calls(tool_calls)CODE
LOW⚡lib/ruby_llm/chat.rb2167 def execute_tools_concurrently(tool_calls, &on_result)CODE
LOW⚡lib/ruby_llm/chat.rb2173 def execute_tool_with_callbacks(tool_call)CODE
LOWlib/ruby_llm/chat.rb1300 def convert_unsupported_attachments(&)CODE
LOWlib/ruby_llm/chat.rb1557 def extract_schema_definition(schema)CODE
LOWlib/ruby_llm/chat.rb1944 def replacing_missing_uploads(request_messages, streamed = -> { false })CODE
LOWlib/ruby_llm/chat.rb2008 def execute_pending_tool_calls(response)CODE
LOWlib/ruby_llm/chat.rb2019 def answer_claimed_tool_calls(claimed, server_calls, decisions, executable, denied)CODE
LOWlib/ruby_llm/chat.rb2059 def respond_to_tool_approvals(tool_calls, decisions)CODE
LOWlib/ruby_llm/chat.rb2070 def partition_pending_tool_calls(pending)CODE
LOWlib/ruby_llm/chat.rb2089 def record_tool_call_decision(tool_call, decision)CODE
LOWlib/ruby_llm/chat.rb2144 def handle_sequential_tool_calls(tool_calls)CODE
LOWlib/ruby_llm/chat.rb2332 def normalize_tool_concurrency(concurrency)CODE
LOWlib/ruby_llm/chat.rb2362 def tool_name_for_choice_class(tool_class)CODE
LOWlib/ruby_llm/protocol.rb380 def render_video_extension_payload(*)CODE
LOWlib/ruby_llm/protocol.rb384 def video_extension_attachment(source)CODE
LOWlib/ruby_llm/protocol.rb428 def render_transcription_options(timestamps:, **)CODE
LOWlib/ruby_llm/protocol.rb609 def resolve_provider_tools_for_request(entries)CODE
LOWlib/ruby_llm/protocol.rb633 def merge_server_tool_entries(payload, entries)CODE
LOWlib/ruby_llm/protocol.rb641 def ensure_embedding_per_text(embedding, text, attachments, response)CODE
LOWlib/ruby_llm/protocol.rb668 def apply_before_request_hooks(payload, hooks)CODE
LOWlib/ruby_llm/protocol.rb695 def replace_unsupported_attachment(attachment, handler, message)CODE
LOWlib/ruby_llm/protocol.rb761 def provider_file_upload_options(_attachment)CODE
LOWlib/ruby_llm/protocol.rb805 def parse_completion_response(response)CODE
LOWlib/ruby_llm/provider.rb531 def cache_write_input_multiplier(_model_id, _ttl) # :nodoc:CODE
LOWlib/ruby_llm/provider.rb686 def configured_remote_providers(config) # :nodoc:CODE
LOWlib/ruby_llm/provider.rb788 def validation_detail_message(detail)CODE
LOWlib/ruby_llm/models.rb255 def models_dev_provider_models(provider_key, provider_data) # :nodoc:CODE
290 more matches not shown…
Over-Commented Block333 hits · 294 pts
SeverityFileLineSnippetContext
LOWArchspec.rb241# job (they word an option list, resolve a speech format, or guess from aCOMMENT
LOW.mutineer.yml1# Mutineer settings shared by bin/mutineer and direct mutineer runs; seeCOMMENT
LOWspec/dummy/config/puma.rb1# frozen_string_literal: trueCOMMENT
LOWspec/dummy/config/puma.rb21# response time (latency) of the application.COMMENT
LOWspec/dummy/config/database.yml21 database: storage/test<%= ENV['TEST_ENV_NUMBER'] %>.sqlite3COMMENT
LOWspec/dummy/config/locales/en.yml1# Files in the config/locales directory are used for internationalization andCOMMENT
LOWspec/dummy/config/locales/en.yml21#COMMENT
LOWspec/dummy/config/environments/production.rb61 # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`COMMENT
LOWspec/dummy/config/environments/test.rb1# frozen_string_literal: trueCOMMENT
LOWspec/dummy/config/initializers/inflections.rb1# frozen_string_literal: trueCOMMENT
LOWspec/dummy/config/initializers/cors.rb1# frozen_string_literal: trueCOMMENT
LOWspec/dummy/db/seeds.rb1# frozen_string_literal: trueCOMMENT
LOW.github/scripts/indexnow.rb1#!/usr/bin/env rubyCOMMENT
LOWlib/ruby_llm.rb61# endCOMMENT
LOWlib/ruby_llm.rb81# - Chat#with_fallbacks tries other models when a request fails.COMMENT
LOWlib/ruby_llm.rb101# format: each request lists them, the model loads the instructions andCOMMENT
LOWlib/ruby_llm.rb121# VideoJob that you can poll. Speech.speak also streams SpeechChunk objectsCOMMENT
LOWlib/ruby_llm.rb141#COMMENT
LOWlib/ruby_llm.rb161# result. Implement Evaluation#perform to return a value, Message, Chat, orCOMMENT
LOWlib/ruby_llm.rb181# method evaluates supplied text, structured data, or images passed as +with:+COMMENT
LOWlib/ruby_llm.rb201# and attempts that produced no message. Provider-reported costs takeCOMMENT
LOWlib/ruby_llm.rb241 # Duplicates the global configuration and yields the copy if a block isCOMMENT
LOWlib/ruby_llm.rb261 # RubyLLM.workflow("Write article", id: "article-42") do |workflow|COMMENT
LOWlib/ruby_llm.rb281 # restore the outer owner when they end. Each fiber and thread keeps itsCOMMENT
LOWlib/ruby_llm.rb301 #COMMENT
LOWlib/ruby_llm.rb321 def mcp(...)COMMENT
LOWlib/ruby_llm.rb341COMMENT
LOWlib/ruby_llm.rb361 # embedding requests, not both. Look up an existing batch withCOMMENT
LOWlib/ruby_llm.rb381 Embedding.embed(...)COMMENT
LOWlib/ruby_llm.rb401 # result = RubyLLM.moderate("Some user input text")COMMENT
LOWlib/ruby_llm.rb441COMMENT
LOWlib/ruby_llm.rb461 def animate_later(...)COMMENT
LOWlib/ruby_llm.rb481 # transcription.textCOMMENT
LOWlib/ruby_llm.rb501 # Ranks documents by relevance to a query on providers with a rerankCOMMENT
LOWlib/ruby_llm.rb521COMMENT
LOWlib/ruby_llm.rb541 endCOMMENT
LOWlib/ruby_llm.rb561 #COMMENT
LOWlib/ruby_llm.rb581 # RubyLLM.configure do |config|COMMENT
LOWlib/ruby_llm/image.rb21 attr_reader :dataCOMMENT
LOWlib/ruby_llm/image.rb41 # images for editing, and +mask:+ constrains which parts of the imageCOMMENT
LOWlib/ruby_llm/image.rb141 endCOMMENT
LOWlib/ruby_llm/video_job.rb1# frozen_string_literal: trueCOMMENT
LOWlib/ruby_llm/tool.rb21 #COMMENT
LOWlib/ruby_llm/tool.rb101 # class Weather < RubyLLM::ToolCOMMENT
LOWlib/ruby_llm/tool.rb121 # the tools in its own namespace:COMMENT
LOWlib/ruby_llm/tool.rb141 # parameter :destination, description: "Destination city name"COMMENT
LOWlib/ruby_llm/tool.rb161 # object :window, description: "Time window to reserve" doCOMMENT
LOWlib/ruby_llm/tool.rb181 # Chat#approve or Chat#deny, so Chat#complete returns cleanly andCOMMENT
LOWlib/ruby_llm/tool.rb201 # request, make that a find-or-create.COMMENT
LOWlib/ruby_llm/tool.rb221 # Without an argument, returns the declared value, or +nil+.COMMENT
LOWlib/ruby_llm/tool.rb241 #COMMENT
LOWlib/ruby_llm/tool.rb261 def deferCOMMENT
LOWlib/ruby_llm/tool.rb481 elseCOMMENT
LOWlib/ruby_llm/tool.rb501 # endCOMMENT
LOWlib/ruby_llm/tool.rb541 # can show it before the result arrives. Chat#after_tool_progressCOMMENT
LOWlib/ruby_llm/fallback.rb1# frozen_string_literal: trueCOMMENT
LOWlib/ruby_llm/video.rb1# frozen_string_literal: trueCOMMENT
LOWlib/ruby_llm/video.rb21 attr_reader :mime_typeCOMMENT
LOWlib/ruby_llm/video.rb41 # +default_video_model+. +provider:+ forces a specific provider, andCOMMENT
LOWlib/ruby_llm/cost.rb1# frozen_string_literal: trueCOMMENT
273 more matches not shown…
Modern AI Meta-Vocabulary27 hits · 75 pts
SeverityFileLineSnippetContext
MEDIUMArchspec.rb18# User-facing objects and orchestration. These are nouns like Chat, Batch,COMMENT
MEDIUMspec/ruby_llm/chat_error_spec.rb80 # Create enough copies to overflow the model's context windowCOMMENT
MEDIUMdocs/_advanced/batches.md135Rails saves approval decisions so another process can resume. See [Tool Approvals]({% link _core_features/tool-executionCODE
MEDIUMdocs/_advanced/error-handling.md97 # Reduce prompt size or use a model with a larger context windowCOMMENT
MEDIUMdocs/_core_features/citations.md67## Citing Tool Results (RAG)COMMENT
MEDIUMdocs/_core_features/moderation.md91Apply a [configured Bedrock guardrail]({% link _getting_started/configuration-providers.md %}#guardrails) without selectCODE
MEDIUMdocs/_data/provider_coverage.json197 "s81": {"title": "Bedrock ApplyGuardrail API", "url": "https://docs.aws.amazon.com/bedrock/latest/userguide/guardraiCODE
MEDIUMdocs/_data/provider_coverage.json371 "s255": {"url": "https://elevenlabs.io/docs/eleven-agents/best-practices/guardrails", "title": "Guardrails"},CODE
MEDIUMlib/ruby_llm/workflow.rb5 # records while leaving orchestration in ordinary Ruby code.COMMENT
MEDIUMlib/ruby_llm/attachment.rb40 # How the model reads a video: +:static+, +:agentic+, or +nil+ for theCOMMENT
MEDIUMlib/ruby_llm/attachment.rb101 # frames across the whole video up front. +:agentic+ lets the modelCOMMENT
MEDIUMlib/ruby_llm/attachment.rb105 # RubyLLM::Attachment.new("lecture.mp4", processing: :agentic)COMMENT
MEDIUMlib/ruby_llm/chat.rb937 # going instead of overflowing the context window. The provider condensesCOMMENT
MEDIUMlib/ruby_llm/error.rb226 # Raised when the request exceeds the model's context window or tokenCOMMENT
MEDIUMlib/ruby_llm/embedding.rb83 # +model:+ selects the embedding model and defaults to theCOMMENT
MEDIUMlib/ruby_llm/embedding_request.rb21 # The Model of the embedding model the request targets.COMMENT
MEDIUMlib/ruby_llm/providers/openrouter/chat.rb21 # would overflow the model's context window. It summarizes nothingCOMMENT
MEDIUMlib/ruby_llm/providers/xai/responses.rb7 # Grok models. Usage counts agentic tool activity.COMMENT
MEDIUMlib/ruby_llm/protocols/gemini/chat.rb238 # the frames of an agentic video, apart from the prompt, and bills itCOMMENT
MEDIUMlib/generators/ruby_llm/generator_helpers.rb276 # scaffold conventions without complicating scaffold templates.COMMENT
MEDIUMlib/generators/ruby_llm/chat_ui/chat_ui_generator.rb8 # Generates a simple chat UI scaffold for RubyLLMCOMMENT
MEDIUMlib/generators/ruby_llm/chat_ui/chat_ui_generator.rb46 # - `scaffold` should stay close to Rails scaffold ERB output.COMMENT
MEDIUMlib/generators/ruby_llm/chat_ui/chat_ui_generator.rb47 # - `tailwind` should stay close to tailwindcss-rails scaffold output.COMMENT
MEDIUMmedia/tour/video/hyperframes/index.html2662 <svg id="b7cur" width="26" height="26" viewBox="0 0 24 24" style="position:absolute;left:300px;top:150px"><path d="MCODE
MEDIUMmedia/tour/video/hyperframes/tools/snippets.rb269 # 9. Agent with approval. Sources: docs/_core_features/tool-execution.md, docs/_advanced/agentic-workflows.mdCOMMENT
MEDIUMmedia/tour/video/hyperframes/tools/snippets.rb460 # agentic-workflows.md:43, chat-request-control.md:80, tokenization.md:57, _reference/models.md:177/220COMMENT
MEDIUMmedia/tour/video/hyperframes/src/index.html2662 <svg id="b7cur" width="26" height="26" viewBox="0 0 24 24" style="position:absolute;left:300px;top:150px"><path d="MCODE
Self-Referential Comments5 hits · 15 pts
SeverityFileLineSnippetContext
MEDIUMspec/ruby_llm/chat_error_spec.rb77 # Create a huge conversation (matching <MASSIVE_TEXT> in spec_helper)COMMENT
MEDIUMspec/ruby_llm/models_refresh_spec.rb169 # Create a temporary file for testingCOMMENT
MEDIUMspec/ruby_llm/chat_schema_spec.rb5# Define a test schema class for testing Schematist::Schema instancesCOMMENT
MEDIUM…ec/ruby_llm/active_record/acts_as_with_context_spec.rb67 # Create a different API key in custom contextCOMMENT
MEDIUMspec/ruby_llm/protocols/gemini/chat_spec.rb8 # Create a test object that includes the module to access private methodsCOMMENT
Decorative Section Separators4 hits · 12 pts
SeverityFileLineSnippetContext
MEDIUMmedia/tour/music-shared/tired_wired.py79# ---------------------------------------------------------------------------COMMENT
MEDIUMmedia/tour/music-shared/tired_wired.py83# ---------------------------------------------------------------------------COMMENT
MEDIUMmedia/tour/music-shared/tired_wired.py595# ---------------------------------------------------------------------------COMMENT
MEDIUMmedia/tour/music-shared/tired_wired.py597# ---------------------------------------------------------------------------COMMENT
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICALspec/ruby_llm/evaluation_live_spec.rb107 messages = report.first.evaluations.first.evidence.fetch(:messages)CODE
AI Slop Vocabulary2 hits · 6 pts
SeverityFileLineSnippetContext
MEDIUMspec/tasks/models_workflow_spec.rb51 # exec calls, and clear inherited Ruby options so the harness stays isolated.COMMENT
MEDIUMconformance/client.rb4# suite. The harness starts a scenario server, passes its URL as the lastCOMMENT
Fake / Example Data5 hits · 5 pts
SeverityFileLineSnippetContext
LOWspec/ruby_llm/chat_tools_spec.rb705 expect(response.content).to match(/simple PDF file|Lorem ipsum/i)CODE
LOWspec/ruby_llm/mcp/input_request_spec.rb11 request = form('name' => { 'type' => 'string', 'default' => 'John Doe' },CODE
LOWspec/ruby_llm/mcp/input_request_spec.rb19 .to eq(action: 'accept', content: { 'name' => 'John Doe', 'age' => 31, 'verified' => false })CODE
LOWdocs/_getting_started/configuration-providers.md440 config.openai_api_key = ENV['CUSTOM_API_KEY'] # Or 'dummy-key' if not requiredCODE
LOWdocs/_getting_started/configuration-providers.md458 config.openai_api_key = "dummy-key" # If required by your serverCODE
Empty Error Handlers1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHmedia/tour/music-shared/preview.py163except ImportError:CODE
Unused Imports4 hits · 4 pts
SeverityFileLineSnippetContext
LOWmedia/tour/video/hyperframes/tools/film.py2CODE
LOWmedia/tour/video/hyperframes/tools/open_test.py3CODE
LOWmedia/tour/video/hyperframes/tools/full.py3CODE
LOWmedia/tour/video/hyperframes/tools/full.py4CODE
Deep Nesting2 hits · 2 pts
SeverityFileLineSnippetContext
LOWmedia/tour/music-shared/tired_wired.py405CODE
LOWmedia/tour/music-shared/verify_tw.py25CODE