Cucumber for Ruby. It's amazing!
This report presents the forensic synthetic code analysis of cucumber/cucumber-ruby, a Ruby project with 5,213 GitHub stars. SynthScan v2.0 examined 28,246 lines of code across 412 source files, recording 102 pattern matches distributed across 5 syntactic categories. The overall adjusted score of 4.4 places this repository in the Likely human-written 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 102 distinct pattern matches across 5 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 | features/lib/support/json.rb | 34 | def normalise_json_step_or_hook(step_or_hook) | CODE |
| LOW | features/lib/support/json.rb | 44 | def update_json_step_or_hook_error_message(step_or_hook) | CODE |
| LOW | spec/cucumber/configuration_spec.rb | 27 | def given_the_following_files(*files) | CODE |
| LOW | spec/cucumber/cli/configuration_spec.rb | 6 | def given_cucumber_yml_defined_as(hash_or_string) | CODE |
| LOW | spec/cucumber/cli/configuration_spec.rb | 12 | def given_the_following_files(*files) | CODE |
| LOW | spec/cucumber/cli/options_spec.rb | 7 | def given_cucumber_yml_defined_as(hash_or_string) | CODE |
| LOW | spec/cucumber/cli/profile_loader_spec.rb | 8 | def given_cucumber_yml_defined_as(hash_or_string) | CODE |
| LOW | spec/cucumber/formatter/json_spec.rb | 800 | def normalise_json_step_or_hook(step_or_hook) | CODE |
| LOW⚡ | lib/cucumber/repository.rb | 116 | def update_test_case_finished(test_case_finished) | CODE |
| LOW⚡ | lib/cucumber/repository.rb | 120 | def update_test_run_hook_started(test_run_hook_started) | CODE |
| LOW⚡ | lib/cucumber/repository.rb | 124 | def update_test_run_hook_finished(test_run_hook_finished) | CODE |
| LOW⚡ | lib/cucumber/repository.rb | 132 | def update_test_step_finished(test_step_finished) | CODE |
| LOW | lib/cucumber/query.rb | 114 | def find_most_severe_test_step_result_by(message) | CODE |
| LOW | lib/cucumber/query.rb | 174 | def find_test_case_started_by(message) | CODE |
| LOW | lib/cucumber/query.rb | 182 | def find_test_case_finished_by(test_case_started) | CODE |
| LOW | lib/cucumber/query.rb | 198 | def find_test_run_hook_started_by(test_run_hook_finished) | CODE |
| LOW | lib/cucumber/query.rb | 206 | def find_test_run_hook_finished_by(test_run_hook_started) | CODE |
| LOW | lib/cucumber/query.rb | 230 | def find_test_steps_started_by(message) | CODE |
| LOW | lib/cucumber/query.rb | 239 | def find_test_steps_finished_by(message) | CODE |
| LOW | lib/cucumber/configuration.rb | 270 | def register_snippet_generator(generator) | CODE |
| LOW | lib/cucumber/configuration.rb | 293 | def with_default_features_path(paths) | CODE |
| LOW | lib/cucumber/configuration.rb | 299 | def remove_excluded_files_from(files) | CODE |
| LOW | lib/cucumber/glue/snippet.rb | 52 | def replace_and_count_capturing_groups(pattern) | CODE |
| LOW | lib/cucumber/glue/snippet.rb | 175 | def append_block_parameter_to(array) | CODE |
| LOW | lib/cucumber/glue/snippet.rb | 189 | def append_block_parameter_to(array) | CODE |
| LOW | lib/cucumber/glue/snippet.rb | 202 | def append_block_parameter_to(array); end | CODE |
| LOW | lib/cucumber/glue/registry_and_more.rb | 84 | def register_rb_step_definition(string_or_regexp, proc_or_sym, options) | CODE |
| LOW | lib/cucumber/glue/registry_and_more.rb | 210 | def test_run_hook_started_envelope(hook, id) | CODE |
| LOW | lib/cucumber/glue/registry_and_more.rb | 221 | def test_run_hook_finished_envelope(test_result, test_run_hook_started_id) | CODE |
| LOW | lib/cucumber/glue/dsl.rb | 29 | def register_rb_step_definition(regexp, proc_or_sym, options = {}) | CODE |
| LOW | lib/cucumber/glue/dsl.rb | 141 | def register_rb_step_definition(regexp, symbol = nil, options = {}, &proc) | CODE |
| LOW | lib/cucumber/cli/options.rb | 538 | def indicate_invalid_language_and_exit(lang) | CODE |
| LOW | lib/cucumber/formatter/usage.rb | 40 | def on_step_definition_registered(event) | CODE |
| LOW | lib/cucumber/formatter/json.rb | 302 | def create_id_from_scenario_source(scenario_source) | CODE |
| LOW | lib/cucumber/formatter/json.rb | 319 | def create_tags_array_from_hash_array(tags) | CODE |
| LOW | lib/cucumber/formatter/json.rb | 325 | def create_tags_array_from_tags_array(tags) | CODE |
| LOW | lib/cucumber/formatter/ast_lookup.rb | 77 | def process_scenario_container(container) | CODE |
| LOW | lib/cucumber/formatter/ast_lookup.rb | 110 | def process_scenario_container(container) | CODE |
| LOW | lib/cucumber/formatter/ast_lookup.rb | 122 | def store_scenario_source_steps(scenario) | CODE |
| LOW | lib/cucumber/formatter/ast_lookup.rb | 128 | def store_background_source_steps(background) | CODE |
| LOW | lib/cucumber/formatter/ast_lookup.rb | 147 | def process_scenario_container(container, original_previous_node) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 101 | def on_hook_test_step_created(event) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 284 | def generate_snippet_envelope(snippet_text_proc, event) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 298 | def on_undefined_parameter_type(event) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 327 | def step_match_arguments_lists(step) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 345 | def argument_group_to_message(group) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 382 | def fake_query_step_definition_ids(test_step) | CODE |
| LOW | lib/cucumber/formatter/message_builder.rb | 386 | def fake_query_step_match_arguments(test_step) | CODE |
| LOW | lib/cucumber/formatter/pretty.rb | 153 | def find_exception_to_be_printed(result) | CODE |
| LOW | lib/cucumber/formatter/pretty.rb | 168 | def calculate_source_indent_for_ast_node(ast_node) | CODE |
| LOW | lib/cucumber/formatter/pretty.rb | 178 | def calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name) | CODE |
| LOW | lib/cucumber/formatter/message_handlers.rb | 8 | def store_current_test_run_hook_started_id(event) | CODE |
| LOW | lib/cucumber/formatter/unicode.rb | 28 | def cucumber_preprocess_output(*out) | CODE |
| LOW | lib/cucumber/formatter/console.rb | 122 | def collect_undefined_parameter_type_names(undefined_parameter_type) | CODE |
| LOW | lib/cucumber/formatter/console.rb | 192 | def do_print_profile_information(profiles) | CODE |
| LOW | lib/cucumber/formatter/console.rb | 202 | def do_print_undefined_parameter_type_snippet(type_name) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | .rubocop_todo.yml | 1 | # This configuration was generated by | COMMENT |
| LOW | compatibility/features/empty/empty_steps.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | .github/lock.yaml | 21 | # Limit to only `issues` or `pulls` | COMMENT |
| LOW | lib/cucumber/step_match.rb | 41 | # | COMMENT |
| LOW | lib/cucumber/running_test_case.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/events.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/query.rb | 21 | end | COMMENT |
| LOW | lib/cucumber/glue/step_definition.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/glue/registry_wrapper.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/glue/proto_world.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/glue/proto_world.rb | 21 | # | name | email | | COMMENT |
| LOW | lib/cucumber/glue/proto_world.rb | 41 | super | COMMENT |
| LOW | lib/cucumber/glue/proto_world.rb | 61 | # }) | COMMENT |
| LOW | lib/cucumber/glue/dsl.rb | 41 | # symbols are the namespaces. | COMMENT |
| LOW | lib/cucumber/glue/dsl.rb | 121 | # Use it for your final clean-ups | COMMENT |
| LOW | lib/cucumber/gherkin/formatter/ansi_escapes.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/gherkin/formatter/ansi_escapes.rb | 21 | # <tt>outline</tt>:: defaults to <tt>cyan</tt> | COMMENT |
| LOW | lib/cucumber/term/ansicolor.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/rake/task.rb | 21 | # To further configure the task, you can pass a block: | COMMENT |
| LOW | lib/cucumber/runtime/meta_message_builder.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/runtime/meta_message_builder.rb | 21 | # - revision: the revision of the git repository (e.g. abcdef) | COMMENT |
| LOW | lib/cucumber/runtime/user_interface.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/formatter/ansicolor.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/formatter/ansicolor.rb | 21 | # class MyFormatter | COMMENT |
| LOW | lib/cucumber/formatter/ansicolor.rb | 41 | # The colours that you can change are: | COMMENT |
| LOW | lib/cucumber/formatter/console.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 121 | # | 7 | 9 | | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 141 | # | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 161 | end | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 221 | # | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 241 | # | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 261 | def map_headers(mappings = {}, &block) | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 281 | end | COMMENT |
| LOW | lib/cucumber/multiline_argument/data_table.rb | 301 | # A Different error is raised if there are missing rows or columns, or | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | lib/cucumber/runtime.rb | 175 | # Define the MessageBuilder - Required until all messages are generated at the source | COMMENT |
| MEDIUM | lib/cucumber/glue/dsl.rb | 7 | # This module provides the methods the DSL you can use to define | COMMENT |
| MEDIUM | lib/cucumber/glue/dsl.rb | 43 | # This method is typically called from one or more Ruby scripts under | COMMENT |
| MEDIUM | lib/cucumber/formatter/ansicolor.rb | 94 | # Define the color-named methods required by Term::ANSIColor. | COMMENT |
| MEDIUM | lib/cucumber/formatter/console.rb | 9 | # This module contains helper methods that are used by formatters that | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | lib/cucumber/glue/dsl.rb | 7 | # This module provides the methods the DSL you can use to define | COMMENT |
| MEDIUM | lib/cucumber/gherkin/formatter/ansi_escapes.rb | 10 | # The colours that you can change are: | COMMENT |
| MEDIUM | lib/cucumber/gherkin/formatter/ansi_escapes.rb | 40 | # Although not listed, you can also use <tt>grey</tt> | COMMENT |
| MEDIUM | lib/cucumber/formatter/ansicolor.rb | 41 | # The colours that you can change are: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lib/cucumber/runtime.rb | 242 | # TODO: can we just use Glue::RegistryAndMore's step definitions directly? | COMMENT |
| MEDIUM | lib/cucumber/glue/proto_world.rb | 46 | # Useful in conjunction with the #step method. | COMMENT |