{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"codehealth","informationUri":"https://codehealth.canine.dev","rules":[{"id":"D1","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D1"},{"id":"D2","name":"Cognitive Complexity","shortDescription":{"text":"Cognitive Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D2"},{"id":"D3","name":"God Classes","shortDescription":{"text":"God Classes"},"helpUri":"https://codehealth.canine.dev/dimensions/D3"},{"id":"D4","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/D4"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D11","name":"Test Reliability","shortDescription":{"text":"Test Reliability"},"helpUri":"https://codehealth.canine.dev/dimensions/D11"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D22","name":"Internal API Consistency","shortDescription":{"text":"Internal API Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D22"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"]}},{"id":"D37","name":"Vulnerability-disclosure Policy","shortDescription":{"text":"Vulnerability-disclosure Policy"},"helpUri":"https://codehealth.canine.dev/dimensions/D37","relationships":[{"target":{"id":"CWE-1059","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1059"]}},{"id":"D43","name":"Malicious Dependencies","shortDescription":{"text":"Malicious Dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/D43","relationships":[{"target":{"id":"CWE-506","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"]}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"AC3","name":"Page structure","shortDescription":{"text":"Page structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AC3"},{"id":"AC7","name":"A11y enforcement","shortDescription":{"text":"A11y enforcement"},"helpUri":"https://codehealth.canine.dev/dimensions/AC7"},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P4","name":"Deployment \u0026 Rollback","shortDescription":{"text":"Deployment \u0026 Rollback"},"helpUri":"https://codehealth.canine.dev/dimensions/P4"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"SelfdriveD.update_events (cyclomatic 156): SelfdriveD.update_events has cyclomatic complexity 156 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"e35cc62245adbf42a1efdb14979c51b170ec97b913c82979c29bc7ce516a37da"}},{"ruleId":"D1","level":"warning","message":{"text":"hardwared.hardware_thread (cyclomatic 63): hardwared.hardware_thread has cyclomatic complexity 63 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/hardwared.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ecbcc49e9cbbf98b36e1eec58989ba0a387c1ed07eb89bc189bae954cb7d11d"}},{"ruleId":"D1","level":"warning","message":{"text":"qcomgpsd.main (cyclomatic 47): qcomgpsd.main has cyclomatic complexity 47 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fc7e78532f9055c2598a0f539313e5220af07c84af762613f9c0c999c28be57"}},{"ruleId":"D1","level":"warning","message":{"text":"serve._render_blocks (cyclomatic 46): serve._render_blocks has cyclomatic complexity 46 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"07133c149e59f4e099cfb4ba6dda8a1e7cf6a0624e82cf0f37299780771734a2"}},{"ruleId":"D1","level":"warning","message":{"text":"CarEvents.create_common_events (cyclomatic 46): CarEvents.create_common_events has cyclomatic complexity 46 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"a962fa39d7a28e94a816c57a870892f867bdb036889f642ad7ceda64bd52da9f"}},{"ruleId":"D1","level":"warning","message":{"text":"modeld.main (cyclomatic 45): modeld.main has cyclomatic complexity 45 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/modeld.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a5b384a44d9d767be8e6e8ae46348f2dae80bdc622915adf18b4a20bfbe86f8"}},{"ruleId":"D1","level":"warning","message":{"text":"generate_report.report (cyclomatic 41): generate_report.report has cyclomatic complexity 41 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1873eb80bdf2bb6313b9abf01ab3c91172f06386fd6c67517ba322cd477097b"}},{"ruleId":"D1","level":"warning","message":{"text":"ChestnutStatus.update (cyclomatic 40): ChestnutStatus.update has cyclomatic complexity 40 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/chestnut/status.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"70635bef810cf874eef505df680f8768d17dccd3f41a00b94edbbd99e12a3901"}},{"ruleId":"D1","level":"warning","message":{"text":"CarEvents.update (cyclomatic 37): CarEvents.update has cyclomatic complexity 37 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"05ce56e9c28b0b5ded0d234e9fb0dd9782cd2db1fd1cf523f1f91bf661f6b348"}},{"ruleId":"D1","level":"warning","message":{"text":"LocationEstimator.handle_log (cyclomatic 33): LocationEstimator.handle_log has cyclomatic complexity 33 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"768540b86b19211f2e9757580d0b37df6f391ad732415b49af8c716f96cd86e1"}},{"ruleId":"D1","level":"warning","message":{"text":"DriverMonitoring._update_events (cyclomatic 32): DriverMonitoring._update_events has cyclomatic complexity 32 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/policy.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1065eaec9460fd1247419c3299fb0277c0c553a056a2cc74c12fafc3e9979a9"}},{"ruleId":"D1","level":"warning","message":{"text":"UnifiedLabel._render (cyclomatic 31): UnifiedLabel._render has cyclomatic complexity 31 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f8d000ddff9a407e7b652e380ee0051bb45d4f88103e1e90de5fa48eaa65d65"}},{"ruleId":"D1","level":"warning","message":{"text":"SimulatorBridge._run (cyclomatic 30): SimulatorBridge._run has cyclomatic complexity 30 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/bridge/common.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"5352634fc9de034c17d79e72462297db0b45c171cdbe6f7ab06a48859e5e4d1d"}},{"ruleId":"D1","level":"warning","message":{"text":"lateral_maneuversd.main (cyclomatic 29): lateral_maneuversd.main has cyclomatic complexity 29 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/lateral_maneuversd.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"73223eeb79ab9f9a15257b37c55e1a9bfd4d4cfb7021b2fdb5d099b369e35a33"}},{"ruleId":"D1","level":"warning","message":{"text":"DriverMonitoring._update_states (cyclomatic 27): DriverMonitoring._update_states has cyclomatic complexity 27 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/policy.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1a58ba3b1c31d16c42ceb8a9f73ea5096c87d796dfc5fe76dbb58c74db9015b"}},{"ruleId":"D1","level":"warning","message":{"text":"GuiScrollPanel2._handle_mouse_event (cyclomatic 27): GuiScrollPanel2._handle_mouse_event has cyclomatic complexity 27 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"626a39ded05a5e9540b6836db7751b0b31c7e308e70af890235805b7b6ed405a"}},{"ruleId":"D1","level":"warning","message":{"text":"Route._get_segments_local (cyclomatic 26): Route._get_segments_local has cyclomatic complexity 26 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5fe9bb6362eadf3c65f40ac23df05cffff7c87d00f2b7e28b1595584778278b"}},{"ruleId":"D1","level":"warning","message":{"text":"DesireHelper.update (cyclomatic 25): DesireHelper.update has cyclomatic complexity 25 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/desire_helper.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"663c7c5aa0884b3462649d1c600d14a4e90691fea5d7449a3739a37f2b0a0a3d"}},{"ruleId":"D1","level":"warning","message":{"text":"StateMachine.update (cyclomatic 25): StateMachine.update has cyclomatic complexity 25 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/state.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcbfec8ea38989c73edf49f93031889c114200224c80ce3963922feec8053154"}},{"ruleId":"D1","level":"warning","message":{"text":"WifiManager._handle_state_change (cyclomatic 25): WifiManager._handle_state_change has cyclomatic complexity 25 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"1af77566dd44d9eec223ac65d41d5c1d615ff0f09cad66ca5b1ae98c7adb6b4d"}},{"ruleId":"D1","level":"warning","message":{"text":"serve.inject_glossary (cyclomatic 24): serve.inject_glossary has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"139a49dc7d14b8d93f13b1ae7fe9ce9d2a449ff7f0abdc4324ee8a6d0f05cb57"}},{"ruleId":"D1","level":"warning","message":{"text":"GuiApplication.render (cyclomatic 24): GuiApplication.render has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"b27232a13da7a8c5bae2b67fd2b2c017a1ba5a752846f705610ab914bdfd15fd"}},{"ruleId":"D1","level":"warning","message":{"text":"serve.render_inline (cyclomatic 23): serve.render_inline has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"aae6ef92c7f2cd9a2926ade5a84cc83ff467c12befdce0d53d94d6fd5158ff31"}},{"ruleId":"D1","level":"warning","message":{"text":"qrcode._parse_data (cyclomatic 23): qrcode._parse_data has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a588b873f59ba322c2783137fb0ec1c584657d3729099a6767873af8fb29928"}},{"ruleId":"D1","level":"warning","message":{"text":"potools.extract_strings (cyclomatic 23): potools.extract_strings has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/translations/potools.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"57000c5e4f7651ad5d96d15f840639af91f6dd2c849648092c7311e85eb14798"}},{"ruleId":"D1","level":"warning","message":{"text":"CheckUpdateButton._update_state (cyclomatic 22): CheckUpdateButton._update_state has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/software.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"dea8331638d2a1dfa9d7cf808c69da6819317f01631134c8966d25af671391de"}},{"ruleId":"D1","level":"warning","message":{"text":"UbloxMsgParser._parse_glonass_ephemeris (cyclomatic 22): UbloxMsgParser._parse_glonass_ephemeris has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/ubloxd.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1e47e104a878c46ab42abc1d555f52ae8457c6bf7aea97f4f20a1dc1bffc49d"}},{"ruleId":"D1","level":"warning","message":{"text":"generate_report.report (cyclomatic 22): generate_report.report has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/generate_report.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf211e1f08a2c911938787b2ac221e6c222d25ed6a6cb1fc0784865c54631224"}},{"ruleId":"D1","level":"warning","message":{"text":"potools.parse_po (cyclomatic 21): potools.parse_po has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/translations/potools.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"f62075e8b182a0e717493a4e20f2b1722386ed25dbaabb1b3e929a3b4af08d04"}},{"ruleId":"D1","level":"warning","message":{"text":"manager.manager_thread (cyclomatic 21): manager.manager_thread has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/manager.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"99c5b67fc63ce65f365e4cdb2c4be95b36216a76c40af205907470d936ca3ece"}},{"ruleId":"D1","level":"warning","message":{"text":"compressed_vipc.decoder (cyclomatic 21): compressed_vipc.decoder has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/camerastream/compressed_vipc.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"c408ce2765636b1086b2a2cc233ad07045c1fdc2c0f8f201947e244a48e80b05"}},{"ruleId":"D1","level":"warning","message":{"text":"ci_results.format_markdown (cyclomatic 21): ci_results.format_markdown has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/ci_results.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a1933b6cb1abc61a1ee7ccf7e5d2d3d924d8428cad4d34a0ef1fc1161b6e584"}},{"ruleId":"D1","level":"warning","message":{"text":"VCruiseHelper._update_v_cruise_non_pcm (cyclomatic 20): VCruiseHelper._update_v_cruise_non_pcm has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/cruise.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3a054bdcaf2af7ad9e6e37442334d02f58b6d6dc0e0d06e7e5c58dacc7240ff"}},{"ruleId":"D1","level":"warning","message":{"text":"file_downloader.cmd_download (cyclomatic 20): file_downloader.cmd_download has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/file_downloader.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"1db712b84386af82c8574f483fe4c1f1028c0b411854d5a681166b80d6093b02"}},{"ruleId":"D1","level":"warning","message":{"text":"metadrive_process.metadrive_process (cyclomatic 20): metadrive_process.metadrive_process has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/bridge/metadrive/metadrive_process.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"04f976f7361d27d3e3bd8026e73f07bdae2b2b1531b6fa7772156b95381a4c8c"}},{"ruleId":"D1","level":"warning","message":{"text":"check_shell.check_text (cyclomatic 20): check_shell.check_text has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lint/check_shell.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b14adeb7d31eb7bfd0a27a2af1268bcf87d2dd9ba6ac21fe8cab33d2f61ca22"}},{"ruleId":"D1","level":"warning","message":{"text":"utils.tabulate (cyclomatic 19): utils.tabulate has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/utils.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"d03aa19fc357c5b842af12e673d2a53fc3dd6865222fe762c8a7619409893765"}},{"ruleId":"D1","level":"warning","message":{"text":"registration.register (cyclomatic 19): registration.register has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/registration.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2fb3a11e7258d2368721301deca0a4e4673e865aa6d713ed6a51ffe448f7b78"}},{"ruleId":"D1","level":"warning","message":{"text":"Widget._process_mouse_events (cyclomatic 19): Widget._process_mouse_events has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/__init__.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"41292e2360f3b3331d0d6995aa0b95f73e6a70f72185281631dba86987fc99e1"}},{"ruleId":"D1","level":"warning","message":{"text":"qrcode._rs_correct (cyclomatic 18): qrcode._rs_correct has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":325}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e99a5f1b77c72bbec2b61d6470d50ee28e16e489922874205542f239c9bfcfb"}},{"ruleId":"D1","level":"warning","message":{"text":"Controls.state_control (cyclomatic 18): Controls.state_control has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/controlsd.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"532e4dde16c9ded97e52fce2afc34d5819f20362d7c72f57440747fcc5fb554b"}},{"ruleId":"D1","level":"warning","message":{"text":"locationd.main (cyclomatic 18): locationd.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc9c55264e4a013c0fe31430ba667cdff66a818478b269f5a00502b6547b43bd"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfdriveD.data_sample (cyclomatic 18): SelfdriveD.data_sample has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"720cbafc1190bade67dafbd8ebd3a196592d80f503bc4a012e9991046f2274f3"}},{"ruleId":"D1","level":"warning","message":{"text":"GuiScrollPanel2._update_state (cyclomatic 18): GuiScrollPanel2._update_state has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"52227b5780ac5d7f12cb5ebc29df8569dcf07bd4256ea8655cfa2f255ff269ba"}},{"ruleId":"D1","level":"warning","message":{"text":"Keyboard._render (cyclomatic 18): Keyboard._render has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/keyboard.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ed28044872c06771accce3c1689332ab857d9de1347af6e2aba4f28d77c6d17"}},{"ruleId":"D1","level":"warning","message":{"text":"StreamSession.message_handler (cyclomatic 18): StreamSession.message_handler has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/webrtc/webrtcd.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"148d6ad9a6b6bc0981bb6761434c9ac1ad02f2231528663ca4817dfe56150640"}},{"ruleId":"D1","level":"warning","message":{"text":"Generator.node_emits (cyclomatic 18): Generator.node_emits has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/generate_event_extractors.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aa66e64f5290eb7f4ea4a4e4e5ee8a3b41413f69f72e05397d0d3c23a8cd300"}},{"ruleId":"D1","level":"warning","message":{"text":"SteeringAccuracyTool.update (cyclomatic 18): SteeringAccuracyTool.update has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/car_porting/measure_steering_accuracy.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cf7ed821c5acb71c29a057cde0f80c70b892f8db03782c674efa5818e5f988f"}},{"ruleId":"D1","level":"warning","message":{"text":"binary_struct._parse_field (cyclomatic 17): binary_struct._parse_field has cyclomatic complexity 17 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/binary_struct.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"a97401cd82ee251e8d1617743cc6efb822e6864995a2f785e25b9d5da0b69416"}},{"ruleId":"D1","level":"warning","message":{"text":"ui.ui_thread (cyclomatic 17): ui.ui_thread has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/replay/ui.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6d7031ddffec423e41252fc6e39dca27cf29e8dd0a3c8379f2a07b62b723b9d"}},{"ruleId":"D1","level":"warning","message":{"text":"max_lat_accel.find_events (cyclomatic 17): max_lat_accel.find_events has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/max_lat_accel.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc070356f3e110c535c06723cfc1d444e097ac4f04d3ae731726625a1feb6547"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfdriveD.__init__ (cyclomatic 16): SelfdriveD.__init__ has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"67b470e2b0ee0af1cc50ef6f5c3d3cc604c8e7d58bcd33520f16a6b126544bcd"}},{"ruleId":"D1","level":"warning","message":{"text":"SoftwareLayout._update_state (cyclomatic 16): SoftwareLayout._update_state has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/software.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"11988affb5d2c66f0be8526a28b9514ce6a2996c5d50cec968f2aa5f453a5c08"}},{"ruleId":"D1","level":"warning","message":{"text":"athenad.log_handler (cyclomatic 16): athenad.log_handler has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":838}}}],"partialFingerprints":{"codehealthFindingId/v1":"c283de8952e84007246e440defa8038ef6e7b4c68e724da34cb57f70af152bb7"}},{"ruleId":"D1","level":"warning","message":{"text":"structs.parse_struct (cyclomatic 16): structs.parse_struct has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/structs.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"60dad32f551cd50f833132634b9a66cda85b4832534db5a4ee0ced5e6d607ae6"}},{"ruleId":"D1","level":"warning","message":{"text":"updated.main (cyclomatic 16): updated.main has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"42fd902f96f2c086823c56344ecfb6df4c2f12cdf2eb050f50f219e77149a392"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfdriveD.update_events (cognitive 191): SelfdriveD.update_events has cognitive complexity 191 (threshold 15). Drivers by points: if/else 81 (116 pts), boolean chains 61, ternaries 5 (13 pts), loops 1 (nesting depth added 43). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"877a0bb9287f71abdb7c933a9de11e5c8dbf4e97e8d1b4f1f2225643e38aa601"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_report.report (cognitive 126): generate_report.report has cognitive complexity 126 (threshold 15). Drivers by points: if/else 26 (86 pts), loops 8 (24 pts), ternaries 3 (11 pts), boolean chains 5 (nesting depth added 84). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"6baa6e406f506fa5ba3b66308ddebd20dbde81baddbbd2e78e069d716c6d4c12"}},{"ruleId":"D2","level":"warning","message":{"text":"serve._render_blocks (cognitive 114): serve._render_blocks has cognitive complexity 114 (threshold 15). Drivers by points: if/else 18 (50 pts), loops 10 (30 pts), ternaries 6 (22 pts), boolean chains 12 (nesting depth added 68). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"12954e8eb565d7c1daa752a94d5b008cd82a96b37a11a00cb1d34c0537df22d4"}},{"ruleId":"D2","level":"warning","message":{"text":"hardwared.hardware_thread (cognitive 110): hardwared.hardware_thread has cognitive complexity 110 (threshold 15). Drivers by points: if/else 28 (64 pts), boolean chains 22, ternaries 7 (14 pts), error handling 3 (9 pts), loops 1 (nesting depth added 49). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/hardwared.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"e634862283a97944cfcceea1876b00a075325eadd7cc5741e9ea631dfa0059d6"}},{"ruleId":"D2","level":"warning","message":{"text":"qcomgpsd.main (cognitive 105): qcomgpsd.main has cognitive complexity 105 (threshold 15). Drivers by points: if/else 21 (55 pts), loops 11 (46 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 71). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b3ddae626088f653a711e46e1ffad2f9896f97f2855c2af0458889ddecc026b"}},{"ruleId":"D2","level":"warning","message":{"text":"modeld.main (cognitive 77): modeld.main has cognitive complexity 77 (threshold 15). Drivers by points: if/else 20 (40 pts), ternaries 9 (16 pts), boolean chains 10, loops 6 (9 pts), error handling 1 (2 pts) (nesting depth added 31). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/modeld.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"f976e593e74de82a522f9c0b22e95cc8c18ee9117215e5bcb414956adce0a76c"}},{"ruleId":"D2","level":"warning","message":{"text":"potools.extract_strings (cognitive 67): potools.extract_strings has cognitive complexity 67 (threshold 15). Drivers by points: if/else 15 (49 pts), ternaries 2 (10 pts), boolean chains 3, loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 44). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/translations/potools.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"469f30f3bafc5e0559c1d8f8e6ed1598537f11f95a16ee405b207f953d68c267"}},{"ruleId":"D2","level":"warning","message":{"text":"SteeringAccuracyTool.update (cognitive 66): SteeringAccuracyTool.update has cognitive complexity 66 (threshold 15). Drivers by points: if/else 15 (43 pts), ternaries 2 (13 pts), loops 3 (9 pts), boolean chains 1 (nesting depth added 45). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/car_porting/measure_steering_accuracy.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"efbb7fc53acd3ee1c9602faaf037ccb5323d8de7bbf94c499489be975ab7022a"}},{"ruleId":"D2","level":"warning","message":{"text":"CarEvents.update (cognitive 59): CarEvents.update has cognitive complexity 59 (threshold 15). Drivers by points: if/else 20 (48 pts), boolean chains 11 (nesting depth added 28). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"15e0bf84d71e0e093a2ad0c541d269453a0d291e82a6f3ff7d6150a5b9f70e26"}},{"ruleId":"D2","level":"warning","message":{"text":"compressed_vipc.decoder (cognitive 57): compressed_vipc.decoder has cognitive complexity 57 (threshold 15). Drivers by points: if/else 13 (44 pts), error handling 2 (7 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 37). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/camerastream/compressed_vipc.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba997f7d0bed9a6505b1521f2fe7e9b0a01efc041c738bbe40950d6768893431"}},{"ruleId":"D2","level":"warning","message":{"text":"UnifiedLabel._render (cognitive 53): UnifiedLabel._render has cognitive complexity 53 (threshold 15). Drivers by points: if/else 24 (44 pts), boolean chains 4, loops 3, ternaries 1 (2 pts) (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"e20bc318e8ae0789f95c4475308da86378194c610067aedafd03df8fd544c47a"}},{"ruleId":"D2","level":"warning","message":{"text":"CarEvents.create_common_events (cognitive 52): CarEvents.create_common_events has cognitive complexity 52 (threshold 15). Drivers by points: if/else 34 (39 pts), boolean chains 11, loops 1, ternaries 1 (nesting depth added 5). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"da53399d9e94d22d6fb58d9dc3bd6ece912712ea5efba035d9d94b28080cd345"}},{"ruleId":"D2","level":"warning","message":{"text":"GuiScrollPanel2._handle_mouse_event (cognitive 52): GuiScrollPanel2._handle_mouse_event has cognitive complexity 52 (threshold 15). Drivers by points: if/else 19 (45 pts), boolean chains 4, ternaries 1 (3 pts) (nesting depth added 28). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"aee274dd3ce19404de4e433af2b25ef21bb3feea57588963a9dd1b0b48dd7fd8"}},{"ruleId":"D2","level":"warning","message":{"text":"lateral_maneuversd.main (cognitive 51): lateral_maneuversd.main has cognitive complexity 51 (threshold 15). Drivers by points: if/else 13 (27 pts), ternaries 4 (14 pts), boolean chains 9, loops 1 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/lateral_maneuversd.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0327363a64a149f9cd5141297a09e1b5384b134560b3f3c405254f07329ce56"}},{"ruleId":"D2","level":"warning","message":{"text":"Route._get_segments_local (cognitive 51): Route._get_segments_local has cognitive complexity 51 (threshold 15). Drivers by points: if/else 11 (25 pts), loops 5 (13 pts), error handling 6 (12 pts), boolean chains 1 (nesting depth added 28). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f662a1608f80a70a48d12f540a7cc54d174b5a6daa6856c814d9fec00629a338"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_report.report (cognitive 50): generate_report.report has cognitive complexity 50 (threshold 15). Drivers by points: if/else 10 (30 pts), loops 5 (10 pts), ternaries 2 (6 pts), boolean chains 4 (nesting depth added 29). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/generate_report.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce3a910f54473e4e690db9da5a6663e2ee9d42e55de50facbd62e2ad8c23efa9"}},{"ruleId":"D2","level":"warning","message":{"text":"serve.inject_glossary (cognitive 48): serve.inject_glossary has cognitive complexity 48 (threshold 15). Drivers by points: if/else 10 (27 pts), ternaries 3 (9 pts), boolean chains 6, loops 3 (6 pts) (nesting depth added 26). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"66c2625ed400ce280f02a1328dba16e8b7388f51a614417f7eef0f67b0f57ed6"}},{"ruleId":"D2","level":"warning","message":{"text":"qrcode._parse_data (cognitive 48): qrcode._parse_data has cognitive complexity 48 (threshold 15). Drivers by points: if/else 6 (15 pts), ternaries 6 (15 pts), loops 4 (10 pts), error handling 2 (7 pts), boolean chains 1 (nesting depth added 29). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"c32fdef35f12d1558361a021dfc12b9b18137da1116cfb006bf7e17ccb1df701"}},{"ruleId":"D2","level":"warning","message":{"text":"ci_results.format_markdown (cognitive 47): ci_results.format_markdown has cognitive complexity 47 (threshold 15). Drivers by points: if/else 11 (20 pts), ternaries 5 (17 pts), loops 4 (7 pts), boolean chains 3 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/ci_results.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"fff48b0985c859d34fb2cd72b25bf534b300b291f0dbca2aa8f5d563cd495b72"}},{"ruleId":"D2","level":"warning","message":{"text":"ChestnutStatus.update (cognitive 46): ChestnutStatus.update has cognitive complexity 46 (threshold 15). Drivers by points: boolean chains 21, if/else 12 (13 pts), ternaries 7 (12 pts) (nesting depth added 6). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/chestnut/status.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"da98a566b4b057a330ae4ae3e3866fea4f4e53cd0a813b5106ed918bc8cb6c53"}},{"ruleId":"D2","level":"warning","message":{"text":"GuiApplication.render (cognitive 46): GuiApplication.render has cognitive complexity 46 (threshold 15). Drivers by points: if/else 18 (37 pts), loops 3 (5 pts), boolean chains 3, error handling 1 (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"96c145bc7e79be48483ea809227c5cb1c4bedcbfae025a8c35bbd40cb5d8ad73"}},{"ruleId":"D2","level":"warning","message":{"text":"LocationEstimator.handle_log (cognitive 45): LocationEstimator.handle_log has cognitive complexity 45 (threshold 15). Drivers by points: if/else 18 (35 pts), boolean chains 10 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"d761bbc42c678c9def46e373324b0dae2a21e1c6a73fd514a03441f3ef8996a5"}},{"ruleId":"D2","level":"warning","message":{"text":"locationd.main (cognitive 40): locationd.main has cognitive complexity 40 (threshold 15). Drivers by points: if/else 8 (24 pts), loops 4 (10 pts), ternaries 2 (4 pts), boolean chains 2 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"67708461e62e7d2515de5713c946380683e9a5eba72d2f565876813638c8c733"}},{"ruleId":"D2","level":"warning","message":{"text":"potools.parse_po (cognitive 40): potools.parse_po has cognitive complexity 40 (threshold 15). Drivers by points: if/else 16 (39 pts), loops 1 (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/translations/potools.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a97407edf7ae795b14d7ab6561bf7980ab7b0d2639c83da1e1dd66da846e4b6"}},{"ruleId":"D2","level":"warning","message":{"text":"Route._get_segments_remote (cognitive 40): Route._get_segments_remote has cognitive complexity 40 (threshold 15). Drivers by points: ternaries 12 (36 pts), if/else 2 (3 pts), loops 1 (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ba5fc053789d0ea6a8cb7a60f08d364d117df52b2f01d7fc9d8b4e7a9f69943"}},{"ruleId":"D2","level":"warning","message":{"text":"SimulatorBridge._run (cognitive 40): SimulatorBridge._run has cognitive complexity 40 (threshold 15). Drivers by points: if/else 9 (27 pts), ternaries 4 (9 pts), boolean chains 2, loops 2 (nesting depth added 23). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/bridge/common.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"7add600035c064ce905aeb64132209f4dbc36f12f0cbdea4b0f0a60dffa42d5d"}},{"ruleId":"D2","level":"warning","message":{"text":"DriverMonitoring._update_events (cognitive 38): DriverMonitoring._update_events has cognitive complexity 38 (threshold 15). Drivers by points: if/else 15 (23 pts), boolean chains 15 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/policy.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"67147e3cff2f7c4f721a466b1678197c2babb2567476eca9afde84cbb1708c09"}},{"ruleId":"D2","level":"warning","message":{"text":"serve.render_inline (cognitive 37): serve.render_inline has cognitive complexity 37 (threshold 15). Drivers by points: if/else 9 (20 pts), boolean chains 10, ternaries 1 (4 pts), loops 2 (3 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a7f83457077fd8e35a9272a9dacb93a72e782e7ecffc43d6f5e9046d7daed39"}},{"ruleId":"D2","level":"warning","message":{"text":"WifiManager._handle_state_change (cognitive 37): WifiManager._handle_state_change has cognitive complexity 37 (threshold 15). Drivers by points: if/else 16 (32 pts), boolean chains 5 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"04f90f4d4c04643872431be681105f9a691a99feff0ac2296955b0c4acf69fe7"}},{"ruleId":"D2","level":"warning","message":{"text":"Keyboard._render (cognitive 37): Keyboard._render has cognitive complexity 37 (threshold 15). Drivers by points: if/else 9 (21 pts), ternaries 4 (10 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/keyboard.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cb5bd59a01b8a6cdaa03f47f6b779b8755e22d08a66d091b856d0c5c94b95a9"}},{"ruleId":"D2","level":"warning","message":{"text":"athenad.log_handler (cognitive 35): athenad.log_handler has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (18 pts), error handling 4 (12 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":838}}}],"partialFingerprints":{"codehealthFindingId/v1":"d010d67577ccd86b0c1c3c311548048c07fa920c5f0fdc31ecb6df768dc8c789"}},{"ruleId":"D2","level":"warning","message":{"text":"athenad.ws_manage (cognitive 35): athenad.ws_manage has cognitive complexity 35 (threshold 15). Drivers by points: ternaries 5 (23 pts), if/else 4 (11 pts), loops 1 (nesting depth added 25). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":982}}}],"partialFingerprints":{"codehealthFindingId/v1":"633f43940aeea97e4ca2be4488d85bf5ce566455b866c414bc33b6b655e3e637"}},{"ruleId":"D2","level":"warning","message":{"text":"registration.register (cognitive 34): registration.register has cognitive complexity 34 (threshold 15). Drivers by points: if/else 9 (17 pts), error handling 3 (9 pts), boolean chains 4, loops 2 (4 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/registration.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"2853c9a9ba90727c60505100566fbc3ea92dadc9bedefca637ad5c57985b7a8e"}},{"ruleId":"D2","level":"warning","message":{"text":"metadrive_process.metadrive_process (cognitive 33): metadrive_process.metadrive_process has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (20 pts), boolean chains 6, loops 2 (4 pts), ternaries 1 (3 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/bridge/metadrive/metadrive_process.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"32dd1ce071d28ab2bf5bbe580f437ab8278d738ffd2d829bba6dd96745ab51a8"}},{"ruleId":"D2","level":"warning","message":{"text":"StateMachine.update (cognitive 32): StateMachine.update has cognitive complexity 32 (threshold 15). Drivers by points: if/else 14 (29 pts), boolean chains 3 (nesting depth added 15). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/state.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"02701ecf5097fab0e319eff830f7076b28ac39c4c8b9d5479d03520d66934a68"}},{"ruleId":"D2","level":"warning","message":{"text":"StreamSession.message_handler (cognitive 32): StreamSession.message_handler has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (22 pts), loops 2 (6 pts), match/switch 1 (2 pts), error handling 1, ternaries 1 (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/webrtc/webrtcd.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8ceaab4a636019056a6aef48344c30e826d10574023eee821305104b81e5b40"}},{"ruleId":"D2","level":"warning","message":{"text":"Generator.node_emits (cognitive 32): Generator.node_emits has cognitive complexity 32 (threshold 15). Drivers by points: if/else 13 (25 pts), ternaries 1 (3 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/generate_event_extractors.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"71bc27dc2d02ced16d7dab1e5ec9726ff472f6032e783561546f4bcc5c0b59f3"}},{"ruleId":"D2","level":"warning","message":{"text":"file_downloader.cmd_download (cognitive 32): file_downloader.cmd_download has cognitive complexity 32 (threshold 15). Drivers by points: if/else 13 (22 pts), error handling 3 (4 pts), loops 2 (3 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/file_downloader.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"a156bb325f4a09fd435adae5667ca0a2b14defeba05e4ed916b6c58911c10073"}},{"ruleId":"D2","level":"warning","message":{"text":"manager.manager_thread (cognitive 31): manager.manager_thread has cognitive complexity 31 (threshold 15). Drivers by points: if/else 11 (20 pts), boolean chains 4, loops 2 (3 pts), error handling 1 (2 pts), ternaries 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/manager.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4bbc7fb2df4514e5d68fb5481e5ab8ccd4ea002a024ead8fcc52efcb9352caf"}},{"ruleId":"D2","level":"warning","message":{"text":"ui.ui_thread (cognitive 31): ui.ui_thread has cognitive complexity 31 (threshold 15). Drivers by points: if/else 14 (24 pts), loops 2 (3 pts), ternaries 2 (3 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/replay/ui.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"aae212a3d78c047bb0af7099adf9bd17cd2827879a33115be33d534b295e0b6b"}},{"ruleId":"D2","level":"warning","message":{"text":"check_shell.check_text (cognitive 31): check_shell.check_text has cognitive complexity 31 (threshold 15). Drivers by points: if/else 5 (14 pts), boolean chains 11, loops 3 (6 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lint/check_shell.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"92305d6911ade0dc44a711210a831f452029c901d0074701cbaa4b9b84c26250"}},{"ruleId":"D2","level":"warning","message":{"text":"DriverMonitoring._update_states (cognitive 30): DriverMonitoring._update_states has cognitive complexity 30 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 13, ternaries 2 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/policy.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcfa3d9f6130c31aac3477f9f80d063f5987a33c0fe2637c16731e5919d89125"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfdriveD.data_sample (cognitive 30): SelfdriveD.data_sample has cognitive complexity 30 (threshold 15). Drivers by points: if/else 11 (24 pts), boolean chains 5, ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"30b8c2f396355fbe13663c3993c9f70a13fa630974dd9e99a4609ac4ace2b9f3"}},{"ruleId":"D2","level":"warning","message":{"text":"wrap_text.wrap_text (cognitive 30): wrap_text.wrap_text has cognitive complexity 30 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 2 (3 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wrap_text.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0f5cb4901d2852812c22540ed8ca18ea5aa7da97bf985f52eb93c6b7d8d9597"}},{"ruleId":"D2","level":"warning","message":{"text":"HardwareComma.get_network_metered (cognitive 29): HardwareComma.get_network_metered has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (20 pts), error handling 2 (5 pts), loops 1 (3 pts), boolean chains 1 (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/comma/hardware.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"2196eeaa73a9d0b71241a5a30fae48d850dc86f03ec4ba490bbfe7e8340d0ee1"}},{"ruleId":"D2","level":"warning","message":{"text":"Car.__init__ (cognitive 28): Car.__init__ has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (22 pts), boolean chains 2, error handling 1 (2 pts), loops 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/card.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30282eb4393cb9b8ec68c78656b3865642179a63c0aafab3732b07176e33048"}},{"ruleId":"D2","level":"warning","message":{"text":"CheckUpdateButton._update_state (cognitive 28): CheckUpdateButton._update_state has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (25 pts), boolean chains 3 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/software.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"d93ce2a4c9bb549a448885b184ed7584bd13dce636642018d4592e164b2aacdb"}},{"ruleId":"D2","level":"warning","message":{"text":"Uploader.list_upload_files (cognitive 28): Uploader.list_upload_files has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (17 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 2, ternaries 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/loggerd/uploader.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa7fc2d714a6e5475f37348d9ec51143f44e20d8d2a8b4e5cec9cb7e389b4c26"}},{"ruleId":"D2","level":"warning","message":{"text":"qrcode._rs_correct (cognitive 27): qrcode._rs_correct has cognitive complexity 27 (threshold 15). Drivers by points: if/else 11 (17 pts), loops 6 (9 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":325}}}],"partialFingerprints":{"codehealthFindingId/v1":"c755fbc4abf149dd481380b55ab457c639c74c4c0d5470e872eae3050fa07f50"}},{"ruleId":"D2","level":"warning","message":{"text":"MiciOffroadAlerts._refresh (cognitive 27): MiciOffroadAlerts._refresh has cognitive complexity 27 (threshold 15). Drivers by points: if/else 11 (23 pts), boolean chains 2, loops 2 (nesting depth added 12). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"88fe905edc52ac18870478030a1a8d3e8e74390b04b4a974634a76c0cca3287c"}},{"ruleId":"D2","level":"warning","message":{"text":"monitoring.chestnut_state_thread (cognitive 27): monitoring.chestnut_state_thread has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (14 pts), ternaries 2 (5 pts), error handling 1 (4 pts), boolean chains 3, loops 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/chestnut/monitoring.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f586a5fcddde1958507950c01ebebc4f8cd9ec486da643ca324d6868fd24b1d"}},{"ruleId":"D2","level":"warning","message":{"text":"sensord.interrupt_loop (cognitive 27): sensord.interrupt_loop has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (16 pts), error handling 2 (8 pts), loops 2 (3 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/sensord/sensord.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d472d63aa186fc97fce67898ec3a87cf9de9cb25ee5c90d1e0d2ff8bf9f6a76"}},{"ruleId":"D2","level":"warning","message":{"text":"GuiScrollPanel._handle_mouse_event (cognitive 27): GuiScrollPanel._handle_mouse_event has cognitive complexity 27 (threshold 15). Drivers by points: if/else 10 (26 pts), boolean chains 1 (nesting depth added 16). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"0937aec57c4ebb6f3d7a17827dabc412be16f5b9bd1366fd92ef9e354657c7e9"}},{"ruleId":"D2","level":"warning","message":{"text":"utils.tabulate (cognitive 26): utils.tabulate has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (11 pts), loops 7 (11 pts), ternaries 2 (4 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/utils.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"df7555b205917046012e0ccaf5195b2ff57d6c7bf0d101f8bf8cff7a5e8b86c4"}},{"ruleId":"D2","level":"warning","message":{"text":"VCruiseHelper._update_v_cruise_non_pcm (cognitive 26): VCruiseHelper._update_v_cruise_non_pcm has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 6, loops 2 (3 pts), ternaries 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/cruise.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"027a073fde5ae1d1facafe0cacb576bf321edf101914e03e633fe69490e268ba"}},{"ruleId":"D2","level":"warning","message":{"text":"UbloxMsgParser._parse_glonass_ephemeris (cognitive 26): UbloxMsgParser._parse_glonass_ephemeris has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (14 pts), error handling 5, loops 3 (4 pts), boolean chains 2, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/ubloxd.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c3d090ce39e66c9f905bc30dff47f5192f006037608c5f7c10a908fef8c2fa9"}},{"ruleId":"D2","level":"warning","message":{"text":"logreader.auto_source (cognitive 26): logreader.auto_source has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (19 pts), error handling 1 (3 pts), loops 2 (3 pts), ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/logreader.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e8bbf9128dad1238cc6377ec3586bccab5ba021e094a48d8ff1c4a670cccf51"}},{"ruleId":"D2","level":"warning","message":{"text":"cycle_alerts.cycle_alerts (cognitive 26): cycle_alerts.cycle_alerts has cognitive complexity 26 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 3 (10 pts), ternaries 1 (4 pts) (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/cycle_alerts.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"3abdc66d92f700a00edd015d2f261c64be726d587292ae982d5d799a6a8d0bb3"}},{"ruleId":"D2","level":"warning","message":{"text":"DesireHelper.update (cognitive 25): DesireHelper.update has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 13, if/else 7 (12 pts) (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/desire_helper.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"621b036a95b2cc0398f60b4d975cd86f2acd878fb4dd3289323700211f642276"}},{"ruleId":"D2","level":"warning","message":{"text":"DeviceLayout._update_calib_description (cognitive 25): DeviceLayout._update_calib_description has cognitive complexity 25 (threshold 15). Drivers by points: if/else 9 (13 pts), error handling 3 (6 pts), ternaries 2 (6 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/device.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"733bd59f9fd3847e9c063c10a202acc130b44b4daa8cc57119b6b43c2fe27af8"}},{"ruleId":"D2","level":"warning","message":{"text":"Widget._process_mouse_events (cognitive 25): Widget._process_mouse_events has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (17 pts), boolean chains 5, loops 2 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/__init__.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"063a865f986c6c3591d6d5821bcf1c758cd397547ac7869b11d5be073ab84a87"}},{"ruleId":"D2","level":"warning","message":{"text":"Serial.readline (cognitive 24): Serial.readline has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (16 pts), error handling 2 (4 pts), ternaries 1 (2 pts), boolean chains 1, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/serial.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"865005c2465bd4b356bd1ea117abde34f5c166aef96d6971936c20f10ddb730d"}},{"ruleId":"D2","level":"warning","message":{"text":"Controls.state_control (cognitive 24): Controls.state_control has cognitive complexity 24 (threshold 15). Drivers by points: if/else 11 (14 pts), boolean chains 5, ternaries 2 (4 pts), loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/controlsd.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"274b45b4cdfe6b21508b4e20e989b5453fdad423d21374fdaac094e19480005a"}},{"ruleId":"D2","level":"warning","message":{"text":"GuiScrollPanel2._update_state (cognitive 24): GuiScrollPanel2._update_state has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 7, ternaries 2 (5 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cfd9f470920d4fe87fefae7fef10bdc1c582380c9c3a42d934089220523c8fc"}},{"ruleId":"D2","level":"warning","message":{"text":"can_printer.can_printer (cognitive 24): can_printer.can_printer has cognitive complexity 24 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 4 (9 pts), ternaries 1 (4 pts), boolean chains 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/can_printer.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9efba850fc68ea2a204f51ef24a3064270621974b81986bedddba659bf771be"}},{"ruleId":"D2","level":"warning","message":{"text":"uploader.main (cognitive 23): uploader.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (12 pts), ternaries 3 (9 pts), error handling 1, loops 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/loggerd/uploader.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"26652b74148a512c21103014547e78d8c8cc3388bc7ddd165f8e740498512dbf"}},{"ruleId":"D2","level":"warning","message":{"text":"build.build (cognitive 23): build.build has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (5 pts), error handling 1 (3 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/build.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbf5ef68de3509efe0d2363bd6c53c3a3768260e426c756729b3fe0a0b30f7ec"}},{"ruleId":"D2","level":"warning","message":{"text":"NetworkConnectivityMonitor._run (cognitive 23): NetworkConnectivityMonitor._run has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (15 pts), error handling 2 (6 pts), boolean chains 1, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_setup.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbe8e0c4f8f33e4cd39f4e1cfac7fe93dbd8656d117a97d34b0d9d50806261cf"}},{"ruleId":"D2","level":"warning","message":{"text":"HtmlRenderer._render (cognitive 23): HtmlRenderer._render has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (19 pts), loops 2 (4 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/html_render.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcaff91efc055168d1b2c8c6ee9661c514b2bb1a188ad3a7f4ee2d14fe9c5b2a"}},{"ruleId":"D2","level":"warning","message":{"text":"debug_fw_fingerprinting_offline.main (cognitive 23): debug_fw_fingerprinting_offline.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (18 pts), loops 2 (4 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/debug_fw_fingerprinting_offline.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"cea49e417147918a1941f6f484c26ccc8131d121db8215d81eb5f3b6248fe27d"}},{"ruleId":"D2","level":"warning","message":{"text":"AtClient.send_apdu (cognitive 22): AtClient.send_apdu has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (17 pts), loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/esim/lpa.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"b18d26fff35bd92786927e24b14eb9a12324865f3e3f94a92504c485ae4b8779"}},{"ruleId":"D2","level":"warning","message":{"text":"lpa.iter_tlv (cognitive 22): lpa.iter_tlv has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (16 pts), loops 2 (4 pts), ternaries 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/esim/lpa.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0ed9a8d67a79eb06d2b7031ff0dab59b32b3b854a63f68684f184624607c664"}},{"ruleId":"D2","level":"warning","message":{"text":"helpers.fft_next_good_size (cognitive 22): helpers.fft_next_good_size has cognitive complexity 22 (threshold 15). Drivers by points: loops 5 (15 pts), ternaries 1 (6 pts), if/else 1 (nesting depth added 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/helpers.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"51b1cb7f82f85fd4f215abb5ee0392b2f733507d62c218aef75d27dd3bbb30fd"}},{"ruleId":"D2","level":"warning","message":{"text":"SoftwareLayout._update_state (cognitive 22): SoftwareLayout._update_state has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (13 pts), boolean chains 9 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/software.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"204179a0f4a06a04af0b2a5a35f89ca37d29906e35dcfcb221ee7b1400c322e9"}},{"ruleId":"D2","level":"warning","message":{"text":"tombstoned.report_tombstone_apport (cognitive 22): tombstoned.report_tombstone_apport has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 2 (4 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/tombstoned.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"a535c709b49f85fa1d05b1d6dc6746a9a18cce645b1a8261e895e3d43d51a1f9"}},{"ruleId":"D2","level":"warning","message":{"text":"UnifiedLabel._update_text_cache (cognitive 22): UnifiedLabel._update_text_cache has cognitive complexity 22 (threshold 15). Drivers by points: if/else 12 (16 pts), loops 2 (3 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":357}}}],"partialFingerprints":{"codehealthFindingId/v1":"8345789a76489ae913006d096b07763ad1c47ff7871e0614371cfdd655bb94e8"}},{"ruleId":"D2","level":"warning","message":{"text":"max_lat_accel.find_events (cognitive 22): max_lat_accel.find_events has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 7 (13 pts), if/else 3 (7 pts), boolean chains 1, loops 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/max_lat_accel.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"3634f64e93e6f3fc4624613f60783af82c80b9a8c03fe229b3de2d687f597108"}},{"ruleId":"D2","level":"warning","message":{"text":"watch_timings.monitor_services (cognitive 22): watch_timings.monitor_services has cognitive complexity 22 (threshold 15). Drivers by points: loops 6 (13 pts), if/else 2 (4 pts), ternaries 1 (4 pts), error handling 1 (nesting depth added 12). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/watch_timings.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"84c46b7b756908c600914aa39b86a4c98158ebbce07ab695a47e94a540b9d85b"}},{"ruleId":"D2","level":"warning","message":{"text":"DriverStateRenderer._render (cognitive 21): DriverStateRenderer._render has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (13 pts), ternaries 2 (5 pts), loops 1 (3 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/driver_state.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"72480643d8dc87734b75e5eb678583752ec859336340c583457ee11a006f4228"}},{"ruleId":"D2","level":"warning","message":{"text":"athenad.upload_handler (cognitive 21): athenad.upload_handler has cognitive complexity 21 (threshold 15). Drivers by points: error handling 5 (10 pts), if/else 5 (9 pts), boolean chains 1, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"96ec1bb7eaf4fd7af9b63efa2e7b8cbedcc491c6ca768793dd28a92020009696"}},{"ruleId":"D2","level":"warning","message":{"text":"HtmlRenderer.parse_html_content (cognitive 21): HtmlRenderer.parse_html_content has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (15 pts), ternaries 1 (4 pts), boolean chains 1, loops 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/html_render.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e67a9aed98d53df0776871b53d11b6841449dc298e248a49eb298d4b7789a5c"}},{"ruleId":"D2","level":"warning","message":{"text":"updated.main (cognitive 21): updated.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (8 pts), error handling 4 (7 pts), boolean chains 3, ternaries 1 (2 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"16938784bdff6db75bdfe5ac4e7a51a3a61f903fc3e8cc1850c5d6024b079fde"}},{"ruleId":"D2","level":"warning","message":{"text":"can_print_changes.update (cognitive 21): can_print_changes.update has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (17 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/can_print_changes.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2223863a6a1466bd0bdb2c9ff19bfd97248d6c116d3fd3335e249e13991d152"}},{"ruleId":"D2","level":"warning","message":{"text":"VehicleParamsLearner.handle_log (cognitive 20): VehicleParamsLearner.handle_log has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 4, ternaries 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/paramsd.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c25adbfdc88c3bcfc1aeec92ee43fe3f35e6ece39b1f2a83286ec33f9c288ac"}},{"ruleId":"D2","level":"warning","message":{"text":"binary_struct._parse_field (cognitive 20): binary_struct._parse_field has cognitive complexity 20 (threshold 15). Drivers by points: if/else 13 (15 pts), error handling 1 (2 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/binary_struct.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"11e279c99628bb7a122593ed0829ff7aba669d8ec0cbea5e824a24687695bf57"}},{"ruleId":"D2","level":"warning","message":{"text":"pigeond.run_receiving (cognitive 20): pigeond.run_receiving has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (4 pts), error handling 1 (3 pts), boolean chains 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/pigeond.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1889793f24d5e5fd0b2e507b5358ac4b39715c5abcbba6d78557b4ee7c9e78d"}},{"ruleId":"D2","level":"warning","message":{"text":"NavWidget._handle_mouse_event (cognitive 20): NavWidget._handle_mouse_event has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 2 (nesting depth added 10). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/nav_widget.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a2a7b81cbf6180ae5c49389e8fabfa7ebc3884dd5c30ff71f68d08b9d94e7e5"}},{"ruleId":"D2","level":"warning","message":{"text":"lpa._parse_install_result (cognitive 19): lpa._parse_install_result has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/esim/lpa.py"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e33c75f75af5a3cf99084f2306e05a60702ef7bff2201b0711df4c6df9a6d8c"}},{"ruleId":"D2","level":"warning","message":{"text":"Serial.read (cognitive 19): Serial.read has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (12 pts), error handling 2 (4 pts), ternaries 1 (2 pts), loops 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/serial.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"88feb3ef0440d7a0e67022791bd2f82964a64b11f067bba76bb9bdf1ca3f6a73"}},{"ruleId":"D2","level":"warning","message":{"text":"pandad.main (cognitive 19): pandad.main has cognitive complexity 19 (threshold 15). Drivers by points: error handling 4 (7 pts), if/else 4 (7 pts), loops 3 (4 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/pandad/pandad.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"d373ab3327403daf35d5dae49647c2607430a11d42ca985d5da6850edbee318d"}},{"ruleId":"D2","level":"warning","message":{"text":"WifiUIMici._update_buttons (cognitive 19): WifiUIMici._update_buttons has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"9730527f8ef0e013a6eb8a9049cd83347efa443e3ac767d9485fdc0d4680097a"}},{"ruleId":"D2","level":"warning","message":{"text":"UIState._update_status (cognitive 19): UIState._update_status has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (8 pts), boolean chains 4, loops 2 (4 pts), ternaries 1 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/ui_state.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"166adddb283e7dff39b1ea61879f5f2ddca8d67c8ef033d8950752b9f68af172"}},{"ruleId":"D2","level":"warning","message":{"text":"VideoClips._available_ranges (cognitive 19): VideoClips._available_ranges has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 4 (6 pts), boolean chains 3, error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":535}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9387245960504b618332f7721d8afce09251f242e0b8946e1bdb6477314f8b8"}},{"ruleId":"D2","level":"warning","message":{"text":"tombstoned.main (cognitive 19): tombstoned.main has cognitive complexity 19 (threshold 15). Drivers by points: error handling 2 (7 pts), if/else 3 (7 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/tombstoned.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"a56d1e91840b5a5adee9e66e159200ba33cf5327069cebf407ed94d214c5da00"}},{"ruleId":"D2","level":"warning","message":{"text":"GuiScrollPanel._update_state (cognitive 19): GuiScrollPanel._update_state has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (14 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbabfd2fe5b1c2d43382f78920c1336386840536be4fa4bf155213082e841c74"}},{"ruleId":"D2","level":"warning","message":{"text":"_Scroller._do_move_animation (cognitive 19): _Scroller._do_move_animation has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (19 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"f40a7b11a42e04b21a10c0174e8f9fd821899c0cd86b3cfd5bcea48425cb7d3c"}},{"ruleId":"D2","level":"warning","message":{"text":"toyota_eps_factor.get_eps_factor (cognitive 19): toyota_eps_factor.get_eps_factor has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/toyota_eps_factor.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"41a16c31e01c7e978383973e919e1a236d1a5e50c7288160f75fb0d39fb18158"}},{"ruleId":"D2","level":"warning","message":{"text":"FaceAnimator.get_dots (cognitive 18): FaceAnimator.get_dots has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 4, ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/body/animations.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"51d6857f35dcded3d553b14efd9c61fe6bc3c7d01065639a8855644ad43cc530"}},{"ruleId":"D2","level":"warning","message":{"text":"TogglesLayout._update_toggles (cognitive 18): TogglesLayout._update_toggles has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 2, boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/toggles.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b79e5a393f929e3d9878ac9fc0e1c99b78bb11ef531a3c6238ae657c45c93df"}},{"ruleId":"D2","level":"warning","message":{"text":"ManagerProcess.stop (cognitive 18): ManagerProcess.stop has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (13 pts), ternaries 1 (4 pts), boolean chains 1 (nesting depth added 9). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/process.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"95b7cb4991aa1865e8ff8f30ed0be1f17d44541e46398e86a727e378ce32b355"}},{"ruleId":"D2","level":"warning","message":{"text":"multilang.load_translations (cognitive 18): multilang.load_translations has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/multilang.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ae8a6ef70e03b3335548c9f4ccfd4156f01e9e2236c0f8131d338f1aa264283"}},{"ruleId":"D2","level":"warning","message":{"text":"Label._update_text (cognitive 18): Label._update_text has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 2 (4 pts), ternaries 1 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"38337a2beb307cae10951eaf8a6c894022eaa6fa7f21d8b1f007539ce32377f4"}},{"ruleId":"D2","level":"warning","message":{"text":"Updater.set_params (cognitive 18): Updater.set_params has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 3, ternaries 1 (3 pts), loops 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"5df2e43bc749ca719e6513f5e28fc03915fcaf3f52ccf72df23a3661efd4c4e2"}},{"ruleId":"D2","level":"warning","message":{"text":"LivestreamBitrateController.run (cognitive 18): LivestreamBitrateController.run has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (14 pts), boolean chains 3, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/webrtc/webrtcd.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d80dd355892f144aef78b439411f6707aff017034d5c213514b8b10dc3a7c3c"}},{"ruleId":"D2","level":"warning","message":{"text":"run.iter_segment_frames (cognitive 18): run.iter_segment_frames has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (13 pts), ternaries 1 (3 pts), boolean chains 1, loops 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/clip/run.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"19e6adfb35cc9049086d20208d008a85990fa7130d7ac627dac591a80c420720"}},{"ruleId":"D2","level":"warning","message":{"text":"run.clip (cognitive 18): run.clip has cognitive complexity 18 (threshold 15). Drivers by points: if/else 11 (14 pts), ternaries 3, loops 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/clip/run.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"b10c05ff356e1ecb4eeb102976b461c4c78ca80d0e8886e4f22e704820c5f98c"}},{"ruleId":"D2","level":"warning","message":{"text":"math_eval.main (cognitive 18): math_eval.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 10 (12 pts), boolean chains 4, loops 2 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/math_eval.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"660dcc9fb7df9538e3bc0a03918cf76c6003b14a4a9d3e1b003d1e23bacbf4f5"}},{"ruleId":"D2","level":"warning","message":{"text":"serve._parse_link (cognitive 17): serve._parse_link has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (6 pts), boolean chains 4, loops 2 (4 pts), ternaries 1 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ea4a3118eeed63e6ec581e5d0dfeece1cb93848722ba61a0f65f4a581668cce"}},{"ruleId":"D2","level":"warning","message":{"text":"markdown.parse_markdown (cognitive 17): markdown.parse_markdown has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 2, boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/markdown.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ca95a64ce5599c886a5ea8cd86340a381522c4d11eaec31a28a383ac54aeb4a"}},{"ruleId":"D2","level":"warning","message":{"text":"TorqueEstimator.handle_log (cognitive 17): TorqueEstimator.handle_log has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (14 pts), boolean chains 3 (nesting depth added 9). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/torqued.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b2a805266924bfefe8c9bff20488d2f1055b76cfd1cd5ff75545978a2116463"}},{"ruleId":"D2","level":"warning","message":{"text":"Parser.parse_mdn (cognitive 17): Parser.parse_mdn has cognitive complexity 17 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 6 (7 pts) (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/parse_model_outputs.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"f734224538dc9377e5a88d2045a985f67858ac0a90897fc43b67c42b3dd38617"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertRenderer.get_alert (cognitive 17): AlertRenderer.get_alert has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 3 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/onroad/alert_renderer.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"beea46bbdf81ed82fc83d116f28bbaf02530a35b0338fa8cf7efd1e7b44775dc"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelRenderer._render (cognitive 17): ModelRenderer._render has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 4, ternaries 3 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/onroad/model_renderer.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"a176f11db7a478ef64d063d6229ac3658e95ce0900f0e0460f5b267a44f806d3"}},{"ruleId":"D2","level":"warning","message":{"text":"VideoClips._worker (cognitive 17): VideoClips._worker has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2df68373808d000f679c39fa33c8b5730b18b4045f8b7a878baf93fc35e496b"}},{"ruleId":"D2","level":"warning","message":{"text":"Uploader.upload (cognitive 17): Uploader.upload has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (10 pts), error handling 3 (5 pts), boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/loggerd/uploader.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"59b1417ae17eb49a13994f5394b43032201a32385d6a04c0a37f4c31c19c0f6b"}},{"ruleId":"D2","level":"warning","message":{"text":"nmeaport.process_nmea_port_messages (cognitive 17): nmeaport.process_nmea_port_messages has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 2 (3 pts), match/switch 1 (3 pts), error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/nmeaport.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed82ca68d42d6911f3befdc2c1e984cf0997458be0e8852417c6491628e8ded4"}},{"ruleId":"D2","level":"warning","message":{"text":"sensord.main (cognitive 17): sensord.main has cognitive complexity 17 (threshold 15). Drivers by points: error handling 4 (7 pts), loops 6, if/else 2 (4 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/sensord/sensord.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c61abc219d38b4482682670096b9d42120772ee5800fdf742768ddae7fe05b6"}},{"ruleId":"D2","level":"warning","message":{"text":"text.wrap_text (cognitive 17): text.wrap_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (3 pts), ternaries 1 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/text.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"18b326f46109e168cdcf63a732cd07821a82800a5b05ed93e54a94711226806e"}},{"ruleId":"D2","level":"warning","message":{"text":"Label._render (cognitive 17): Label._render has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (12 pts), boolean chains 3, loops 1, ternaries 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b4d669171c8f9b2c3e583113410ef1b17a360c326c25e01d601e4231cec8b0"}},{"ruleId":"D2","level":"warning","message":{"text":"_Scroller._layout (cognitive 17): _Scroller._layout has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 2 (3 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4095014722b7fa1250a6ac3322e3232263f5051dbba3b664f4fa0345dfe0612"}},{"ruleId":"D2","level":"warning","message":{"text":"Generator.emit_node (cognitive 17): Generator.emit_node has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (14 pts), ternaries 1 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/generate_event_extractors.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa7cb3a29be0b5ab89a9b7926b71cd78dd25e4ccad0e6fde9a45da809573629c"}},{"ruleId":"D2","level":"warning","message":{"text":"joystickd.joystickd_thread (cognitive 17): joystickd.joystickd_thread has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 6, ternaries 1 (3 pts), loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/joystick/joystickd.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea6f291f68d40bf5ebfdba946378c5bc10bccdb3b00115786c736b23190656ac"}},{"ruleId":"D2","level":"warning","message":{"text":"auth.login (cognitive 17): auth.login has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (12 pts), boolean chains 2, error handling 1, loops 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/auth.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"315d6a1bc7ecb822c313b296fd615d5b42c3b2ea00dc924fd2fc22bc333e191e"}},{"ruleId":"D2","level":"warning","message":{"text":"ci_results.get_jenkins_status (cognitive 17): ci_results.get_jenkins_status has cognitive complexity 17 (threshold 15). Drivers by points: if/else 2 (7 pts), error handling 2 (6 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/ci_results.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a79694dcbaf14e6757cc63cd9c18f7be5e7d3c64d6a658ffc3517b3be6d9118"}},{"ruleId":"D2","level":"warning","message":{"text":"fingerprint_from_route.get_fingerprint (cognitive 17): fingerprint_from_route.get_fingerprint has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (7 pts), loops 3 (6 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/fingerprint_from_route.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e50e3bd6c0dbaabdd1b322d66ec5438b549d2e6aa102847379c268d7c5f7e61"}},{"ruleId":"D2","level":"warning","message":{"text":"RadarD.update (cognitive 16): RadarD.update has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 3 (4 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/radard.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"af84374a93915b04c933c4faed47a405fc38cb3b5b815d2bd35e25b1192b5317"}},{"ruleId":"D2","level":"warning","message":{"text":"lagd.main (cognitive 16): lagd.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 2 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/lagd.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4311f9f5d8c1304e8be70cae2745d8337cb2765f7b589e85d5ca27fa64b31d2"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertRenderer.get_alert (cognitive 16): AlertRenderer.get_alert has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 3 (nesting depth added 7). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cd0882360d19587deb7f19009c0e5f1b62c10d52511aad80bae8e09e389dbee"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertRenderer._draw_text (cognitive 16): AlertRenderer._draw_text has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (10 pts), ternaries 4 (5 pts), boolean chains 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bd9e0374f4bc9b08f9ee103b2205598e5365b7907e6f1a2eaa17f91319eddba"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelRenderer._render (cognitive 16): ModelRenderer._render has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 3, ternaries 3 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"44844bfde9a3a7da9a0fb5d575edb754a758fe1921519326c020e53e4428e9cd"}},{"ruleId":"D2","level":"warning","message":{"text":"helpers.unblock_stdout (cognitive 16): helpers.unblock_stdout has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (8 pts), error handling 2 (6 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/helpers.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aa231059eb080469165ab5a2da9fe37a21044827637f806227fccb3bcf5e2f4"}},{"ruleId":"D2","level":"warning","message":{"text":"WifiManager._monitor_state (cognitive 16): WifiManager._monitor_state has cognitive complexity 16 (threshold 15). Drivers by points: loops 6 (10 pts), if/else 1 (3 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":332}}}],"partialFingerprints":{"codehealthFindingId/v1":"83a949e50dc26aaacc53991e09ed4d60b61b75e8bf0e5c0c337c8f177766fed7"}},{"ruleId":"D2","level":"warning","message":{"text":"WifiManager._update_active_connection_info (cognitive 16): WifiManager._update_active_connection_info has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 1 (3 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":905}}}],"partialFingerprints":{"codehealthFindingId/v1":"991bb03cacc1edd2ba89eb365f1ffc2ff2472d97cd76a4a8b07c96828b4c45c2"}},{"ruleId":"D2","level":"warning","message":{"text":"Keyboard.__init__ (cognitive 16): Keyboard.__init__ has cognitive complexity 16 (threshold 15). Drivers by points: loops 3 (6 pts), if/else 2 (5 pts), ternaries 1 (5 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/keyboard.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b3e994519e18f6c3aa59dc351833bf5e8caf2b74212ca7d3d3fa686dc69e6ce"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: athena/athenad.py: FileTooLong \u2014 837 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 337 over it, 1.67\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"274c67d329fd16aae75dcaa7ce13d3e8d24a564be917d7605504301bc671d9cf"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: selfdrived/events.py: FileTooLong \u2014 745 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 245 over it, 1.49\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/events.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f928d91b715f4309c02b5cd20606d0b74ca56f97f52e78f56cf1b653c7ce833f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: lib/wifi_manager.py: FileTooLong \u2014 682 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 182 over it, 1.36\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"789108bcef897bd3275f57fe575c54656a2237192c71d5046337dc27950d16bc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: esim/lpa.py: FileTooLong \u2014 637 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 137 over it, 1.27\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/esim/lpa.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"55191bab6b496ec891b7ea7769ea48d6f91a400274c1636a8b481dd15ed8920f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: WifiManager: TooManyMethods \u2014 36 methods. The bar is 30 methods; this is 6 over it, 1.20\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"79a32c525de865cf5c042f4500d155044b778c8face7b9c1b65b158673807fff"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: GuiApplication: TooManyMethods \u2014 35 methods. The bar is 30 methods; this is 5 over it, 1.17\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4d83cbdee7963071a9ffd53903625b5bfb1ac73f0c518bb4de3aa3663e1ff30"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: common/qrcode.py: FileTooLong \u2014 577 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 77 over it, 1.15\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b28f3f7b4b48e028ccae46e06e86bd0d758fdde4d3d5f44ac9dc49adf9bb93ba"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: lib/application.py: FileTooLong \u2014 552 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 52 over it, 1.10\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"246e7a74a5366176f171102f7cda30e2343c0b27f047863939bef011fca29acc"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: HardwareComma: TooManyMethods \u2014 33 methods. The bar is 30 methods; this is 3 over it, 1.10\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/comma/hardware.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b5e2f2333dfe465bdfbe2c4e4d2a4b2dc18e383497ea6a8dbe738dd95dfa316"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: comma/modem.py: FileTooLong \u2014 520 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 20 over it, 1.04\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/comma/modem.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb0dde4d085295f1eca737553376d74be025ac4e7804210ce305544057aa7636"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: HardwareBase: TooManyMethods \u2014 31 methods. The bar is 30 methods; this is 1 over it, 1.03\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/base.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"f329735a14d70bfdceec24316899670c6e3f2e0ed78820f65efafdf84d9fe56e"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Modem: TooManyMethods \u2014 31 methods. The bar is 30 methods; this is 1 over it, 1.03\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/comma/modem.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ff35d0fee058735ad957d6636e746f8c24631eaf267c7e94a574b9f3b8c5be8"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: webrtc/webrtcd.py: FileTooLong \u2014 510 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 10 over it, 1.02\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/webrtc/webrtcd.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd5e3935f3a16c5ce20281d007901b551b7c5cea62ba3b24afc70515c0d59026"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (39 shared lines): openpilot/tools/lateral_maneuvers/generate_report.py:28-212 | openpilot/tools/longitudinal_maneuvers/generate_report.py:23-148 \u2014 These two members are variants of one another: 39 of their lines are already reported as duplicated blocks below, spread through both bodies rather than gathered into one. Read them as a single construct written twice. The repair is at the members\u0027 grain \u2014 factor the shared pipeline into one implementation the two call with their differences as parameters or as an injected step, or, where the difference is systematic (sync against async, one transport against another), generate one from the other. Extracting the individual blocks below is not the same fix: it leaves the two bodies in place and the next edit still has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7efa5ca66087c3e30175b15bae9536ffea775ce2491de32301a23bae335128c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (49 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:409-457 | openpilot/selfdrive/ui/onroad/model_renderer.py:361-409 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"429c4ae0956b7ce2581d5649a1b2deefd3377f0a0dcd61c76621c19cbb353853"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:224-267 | openpilot/selfdrive/ui/onroad/cameraview.py:184-227 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"4753e8dfd6319cb754e4106691cb016a8eb2cdeec51dc038358551a2b7e64cd6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:103-139 | openpilot/selfdrive/ui/onroad/model_renderer.py:88-124 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"97a4fd95d224dbd908802ca3d98b0ffd5d61164cbaabda392866abaa9e5b11e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2): openpilot/system/ui/mici_setup.py:515-546 | openpilot/system/ui/tici_setup.py:360-391 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060openpilot/system/ui/mici_setup.py:511\u0060 calls \u0060set_shown_callback\u0060, \u0060push_widget\u0060 and \u0060openpilot/system/ui/tici_setup.py:357\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_setup.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"d391c08dc61eb7fad3aff3d8b1c12a37eda5d8d81b50d01271b0a71661a75ceb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:274-297 | openpilot/selfdrive/ui/onroad/cameraview.py:234-257 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py:298\u0060 calls \u0060_update_texture_color_filtering\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py:258\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"c164956c5007352534a799f9b3edf4c7d206fd8cdaddb9881efd25c0386cf0df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:131-151 | openpilot/selfdrive/ui/onroad/cameraview.py:88-108 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"e427738f2ebe436cc82b3b15aa56864b964df2034389f3d6e0fee287cdbbef26"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:367-385 | openpilot/selfdrive/ui/onroad/cameraview.py:320-338 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"26920076cb57233bfc0baee92031bd52e384dea00a61ff5c4a99f84aac9f0a24"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): openpilot/selfdrive/ui/translations/potools.py:38-56 | openpilot/system/ui/lib/multilang.py:54-72 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/translations/potools.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dc3e6b477a1ad5ebe8953cd33516c55b10081b59672bcce527ceb6d177b3bf5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/alert_renderer.py:127-144 | openpilot/selfdrive/ui/onroad/alert_renderer.py:91-108 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6c8a85a1702fe4e5a3d27bac69551151ba1fb12c5b3c2244b215ef9cc5a9980"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py:267-284 | openpilot/selfdrive/ui/onroad/augmented_road_view.py:132-149 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/augmented_road_view.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 47 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"51d827e41c8679b725fffea96d7c1edcd162f7748a7aac3be085724a11a2e70a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:329-346 | openpilot/selfdrive/ui/onroad/cameraview.py:282-299 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":329}}}],"partialFingerprints":{"codehealthFindingId/v1":"805798954655347a9826a1cbdd1cb0aaafacf284badc2dac3f7f67b742dbb860"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:263-279 | openpilot/selfdrive/ui/onroad/model_renderer.py:236-252 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1ccbe1e168f9f4b589b0a9944239ad2611b47fbbdae55037564e1047d3df87e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): openpilot/tools/lateral_maneuvers/generate_report.py:28-44 | openpilot/tools/longitudinal_maneuvers/generate_report.py:23-39 \u2014 \u0060openpilot/tools/lateral_maneuvers/generate_report.py\u0060 and \u0060openpilot/tools/longitudinal_maneuvers/generate_report.py\u0060 are one unit implemented once per sibling directory, so they are most likely parallel implementations of one contract rather than a copy of each other \u2014 this scan matched 3 separate duplicated blocks between them, totalling at least 39 lines. If both are selected at run time, neither can be retired in favour of the other, and the lines that DIFFER between them are the reason both exist. The move that pays here is to hoist the identical part into a shared location the whole family can reach and give what differs a parameter or a seam, so a change lands once instead of once per sibling; extracting one helper per block leaves every sibling to drift on its own."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"029f0f3604fe90f696709f55da1b28d0f4fbbaa9ea4ca4e47c36b4cb7eedd300"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:110-125 | openpilot/selfdrive/ui/onroad/cameraview.py:71-86 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"e63eb193117f65ee713550d87eb438ea2f2aba92737ffa1c62007f96a0cde62d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:206-221 | openpilot/selfdrive/ui/onroad/cameraview.py:166-181 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"13e3e8aa0407bc9fd72a2bdc38b7a36c69017261b27b78e05da06b3bf99e9618"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:349-364 | openpilot/selfdrive/ui/onroad/cameraview.py:302-317 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"41613e201cfb8b4647e48d8fd36970d56a23cdfc436d24602ac7670cb925ff02"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py:314-328 | openpilot/selfdrive/ui/onroad/augmented_road_view.py:175-189 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/augmented_road_view.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 47 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6bdd83bc381b4c0190aac8b6dfe909b828056f6fd7c6cbec64091de0c45f78e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:77-91 | openpilot/selfdrive/ui/onroad/model_renderer.py:64-78 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bfffa14d6e98510dce17cda904606be1e128bab2e1aacf30e808ad2f64d7d5a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py:248-261 | openpilot/selfdrive/ui/onroad/augmented_road_view.py:113-126 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/augmented_road_view.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 47 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ee74a871b5c5390a85aad76af98fae615b574a0c12a3329386e31b805615d28"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:166-179 | openpilot/selfdrive/ui/onroad/cameraview.py:127-140 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a2badc3b7882a770001252e7a21375fcb9a8ca9c9db19fdf8bc3f19e49d009a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:54-67 | openpilot/selfdrive/ui/onroad/model_renderer.py:47-60 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"c018460e694e883523b757bef2706b25354fba3ee72fce0d37d4ccd26ef141c0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:380-393 | openpilot/selfdrive/ui/onroad/model_renderer.py:321-334 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"334184f382c1ba0d95b726aaf115e34c093807e6fc20009ed761849efd64f3ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:90-103 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:118-131 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:90\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"84fe453742105d4b6c489fc97537ad56862a83cf410319fd6ec2e7cfface7979"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:67-79 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:186-198 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:210-222 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:67\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"c746998a9778f0522993b2e005334cdd01a1b28f02d94e063c5db3035e624119"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:396-408 | openpilot/selfdrive/ui/onroad/cameraview.py:349-361 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"1483ac90c6294a7dc78929acda77ee2367fabab33d85836cf13aa478781bb467"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:164-176 | openpilot/selfdrive/ui/onroad/model_renderer.py:148-160 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"48e0946aa1535a82d16ec47f86187687545d2d0f81b34e1381277531c18a2788"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 3): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:130-142 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:152-164 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:170-180 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:170\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb4d16da0220272bfeb0160e5d9b9efaa1e1dce953cabfdd92ca20bb26bcda07"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): openpilot/common/transformations/transformations.py:277-288 | openpilot/common/transformations/transformations.py:316-327 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/transformations/transformations.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"14aee5dd4bbef08d1d19e724c355ecce9607bd20ce5c830ea2ad4931b9006a88"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): openpilot/system/ui/lib/wifi_manager.py:433-444 | openpilot/system/ui/lib/wifi_manager.py:470-481 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":433}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ccf80b6588105a4626b76d92944b69e2015424005ff0e9fb9865600045f9aeb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:126-137 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:240-251 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:126\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ee0dad3797733150cd0a088272ec4cce16d291338520f1bccd466e6ba6c815d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:148-159 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:217-228 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:148\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"5151377fa093fc2b3ce6341a7afbd7a22d38ed46bb65a4a3241883d8312b7273"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:48-58 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:236-246 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:260-270 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"4935cdd6ebc701225a3cb97da29e84813c7ecfde216434abfea9f29cbcd244eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:125-135 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:239-249 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:263-273 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:125\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff8f9c9eada0980f85940e000e0350a7c825da52835d6a143b5e616560ed570c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:235-245 | openpilot/selfdrive/ui/onroad/model_renderer.py:204-214 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa44e744f587b59208fd7a0acb709d842a2c7c7db40f137f570733c91cd055b4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:246-256 | openpilot/selfdrive/ui/onroad/model_renderer.py:215-225 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"02bae64d80f8a08803b9f17fc1d7131220c35ee3eafb6e6f6161d48eea2fb242"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): openpilot/system/ui/mici_reset.py:104-114 | openpilot/system/ui/tici_reset.py:48-58 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_reset.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"346ad394731ff30a85353c6d25bc0b786f8bb323c4dded64c66f99fe9b01a378"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): openpilot/tools/lateral_maneuvers/generate_report.py:185-195 | openpilot/tools/longitudinal_maneuvers/generate_report.py:120-130 \u2014 \u0060openpilot/tools/lateral_maneuvers/generate_report.py\u0060 and \u0060openpilot/tools/longitudinal_maneuvers/generate_report.py\u0060 are one unit implemented once per sibling directory, so they are most likely parallel implementations of one contract rather than a copy of each other \u2014 this scan matched 3 separate duplicated blocks between them, totalling at least 39 lines. If both are selected at run time, neither can be retired in favour of the other, and the lines that DIFFER between them are the reason both exist. The move that pays here is to hoist the identical part into a shared location the whole family can reach and give what differs a parameter or a seam, so a change lands once instead of once per sibling; extracting one helper per block leaves every sibling to drift on its own."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"62e3bb4ddec531820bbc963f1c43cbef021e6c43f4eb027ff0901ef6dd067d3e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): openpilot/tools/lateral_maneuvers/generate_report.py:202-212 | openpilot/tools/longitudinal_maneuvers/generate_report.py:138-148 \u2014 \u0060openpilot/tools/lateral_maneuvers/generate_report.py\u0060 and \u0060openpilot/tools/longitudinal_maneuvers/generate_report.py\u0060 are one unit implemented once per sibling directory, so they are most likely parallel implementations of one contract rather than a copy of each other \u2014 this scan matched 3 separate duplicated blocks between them, totalling at least 39 lines. If both are selected at run time, neither can be retired in favour of the other, and the lines that DIFFER between them are the reason both exist. The move that pays here is to hoist the identical part into a shared location the whole family can reach and give what differs a parameter or a seam, so a change lands once instead of once per sibling; extracting one helper per block leaves every sibling to drift on its own."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lateral_maneuvers/generate_report.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"225cf3e5831a7f8056ad5134c5ae87d26c57789e6529975946dafd1d7b94ade0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/selfdrive/car/card.py:262-271 | openpilot/selfdrive/selfdrived/selfdrived.py:577-586 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/card.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"199a8521f85a0e768a8d3f3dacfbe99915cd99880268e72c5c0fed0079ba5b8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/selfdrive/ui/layouts/settings/device.py:162-171 | openpilot/selfdrive/ui/layouts/settings/device.py:174-183 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/device.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"d19fe70cd4d0a29dab835c3b34172971bba50798d3a89e93d6c00b97e5ca7cbb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:346-355 | openpilot/selfdrive/ui/onroad/model_renderer.py:291-300 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py:346\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"acfaa7224ba9aa423e6673e44b90211379ade725b8624d68f18b00c446ba15c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:473-482 | openpilot/selfdrive/ui/onroad/model_renderer.py:425-434 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py:473\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bec8dff5eefe2e876196ffa21eb1e9b4aa59f79fa78381c17f54fcf519f954e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:220-229 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:243-252 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:220\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"83971c1fdf9a5306a91ea225da76e4f5bc294c0d24434a24cf9f5e7d0c8af4fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:51-59 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:125-133 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:239-247 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:263-271 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:51\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a4e036bd64f3953c9327f796f4c16b8acbde66ffd4212250ecf4dc21a3b6917"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:43-51 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:255-263 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:279-287 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:43\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"e159d0aa01506fd7493aaae0277c067dc898ae6856812a9dd78ca038ecc17d6d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:303-310 | openpilot/selfdrive/ui/onroad/cameraview.py:262-269 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py:298\u0060 calls \u0060_update_texture_color_filtering\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py:257\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bd19600afc93b5317fb36f0433b6d235a4336d7b03b4a91db44665d1c791b8f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): openpilot/tools/jotpluggler/generate_event_extractors.py:320-327 | openpilot/tools/jotpluggler/generate_event_extractors.py:341-348 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/generate_event_extractors.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"e025f8da4c5d07037a34756696d59aeaf3488bb54661a4ea6b829f605a1ea76c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 6): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:45-51 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:141-147 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:163-169 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:233-239 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:257-263 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:281-287 \u2014 all 6 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:45\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"0562cd13a267c81efc650c52400a53531b924194d34a1dba11dbe654059067bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:44-50 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:66-72 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:256-262 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:280-286 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:44\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"578eb63c9af6fac8115a0b69d98c948908cb202b2fa6360c1c6bb584fdedf5ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): openpilot/selfdrive/locationd/locationd.py:103-109 | openpilot/selfdrive/locationd/locationd.py:123-129 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e8f39752e7edd33688dc2f9223a396bfca015af0ccf09b57570cdba11915247"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): openpilot/selfdrive/locationd/locationd.py:265-271 | openpilot/selfdrive/locationd/paramsd.py:246-252 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc3eefd832464375920e83e6f0272d9f826ca1d7929fee1b4b92917b5eceab20"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:402-408 | openpilot/selfdrive/ui/onroad/model_renderer.py:354-360 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"9be65522f6ee3c3d772bbab0ee6735063c09f3141dd92f987589f2af6e5dd625"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/common/transformations/transformations.py:297-302 | openpilot/common/transformations/transformations.py:337-342 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/transformations/transformations.py"},"region":{"startLine":297}}}],"partialFingerprints":{"codehealthFindingId/v1":"0721cfab154fb1fae165f05f5ee0070412fa64ea44f96d1ec7bbbb41c6bf0c4e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/selfdrive/locationd/lagd.py:403-408 | openpilot/selfdrive/locationd/paramsd.py:260-265 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/lagd.py"},"region":{"startLine":403}}}],"partialFingerprints":{"codehealthFindingId/v1":"0112a5648bbe15da2b398dfd4d73898f66fc2293b50c335010194ac234de9730"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/selfdrive/ui/layouts/settings/software.py:185-190 | openpilot/selfdrive/ui/mici/layouts/settings/software.py:201-206 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/software.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cf598a09a199c0fce984daa1657f4cfb481a4ddf75dac8f4c0ff45e76fab6bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/selfdrive/ui/mici/layouts/onboarding.py:32-37 | openpilot/selfdrive/ui/mici/onroad/cabin_camera_dialog.py:75-80 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/onboarding.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a8d8f665d2e17e916302ea2b8d568a629f93da84fffba7589c9ac720c154fae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/tools/jotpluggler/generate_event_extractors.py:335-340 | openpilot/tools/jotpluggler/generate_event_extractors.py:355-360 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060openpilot/tools/jotpluggler/generate_event_extractors.py:362\u0060 calls \u0060emit\u0060 and \u0060openpilot/tools/jotpluggler/generate_event_extractors.py:342\u0060 does not \u2014 after which the two agree again for 3 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/jotpluggler/generate_event_extractors.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"00fcdd81e4fd824f980d8db0aa1acd5ba22747a859cf7a55b1e773d45546757a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:90-95 | openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:210-215 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py:90\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"841511e1905be57efbf462da21b42654325f78275740ca5c544eecf4f0025a5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): openpilot/selfdrive/ui/mici/layouts/onboarding.py:32-36 | openpilot/selfdrive/ui/mici/layouts/settings/network/esim_ui.py:122-126 | openpilot/selfdrive/ui/mici/onroad/cabin_camera_dialog.py:75-79 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/onboarding.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"095854c01f4bb8a910554bbae158f41cdf4ed9b33ca34549c1f478d1917ce30b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:313-317 | openpilot/selfdrive/ui/onroad/cameraview.py:272-276 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py:318\u0060 calls \u0060_update_texture_color_filtering\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py:277\u0060 does not \u2014 after which the two agree again for 3 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"2221ef6a177eb8c29da5dbaece857804fbdfcaf0c289b9f736e2d41c85475b6f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:364-368 | openpilot/selfdrive/ui/onroad/model_renderer.py:305-309 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"59fdd75ed0abdd5ab17a59ba90cfd8b85af19819c9a09578549604fe42fe21cd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): openpilot/selfdrive/ui/mici/layouts/settings/developer.py:14-27 | openpilot/selfdrive/ui/mici/layouts/settings/toggles.py:17-37 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/developer.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b5960f48167ac57da038f0a9f43dee55d15f5e537b11686a0b1fc595f442be5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:373-377 | openpilot/selfdrive/ui/onroad/model_renderer.py:314-318 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"98a4089683a986ed525a95a6cbe411e20da3b04cc13ea7ebf34da1fe461c37c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:463-469 | openpilot/selfdrive/ui/onroad/model_renderer.py:415-421 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"73af0e6d00793547d9c60b264a1f5165f953753948d2b571976a5c5e0c5203e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): openpilot/selfdrive/locationd/lagd.py:158-162 | openpilot/selfdrive/locationd/lagd.py:164-168 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/lagd.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"091d5faff5ff61ce823a5063f829595db9e8ad1c250f2b7b7ececa9e07674a69"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/cameraview.py:388-393 | openpilot/selfdrive/ui/onroad/cameraview.py:341-346 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/cameraview.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 220 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060openpilot/selfdrive/ui/mici/onroad/cameraview.py:388\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cameraview.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"13ded006147db52e12bc500069497ac0b86ca5a8f6ad5d8f1eaa7be5d1bcc7dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/hud_renderer.py:306-315 | openpilot/selfdrive/ui/onroad/hud_renderer.py:171-180 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/hud_renderer.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f9d44877cbb7e5410fdcd167b24f8f38ce3c80ec5a2fbda46198d0064baa671"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/model_renderer.py:150-161 | openpilot/selfdrive/ui/onroad/model_renderer.py:134-145 \u2014 before extracting anything, compare \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py\u0060 and \u0060openpilot/selfdrive/ui/onroad/model_renderer.py\u0060 as WHOLE FILES: this scan already matched 16 separate duplicated blocks between them, totalling at least 237 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060openpilot/selfdrive/ui/onroad/model_renderer.py:131\u0060 calls \u0060_draw_lead_indicator\u0060 and \u0060openpilot/selfdrive/ui/mici/onroad/model_renderer.py:144\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/model_renderer.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"de07f99b0219f6e42d05daa3767155233a25ce76ddb84db7fbdb44c058b1c5e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): openpilot/selfdrive/ui/mici/onroad/torque_bar.py:236-240 | openpilot/selfdrive/ui/mici/onroad/torque_bar.py:241-245 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/torque_bar.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfd9710c8f28f3264f52ebb600ffb525f5f997140962f2dad3f34561ba5bdd8a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): openpilot/system/ui/widgets/slider.py:189-194 | openpilot/system/ui/widgets/slider.py:199-204 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/slider.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"501ba68243219bab78d16ad422ad1054d9b7f40d47327f2b7adb4e5123664672"}},{"ruleId":"D11","level":"error","message":{"text":"Test declared unreliable: test_clean_exit: This test is disabled or skipped with a reason naming unreliability \u2014 the repository\u0027s own words: \u0022this test is flaky the way it\u0022. A test that is skipped for flakiness is neither passing nor protecting the code it covers; either stabilise it or delete it, but do not leave it disabled indefinitely. (Found by reading the repository\u0027s own test source \u2014 the suite itself was not re-run, since the reliability runner does not support this ecosystem.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/test/test_manager.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e7c311a6ad28c3dee59d2119535ce3919578b713c183dfe63afd8c585b20a12"}},{"ruleId":"D11","level":"error","message":{"text":"Test declared unreliable: test_database: This test is disabled or skipped with a reason naming unreliability \u2014 the repository\u0027s own words: \u0022huggingface is flaky, run this test manually to check for issues\u0022. A test that is skipped for flakiness is neither passing nor protecting the code it covers; either stabilise it or delete it, but do not leave it disabled indefinitely. (Found by reading the repository\u0027s own test source \u2014 the suite itself was not re-run, since the reliability runner does not support this ecosystem.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/tests/test_comma_car_segments.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5038102cf5f8ff7757a02d9276ef4eec88ec4d852572d9abb32b884ba6a2d33"}},{"ruleId":"D11","level":"error","message":{"text":"Test declared unreliable: test_indirect_parsing: This test is disabled or skipped with a reason naming unreliability \u2014 the repository\u0027s own words: \u0022this got flaky. internet tests are stupid.\u0022. A test that is skipped for flakiness is neither passing nor protecting the code it covers; either stabilise it or delete it, but do not leave it disabled indefinitely. (Found by reading the repository\u0027s own test source \u2014 the suite itself was not re-run, since the reliability runner does not support this ecosystem.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/tests/test_logreader.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b79a57857ff0dab5db859c600a3b2ff34a1edfd6cfb91ba3f31d806ef4b99b2"}},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1a441f2b7326aef0df7acd8c19c2f063861eb52d9979e95e0deb1c676634df6b"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/selfdrived/selfdrived.py: openpilot/selfdrive/selfdrived/selfdrived.py changed 19 times in last 90 days, max cyclomatic complexity 156 in SelfdriveD.update_events at line 153. 2 of those changes were fix/bug commits, and the other 17 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/selfdrived/selfdrived.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0f7ecc8b438b9a7d7889e16eb2be89683fa8bbde6d870dce4ca3e8437196781"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/modeld/modeld.py: openpilot/selfdrive/modeld/modeld.py changed 51 times in last 90 days, max cyclomatic complexity 45 in modeld.main at line 229. 9 of those changes were fix/bug commits, and the other 42 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/modeld/modeld.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/modeld.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bca03ab9ff994b2288329b9ef08c22a46ad42ee55faec99682cccc75662b860"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/hardware/hardwared.py: openpilot/system/hardware/hardwared.py changed 17 times in last 90 days, max cyclomatic complexity 63 in hardwared.hardware_thread at line 197. 2 of those changes were fix/bug commits, and the other 15 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/hardware/hardwared.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/hardwared.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"0360748bc204cdb1893e429c75eb5846676216d23212e057374d592a54e7c88c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/ui/mici/layouts/settings/software.py: openpilot/selfdrive/ui/mici/layouts/settings/software.py changed 11 times in last 90 days, max cyclomatic complexity 22 in CheckUpdateButton._update_state at line 104. 2 of those changes were fix/bug commits, and the other 9 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/ui/mici/layouts/settings/software.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/software.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f95c76ce0aaf4c5ba82675613d0327c1af23567a854eb7712c8ca319e7f6fdc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/athena/athenad.py: openpilot/system/athena/athenad.py changed 13 times in last 90 days, max cyclomatic complexity 16 in athenad.log_handler at line 838. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/athena/athenad.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":838}}}],"partialFingerprints":{"codehealthFindingId/v1":"67d6865729014417bf5fc41f11e6133e0085fa78b4f658869ffb866899cea6e6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/hardware/chestnut/status.py: openpilot/system/hardware/chestnut/status.py changed 5 times in last 90 days, max cyclomatic complexity 40 in ChestnutStatus.update at line 31. 1 of those changes was a fix/bug commit, and the other 4 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/hardware/chestnut/status.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/hardware/chestnut/status.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1f5cba7bfae79c6900b86bdb1f3e136bcdb6c5055df813ca3dbd119ecf844ce"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/webrtc/webrtcd.py: openpilot/system/webrtc/webrtcd.py changed 8 times in last 90 days, max cyclomatic complexity 18 in StreamSession.message_handler at line 281. 1 of those changes was a fix/bug commit, and the other 7 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/webrtc/webrtcd.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/webrtc/webrtcd.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"38aaf0d5134c8fc3f657e566c3dd160fb565b193006a3a3ddc873d2c2242856b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/monitoring/policy.py: openpilot/selfdrive/monitoring/policy.py changed 4 times in last 90 days, max cyclomatic complexity 32 in DriverMonitoring._update_events at line 314. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/monitoring/policy.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/policy.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"9df6f7f27e2e0aab793d69b5d5a8e19c1f01b789e255243920919fe3f4c43b26"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/ui/widgets/label.py: openpilot/system/ui/widgets/label.py changed 4 times in last 90 days, max cyclomatic complexity 31 in UnifiedLabel._render at line 461. 1 of those changes was a fix/bug commit, and the other 3 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/ui/widgets/label.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbb60dd5c7a3e636c28ec6bc489bf70024f178de69494c249fcdc76bf913a720"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/ui/lib/wifi_manager.py: openpilot/system/ui/lib/wifi_manager.py changed 4 times in last 90 days, max cyclomatic complexity 25 in WifiManager._handle_state_change at line 394. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/ui/lib/wifi_manager.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb0fe1c2aa0d4c201b39b9e40a9291895c540c56cb623b8cdfad9de443186523"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/locationd/locationd.py: openpilot/selfdrive/locationd/locationd.py changed 3 times in last 90 days, max cyclomatic complexity 33 in LocationEstimator.handle_log at line 100. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/locationd/locationd.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/locationd.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"40a595e430aec0179888a158bc4a00abe978adab1c405c35ed7a2d5735bbd4af"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/ui/lib/application.py: openpilot/system/ui/lib/application.py changed 4 times in last 90 days, max cyclomatic complexity 24 in GuiApplication.render at line 603. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/ui/lib/application.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"a685efc89ae3237f9392754e533327f4e2cbc4e9b0b20e4ed7c43517d43d335c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/qcomgpsd/qcomgpsd.py: openpilot/system/qcomgpsd/qcomgpsd.py changed 2 times in last 90 days, max cyclomatic complexity 47 in qcomgpsd.main at line 182. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/qcomgpsd/qcomgpsd.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"b61239f439287b7b34a36eb4e1073cead7709600cb17350af4ce1246f000a084"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/common/qrcode.py: openpilot/common/qrcode.py changed 4 times in last 90 days, max cyclomatic complexity 23 in qrcode._parse_data at line 425. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/common/qrcode.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/qrcode.py"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"2721f168f0ca3335d16d1de1a0a0a1f9ebd8f4c4d1bc08880c88746f94fc00f2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/car/car_events.py: openpilot/selfdrive/car/car_events.py changed 2 times in last 90 days, max cyclomatic complexity 46 in CarEvents.create_common_events at line 96. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/car/car_events.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"34b3706e550fda7d0b33bc172e046c51bc6e80d93e07770edf5e1cbd8c27c76b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: docs/serve.py: docs/serve.py changed 2 times in last 90 days, max cyclomatic complexity 46 in serve._render_blocks at line 283. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- docs/serve.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/serve.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eb2f98a5a91677f6529016299cb17feeaf0bdb9fc2adaacad7ef00133b64f6e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/tools/replay/ui.py: openpilot/tools/replay/ui.py changed 5 times in last 90 days, max cyclomatic complexity 17 in ui.ui_thread at line 32. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/tools/replay/ui.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/replay/ui.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"0df4f0c5d35592a2fe8c6398ebe1e1a0f6bf5e50763166b13c9b7ab9a874fb76"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/tools/camerastream/compressed_vipc.py: openpilot/tools/camerastream/compressed_vipc.py changed 4 times in last 90 days, max cyclomatic complexity 21 in compressed_vipc.decoder at line 27. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/tools/camerastream/compressed_vipc.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/camerastream/compressed_vipc.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"5af400880ec9f0e97c35f661c35eda6348ce7fcfde454c31887dcb749932754a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/ui/widgets/__init__.py: openpilot/system/ui/widgets/__init__.py changed 4 times in last 90 days, max cyclomatic complexity 19 in Widget._process_mouse_events at line 157. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/ui/widgets/__init__.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/__init__.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d79f65fbc81c6644c0578e908869d7944cf846d657b9e23786bef8ef672e58b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/updated/updated.py: openpilot/system/updated/updated.py changed 4 times in last 90 days, max cyclomatic complexity 16 in updated.main at line 413. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/updated/updated.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e26032b489ac2a38c29e668d185825a369434b38cf1f68ed76f55390941cc3d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py: openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py changed 4 times in last 90 days, max cyclomatic complexity 15 in MiciOffroadAlerts._refresh at line 271. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d4ced13decad78f5a5b76884e03e20db54b3cdb70329038ab9b298e4567b028"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/locationd/paramsd.py: openpilot/selfdrive/locationd/paramsd.py changed 3 times in last 90 days, max cyclomatic complexity 15 in VehicleParamsLearner.handle_log at line 67. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/locationd/paramsd.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/paramsd.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"578c2963563cbc4533335612f339bba989684498f2ee74d718a0a198e05ee4d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/ui/onroad/model_renderer.py: openpilot/selfdrive/ui/onroad/model_renderer.py changed 3 times in last 90 days, max cyclomatic complexity 15 in ModelRenderer._render at line 84. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/ui/onroad/model_renderer.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/onroad/model_renderer.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"3329c26e35f4b64a5cf399594d0600f389c2f3e86271873880fcddbffdcd2e20"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/tools/clip/run.py: openpilot/tools/clip/run.py changed 3 times in last 90 days, max cyclomatic complexity 15 in run.clip at line 285. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/tools/clip/run.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/clip/run.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"800277817284b21b03deb348d325d50a37ef1ed14548971dfbc3da0860aac333"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/system/manager/manager.py: openpilot/system/manager/manager.py changed 2 times in last 90 days, max cyclomatic complexity 21 in manager.manager_thread at line 100. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/system/manager/manager.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/manager.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b4450017cdc6dffb14bffb879a447653b922ae5f3dd7577e76165f1c2b141e0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/tools/lib/file_downloader.py: openpilot/tools/lib/file_downloader.py changed 2 times in last 90 days, max cyclomatic complexity 20 in file_downloader.cmd_download at line 103. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/tools/lib/file_downloader.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/file_downloader.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"c079545f09e498c8fedaf094ebbde9a71e807472759bb9570e0c4ecc4062a19e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/common/utils.py: openpilot/common/utils.py changed 2 times in last 90 days, max cyclomatic complexity 19 in utils.tabulate at line 174. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/common/utils.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/utils.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"1129a14a5592465cc5eb11dc73be5fe9288594686c340978d1b013262d71e6cc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: openpilot/selfdrive/ui/layouts/settings/software.py: openpilot/selfdrive/ui/layouts/settings/software.py changed 2 times in last 90 days, max cyclomatic complexity 16 in SoftwareLayout._update_state at line 89. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-27..2026-09-25, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-27 16:15:25 -07:00\u0027 --until=\u00272026-09-25 16:15:25 -07:00\u0027 --full-history --no-merges -- openpilot/selfdrive/ui/layouts/settings/software.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/software.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0227bc48b67614a66b019dc2954eacbe60cb7b43f1df3d34177f7a693cc306f"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 21 significant file(s) lose their only recent owner: openpilot/system/ubloxd/ubloxd.py, openpilot/tools/jotpluggler/generate_event_extractors.py, openpilot/tools/lib/vidindex.py, openpilot/system/ubloxd/pigeond.py, openpilot/selfdrive/ui/translations/potools.py, openpilot/tools/camerastream/ffmpeg_decoder.py, openpilot/common/fuzzy.py, scripts/ci_results.py (\u002B13 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c6460994203dfa9e4b4d34fd54e393526075c455829f96d089f58bb50dccac3a"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #2: If anonymized user #2 becomes unavailable, 4 significant file(s) lose their only recent owner: openpilot/system/ui/mici_setup.py, openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py, openpilot/system/ui/widgets/nav_widget.py, openpilot/system/ui/widgets/slider.py. Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5f689a74aadecc481613b6b51bb2da9dfcfe7129d1a3f6bd848cbaf31db6e592"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this should be automatically determined using the capnp schema \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/services.py"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"51c55504b302824e81c013b3aece42b070e7a7c81015d03b564cc020b46479a7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: print when we drop packets? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/__init__.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"41e7168e97694bafc89b969a6448a2fe1a264bc9cb42222f7c44f8ce0dca57b9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Handle case where cur_time is less than prev_time \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/__init__.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cbdd821a1b8ba885fdc01fff729b528173b032e8f2bd3279881bba46ac158c9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: break this test up to individually test SubMaster.update and SubMaster.update_msgs \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/tests/test_pub_sub_master.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"d131f7fb5bd114845024c7baae7297a5fbdf1cdf6e143073e73436e2a69afdd5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this should take any capnp struct and returrn a msg with random populated data \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/tests/test_messaging.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"282dcb1a127ca04657fbb711a2a1b8717951e77a27f8dd0c0007e8873d0f0f82"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this should compare any capnp structs \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/tests/test_messaging.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9af44024a470b278d44d5938d1e9c892de7c23f44e4dca3f5c94377bd28e2482"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: check all types \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/cereal/messaging/tests/test_messaging.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"10642f3b44f979daba9cecc8b3c608f44e5417e5dfe2c239b720ee698179c51a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO suppresses warning about forking proc with zmq socket, fix root cause \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/swaglog.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a27c581987b154ab1167300295323018635f089823a5a064fd6f0a1a6af0f85"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add session to Api \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/api.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f2375d01eb31ed04db7931415f8a0079bf4b64ee1b758e748b4e3a7a0a01d8c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: yield in smaller chunks. Yielding only block_sz is too slow. Largest observed data chunk is 252 MB. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/common/hardware/comma/agnos.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"25251641c83f14e21e84938522b393cf1a1a5a0b7e7404f5fcd965efb52e0615"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # handle button presses. TODO: this should be in state_control, but a decelCruise press \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/cruise.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"322eb34e3add0f69ca1c69cb60a03c54c7214c8091492a24e11be33b69f3e36d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: mirror the carState.cruiseState struct? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/card.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"f16d9d4fd2a4af07ad4674da5a25239528e2add30edb124b85564df07bd6b10b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this can make us miss at least a few cycles when doing an ECU knockout \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/card.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a6173e350341d58298a93e526f0112bfbffbe5a2d7436a916061ced04f32109"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: when we check for unexpected disengagement, check gear not S1, S2, S3 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"52b01d3255b48891d803e9b2e5d9b1e24193c507f10e7cbf3c722227fa232d05"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac7ddac999ac03f5ce212aff5f237fd34a17775cd50bcaeedaa48e357c38be8f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this needs to be implemented generically in carState struct \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c33bb10dc31f6ef2c42470f407d6afae2747a979333618e0240a370998ef98d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: cleanup the honda-specific logic \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"4015168ef2fe59e491945cc9c8bc993979b7c1539265f7e29c6353dc7409d03c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: on some hyundai cars, the cancel button is also the pause/resume button, \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"f67b92f04e1f44e5defdef8a860426fdaf85e97f82bf21a1619ea1c49cb3c9f7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: only check the cancel button with openpilot longitudinal on all brands to match panda safety \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/car_events.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1dcf554a8482e02318873d033599c9d7024c5c355030c60a655406bb7e69f34"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: test pcmCruise \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/tests/test_cruise_speed.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"504ed0ed9f1d497e386091e092c77e3be2a2b51b99f1a6b378eb3c1e4541acd3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: fix skipping first run due to enabled on rising edge exception \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/tests/test_cruise_speed.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ee1406dcc5c58fcd833f43d27212bc2fca0c720e01da9b87a077b1428a15e2d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: wait until card refactor is merged to run controller a few times \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/car/tests/test_car_interfaces.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"0122a1e434475d356c034dd9109788e66b98eb45765d002bb3206ab9f50610a4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: both controlsState and carControl valids should be set by \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/controlsd.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"9206b2872902e59c90a0efd46b23ef13d0eb3490162eb5fb335f989f6dcd6e37"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO counter is only needed because radar is glitchy, remove once radar is gone \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/longitudinal_planner.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"d695e7ac5ccc99168eb913d7913dcfc90b8c969bda286038958d317520a1497e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: can we just go straight to stopAccel? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/longcontrol.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b9200717bda7cc9991bafddaf44b588dbeda5572303c03c446d3d1baacc2aa5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: log lat accel? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/latcontrol_torque.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aeb3e5db17a7d9a35bb454d45ce16270bcb8bbe331b8a5410428f7b0530c9ec"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO left is positive in this convention \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/latcontrol_torque.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a49a3634a67459796ba3ea1fee369724958fb99f79334d466546fe97e19e538"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO This is speed dependent \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/latcontrol_angle.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b31beb93a24cd1fefba3aa2971557fc5b9c63f6f97ded0a02490b106f420368"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # or relying on EPS (Ford Q3), carOutput does not capture maxing out torque  # TODO: this can be improved \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/latcontrol_angle.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"6787d70311a3aeb8c7ad2089bed91df984f3b2838c577394fae702f44131c81f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO don\u0027t hardcode A_CHANGE_COST idx \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc4d2f045e70a671dfb818e56d728bdbf9fda513314c7460fa3de8028b2611b7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO add lataccelfactor and friction check when we have more accurate estimates \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"502cfac5d5a5c27272c7f8e88b1aa0b834fe7168ad5f98efe38039dba0454b24"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: check if high aEgo affects resulting lateral accel \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/torqued.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"d79b1a1d404607ccd42e53b3f54d651f2b89ee7c5b8a3c0bf931bbe6ed3931a0"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add height spread check with smooth transition too \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/calibrationd.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0c79b8f1951acfec6c7bf1e4e5bf29e15b7b2f5391926a2b7a91a2b1b2faebe"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO find a new segment to test \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/locationd/test/test_locationd_scenarios.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ed1cc8786dbaed2a5a2e20d83d432b63a6a09affaec25d06148e3d87961a1f5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO this needs more thought, use .2s extra for now to estimate other delays \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/modeld.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"7665507e8b6ab38cdd4cfe282fcf17ba7391351be3cbacaf3762c01226debe53"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO Move smooth seconds to action function \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/modeld/modeld.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9e7be4b8bcfa706aa9bbdf54a696cfb303adf45888f1e2de4ad4fd5800affac"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: test both separately when e2e is used \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/monitoring/test_monitoring.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cc2df3b869d1a8cd7d11582aed0624287f7d6b352a73df8dc33e8c02a11d63a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: wrap all panda exceptions in a base panda exception \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/pandad/pandad.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"68a3ed550fc8d01d5ea991669361ae5e2a939e82c265d0dead0d771386fa23db"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: enable this \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/pandad/tests/test_pandad_spi.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b0465a90ae738472b8204988ecc4471f936094641305186561b50ad67baf0c4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: de-couple selfdrived with card/conflate on carState without introducing controls mismatches \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cb9d94473c552d696ac46ec79e6d71b850be08f89f07beda29d42423206efee"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: lac.saturated includes speed and other checks, should be pulled out \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":435}}}],"partialFingerprints":{"codehealthFindingId/v1":"895edfbcc4ca7c905efe2e227970a72d19167ec9b708472c6c570c06922cc7bf"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: fix simulator \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/selfdrived.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"429f7da57f7ba497b0e5d3f2647de1b0c288a26fb32e092016aba7fc08674af2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add callback alerts \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/tests/test_alerts.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"39a87c317985a3f9bb6bde5224966b8106a5f2f6479454d8819aaf244ea8ee9a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add callback alerts \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/selfdrived/tests/test_alerts.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c53512f5c5302b9a2db56e7f6831762c9154050666f7677bc8f02ffe82a9d4d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this isn\u0027t super stable between different devices \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/test_onroad.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"02fdbff6d861fed2b800b4732882a6eb516e25bf0449c8b735f98f11b6e997b5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: ~6-11ms, increase consistency \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/test_onroad.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d70689a77fab27a45126867eb64cfa0dc75c395bde4c6564f50f94b11e4e26b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make new FCW tests \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3196cc73a89ae3d48d93c0e8e50645b7f1cf965afd7ac0d962eb676620e1144"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO use real radard logic for this \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/longitudinal_maneuvers/plant.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"085155d6c5b0cde47108e400937d0d881b8ebb3b6a5c05aa4d48678d9bcbdd50"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME the sensor timings are bad in mazda segment, we\u0027re not fully testing it, but it should be replaced \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/test_processes.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"0662d3e0154c9327bec6cb4941773f1818bc6fe9f4d5546a243362abcb8b8f07"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: get new RAV4 route without enableDsu \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/test_processes.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"f51118dca5e430fab2b7a409301fa8f55b15c939737390dd42ba17aa18838612"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Make each one testable \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/test_fuzzy.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"8641f80ee69157d5d82b46910edf21eb5afecdf93101d780c095585393bd7bdd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make this faster and increase examples \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/test_fuzzy.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"c74d8f5df0af40aa53baf39d406b898033fb68de62687410d0742c339944581c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO some init can happen in first iteration \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/model_replay.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7bcd4c25939e7c33175a4cb4e4b58f21e33355bbb1ebaaeee92b91277a24fa5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO We ignore whole bunch so we can compare important stuff \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/model_replay.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"4813baf1100bd39ee82823303f0f85dc200cfc94e5c2a789887cb7ae48e6cbfe"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: safety param migration should be handled automatically \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/migration.py"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc725d93fe59d395142794ce02e87df81216aea5fa167a8955d89b85ea7062fd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: get new Ford route \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/test/process_replay/migration.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6d38d1d95089a500507380ab2cbc4d61c2b49b303139f1a47f139a39eff8eaa"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Label doesn\u0027t top align when wrapping \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/onboarding.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc8521d46d77f10731b5532e4889a59c249fd39ae95c3ea17c168a2259805ed6"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make a param control list item so we don\u0027t need to manage internal state as much here \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/toggles.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"c46eef6a8cffdeb6e000936883b5f1090b94e4e09578a27345e2c58e73f78fb5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make a param control list item so we don\u0027t need to manage internal state as much here \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/developer.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"6582780cd3d958b2219f9386eb02dfd71630bec919dd7c2fa0dfdf6b6d612e1b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: remove this. updater fails to respond on startup if time is not correct \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/software.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"77e1b6662137e2d2e4ccbbce5ba20e667674896e18018a07ac8a08fad02f8488"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add back once reliable \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/firehose.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"42ca87ea1677ef462c61dd197533bb22af3c813a0b1fa244807e13df28016b41"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: we can do an onroad cycle, but alpha long toggle requires a deinit function to re-enable radar and not fault \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/layouts/settings/developer.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"a230b383d3dd32bfc39871e665940eb1f1481e4d09b8c3553a603192accedda6"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: when nav stack sends hide event to widget 2 below on push, this needs to be moved \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/onboarding.py"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"53c60a1741cd22335ef1e6e3ded1a1064123c2956e47b68d9e27293877eb035d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: click should always go somewhere: home or specific settings pane \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"6747d8a3eeb1c455a4e48338e08421b7e2cc6bbfbd87913f861a50dda0159713"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: set parent rect and use it if never passed rect from render (like in Scroller) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/main.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"a984cac1ee580cf0ad72a7dd62c5585e260fd36519f082fe757861f75043d02b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Hack to run alert updates while not in view. Add a nav stack tick? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/main.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f7019099b357372d784fd5989f1ec3a62c3ea78af2db471e7685422282e2c96"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: these two pops can interrupt user interacting in the settings \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/main.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e79d90c024fc32aa0a26481f5b8876ce338fc7c2e23f90490b0d926a0baf6e6"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: why is there extra space here to get it to be flush? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/home.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"c10a8e2c579d9a54bb8ea982027eb046dc39159ef0cc55788f0fabd9ae4b3327"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add alignment to hboxlayout and add to there \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/home.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"96d6691732fb8c1d193f265758c4e3c7a682ab5634b8485542379f056c9ca353"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: if true, we stay on the dialog if not exit_on_confirm until normal onroad timeout \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/device/device_layout.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7a2cccf3b11cddb6c498925fe443ce20d2a43baf454c2d83ff9a1ccd07d91c9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: deactivate before forget and add DISCONNECTING state \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"452f551bfb32bfa51f02a09a5427e22c789fd490cb20d6d7e5a1359d23beb925"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: signal for current network metered type when changing networks, this is wrong until you press it once \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"992e2603b3b1bde118fd00cc21366c2367c6ea140ded79081c85dc18c69af7c9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: disable when not connected \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"733d4ee82b801dd05365f6571df2416cce2b2b23ad4939f297532c37aebb578e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use real signals (like activated/settings changed, etc.) to speed up re-enabling buttons \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f347e6db2bac8abefdc32192d25e1121cd0ebf06f90b4fdd399a70baa139c55"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make sure we handle hidden ssids \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/layouts/settings/network/__init__.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"37c048afc6ff7cd4834700fbc1a0d9cc21b20267792928c11bdef12ebe77e583"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: arc_bar_pts doesn\u0027t consider rounded end caps part of the angle span \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/torque_bar.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b10e266d42a773fb9c7f0873cf6a46ad5d46d52dd86665fee369c043443e781"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Only left for DM preview, remove \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/driver_state.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c26c62c5a3f308bfb90a65e8729edb67715c3371ae85e10a3adee3dc7dd0ae8"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: replace with distort_points \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cabin_camera_dialog.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"3842920e915f3b819e877fc83ec9f49703c4d53ebf25977bd13749be65a4ed7b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: replace with distort_points \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/onroad/cabin_camera_dialog.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"a17f27337b720e8816323ff44e0fb6a4a6eb7d24b276a34775d14aaef4de1e24"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this can grow unbounded, should be given some thought \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/cabin_camera_dialog.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf4d13528525819fd599c81c03bfd36532a6a4cfdcba08685742296bfe9d2ebe"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this can grow unbounded, should be given some thought \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/onroad/cabin_camera_dialog.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc212c9548dd65f0b4bae35ba0d5974ffca69ff71caf76e13db94a4129c4e6d0"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use 0.1 but with proper alert height calculation \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cfb48988ac60e84c35800873a775d40618b40f643ac64c0fc31f552dc121e06"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: hack \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":297}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6cc7278bd83f9b86a38d4056c076e8b335f18b7ac8c416ea62b97a33a5e0320"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: there should be a common way to determine font size based on text length to maximize rect \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/onroad/alert_renderer.py"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac9a2f3cb4478b317e442372ba5133a2ef466b1f6980ed63de789137363022eb"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: known small leaks not worth worrying about at the moment \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/tests/test_widget_leaks.py"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7ef45034df5317addb082d1098a77ac07335ad4d3e327fa20c7d0d034355ba4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: move to update state \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/widgets/dialog.py"},"region":{"startLine":210}}}],"partialFingerprints":{"codehealthFindingId/v1":"30c19357747fdabf1e70440e16f51d7e646013ef095406083a8828f8188c17e2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: need to track where press was so enter and back can activate on release rather than press \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/widgets/dialog.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c0499b6b3b07d042a2d6aea7d84f5387051ae0b70e16c4c192f47bc025737ed"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: param control base class \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/mici/widgets/button.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a436c75cdbc69215110cc138d9a219fb308f6241c306f085f6e82b39f97257d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add test with micd for checking that soundd actually outputs sounds \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/tests/test_soundd.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"8da3af12ad348b924d1d9b118a9c2518f87a80ac8eb79505d0027bc1080f3879"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # second page, go back (TODO: make driver cam preview work) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/tests/diff/replay_script.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"07b02829662cc2d38a23b7375770e3274fdbb63fed7645b827a617a9112ed15d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: preview cabin camera; enabling this causes MultiplePublishersError later in onroad alert tests \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/tests/diff/replay_script.py"},"region":{"startLine":324}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5a0f55766ec4ebc4e4d613663b66404863a81abe7aa36840afa8b4423a354c1"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Better way of organizing the events \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/tests/diff/replay_script.py"},"region":{"startLine":426}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f3cfc8e3379b597a08de7bb176bff3a03856f81054db04f59b810daf5ef5a0a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: mock networks \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/tests/diff/replay_script.py"},"region":{"startLine":465}}}],"partialFingerprints":{"codehealthFindingId/v1":"06711bc1d508e974119714fb6cf6c4f0c7c6fd5077c1e8ad28854f7915f3c040"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: just use a Scroller? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/ui/widgets/offroad_alerts.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"91339a98e54b67de5cc05b7faeea30a7ededd3b44b9a2be80b15db57fe417926"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: remove once sounddevice uses np.reshape internally. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/micd.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"3120c83ceafca902b283f682b2e5de5c19ed90a74614ed62a3f9d449377863ef"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: scan once then use inotify to detect file creation/deletion \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":819}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fa1b98ce2fa42cafa0fe86da9f94838b05b2e78584d765cc8822f396f960773"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: TCP_USER_TIMEOUT is effectively 2x for some reason (32s), so it\u0027s mostly unused \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":995}}}],"partialFingerprints":{"codehealthFindingId/v1":"08781d843dada398736915d681abb90863630c477284519c2771dc4d1eaebb22"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: verify that upload actually succeeded \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/tests/test_athenad.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3b9fed8c0bf3f6b0d0681e643a804a3803de850578d0997cbc6ee7bc4c851b5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: also check that end_event and metered network raises AbortTransferException \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/tests/test_athenad.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f6990c813dfd7fac6bcd74074e1d7618ac058dae9986ce493118188451b2499"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this should run faster than real time \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/loggerd/tests/test_encoder.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"b61e7eacc0bda61f34e507c97be9c977381ade7490185e31c135a97ee0bf9591"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this ffprobe call is really slow \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/loggerd/tests/test_encoder.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b33944ea2cfd245c27d19657238ef52a6995853d190701dc403beb08bc9a5ae"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: ensure there are blacklisted procs until we have a dedicated test \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/test/test_manager.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbeb9dc9f1a87c25aaf832092924a7e13663c853767965ece48c28f4a48095c1"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: interrupted blocking read exits with 1 in cereal. use a more unique return code \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/test/test_manager.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"f512abaeee2f469b3e3e142bdd5fbe7a9f4862c1fe34d026fe453adccb85f618"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: it has to reboot for this to take effect \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ee86c4b001675e59150ae664fa3fb3897871d523449d30d88ddd440c5d59ca5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: should we save cdmaClockInfo? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"46923796cc71118ac45cba9f525d26806e75001ea93b65ec23618cbf9e3cd04b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO needs update if there is another leap second, after june 2024? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/qcomgpsd/qcomgpsd.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"b131dc4ec5e14dc1ab3f9a00d45bba2fd27fa077ed7935c405fcd2d21f4dd844"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: set scale. Default is \u002B- 250 deg/s \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/sensord/sensors/lsm6ds3_gyro.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c39abd0fce78e78329f793d5eb3afa6ce3f02ed113999a8420500331f7847c4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: test TTFF when we have good A-GNSS \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ubloxd/tests/test_pigeond.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"839a23684dc90cf680856d8958b1435bbe9509f8fff1ad136c48d563969a1e5c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: just import it and run in a thread without a subprocess \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/tici_updater.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"44b1935f6809fbc3a288c5dbb97321a300b5b78fa97f062e23a6416c68882cc9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: just import it and run in a thread without a subprocess \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_updater.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d10d63787a28d971d26fece55047c9941b292044ba109b90ec88876ed5c5f94"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: unifi with updater\u0027s progress page \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_setup.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"48fd7064d0aedcf06f7f9855cc4923d23e37de6d93ce1a3a075bd14db620e868"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: fire show/hide events on visibility changes \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_setup.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ab5c65e2b0573e15c7eb1e7b742d8047ee2ba8200d2deb027a1fcc566e3d6d3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: cancel if connect is transient \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/mici_setup.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fc62c80d03269949a1ee83943208098c0cfc0798c6686c2164251599fef8b31"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: wait for state thread to start before adding tethering connection, tiny race currently \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0120ee4add46986afbba008a253d97eb74432df735f4a69b2860e4f1d0582ff"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Handle (FAILED, SSID_NOT_FOUND) and emit for UI to show error \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"a494f912d2fb42272b12e446614ab8e25166bae5515eba9039086e7d1aa991a5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: sometimes on PC it\u0027s observed no future signals are fired if mouse is held down blocking wrong password dialog \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":449}}}],"partialFingerprints":{"codehealthFindingId/v1":"381995ea985ab09b21f6660238618db03b6bad0d4f158292e641c5ae3411d009"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: expose a failed connection state in the UI \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":671}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5216fbc019ab2f9b8473becc46d8f240a8dc9164dabe93ab69b5587b93af0de"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: expose a failed connection state in the UI \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":680}}}],"partialFingerprints":{"codehealthFindingId/v1":"edd2f964af39ab037e23205a9fdb0353e6141f5d27f7108d7fededf7db2444e3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: expose a failed connection state in the UI \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":708}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f7b1a22cf3ae7f5c7029056bbf46355dbc6b95f2640e5c1ed7a7843c6a973e4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: expose a failed connection state in the UI \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/wifi_manager.py"},"region":{"startLine":717}}}],"partialFingerprints":{"codehealthFindingId/v1":"2136938232a42d56df2f04b025ec278aea8e4c4337eac1895737c37af92ce83f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: consider deduping close screenspace points \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/shader_polygon.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bc10222119dff71c26b7eb445516f999c03005999554525fa45b5a849900565"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: not sure what that means or if it\u0027s accurate anymore \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f6ed666a87a6c1fc7688bac4d9d7b754c03e952e9da7eb1a81322727449f1b0"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this heuristic false-positives on fast swipes because 140Hz touch polling \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec69a3d5a4f13f15a5d8bd3c369c972baf500b80c94ef99f4578bbaf770136db"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: we should just set velocity and let autoscroll go back to steady. delays one frame but who cares \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce84457020ead1fd64530bfbd092d543016ed94978e2a46423481e59310346bd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this drifts when dragging quickly \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"f53f10163322ec75992f2fdcc000dc7b0413a38b0c722c42fe0a741a74e6405e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make get_offset return float \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel2.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"438033275651b30bed0075bd4f35cef09d7a2623ff99cee63f49c951d2640219"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: stop scrolling with any tap, need to fix is_touch_valid \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"625c9a4c5888012fa5919ab93bfe7913e22340e513232a1f0952606ae0022c1b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: just store last mouse event! \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/scroll_panel.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a618f5de14ca465e5300d7f3316c386e45c2dacc1b470cabfffffa5a087e608"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: read touch events from evdev directly to get real kernel timestamps. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"669d4afb8ccb581b4e3e90e08df44399a8ebb216c97a520bf0e8eff3493b963f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: change these to touch_valid \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/application.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8b77cbc95bfc607d5f186cfb879d210197e43d71977931ea44b7ad80fb8915c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # \u0022TODO: FAILED(SSID_NOT_FOUND) should emit error for UI\u0022 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/lib/tests/test_handle_state_change.py"},"region":{"startLine":775}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c752b94bdc6913222e9400a50da4133d33df338c6249958ab4ec20c9b663a48"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use click callback \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/toggle.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed41c94001fd1bcdc5a1bcfa6e60f68ce714d03d9f6663f0c6c71e7e86e3f62b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this math can probably be cleaned up to remove duplicate stuff \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/slider.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"28652255031c21eb95a4168d252b2e09a37e3dee65fff71d3e6a18ac5676f199"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: don\u0027t draw items that are not in the viewport \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller_tici.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd24f2070d4fe6efafab039ff4425c01fd3d1ed54c77cbb173f7f02dbf0ed053"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: the padding correction doesn\u0027t seem correct \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"1de5fd49dfd33cd90b239487438872385de11cd5998a813acd2abe36009ab3aa"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this doesn\u0027t handle two small buttons at the edges well \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"4efbde1333fc2cce5d8542b625e84ec996939c29a1c295d2fc73df5e14a27388"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: only used for offroad alerts, remove when horizontal \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"e569bbb03acc0f24e4d7ec9de55bff9b8a4905735a49614c562fb16f81c41de2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: only used for a few vertical scrollers, remove when horizontal \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/scroller.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d8f585a1efe029235bbadd6be0e113e435928320872f8f215a595b96cfdb7fa"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add this functionality to push_widget \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/nav_widget.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a5a9b45ac2edf4f833744075a06ed1f4a31433c008781570508f9ff1b9df507"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: move this state into NavBar \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/nav_widget.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"c49816261370ed052b03b7008ec7738e7f158b05731c6731177e983738ce05bc"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: disabling this widget on new push_widget still causes this widget to track mouse events without mouse down \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/nav_widget.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"86895ca5071e7fe1476dac964717349c9665a67010bc7fecd4caddd58c705666"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: implement this \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/mici_keyboard.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce36701c5feeea86c022eee9c61564a985d74b33a33d7ce92ba9afe85ea42bdd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: 2 should be 116 with extra control keys added in \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/mici_keyboard.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"87007835dcfa6b07c58d783f994586b39abcb05220f4e2dab4262df0a3dd69c7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: slow enough to use an approximation or nah? also caching might work \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/mici_keyboard.py"},"region":{"startLine":377}}}],"partialFingerprints":{"codehealthFindingId/v1":"88af54ecf2bf6475d58f60be3223a2c9a9a8ba35f159bf72f3adf72c7fd07234"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: I like the push amount, so we should clip the pos inside the keyboard rect \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/mici_keyboard.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"73842e88872524a6cd42570ad490277874891690f96f28f61c8ea255ddc60f98"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: just use the generic Widget click callbacks everywhere, no returning from render \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/list_view.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"86011a736dcf921a7479b451245c8a5d79db8a6a0902920fa964c7c1cb6aa662"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: implement \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/layouts.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"10b7970ea50823df221eb9bfa9e6733cf0f8c139a02eee68fe1401703c0fe78a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make this common \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4ad74b3744dda739aaaea5c77ffed809f54110e3f5f06d309dbda9dd83cf3ea"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: This should be a Widget class \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa90190e6bfa8df09ea86f85b7fa229b6a2a4861e110e289a8880e137c04bad4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add wrapping and proper centering for multiline text \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c821f53bb3d6f710f03f87e2bb216fc209e0dbccabc2b43a05cdc41ac844375"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: cache until text changed \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/label.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee51f91357d1e4974612e22419dae46df7946d94c72da930560716920f236186"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: speed up by removing duplicate calculations across renders \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/html_render.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"db38785e3f7cbb563d8cac252a2d67df5c03d70e37b27cccd4e8be583054a022"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: ideally we emit release events when going disabled \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/ui/widgets/__init__.py"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"84848d68d6309439b249b0a5244888a351a0957fc2aa5673474ba5612fb09d98"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: cleanly interrupt this and invalidate old update \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"babfc78da8d51a550882a5698e0987e27612ab02275608ac20657eefb84f8216"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: show agnos download progress \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":403}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea07e4fb442723ccf561a22a3e557e2f8dec692e3db4b9ccad18016a46e2a68d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Load from param? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":435}}}],"partialFingerprints":{"codehealthFindingId/v1":"29768acf87e59031c76653240918e306dfc4b95e4c6f307ce88c1a2b6b2d9b75"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: reuse overlay from previous updated instance if it looks clean \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/updated/updated.py"},"region":{"startLine":452}}}],"partialFingerprints":{"codehealthFindingId/v1":"08be9fa7ad02760cc90803976bc4c2c4723db3199282660ba8115aacf0aa24e0"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: find a way to get this from API or detect gamepad/PC, perhaps \u0022inputs\u0022 doesn\u0027t support it \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/joystick/joystick_control.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7bd375a36e6307b6a91a0b7bbb6a44a643369928e1012ab6aac0ee34f66b4e4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: once the longcontrol API is finalized, we can replace this with outputting gas/brake and steering \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/joystick/joystick_control.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"7979773f62551dbd07fd78c3c6efbd2cc63e681ff0d09ed75ed46d8eb2fa725b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: parse dependent_slice_segment_flag and slice_segment_address and get real slice_type \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/vidindex.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"bab00c0b3eff32360c60c5b7a335b48cbafa685fd6d4523fd96f2cd0aaf760a7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: get from PPS_NUT pic_parameter_set_rbsp( ) for corresponding slice_pic_parameter_set_id \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/vidindex.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"29c80e03f0db89eed1b0bb4fea714b87898e91cae6bdf6ef30490d7a2918ad71"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: refactor this, it\u0027s super repetitive \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4137c81033c7be7cca20f79c5a11a8d5b3ab8c69941f32212c33f138377d9af"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: add constructor that takes dongle_id, time_str, segment_num and then create instances \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"24b6efe1cb81dc952124b2f289659d4bb300f0c67642c1647a6f7608b6993323"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO should only use one name \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/route.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"f99eb00ea474a82bade960c9566786a3794c24c076a6cb9cf0ab2ed2ae0d2c7d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO this should apply to camera files as well \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/logreader.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ab1c0ebc14b79f0fc15fd4b7c1481fedf1b11ac9b2200e2e4c8f37cf98129e9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: support these \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/log_time_series.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"08feb37f578fb231972e75b21f9754369aacf3bca2f739fbce593d9a16eb0f4d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: is there a better way to detect inhomogeneous shapes? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/log_time_series.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"62a635b4728acbba2b445d92bb86e721e1750613bd0c453aafd8f16bc1fd2c3c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: remove this when commaCarSegments is updated to remove selector \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/comma_car_segments.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"a17645395dee7129a3d25114b3309a4a9e1d9f3465994f4dac334da2e2156606"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: implement an API endpoint for this \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/bootlog.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d2022f8228230ce8e718c7b81739a4159872af91d7de1abffc2d7c3f81e532"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: this should be merged into common.api \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/api.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"66b281e56ec70133a4d0659f375ece8d540cd826f0c53486cff7f025db21c8a4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: parameterize the defaults so we don\u0027t rely on hard-coded values in xx \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/lib/tests/test_caching.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"94a0f52ceb595c3a04aa05adb592e3d58050b954ef6daf1e6ac45b5f8fb51c52"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO localizer accel \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/longitudinal_maneuvers/generate_report.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"112b2d9467a19f470a10a3c69a21fdc5f2b960f67372ded65be9d291e3a473bf"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: also test that layouts successfully load \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/plotjuggler/test_plotjuggler.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"77bf70f1f2188fd7f2c1784112da6fd24373944468cfe358d2790186c8405338"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO gas is deprecated \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/replay/ui.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"41b4651dbf504d8c780a1453e9209852a942eafdadae37f5c98b032466709ea8"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO brake is deprecated \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/replay/ui.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c5753b3c4274764322355afb24d0d1b266901f3501ffcd7c3c6f0a169621945"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use the IMU timestamp \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/lib/simulated_sensors.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"075c02dc06ae045998257554e5e22bd2401690dd623b50c69b6c7beb552ab55e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use the IMU timestamp \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/lib/simulated_sensors.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"2868ca0c332fa1620b75315c806d642025a9a88f4146131a009674c99d9e4f57"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: remove this once https://github.com/astral-sh/ruff/issues/8705 is closed"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lint/check_indentation.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e1d3aae23c9c46857919eb21760c431b5581e3d8c90d7e1803451979fbe4b7d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make this a nice tool for car ports. should also work with qlogs for FW \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/fingerprint_from_route.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"29b0e2e2f4d70415b8d26ee07d79e389c20bf8a35369d83c619c65939f82b0ba"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: also print the fw fingerprint merged with the existing ones \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/fingerprint_from_route.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"44f02b047fe3bf6560424405d9f86c42912e50ee2a49cc2db67cc20bad13f819"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: extend UDS library to allow custom/vendor-defined data identifiers without ignoring type checks \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/vw_mqb_config.py"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"685ca67210bed1ae65970a006e02cce316b7b0c864ad2ea24da2be256947738b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: extend UDS library security_access() to take an access level offset per ISO 14229-1:2020 10.4 and remove this \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/vw_mqb_config.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"c58077a2674fa56ec85e440f28611418dc15d56cd53933193de66c08d4909d09"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: record max lat accel at the end of the event, need to use the past lat accel as overriding can happen before we detect it \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tools/scripts/car/max_lat_accel.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"894f856593cf4bab994ba3a737916776d8c57d8f3e7b7c258bad936df9396d4f"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no project overview: The document is entirely limitations content with no description of what openpilot ALC/LDW/ACC/FCW does or what the project is for. Add a one-paragraph overview stating that this document explains the known operational limits and driver responsibilities of each component."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/LIMITATIONS.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"850782e4d697aa28aeff5b484c0d8c2e82906ac45e2b2476b24f7828dc102870"}},{"ruleId":"D22","level":"warning","message":{"text":"Redundant operations with identical signatures and likely identical behavior. \u0027recv_one\u0027 and \u0027recv_one_or_none\u0027 are semantically equivalent in this context (returning a single message or None), creating unnecessary API surface duplication.: Remove \u0027recv_one\u0027 and keep \u0027recv_one_or_none\u0027 (or vice versa, depending on naming preference for explicitness), or deprecate one. (signatures: messaging.recv_one(sock: SubSocket): _DynamicStructReader | None | messaging.recv_one_or_none(sock: SubSocket): _DynamicStructReader | None)"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"45d38d6fe1bc9376353aa3933b4053b83f450b35dfb80ccec587b094a63a629e"}},{"ruleId":"D22","level":"warning","message":{"text":"Overlap in intent. \u0027all_readers_updated\u0027 checks the current state, while \u0027wait_for_readers_to_update\u0027 waits for that state. While one is blocking and one is non-blocking, the naming convention is inconsistent with standard patterns (e.g., \u0027has_readers\u0027 vs \u0027wait_for_readers\u0027). More critically, \u0027wait_for_readers_to_update\u0027 takes a \u0027dt\u0027 parameter which is ambiguous (is it a timeout? a delta time?).: Rename \u0027wait_for_readers_to_update\u0027 to \u0027wait_for_readers\u0027 or \u0027await_readers\u0027 to clearly distinguish it from the state-checking \u0027all_readers_updated\u0027. Clarify the \u0027dt\u0027 parameter or remove it if it\u0027s redundant with \u0027timeout\u0027. (signatures: PubMaster.wait_for_readers_to_update(self, s: str, timeout: int, dt: float): bool | PubMaster.all_readers_updated(self, s: str): bool)"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"06fd42df254ddba793f40fb29c388989fc4634a8ac4d36532747571dbdea4299"}},{"ruleId":"D22","level":"warning","message":{"text":"Type hierarchy inconsistency. \u0027HardwareBase.get_sim_lpa\u0027 returns \u0027LPABase\u0027, but the concrete implementation \u0027LPA\u0027 is a subclass of \u0027LPABase\u0027. However, the module \u0027openpilot.common.esim.lpa\u0027 exposes a module-level \u0027LPA\u0027 class that seems to duplicate the interface of \u0027LPABase\u0027 but is not clearly positioned in the hierarchy relative to the base class in the exposed surface. It\u0027s unclear if \u0027LPA\u0027 is the only implementation or if there are others, and the return type \u0027LPABase\u0027 suggests polymorphism that isn\u0027t fully reflected in the distinct \u0027LPA\u0027 class exposure.: Ensure the relationship between \u0027LPABase\u0027 and \u0027LPA\u0027 is clear. If \u0027LPA\u0027 is the sole implementation, consider returning \u0027LPA\u0027 directly or documenting the polymorphism better. The current surface makes it look like \u0027LPABase\u0027 is a concrete type used for return values, which is confusing if it\u0027s an abstract base. (signatures: HardwareBase.get_sim_lpa(self): LPABase | LPA.__init__(self) | LPABase.__init__(self))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4c78d32744c698e5096a5ce9aa6867f9762bf15e294fd92d9d946b732320547d"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"caadf16b504ec8ceb3dbbcacc07fdb6e8b7a301ce1afe4c6088199af9a0ff831"},"properties":{"commitSha":"310597c60ca2bfc9ac2bb5374b598b98272cf2c8"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6701d9f920dd84ae9eec4ac0d5047cb59633b55637e721f67e9112d65f4c4a7d"},"properties":{"commitSha":"9c2632d9d1756628719acb6140869245fb4fc6c4"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e98edcb06da9fd3e408d36b57546b5029d5de47167b23a6df148ea89ad9ab4c1"},"properties":{"commitSha":"9c2632d9d1756628719acb6140869245fb4fc6c4"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4075bfd92bc679437fe27add5364c17045f8818b6033080b1030852cf84c90a5"},"properties":{"commitSha":"79ca8c9ec9763ec0f23839fa8389589451ed4e7c"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d916971dcf80079d354921eb39f7575e89c69fb6d21d0730250f75ea574de522"},"properties":{"commitSha":"5f22ca2fce233b24f7e1903abf67cc22a4acd1ad"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"64ae4f80342e773cf40e9e60d039e55b86f4f74a669ec0c9413abb0612d00f7b"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ee503d53ed06793375229e08390c2a7cabf3c17e8dce626591646331c6212f9a"},"properties":{"commitSha":"c94c6e36c69cc14474411ce676942bd407698979"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f6b8aa7155f1e9c8c9244f6a92a2c6238cceb21fb52c49ebdd81681e8c3d4d21"},"properties":{"commitSha":"10af4af68fc2f15a4e3f0fffa8aef1b719da6f57"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3058981bbcadbf00d7e24b8a016fe3f99d597cc05dc0116b34527ff065753afb"},"properties":{"commitSha":"99c5800ea5bb0704d96a6e459af2acf1a1050e3c"}},{"ruleId":"D28","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3cdfd7beb31b791ae18dcb425e21eb157c842e7bbcd522cc330573c1a6538db1"}},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"11f9f14ce37c7c0b2062d3128ed995af296b7f45b141ce723d4fdfbb1aeedaf1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"963ce85e2ce83df65dfaca0efca0e83b78a55cf0001278c100dc852d9e4979b3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"873ab3f70bf89ab48f9ad9afb3e97b54487bdf338cff78a788d8afada8c45a8b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f0a4110758d5f1a9cedcc7d92f821ae06d797a8c4dcd62c465d80b2f7ce30cc2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b7a4832380b6ae965c7cac8327ee0ffd2fef6e884e3731a751d6672457de141a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3176cbb3904749e2358f643250fdcd7acf729b0d35b2b60453d184eda73a01f0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8e81defb8650b7e369ab9795d9fcc1abd6cd57e533cd04c0800df7b244f7b4f7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"62f078098d20ffd441a965cdc9f7712f740f9b9d07e387d96392360a4d271eb5"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b5248e335ea609aee1cab26835c586a953f6dcd23b49be25e3a31f789332c7be"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"05d17baf6e01969ef67ae71a33c03e461fa01c6c1f80f6d1b5d20a950ea4a3cb"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"51d2cc35543949624e2dc7f707ee4d52b9ec7014844ff818ceeeee234c2004a3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5a183109734588cbc6a01b480487235f7346a90cabdae9cf7b559874bfdd20e6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"aaade4e2fc99a306e52c90ea02ec2073bc215ad1c8f021056a867957fc612d5d"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7cef2e2cdedb3b9eb73f48afdf4dcb844fc9d365ee32ac3314dcd0b2843336ae"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d7644f575e9230a5eee28a01835d40b8ddb0c962287fa99c131ef1e5e7a9e083"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7fd4bc83c1146ba7e483416f5623a29a1a8f41bb4261579ccfcaa93a9a8a80de"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"54869d383133cb106e10b9f66195fa82dfe6939ecf1525159d0f52e352a22ffb"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ca527fd0ff5f72e05389d7a511541059b3f5754e8cef539ab7cdad0a9e3e8748"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d8fee6ccafa4b95d25cd6b99c0107a24e16d973191c516104acf15b27e386d70"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a189c8ffd0ac28b4cf6538e2d11d97287aabf75a4093772681268913681c957e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"57ee3577a13d3a9e4820ae070965a7a2c276579c0e88ac1edabfcad7dab0b7c1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f70dc88defe7cccbbd9014b74bc0e3dbcd3600cdbdd4b01b33f5bd1f446f567a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e3ccfe854ff4d45329009ccf9a04a9794833088aca8fb4b6ad269f7e2a60eca3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"70616fa0eecf98a712c8737681e3cc79b605534df643a2ce294f1c857a21a185"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ddbe1f74e8fd915721949d9d3bbeb53bdae87b5dd4988f6fa9a11aeb747b100e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ac5f6c68c42a1e74124cbca81c1be43c357a37f8fa2df23d63990114944720e7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fc9a75bdf2c55290c0240d4fde537bf5394d8108c7fd4eff3e5d9de776ca6ac6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"460230520e8836d47eb5a1c157e254c4c9e9cc3986514375e3c4e5b77e41cb98"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5eaf73c52fabf822d6e8da2d694e4effccbfc4be4ab0570b956a0e4c6102a6b8"},"taxa":[{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6ed059458dc0d864f79fffc2c8cd3f09ac2213f256b255ba1e07734350228541"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7be0e304393e48a142ea4c2cbde675dd273f4f8e338c91232bf33e97f7b3946e"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"206a821ee25ee9166df620189e97a71bd5c0b2b80edfb43e2f469cb4a54b6df2"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8252f22d8d72f7ff01bad207bedd52e6cca90d51fa34dd62411b75e445ec8ecf"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"50ae70fc848a25e032b2e9784d16afa1d1aa167c8dddbb5937c348e456b76485"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2a22916cf6befcef7d5a2a14b6bc21535553e6a49a793f98043ae4b29dfc5109"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0dd6ad10fd683613203a1185b54b8b6652dfb675b2cc8f815af7750719289e01"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"585ff774d8ff0a6c84f780e75001a75b913fd9e22f63a26d6b5f9218549cb1e6"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"86c49b76266981596b1044c10731b8a28da6b1bedd9013116ac17a5d78b6eb03"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"80cf319801198e10dadb811054c4be823637da3f90d99d31d11b42fe734c0746"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"60e360606a52ed3c500537ca2b10c2ee4b1a20521f0179ebcc797e623b7a5e99"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e6b30e65b9eb1b24c60c3f49b5ef938fc7e90d7aa018c5daafd113b3d80d7829"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b2c97d44d96793225fc3558499923cfa6f8c81b464f7eac17a03a0d403d8a878"},"taxa":[{"id":"CWE-319","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6187c7484ff65d9b4bade3b16688d2d55a31856f407480ab3cce709f07137f8f"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"74525d56b3d5097983c863488fc1546bffd2994fb163a89f4d0db275d58244b1"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c1c0be6e54bf56340b9d0b8228f21e916492bc275b1dc07a589871a980f739d3"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a4ae986d653ffedd39202697f17882239a437902892fe3a5d50a0130006e0423"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D34","level":"note","message":{"text":"Orphaned files with no living knowledge: 4 of 225 analysed file(s) have no living knowledge left \u2014 their last meaningful change has decayed away, so if one breaks, no one currently understands it (counted over production source files of roughly 2,400 bytes or more, excluding vendored, generated and example/demo trees and test files identified by path convention, largest first; 225 of the 393 production source files in this repository met that bar). None is large enough to earn a read-through of its own, so this row stands in for the per-file rows rather than raising one each \u2014 most significant first: openpilot/system/qcomgpsd/structs.py, openpilot/common/logging_extra.py, openpilot/tools/sim/lib/keyboard_ctrl.py, openpilot/tools/lib/azure_container.py. Attach the read to the next change that touches one of them: have a second person review that change, and leave behind a short comment or test recording what the file is for, so the knowledge comes back at the cost of a change you were making anyway."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ce861fd78f6935114d3a342cb90ad25870f984e1042954fcbbe27c0e23be3658"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: athenad.py \u2194 qlog_size.py: \u0060openpilot/system/athena/athenad.py\u0060 (context openpilot) and \u0060tools/scripts/qlog_size.py\u0060 (context tools) sit in DIFFERENT parts of the tree yet change together 50% of the time (5 of the 10 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well, and counted over this repository\u0027s 10,000 most recent commits rather than its whole history \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see. You can check this without leaving the row: of the 5 shared commits counted here, the most recent 3 are \u0060954b567b\u0060 merge a bunch of misc stuff into common.utils (#36463) (at that commit the files were still \u0060system/athena/athenad.py\u0060 and \u0060selfdrive/debug/qlog_size.py\u0060); \u006027c11eb5\u0060 athena upload: streaming file upload (#34559) (at that commit the files were still \u0060system/athena/athenad.py\u0060 and \u0060selfdrive/debug/qlog_size.py\u0060); \u00609bc35c09\u0060 Revert \u0022athena upload: reduce memory usage and improve efficiency wit\u2026 (at that commit the files were still \u0060system/athena/athenad.py\u0060 and \u0060selfdrive/debug/qlog_size.py\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/athena/athenad.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"40067fcdc4c5b1fd2c691379d13654427c59f6d58258c242fd18c05219bdd263"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling clique: latcontrol_angle.py, latcontrol_pid.py, latcontrol_torque.py: 3 files \u2014 \u0060openpilot/selfdrive/controls/lib/latcontrol_angle.py\u0060, \u0060openpilot/selfdrive/controls/lib/latcontrol_pid.py\u0060, \u0060openpilot/selfdrive/controls/lib/latcontrol_torque.py\u0060 \u2014 all change together with no explicit dependency: a fully-connected co-change clique, not 3 separate couplings. They share one concern (thin parallel siblings over a common abstraction), so extract the shared part into ONE unit and the whole clique\u0027s coupling clears at once \u2014 you do not need to break each pair individually."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/controls/lib/latcontrol_angle.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aa5f1478cebb01a3c09f97d9845ca3c34767376bdafc9ac67e96213cb25c389"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: manager.py \u2194 tombstoned.py: \u0060openpilot/system/manager/manager.py\u0060 and \u0060openpilot/system/tombstoned.py\u0060 change together 55% of the time (6 of the 11 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well, and counted over this repository\u0027s 10,000 most recent commits rather than its whole history \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 6 shared commits counted here, the most recent 3 are \u00606bbdf8ad\u0060 remove sentry (#38790); \u0060cea5273f\u0060 move version to common/ (#38210) (at that commit the files were still \u0060system/manager/manager.py\u0060 and \u0060system/tombstoned.py\u0060); \u00607a3e454d\u0060 move sentry/stats to system/ (#32490) (at that commit the files were still \u0060selfdrive/manager/manager.py\u0060 and \u0060system/tombstoned.py\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/system/manager/manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"89f231360cc1d4caeb68b9c6e9acc6d1d823a14995dd0aa0add1f9a4da36c1e5"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: metadrive_bridge.py \u2194 metadrive_process.py: \u0060openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py\u0060 and \u0060openpilot/tools/sim/bridge/metadrive/metadrive_process.py\u0060 change together 50% of the time (8 of the 16 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well, and counted over this repository\u0027s 10,000 most recent commits rather than its whole history \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency between them. They sit in the same directory, but in this ecosystem each file is its own module \u2014 a sibling reference still needs an import \u2014 so the missing import edge is real: the coupling runs through shared behaviour, not a declared dependency. If they duplicate structure, extract the common part into one unit; otherwise the coupling is hidden and worth breaking. You can check this without leaving the row: of the 8 shared commits counted here, the most recent 3 are \u0060dc094792\u0060 Revert \u0022ci: faster metadrive test (#33755)\u0022 (at that commit the files were still \u0060tools/sim/bridge/metadrive/metadrive_bridge.py\u0060 and \u0060tools/sim/bridge/metadrive/metadrive_process.py\u0060); \u0060d7c0906d\u0060 ci: faster metadrive test (#33755) (at that commit the files were still \u0060tools/sim/bridge/metadrive/metadrive_bridge.py\u0060 and \u0060tools/sim/bridge/metadrive/metadrive_process.py\u0060); \u0060b8fd64f3\u0060 CI: Drive a loop in MetaDrive (#32308) (at that commit the files were still \u0060tools/sim/bridge/metadrive/metadrive_bridge.py\u0060 and \u0060tools/sim/bridge/metadrive/metadrive_process.py\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2454f7efd03b3bde79683b47e63d917ef93131a3f6168efccc08e0c1c301fbee"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b213f6eedd4b140d0bc37bdf1496f72811a643f34064f12518b32e9e83bcfc7"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e17f71490e4d120a48b2b2881ab866c93b272bef2febb673a3e8e42b2c288ab"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb00976a698a5d68999b7ee6d27206fd374e916853e7ff1ead5eed42386f043f"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d068c977b62d9a977df1bb6f53e8b00b586c3abee955f91d715f92b8e019d624"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ace515990e7ee0f17b5c17e44dd168a5bdecf90804a3a3dd845cf05540978013"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h3 to h5: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"openpilot/selfdrive/assets/offroad/fcc.html"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"87157652956852f7668852bf42da5ccb9665952889bd654faffb74aef2973d7a"}},{"ruleId":"AC7","level":"warning","message":{"text":"Accessibility enforcement below the top rung: No accessibility enforcement found \u2014 no automated accessibility check runs over the HTML your app renders. Assert the accessibility invariants over that HTML in the test suite you already have (parse the output and assert, or drive a browser), and gate that test in CI so a regression blocks the merge. What was searched, so you can tell an absence from a miss: the 2 markup file(s) this pass actually assessed, the linter configuration checked in beside them, and this repository\u0027s test and CI files \u2014 matched by name against the accessibility checkers this dimension carries. An audit run outside the repository, a hosted scanner, or a check whose name is not one of those, is not seen here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d46019b86eff5ddad9db289e6802ac158899e980df54c34f67722442787ead62"}},{"ruleId":"M2","level":"note","message":{"text":"No ADRs: No Architecture Decision Records found \u2014 no conventional ADR directory, no numbered \u0060NNNN-title\u0060 documents in any markup this check reads, and nothing ADR-shaped by content. Design rationale recorded elsewhere (a design-notes tree, a mailing list, pull-request discussion) is not visible to this check and is not re-findable per decision, so a future maintainer cannot ask why one choice was made and get an answer."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"670b3d6e36a756d63097d0dfbf90afd5fc761308800b9354894a07c3f4e4aa14"}},{"ruleId":"M3","level":"note","message":{"text":"No src/ separation: Production code isn\u0027t grouped under a src/ folder \u2014 it all sits under openpilot/ alongside the root build files, so the conventional src/ boundary between the product and its tooling isn\u0027t drawn."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fdf7f5b24e313364d10170a5c2542959902fe0d26ed70edef3eaa10ec5bcdb1d"}},{"ruleId":"P3","level":"note","message":{"text":"No SAST: No static application security testing detected. For this repository\u0027s stack, add bandit, \u0060semgrep --config=p/python\u0060, or CodeQL\u0027s python pack as a CI step. What was searched, so you can tell an absence from a miss: the 42916 CI workflow file(s) in this repository, and the scanner and linter configuration checked in beside them. A scan that runs outside CI, one configured in your forge\u0027s web UI rather than in a committed file, or a tool whose name is none of those this check carries, is not seen \u2014 if that is your case the row is wrong, and saying so is more useful than adding a second scanner."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6e54424179c892f03ef2fd003130ac4bd43f39bbf3b1ca0a0143e25acb80ec87"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1059","guid":"a2381a08-60f6-9554-a8b8-f3018cfaaca5","name":"Insufficient Technical Documentation","shortDescription":{"text":"Insufficient Technical Documentation"},"helpUri":"https://cwe.mitre.org/data/definitions/1059.html"},{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-319","guid":"7af97476-9f0d-4458-9163-3d2043918a1a","name":"CWE-319","shortDescription":{"text":"CWE-319"},"helpUri":"https://cwe.mitre.org/data/definitions/319.html"},{"id":"CWE-327","guid":"e51910ff-67b5-3c51-aa3d-92837d9eab90","name":"CWE-327","shortDescription":{"text":"CWE-327"},"helpUri":"https://cwe.mitre.org/data/definitions/327.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"CWE-353","shortDescription":{"text":"CWE-353"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-502","guid":"f7d3b296-aac0-5c5a-b706-e07faba26c36","name":"CWE-502","shortDescription":{"text":"CWE-502"},"helpUri":"https://cwe.mitre.org/data/definitions/502.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"CWE-506","shortDescription":{"text":"CWE-506"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"CWE-829","shortDescription":{"text":"CWE-829"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-939","guid":"12397742-f2c4-8254-8012-482c3356c551","name":"CWE-939","shortDescription":{"text":"CWE-939"},"helpUri":"https://cwe.mitre.org/data/definitions/939.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":63,"secretScannerRunsExcluded":0}},"redactionTokens":["A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."]}]}