High Performance Open Source Radio Control Link
This report presents the forensic synthetic code analysis of ExpressLRS/ExpressLRS, a C project with 5,078 GitHub stars. SynthScan v2.0 examined 112,172 lines of code across 443 source files, recording 273 pattern matches distributed across 12 syntactic categories. The overall adjusted score of 2.7 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 273 distinct pattern matches across 12 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 | src/.travis.yml | 1 | # Continuous Integration (CI) is the practice, in software | COMMENT |
| LOW | src/.travis.yml | 21 | COMMENT | |
| LOW | src/.travis.yml | 41 | # - platformio run | COMMENT |
| LOW | src/.travis.yml | 61 | # | COMMENT |
| LOW | src/user_defines.txt | 1 | ### The Legal Stuff ### | COMMENT |
| LOW | src/user_defines.txt | 21 | #-DRegulatory_Domain_EU_868 | COMMENT |
| LOW | src/user_defines.txt | 41 | ### COMPATIBILITY OPTIONS: ### | COMMENT |
| LOW | src/user_defines.txt | 61 | COMMENT | |
| LOW | src/user_defines.txt | 81 | # The ID is generated on the TX side and overwrites CH1-CH4 and increments once for every | COMMENT |
| LOW | src/test/test_msp2crsf2msp/test_msp2crsf2msp.cpp | 61 | COMMENT | |
| LOW | src/test/test_crc/test_crc.cpp | 1 | #include <cstdint> | COMMENT |
| LOW | src/test/test_msp/msp_tests.cpp | 1 | #include <cstdint> | COMMENT |
| LOW | src/python/test_tools/power_sweep.py | 1 | # This script runs an automated voltage sweep while collecting ADC DBGLN() output | COMMENT |
| LOW | src/python/external/six.py | 1 | # Copyright (c) 2010-2020 Benjamin Peterson | COMMENT |
| LOW | src/python/external/esptool/esptool.py | 1 | #!/usr/bin/env python | COMMENT |
| LOW | src/python/external/jmespath/functions.py | 101 | # Type checking involves checking the top level type, | COMMENT |
| LOW | src/python/external/jmespath/visitor.py | 21 | # False | COMMENT |
| LOW | src/include/native.h | 1 | #pragma once | COMMENT |
| LOW | src/include/common.h | 1 | #pragma once | COMMENT |
| LOW | src/include/crsf_protocol.h | 1 | #pragma once | COMMENT |
| LOW | src/include/crsf_protocol.h | 21 | #define CRSF_CHANNEL_VALUE_1000 191 // 1000us | COMMENT |
| LOW | src/include/telemetry_protocol.h | 1 | #pragma once | COMMENT |
| LOW | src/include/targets.h | 1 | #pragma once | COMMENT |
| LOW | src/include/targets.h | 21 | #define ICACHE_RAM_ATTR IRAM_ATTR | COMMENT |
| LOW | src/include/targets.h | 41 | extern bool pwmSerialDefined; | COMMENT |
| LOW | src/include/targets.h | 61 | #if !(defined(Regulatory_Domain_AU_915) || defined(Regulatory_Domain_FCC_915) || \ | COMMENT |
| LOW | src/include/target/Unified_ESP8285_TX.h | 1 | // Serial | COMMENT |
| LOW | src/include/target/Unified_ESP8285_TX.h | 21 | COMMENT | |
| LOW | src/include/target/Unified_ESP8285_TX.h | 41 | #define POWER_OUTPUT_VALUES2_COUNT POWER_OUTPUT_VALUES_COUNT | COMMENT |
| LOW | src/include/target/Unified_ESP8285_TX.h | 61 | #define WS2812_VTX_STATUS_LEDS hardware_i16_array(HARDWARE_ledidx_rgb_vtx) | COMMENT |
| LOW | src/include/target/Unified_ESP8285_TX.h | 81 | #define OPT_HAS_GSENSOR_STK8xxx false | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 1 | // Serial | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 21 | #define LR1121_RFSW_CTRL hardware_u16_array(HARDWARE_radio_rfsw_ctrl) | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 41 | #define SKY85321_PDET_SLOPE hardware_float(HARDWARE_power_pdet_slope) | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 61 | #define USER_BUTTON_LED hardware_pin(HARDWARE_button_led_index) | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 81 | COMMENT | |
| LOW | src/include/target/Unified_ESP32_TX.h | 101 | // OLED/TFT | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 121 | #define GPIO_PIN_DEBUG_TX hardware_pin(HARDWARE_debug_backpack_tx) | COMMENT |
| LOW | src/include/target/Unified_ESP32_TX.h | 141 | #define OPT_HAS_THERMAL_LM75A hardware_flag(HARDWARE_thermal_lm75a) | COMMENT |
| LOW | src/include/target/Unified_ESP_RX.h | 1 | // Serial | COMMENT |
| LOW | src/include/target/Unified_ESP_RX.h | 21 | #define OPT_USE_HARDWARE_DCDC hardware_flag(HARDWARE_radio_dcdc) | COMMENT |
| LOW | src/include/target/Unified_ESP_RX.h | 41 | COMMENT | |
| LOW | src/include/target/Unified_ESP_RX.h | 61 | #define GPIO_LED_GREEN_INVERTED false | COMMENT |
| LOW | src/include/target/Unified_ESP_RX.h | 81 | COMMENT | |
| LOW | src/include/target/Unified_ESP_RX.h | 101 | #define GPIO_PIN_FAN_SPEEDS hardware_u16_array(HARDWARE_misc_fan_speeds) | COMMENT |
| LOW | src/html/build-plugins/feature-blocks-plugin.js | 1 | // Feature marker processor shared by build-time plugins. | COMMENT |
| LOW | src/lib/WIFI/lr1121.cpp | 1 | #include "targets.h" | COMMENT |
| LOW | src/lib/WIFI/devWIFI.cpp | 1 | #include "device.h" | COMMENT |
| LOW | src/lib/WIFI/devWIFI.cpp | 21 | #endif | COMMENT |
| LOW | src/lib/WIFI/devWIFI.cpp | 41 | #endif | COMMENT |
| LOW | src/lib/WIFI/wifiJoystick.cpp | 1 | #include "device.h" | COMMENT |
| LOW | src/lib/AnalogVbat/devAnalogVbat.cpp | 1 | #include "devAnalogVbat.h" | COMMENT |
| LOW | src/lib/LR1121Driver/LR1121.cpp | 1 | #include "LR1121.h" | COMMENT |
| LOW | src/lib/LR1121Driver/LR1121_Regs.h | 41 | #define LR1121_POWER_MAX_LP_PA (14) | COMMENT |
| LOW | src/lib/LR1121Driver/LR1121Driver.h | 1 | #pragma once | COMMENT |
| LOW | src/lib/VTXSPI/devVTXSPI.cpp | 1 | #include "targets.h" | COMMENT |
| LOW | src/lib/VTXSPI/devVTXSPI.cpp | 21 | COMMENT | |
| LOW | src/lib/FHSS/FHSS.cpp | 1 | #include "FHSS.h" | COMMENT |
| LOW | src/lib/FHSS/FHSS.h | 1 | #pragma once | COMMENT |
| LOW | src/lib/CRSF2MSP/crsfmsp_common.h | 1 | COMMENT | |
| 95 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | …ython/external/esptool/esptool/targets/esp32h2beta1.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | …ython/external/esptool/esptool/targets/esp32s3beta2.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | src/python/external/esptool/esptool/targets/esp32s3.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | src/python/external/esptool/esptool/targets/esp32c3.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | src/python/external/esptool/esptool/targets/esp32s2.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | src/python/external/esptool/esptool/targets/esp32c2.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| HIGH | …ython/external/esptool/esptool/targets/esp32h2beta2.py | 0 | access class for esp32h2beta2 stub loader, runs on top of rom. (basically the same as esp32stubloader, but different bas | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/bind.py | 5 | CODE | |
| LOW | src/python/set_model.py | 5 | CODE | |
| LOW | src/python/external/six.py | 23 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 42 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 68 | CODE | |
| LOW | src/python/external/jmespath/compat.py | 1 | CODE | |
| LOW | src/python/external/jmespath/compat.py | 3 | CODE | |
| LOW | src/python/external/jmespath/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 1 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 1 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE | |
| LOW | src/python/external/inputimeout/__init__.py | 2 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/external/esptool/esptool/bin_image.py | 645 | def get_alignment_data_needed(segment): | CODE |
| LOW | src/python/external/esptool/esptool/__init__.py | 893 | def get_default_connected_device( | CODE |
| LOW | src/python/external/esptool/esptool/cmds.py | 225 | def _update_image_flash_params(esp, address, args, image): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32.py | 102 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32.py | 147 | def get_encrypted_download_disabled(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32.py | 156 | def get_flash_encryption_enabled(self): | CODE |
| LOW | …ython/external/esptool/esptool/targets/esp32h2beta1.py | 129 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32c3.py | 152 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32s2.py | 207 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32s3.py | 130 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/esptool/esptool/targets/esp32c2.py | 120 | def is_flash_encryption_key_valid(self): | CODE |
| LOW | src/python/external/jmespath/functions.py | 361 | def _convert_to_jmespath_type(self, pyobject): | CODE |
| LOW | src/python/external/jmespath/parser.py | 140 | def _token_nud_unquoted_identifier(self, token): | CODE |
| LOW | src/python/external/jmespath/parser.py | 143 | def _token_nud_quoted_identifier(self, token): | CODE |
| LOW | src/python/external/jmespath/parser.py | 472 | def _raise_parse_error_for_token(self, token, reason): | CODE |
| LOW | src/python/external/jmespath/parser.py | 479 | def _raise_parse_error_maybe_eof(self, expected_type, token): | CODE |
| LOW | src/python/external/jmespath/visitor.py | 166 | def visit_function_expression(self, node, value): | CODE |
| LOW | src/python/external/jmespath/lexer.py | 120 | def _initialize_for_expression(self, expression): | CODE |
| LOW | src/python/external/jmespath/lexer.py | 179 | def _consume_quoted_identifier(self): | CODE |
| LOW | src/python/external/jmespath/lexer.py | 192 | def _consume_raw_string_literal(self): | CODE |
| LOW | src/html/dev-plugins/dev-mock-plugin.js | 158 | function countVoltageSourcesFromHardware(hardware) { | CODE |
| LOW | src/html/dev-plugins/dev-mock-plugin.js | 167 | function syncVoltageSourcesFromHardware(hardware) { | CODE |
| LOW | …html/build-plugins/inline-static-html-assets-plugin.js | 19 | export function inlineStaticHtmlAssetsPlugin() { | CODE |
| LOW | src/html/build-plugins/feature-blocks-plugin.js | 18 | export function createFeatureBlockProcessor(env) { | CODE |
| LOW | src/html/build-plugins/css-tree-shake-plugin.js | 55 | function collectUsedCssTokensFromBundle(bundle) { | CODE |
| LOW | src/html/build-plugins/css-tree-shake-plugin.js | 129 | function extractRequiredTokensFromSelector(selector) { | CODE |
| LOW | src/html/build-plugins/css-tree-shake-plugin.js | 157 | function selectorIsDefinitelyUnused(selector, usedTokens) { | CODE |
| LOW | src/html/build-plugins/css-tree-shake-plugin.js | 215 | async function collectUsedCssTokensFromSource(root, processHtml, processJs) { | CODE |
| LOW | src/html/src/pages/voltage-calibration-panel.js | 41 | function getVoltageSourcesFromHardware(hardware) { | CODE |
| LOW | src/lua/elrs.lua | 444 | local function parseParameterInfoMessage(data) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/crsf.py | 54 | CODE | |
| LOW | src/python/crsf.py | 101 | CODE | |
| LOW | src/python/UnifiedConfiguration.py | 38 | CODE | |
| LOW | src/python/BFinitPassthrough.py | 40 | CODE | |
| LOW | src/python/BFinitPassthrough.py | 114 | CODE | |
| LOW | src/python/serials_find.py | 5 | CODE | |
| LOW | src/python/binary_flash.py | 126 | CODE | |
| LOW | src/python/binary_configurator.py | 52 | CODE | |
| LOW | src/python/binary_configurator.py | 120 | CODE | |
| LOW | src/python/binary_configurator.py | 174 | CODE | |
| LOW | src/python/test_tools/power_sweep.py | 50 | CODE | |
| LOW | src/python/test_tools/power_sweep.py | 68 | CODE | |
| LOW | src/python/external/esptool/esptool/bin_image.py | 50 | CODE | |
| LOW | src/python/external/esptool/esptool/bin_image.py | 606 | CODE | |
| LOW | src/python/external/esptool/esptool/bin_image.py | 830 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 76 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 870 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 929 | CODE | |
| LOW | src/python/external/esptool/esptool/__init__.py | 732 | CODE | |
| LOW | src/python/external/esptool/esptool/loader.py | 1390 | CODE | |
| LOW | src/python/external/esptool/esptool/loader.py | 604 | CODE | |
| LOW | src/python/external/esptool/esptool/cmds.py | 67 | CODE | |
| LOW | src/python/external/esptool/esptool/cmds.py | 309 | CODE | |
| LOW | src/python/external/esptool/esptool/cmds.py | 772 | CODE | |
| LOW | src/python/external/jmespath/functions.py | 136 | CODE | |
| LOW | src/python/external/jmespath/functions.py | 197 | CODE | |
| LOW | src/python/external/jmespath/functions.py | 295 | CODE | |
| LOW | src/python/external/jmespath/parser.py | 391 | CODE | |
| LOW | src/python/external/jmespath/lexer.py | 26 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/UnifiedConfiguration.py | 145 | except Exception: | CODE |
| LOW⚡ | src/python/external/esptool/esptool/__init__.py | 792 | except Exception as e: | CODE |
| LOW⚡ | src/python/external/esptool/esptool/__init__.py | 799 | except Exception as e: | CODE |
| LOW | src/python/external/esptool/esptool/loader.py | 56 | except Exception: | CODE |
| LOW | src/python/external/esptool/esptool/cmds.py | 254 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/python/external/esptool/esptool/__init__.py | 795 | # Check if XMC SPI flash chip booted-up successfully, fix if not | COMMENT |
| LOW⚡ | src/python/external/esptool/esptool/__init__.py | 809 | # Check if stub supports chosen flash size | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/external/esptool/esptool/loader.py | 426 | # otherwise, just return the 'val' field which comes from the reply header | COMMENT |
| LOW | src/python/external/jmespath/parser.py | 188 | # just use emit an index node here if we're not dealing | COMMENT |
| LOW | src/python/external/jmespath/parser.py | 333 | # we can avoid creating another node and instead just add | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/lib/Baro/baro_spl06.cpp | 50 | // Step 1: Load calibration data | COMMENT |
| LOW | src/lib/Baro/baro_spl06.cpp | 69 | // Step 2: Set up oversampling and FIFO | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/lib/Baro/baro_spl06.cpp | 50 | // Step 1: Load calibration data | COMMENT |
| LOW | src/lib/Baro/baro_spl06.cpp | 69 | // Step 2: Set up oversampling and FIFO | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/external/streamexpect.py | 795 | __all__ = [ | CODE |
| LOW | src/python/external/esptool/esptool/__init__.py | 8 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/python/external/jmespath/parser.py | 510 | CODE |