AI Slop Code Risk Monitor

ruffle-rs/ruffle

SlopCodeMonitor badge for ruffle-rs/ruffle Adjusted legacy signal; badge bands: 25 / 50 / 75 (different from dashboard bands).

A Flash Player emulator written in Rust

1.6 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for ruffle-rs/ruffle, a Rust project with 18,781 GitHub stars. SynthScan examined 967,581 lines of code across 12695 source files, recording 1546 pattern matches distributed across 12 syntactic categories. The legacy adjusted pattern signal is 1.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.

1.6
Adjusted Signal
1.6
Raw Pattern Score
100%
Time Factor
2026-10-31
Last Push
18.8K
Stars
Rust
Language
967.6K
Lines of Code
12.7K
Files
1.5K
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 7.2/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.3/100 · LOW

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

Agent Over-Engineering Ratio 0.1/100 · LOW

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

PR Review Velocity Impact 7.8/100 · LOW

Which changes need focused human review? 1546 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 0MEDIUM 11LOW 1534

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 1546 distinct pattern matches across 12 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.

Over-Commented Block1463 hits · 1391 pts
SeverityFileLineSnippetContext
LOWdeny.toml61 { name = "tracy-client", deny-multiple-versions = true },COMMENT
LOWvideo/software/src/decoder.rs21 /// Preload a frame.COMMENT
LOWvideo/external/src/decoder.rs1// cargo install bindgen-cliCOMMENT
LOWvideo/external/src/decoder/openh264_sys.rs101#[doc = "< Intra Refresh in predifined 2% MB"]COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs141pub type SliceInfo = SliceInformation;COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs641 #[doc = "< application type; please refer to the definition of EUsageType"]COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs741 #[doc = "< get V PSNR stats for the whole video sequence"]COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs861}COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs901 #[doc = "< max-cpb"]COMMENT
LOWvideo/external/src/decoder/openh264_sys.rs1021 #[doc = "< level idc according to Annex A-1"]COMMENT
LOWvideo/src/backend.rs1use crate::VideoStreamHandle;COMMENT
LOWvideo/src/backend.rs41 /// video data should be inspected to determine inter-frame dependenciesCOMMENT
LOWvideo/src/backend.rs61 /// Frames may be decoded in any order that does not violate the frameCOMMENT
LOWcore/build_playerglobal/src/avm2.rs21// should be of the form `[Ruffle(key1 = value1, key2 = value2)]`COMMENT
LOWcore/build_playerglobal/src/avm2.rs441COMMENT
LOWcore/build_playerglobal/src/avm2.rs721 pub mod #mod_name {COMMENT
LOWcore/build_playerglobal/src/avm2.rs741 // If so, we replace it with a `NativeMethod` constructedCOMMENT
LOWcore/build_playerglobal/src/avm2.rs761COMMENT
LOWcore/macros/src/lib.rs21///COMMENT
LOWcore/macros/src/lib.rs381/// assumed to be in scope and will be used to retrieve the interned string. Otherwise, theCOMMENT
LOWcore/common/src/tag_utils.rs101 /// header declares.COMMENT
LOWcore/common/src/duration.rs1//! A custom Duration type for representing time intervals with f64 precision.COMMENT
LOWcore/common/src/duration.rs41COMMENT
LOWcore/common/src/buffer.rs1//! Shared-ownership buffer typesCOMMENT
LOWcore/common/src/buffer.rs241 UpperHex::fmt(&self.data(), f)COMMENT
LOWcore/common/src/sandbox.rs1//! Security Sandbox implementation, seeCOMMENT
LOWcore/common/src/utils.rs1use gc_arena::{Collect, Gc};COMMENT
LOWcore/src/frame_lifecycle.rs1//! Frame events managementCOMMENT
LOWcore/src/frame_lifecycle.rs21/// Which phase of the frame we're currently in.COMMENT
LOWcore/src/frame_lifecycle.rs41 ///COMMENT
LOWcore/src/frame_lifecycle.rs101 broadcast_frame_exited(context);COMMENT
LOWcore/src/vminterface.rs1//! Any-AVM object referencesCOMMENT
LOWcore/src/vminterface.rs21 /// situations in which one might flag a VM action as movie-triggeredCOMMENT
LOWcore/src/vminterface.rs41 /// objects should be created as AVM2 objects and any custom constructorsCOMMENT
LOWcore/src/vminterface.rs61///COMMENT
LOWcore/src/events.rs101 Self::HandledCOMMENT
LOWcore/src/events.rs121/// * AVM2 delivers broadcasts to all registered `EventDispatcher`sCOMMENT
LOWcore/src/events.rs161 ///COMMENT
LOWcore/src/events.rs181COMMENT
LOWcore/src/events.rs201COMMENT
LOWcore/src/events.rs221 /// AVM1 and AVM2. The target of this event is determined by the positionCOMMENT
LOWcore/src/events.rs241 /// Mouse moved out of a display object.COMMENT
LOWcore/src/events.rs281 /// Middle mouse button was released inside a previously-pressed display object.COMMENT
LOWcore/src/events.rs501}COMMENT
LOWcore/src/orphan_manager.rs1//! Special handling for AVM2 orphan objectsCOMMENT
LOWcore/src/orphan_manager.rs61COMMENT
LOWcore/src/tag_utils.rs41 Continue,COMMENT
LOWcore/src/config.rs61 /// All networking APIs are permitted in the SWF file.COMMENT
LOWcore/src/streams.rs61 fn from(err: SubstreamError) -> NetstreamError {COMMENT
LOWcore/src/streams.rs141 Avm2(NetStreamObject<'gc>),COMMENT
LOWcore/src/streams.rs221 /// This points to the first byte that the stream has *never* processedCOMMENT
LOWcore/src/streams.rs461 /// either the prior or next keyframe depending on seek direction. If theCOMMENT
LOWcore/src/streams.rs801 /// Generally speaking, streams are only to be used once. However, theCOMMENT
LOWcore/src/limits.rs1use crate::context::UpdateContext;COMMENT
LOWcore/src/display_object.rs81/// - Changing the color transformCOMMENT
LOWcore/src/display_object.rs201 /// Masks are usually skipped when rendering, but when e.g. renderingCOMMENT
LOWcore/src/display_object.rs241 /// Stencil masks are the classic, default masks used in Flash Player.COMMENT
LOWcore/src/display_object.rs301 /// The opaque background color of this display object.COMMENT
LOWcore/src/display_object.rs481COMMENT
LOWcore/src/display_object.rs1241 // There are two parts to 'DisplayObject.scrollRect':COMMENT
1403 more matches not shown…
Fake / Example Data45 hits · 50 pts
SeverityFileLineSnippetContext
LOW…_gnash/actionscript.all/TextField-v7/output.fp9-14.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…_gnash/actionscript.all/TextField-v7/output.fp9-14.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…gnash/actionscript.all/TextField-v7/output.fp13-17.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…gnash/actionscript.all/TextField-v7/output.fp13-17.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…om_gnash/actionscript.all/TextField-v7/output.fp16.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…om_gnash/actionscript.all/TextField-v7/output.fp16.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…actionscript.all/TextField-v7/output.fp9-14.ruffle.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…actionscript.all/TextField-v7/output.fp9-14.ruffle.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…h/actionscript.all/TextField-v7/output.fp16.ruffle.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…h/actionscript.all/TextField-v7/output.fp16.ruffle.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…ctionscript.all/TextField-v7/output.fp13-17.ruffle.txt546PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…ctionscript.all/TextField-v7/output.fp13-17.ruffle.txt548PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…_gnash/actionscript.all/TextField-v6/output.fp9-14.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…_gnash/actionscript.all/TextField-v6/output.fp9-14.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…gnash/actionscript.all/TextField-v6/output.fp13-17.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…gnash/actionscript.all/TextField-v6/output.fp13-17.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…om_gnash/actionscript.all/TextField-v6/output.fp16.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…om_gnash/actionscript.all/TextField-v6/output.fp16.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…actionscript.all/TextField-v6/output.fp9-14.ruffle.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…actionscript.all/TextField-v6/output.fp9-14.ruffle.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…h/actionscript.all/TextField-v6/output.fp16.ruffle.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…h/actionscript.all/TextField-v6/output.fp16.ruffle.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…ctionscript.all/TextField-v6/output.fp13-17.ruffle.txt521PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…ctionscript.all/TextField-v6/output.fp13-17.ruffle.txt523PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…_gnash/actionscript.all/TextField-v8/output.fp9-14.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…_gnash/actionscript.all/TextField-v8/output.fp9-14.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…gnash/actionscript.all/TextField-v8/output.fp13-17.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…gnash/actionscript.all/TextField-v8/output.fp13-17.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…om_gnash/actionscript.all/TextField-v8/output.fp16.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…om_gnash/actionscript.all/TextField-v8/output.fp16.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…actionscript.all/TextField-v8/output.fp9-14.ruffle.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…actionscript.all/TextField-v8/output.fp9-14.ruffle.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…h/actionscript.all/TextField-v8/output.fp16.ruffle.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…h/actionscript.all/TextField-v8/output.fp16.ruffle.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…ctionscript.all/TextField-v8/output.fp13-17.ruffle.txt547PASSED: tf._target == '/fake_name' [./TextField.as:1207]CODE
LOW…ctionscript.all/TextField-v8/output.fp13-17.ruffle.txt549PASSED: tf._name == 'fake_name' [./TextField.as:1209]CODE
LOW…sts/tests/swfs/avm2/edittext_getlinemetrics/output.txt16//Lorem ipsum dolor sit amet!!COMMENT
LOW…sts/tests/swfs/avm2/edittext_getlinemetrics/output.txt16//Lorem ipsum dolor sit amet!!COMMENT
LOW…sts/tests/swfs/avm2/edittext_getlinemetrics/output.txt97//Lorem ipsum\n\ndolor sit\n ametCOMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt14/// new TextFormat("Noto Sans").getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");COMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt14/// new TextFormat("Noto Sans").getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");COMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt27/// new TextFormat("Noto Sans").getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 100);COMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt27/// new TextFormat("Noto Sans").getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 100);COMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt40/// new TextFormat("Noto Sans", 18).getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 100);COMMENT
LOWtests/tests/swfs/avm1/gettextextent/output.txt40/// new TextFormat("Noto Sans", 18).getTextExtent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 100);COMMENT
AI Slop Vocabulary11 hits · 28 pts
SeverityFileLineSnippetContext
LOWdeny.toml66 # need it (Flash Player didn't support it), so it would just add bloat.COMMENT
MEDIUMcore/macros/src/lib.rs25/// TODO: This isn't completely robust for all cases, but should be good enoughCOMMENT
MEDIUMcore/src/avm2/activation.rs93 /// NOTE: In avmplus this is more nuanced — the default namespace is a propertyCOMMENT
MEDIUMcore/src/avm1/object_reference.rs143 // Essentially, changes to `_name` are reverted after the clip is re-createdCOMMENT
MEDIUMcore/src/avm1/globals/movie_clip.rs1031 // Definitely not Object properties.COMMENT
MEDIUMtests/framework/src/backends/ui.rs77/// Fundamentally, this is mostly the same as [`NullUiBackend`] with the following differences:COMMENT
MEDIUMtests/tests/regression_tests.rs89 // Manual tests here, since #[test] doesn't work once we use our own test harnessCOMMENT
MEDIUMrender/src/shape_utils.rs1033 // 1) Solving the quadratic needs to be numerically robust, particularly near the endpoints 0.0 and 1.0, and as the COMMENT
MEDIUMrender/src/shape_utils.rs1169/// TODO: This probably isn't numerically robustCOMMENT
LOW.github/workflows/test_rust.yml200 # If not, someone force pushed and just use the parentCOMMENT
LOW.github/workflows/download_translations.yml32 # so just create them here instead of relying on Crowdin.COMMENT
Hyper-Verbose Identifiers11 hits · 11 pts
SeverityFileLineSnippetContext
LOWweb/packages/selfhosted/test/utils.ts243export async function hideHardwareAccelerationModal(CODE
LOW…selfhosted/test/integration_tests/context_menu/test.ts17async function supportsClipboardReadText(): Promise<boolean> {CODE
LOWweb/packages/core/src/js-polyfills.ts16function polyfillArrayPrototypeReduce() {CODE
LOWweb/packages/core/src/ruffle-imports.ts13export function copyToAudioBufferInterleaved(CODE
LOWweb/packages/core/src/internal/player/inner.tsx2440export function workaroundYoutubeMixedContent(CODE
LOWweb/packages/extension/src/utils.ts15export function enableBrowserOnOutdatedChromium() {CODE
LOWweb/packages/extension/src/utils.ts83export async function hasHostPermissionForSpecifiedTab(CODE
LOWweb/packages/extension/src/utils.ts98export async function hasHostPermissionForActiveTab() {CODE
LOWweb/packages/extension/src/background.ts13async function getPluginPolyfillRegistration(CODE
LOWweb/packages/extension/src/background.ts39async function isHeaderConditionSupported() {CODE
LOW.github/scripts/release.py46def get_today_nightly_tag_name():CODE
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICAL…/swfs/from_gnash/misc-mtasc.all/inheritance/output.txt10PASSED: this.constructor.prototype.constructor.prototype.test() [inheritance.as:34]CODE
Verbosity Indicators3 hits · 7 pts
SeverityFileLineSnippetContext
LOW⚡render/src/lines.rs46 // Step 1: Create a 1px thick line with the proper length.COMMENT
LOW⚡render/src/lines.rs48 // Step 2: Rotate it, so it still starts at `(0,0)` but points to `b-a`.COMMENT
LOW⚡render/src/lines.rs50 // Step 3: Translate it to `a`, so that it points to `b`.COMMENT
Structural Annotation Overuse3 hits · 7 pts
SeverityFileLineSnippetContext
LOW⚡render/src/lines.rs46 // Step 1: Create a 1px thick line with the proper length.COMMENT
LOW⚡render/src/lines.rs48 // Step 2: Rotate it, so it still starts at `(0,0)` but points to `b-a`.COMMENT
LOW⚡render/src/lines.rs50 // Step 3: Translate it to `a`, so that it points to `b`.COMMENT
Decorative Section Separators3 hits · 6 pts
SeverityFileLineSnippetContext
MEDIUM…tests/swfs/avm2/focus_events_mouse_basic/input.json.py15 'void', 'esc', # ================CODE
MEDIUM…tests/swfs/avm2/focus_events_mouse_basic/input.json.py29 'void', 'esc', # ================CODE
MEDIUM…tests/swfs/avm2/focus_events_mouse_basic/input.json.py37 'void', 'esc', # ================CODE
Deep Nesting2 hits · 2 pts
SeverityFileLineSnippetContext
LOW.github/scripts/release.py271CODE
LOW.github/scripts/coverage.py94CODE
Unused Imports2 hits · 2 pts
SeverityFileLineSnippetContext
LOW.github/scripts/coverage.py6CODE
LOW.github/scripts/coverage.py7CODE
Example Usage Blocks1 hit · 2 pts
SeverityFileLineSnippetContext
LOWcore/src/avm1/property_decl.rs286/// # Usage:COMMENT
Slop Phrases1 hit · 2 pts
SeverityFileLineSnippetContext
LOWweb/packages/extension/tools/submit_xpi.ts107# OR alternatively, if you have to use 'sudo docker', make sure to use $(sudo docker ...) for the second docker command:COMMENT