Track changes to your rails models
This report summarizes scanner evidence for paper-trail-gem/paper_trail, a Ruby project with 7,030 GitHub stars. SynthScan examined 15,374 lines of code across 224 source files, recording 70 pattern matches distributed across 6 syntactic categories. The legacy adjusted pattern signal is 5.3 (Moderate 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? 70 finding(s).
Are imports declared and package/API names verified? 0 finding(s).
Are wrappers, guards, and repeated structures necessary? 20 finding(s).
Which changes need focused human review? 70 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 70 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.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | .rubocop_todo.yml | 1 | # This configuration was generated by | COMMENT |
| LOW | spec/spec_helper.rb | 41 | end | COMMENT |
| LOW | spec/support/paper_trail_spec_migrator.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/dummy_app/app/models/elephant.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/dummy_app/config/environments/production.rb | 41 | # See everything in the log (default is :info) | COMMENT |
| LOW | spec/dummy_app/config/environments/production.rb | 61 | # config.action_mailer.raise_delivery_errors = false | COMMENT |
| LOW | …c/dummy_app/config/initializers/backtrace_silencers.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/dummy_app/config/initializers/mime_types.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/dummy_app/config/initializers/session_store.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/dummy_app/config/initializers/inflections.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail.rb | 61 | # Set variables for the current request, eg. whodunnit. | COMMENT |
| LOW | lib/paper_trail.rb | 121 | end | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 81 | # | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 101 | Queries::Versions::WhereObject.new(self, args).execute | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 121 | # attribute had a given value. Imagine, in the example above, that someone | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 141 | # `where_object_changes` which will find both the changes before and | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 241 | # @api private | COMMENT |
| LOW | lib/paper_trail/version_concern.rb | 321 | changes = ActiveSupport::HashWithIndifferentAccess.new(object_changes_deserialized) | COMMENT |
| LOW | lib/paper_trail/cleaner.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail/request.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail/request.rb | 21 | # | COMMENT |
| LOW | lib/paper_trail/reifier.rb | 41 | # unversioned attributes to `nil`. | COMMENT |
| LOW | lib/paper_trail/reifier.rb | 121 | # this method returns the constant `Dog`. If `attrs["species"]` is blank, | COMMENT |
| LOW | lib/paper_trail/has_paper_trail.rb | 21 | # Each version of the model is available in the `versions` association. | COMMENT |
| LOW | lib/paper_trail/has_paper_trail.rb | 41 | # - :skip - Fields to ignore completely. As with `ignore`, updates to | COMMENT |
| LOW | lib/paper_trail/compatibility.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | …ail/attribute_serializers/cast_attribute_serializer.rb | 21 | # ``` | COMMENT |
| LOW | …b/paper_trail/queries/versions/where_object_changes.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail/events/base.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail/events/base.rb | 301 | # Returns a boolean indicating whether to store serialized version diffs | COMMENT |
| LOW | lib/paper_trail/frameworks/rails/railtie.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/paper_trail/frameworks/rails/controller.rb | 21 | # | COMMENT |
| LOW | lib/paper_trail/frameworks/rails/controller.rb | 41 | # | COMMENT |
| LOW | lib/paper_trail/frameworks/rails/controller.rb | 61 | # ``` | COMMENT |
| LOW | lib/generators/paper_trail/install/install_generator.rb | 81 | end | COMMENT |
| LOW | …enerators/paper_trail/install/templates/paper_trail.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | …enerators/paper_trail/install/templates/paper_trail.rb | 21 | ## Define error handling behaviour. | COMMENT |
| LOW | doc/bug_report_template.rb | 1 | # frozen_string_literal: true | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | spec/support/custom_object_changes_adapter.rb | 21 | def where_object_changes_from(klass, attributes) | CODE |
| LOW | lib/paper_trail/version_concern.rb | 145 | def where_object_changes_from(args = {}) | CODE |
| LOW | lib/paper_trail/reifier.rb | 74 | def init_model_by_finding_item_id(klass, version) | CODE |
| LOW | lib/paper_trail/reifier.rb | 131 | def version_reification_class(version, attrs) | CODE |
| LOW | lib/paper_trail/model_config.rb | 134 | def assert_concrete_activerecord_class(class_name) | CODE |
| LOW | lib/paper_trail/model_config.rb | 141 | def assert_valid_recording_order_for_on_destroy(recording_order) | CODE |
| LOW | lib/paper_trail/model_config.rb | 172 | def check_versions_association_name(options) | CODE |
| LOW | lib/paper_trail/model_config.rb | 192 | def ensure_versions_option_is_hash(options) | CODE |
| LOW | lib/paper_trail/model_config.rb | 237 | def setup_callbacks_from_options(options_on = []) | CODE |
| LOW | lib/paper_trail/record_trail.rb | 204 | def assign_and_reset_version_association(version) | CODE |
| LOW | lib/paper_trail/events/base.rb | 61 | def assert_metadatum_key_is_permitted(key) | CODE |
| LOW | lib/paper_trail/events/base.rb | 80 | def nonskipped_attributes_before_change(is_touch) | CODE |
| LOW | lib/paper_trail/events/base.rb | 95 | def attribute_in_previous_version(attr_name, is_touch) | CODE |
| LOW | lib/paper_trail/events/base.rb | 197 | def merge_metadata_from_controller_into(data) | CODE |
| LOW | lib/paper_trail/events/base.rb | 206 | def merge_metadata_from_model_into(data) | CODE |
| LOW | lib/paper_trail/events/base.rb | 234 | def metadatum_from_model_method(event, method) | CODE |
| LOW | lib/paper_trail/events/base.rb | 265 | def object_attrs_for_paper_trail(is_touch) | CODE |
| LOW | lib/paper_trail/events/base.rb | 285 | def recordable_object_changes(changes) | CODE |
| LOW | lib/paper_trail/events/update.rb | 57 | def merge_object_changes_into(data) | CODE |
| LOW | lib/generators/paper_trail/migration_generator.rb | 21 | def add_paper_trail_migration(template, extra_options = {}) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | .rubocop.yml | 172 | # The semantic style is too nuanced to lint, so the cop is disabled. | COMMENT |
| MEDIUM | .rubocop.yml | 194 | # and it's not clear that it can be linted. Certainly, the default | COMMENT |
| LOW | spec/paper_trail/version_limit_spec.rb | 56 | # just create them out-of-order: | COMMENT |
| LOW | spec/models/widget_spec.rb | 888 | # Workaround for AR 3. When we drop AR 3 support, we can simply use | COMMENT |
| LOW | lib/paper_trail/record_trail.rb | 174 | # `@record.update_columns` skips dirty-tracking, so we can't just use | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | spec/models/pet_spec.rb | 55 | # Creating an object from the base class is correctly identified as "Animal" | COMMENT |
| MEDIUM | spec/generators/paper_trail/install_generator_spec.rb | 73 | contains "# This file is automatically generated" | CODE |
| MEDIUM | …enerators/paper_trail/install/templates/paper_trail.rb | 3 | # This file is automatically generated by `rails generate paper_trail:install` | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lib/paper_trail/frameworks/rails/controller.rb | 37 | # in your `versions` table, so don't forget to add any new columns | COMMENT |
| LOW | lib/paper_trail/frameworks/rails/controller.rb | 37 | # in your `versions` table, so don't forget to add any new columns | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lib/paper_trail/version_number.rb | 14 | # Set PRE to nil unless it's a pre-release (beta, rc, etc.) | COMMENT |