{"$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":"D6","name":"Cohesion (LCOM4)","shortDescription":{"text":"Cohesion (LCOM4)"},"helpUri":"https://codehealth.canine.dev/dimensions/D6"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"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"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"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":"D20","name":"ADR Quality","shortDescription":{"text":"ADR Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D20"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D26","name":"Project Cohesion","shortDescription":{"text":"Project Cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/D26"},{"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"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"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"]},{"target":{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"],"owasp":"A05:2025"}},{"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"]},{"target":{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"],"owasp":"A03:2025"}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"AC1","name":"Text alternatives","shortDescription":{"text":"Text alternatives"},"helpUri":"https://codehealth.canine.dev/dimensions/AC1"},{"id":"AC2","name":"Forms \u0026 labels","shortDescription":{"text":"Forms \u0026 labels"},"helpUri":"https://codehealth.canine.dev/dimensions/AC2"},{"id":"AC3","name":"Page structure","shortDescription":{"text":"Page structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AC3"},{"id":"AC6","name":"Visual \u0026 motion safety","shortDescription":{"text":"Visual \u0026 motion safety"},"helpUri":"https://codehealth.canine.dev/dimensions/AC6"},{"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":"AX3","name":"Project dependency cycles","shortDescription":{"text":"Project dependency cycles"},"helpUri":"https://codehealth.canine.dev/dimensions/AX3"},{"id":"AX4","name":"Dependency direction","shortDescription":{"text":"Dependency direction"},"helpUri":"https://codehealth.canine.dev/dimensions/AX4"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"ED5","name":"Idempotency","shortDescription":{"text":"Idempotency"},"helpUri":"https://codehealth.canine.dev/dimensions/ED5"},{"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":"P10","name":"Library API \u0026 versioning","shortDescription":{"text":"Library API \u0026 versioning"},"helpUri":"https://codehealth.canine.dev/dimensions/P10"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P2","name":"Observability","shortDescription":{"text":"Observability"},"helpUri":"https://codehealth.canine.dev/dimensions/P2"},{"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":"PF1","name":"Benchmark discipline","shortDescription":{"text":"Benchmark discipline"},"helpUri":"https://codehealth.canine.dev/dimensions/PF1"},{"id":"X1","name":"Async correctness","shortDescription":{"text":"Async correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X1"},{"id":"X10","name":"Duplicated predicate","shortDescription":{"text":"Duplicated predicate"},"helpUri":"https://codehealth.canine.dev/dimensions/X10"},{"id":"X12","name":"Unreachable branch","shortDescription":{"text":"Unreachable branch"},"helpUri":"https://codehealth.canine.dev/dimensions/X12"},{"id":"X13","name":"Undrained process stream","shortDescription":{"text":"Undrained process stream"},"helpUri":"https://codehealth.canine.dev/dimensions/X13"},{"id":"X14","name":"Bypassable address classification","shortDescription":{"text":"Bypassable address classification"},"helpUri":"https://codehealth.canine.dev/dimensions/X14"},{"id":"X15","name":"Unvalidated length from an untrusted reader","shortDescription":{"text":"Unvalidated length from an untrusted reader"},"helpUri":"https://codehealth.canine.dev/dimensions/X15"},{"id":"X17","name":"Uncapped recursion over a caller-supplied document","shortDescription":{"text":"Uncapped recursion over a caller-supplied document"},"helpUri":"https://codehealth.canine.dev/dimensions/X17"},{"id":"X19","name":"Unrestored process-global state","shortDescription":{"text":"Unrestored process-global state"},"helpUri":"https://codehealth.canine.dev/dimensions/X19"},{"id":"X20","name":"Mistyped argument guard","shortDescription":{"text":"Mistyped argument guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X20"},{"id":"X21","name":"Side-effecting pattern guard","shortDescription":{"text":"Side-effecting pattern guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X21"},{"id":"X22","name":"Contradicted release guard","shortDescription":{"text":"Contradicted release guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X22"},{"id":"X23","name":"Unguarded diagnostic materialisation","shortDescription":{"text":"Unguarded diagnostic materialisation"},"helpUri":"https://codehealth.canine.dev/dimensions/X23"},{"id":"X24","name":"Document value interpolated into markup unescaped","shortDescription":{"text":"Document value interpolated into markup unescaped"},"helpUri":"https://codehealth.canine.dev/dimensions/X24"},{"id":"X25","name":"Inert configuration knob","shortDescription":{"text":"Inert configuration knob"},"helpUri":"https://codehealth.canine.dev/dimensions/X25"},{"id":"X26","name":"Unsynchronised callback handoff","shortDescription":{"text":"Unsynchronised callback handoff"},"helpUri":"https://codehealth.canine.dev/dimensions/X26"},{"id":"X27","name":"Collection changed while being enumerated","shortDescription":{"text":"Collection changed while being enumerated"},"helpUri":"https://codehealth.canine.dev/dimensions/X27"},{"id":"X28","name":"Index access outside its own emptiness guard","shortDescription":{"text":"Index access outside its own emptiness guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X28"},{"id":"X3","name":"Exception handling","shortDescription":{"text":"Exception handling"},"helpUri":"https://codehealth.canine.dev/dimensions/X3"},{"id":"X30","name":"Support guard that admits what it rejects","shortDescription":{"text":"Support guard that admits what it rejects"},"helpUri":"https://codehealth.canine.dev/dimensions/X30"},{"id":"X32","name":"Type resolved by simple name across every loaded assembly","shortDescription":{"text":"Type resolved by simple name across every loaded assembly"},"helpUri":"https://codehealth.canine.dev/dimensions/X32"},{"id":"X4","name":"Structured logging","shortDescription":{"text":"Structured logging"},"helpUri":"https://codehealth.canine.dev/dimensions/X4"},{"id":"X6","name":"Hand-rolled structured-format parsing","shortDescription":{"text":"Hand-rolled structured-format parsing"},"helpUri":"https://codehealth.canine.dev/dimensions/X6"},{"id":"X7","name":"Silent fallback defaults","shortDescription":{"text":"Silent fallback defaults"},"helpUri":"https://codehealth.canine.dev/dimensions/X7"},{"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":"narrowphase.func_contact_overlap_axes (cyclomatic 133): narrowphase.func_contact_overlap_axes has cyclomatic complexity 133 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1931}}}],"partialFingerprints":{"codehealthFindingId/v1":"8abd4256a8c59d845ddb51166570ccde725a1b79d36ae69e55035ddef24aec02"}},{"ruleId":"D1","level":"warning","message":{"text":"box_contact.func_box_box_contact (cyclomatic 129): box_contact.func_box_box_contact has cyclomatic complexity 129 (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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"1185447cfdda40af05823207b9cfff251c789c46f17dad165389072d0c5aacf9"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntityDescription._parse_scene (cyclomatic 96): KinematicEntityDescription._parse_scene has cyclomatic complexity 96 (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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5de3c0facfed236c9571bbcb40ddf89d269fc349a0a7fbd6089bbc4d31deeff"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_add_polytope_vertex_contacts_sdf (cyclomatic 92): narrowphase.func_add_polytope_vertex_contacts_sdf has cyclomatic complexity 92 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"882b15fb84f80bc03a6ecc8c8a077dff628b10705fcf2f4136e236a441b12106"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_geometry.parse_prim_geoms (cyclomatic 78): usd_geometry.parse_prim_geoms has cyclomatic complexity 78 (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":"genesis/utils/usd/usd_geometry.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"11a8199e04af0c9b1346b23c7648879f2c46880f8da8a8f3f6306adea481aee6"}},{"ruleId":"D1","level":"warning","message":{"text":"linesearch.func_linesearch_islands_coop (cyclomatic 70): linesearch.func_linesearch_islands_coop has cyclomatic complexity 70 (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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1191}}}],"partialFingerprints":{"codehealthFindingId/v1":"b10e5dea96358a003fa876c5f31ebe0217e224d25c18dc42bbf33cc90c0a3e94"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_add_polytope_vertex_contacts_sdf_shell (cyclomatic 69): narrowphase.func_add_polytope_vertex_contacts_sdf_shell has cyclomatic complexity 69 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":597}}}],"partialFingerprints":{"codehealthFindingId/v1":"230a9f3c9c09cfe2bee1c254dc093724bb17f60eea8d3aefc758725e8f83af1c"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_island_assemble_factor_solve_tiled (cyclomatic 68): solver.func_island_assemble_factor_solve_tiled has cyclomatic complexity 68 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2764}}}],"partialFingerprints":{"codehealthFindingId/v1":"103e841c6e2f2af43eba3eddd1a48098a0be0d34f9c5e4b3f91e2f8f7ec5f92a"}},{"ruleId":"D1","level":"warning","message":{"text":"mesh._postprocess_collision_geoms_impl (cyclomatic 66): mesh._postprocess_collision_geoms_impl has cyclomatic complexity 66 (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":"genesis/utils/mesh.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"13be8425e9b618c8ed874716f19d966b2d82646bc5a60b64cc66b310f0f60099"}},{"ruleId":"D1","level":"warning","message":{"text":"multi_contact.func_multi_contact (cyclomatic 64): multi_contact.func_multi_contact has cyclomatic complexity 64 (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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b4d435df2b35abe06a5a017f3cf6281c162170864a59a493cf9242b594a92b"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_convex_convex_contact (cyclomatic 64): narrowphase.func_convex_convex_contact has cyclomatic complexity 64 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2475}}}],"partialFingerprints":{"codehealthFindingId/v1":"133466994b87a600f0c34b7d3328f808e3b6c33c8c08b50e5eb7153ed44b0146"}},{"ruleId":"D1","level":"warning","message":{"text":"genesis.init (cyclomatic 62): genesis.init has cyclomatic complexity 62 (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":"genesis/__init__.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff6b511238a97de38cfff4bbf2e65f970adeb2a2277933a3d467dcc8eece962b"}},{"ruleId":"D1","level":"warning","message":{"text":"Collider.get_contacts (cyclomatic 60): Collider.get_contacts has cyclomatic complexity 60 (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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":881}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bef377b0638c5000db5fb63d2dcaaa237cea39294eb26483d80de46d3949a6f"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_rigid_entity._parse_link (cyclomatic 60): usd_rigid_entity._parse_link has cyclomatic complexity 60 (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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b88f036cdb4377de5c91e76ef89f9626a74c815f02f59f0e5415a35f8a6a56e"}},{"ruleId":"D1","level":"warning","message":{"text":"contact.func_clamp_prune_contacts_coop (cyclomatic 59): contact.func_clamp_prune_contacts_coop has cyclomatic complexity 59 (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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1446}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ab5d559b041aac4b8923a3c2195b535206b50a8689d58a5b141e03d248946e6"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_recompute_perturbed_contact (cyclomatic 59): narrowphase.func_recompute_perturbed_contact has cyclomatic complexity 59 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1543}}}],"partialFingerprints":{"codehealthFindingId/v1":"31943b22a2343373258071b26df1cc5965843fe591bd6f1c255f8c7ce986e8d0"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver._build_static_config (cyclomatic 59): RigidSolver._build_static_config has cyclomatic complexity 59 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"29e955018273a4c6e68d40d84fa46f47977998396cdd3451e2b527b99df7a8f3"}},{"ruleId":"D1","level":"warning","message":{"text":"broadphase._func_broad_phase_sap (cyclomatic 58): broadphase._func_broad_phase_sap has cyclomatic complexity 58 (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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"1be5514c265b4fe6a1421ccf25c6ceed6f008b9bc84a0f513ef8241e2564af4e"}},{"ruleId":"D1","level":"warning","message":{"text":"island.func_build_islands_coop (cyclomatic 58): island.func_build_islands_coop has cyclomatic complexity 58 (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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":514}}}],"partialFingerprints":{"codehealthFindingId/v1":"72bab72c3420e7e3d56747d1cfda920c62586e2a1f0772c5d2524ecec4ce2e3d"}},{"ruleId":"D1","level":"warning","message":{"text":"urdf.parse_urdf (cyclomatic 58): urdf.parse_urdf has cyclomatic complexity 58 (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":"genesis/utils/urdf.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"3185decd87074f616f0c1a0c5b18ae6737796d1f9071ffbfb1273afb383c8a27"}},{"ruleId":"D1","level":"warning","message":{"text":"backward.kernel_manual_add_equality_constraints_bw (cyclomatic 54): backward.kernel_manual_add_equality_constraints_bw has cyclomatic complexity 54 (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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":784}}}],"partialFingerprints":{"codehealthFindingId/v1":"4302efbc8af30e2f47297432e623595ee781e8d63bdf21485d0fb48d117412a9"}},{"ruleId":"D1","level":"warning","message":{"text":"inverse_kinematics.func_inverse_kinematics (cyclomatic 52): inverse_kinematics.func_inverse_kinematics has cyclomatic complexity 52 (threshold 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":363}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6fe56403075076aa3fe0dffa6d4a8024c91cde5917ed452921995853a19e9fc"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase._func_multicontact_detect (cyclomatic 51): narrowphase._func_multicontact_detect has cyclomatic complexity 51 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3163}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd4897315f9bfe4a0be0505b57252c4e729d3a02ac14107786ac98bfad4e278d"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_narrowphase_multicontact (cyclomatic 47): narrowphase.func_narrowphase_multicontact 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3734}}}],"partialFingerprints":{"codehealthFindingId/v1":"262841256b12339fb9de60a889f79c82cfb43caa2a288612b96e1f68b8538be6"}},{"ruleId":"D1","level":"warning","message":{"text":"bvh.func_build_bvh (cyclomatic 46): bvh.func_build_bvh has cyclomatic complexity 46 (threshold 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":"genesis/engine/bvh.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"86b6223ac978bdfc52d4f7c29958878ae8d7ee96fd8d61ce057ae2f36ad40a3c"}},{"ruleId":"D1","level":"warning","message":{"text":"Collider._compute_collision_pair_idx (cyclomatic 46): Collider._compute_collision_pair_idx 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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3923fb4d0dda289ff34b99b93f59fddcd4db665ed77bea3189409f359f7373c"}},{"ruleId":"D1","level":"warning","message":{"text":"mjcf.parse_link (cyclomatic 46): mjcf.parse_link 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":"genesis/utils/mjcf.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"923921c57872947f962aae8594963fd5cc6fcbc971d5876f1534d99dccddc516"}},{"ruleId":"D1","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_entity_browser (cyclomatic 44): ImGuiOverlayPlugin._render_entity_browser has cyclomatic complexity 44 (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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":1059}}}],"partialFingerprints":{"codehealthFindingId/v1":"681c659e9c1c9d6fb4e9661d79046d91fa5829426721bbe134bedd25311cd109"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntity.attach (cyclomatic 43): KinematicEntity.attach has cyclomatic complexity 43 (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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"63832e553bc289a23b57eb3c12f14438f4c3818eb09e58dbe2c0abe03cdda869"}},{"ruleId":"D1","level":"warning","message":{"text":"solver._add_collision_constraints_per_contact (cyclomatic 43): solver._add_collision_constraints_per_contact has cyclomatic complexity 43 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":916}}}],"partialFingerprints":{"codehealthFindingId/v1":"004ecf347e722c9144d4d8e728f5ec5399bb555432eb86de5ed1b8d47f196f3d"}},{"ruleId":"D1","level":"warning","message":{"text":"Camera.set_pose (cyclomatic 43): Camera.set_pose has cyclomatic complexity 43 (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":"genesis/vis/camera.py"},"region":{"startLine":592}}}],"partialFingerprints":{"codehealthFindingId/v1":"471af1dca50cd7511b0191076d7256d58558377551b1f539d4d458a2b84065ad"}},{"ruleId":"D1","level":"warning","message":{"text":"contact.func_contact_support_hull (cyclomatic 42): contact.func_contact_support_hull has cyclomatic complexity 42 (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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":953}}}],"partialFingerprints":{"codehealthFindingId/v1":"5333d3afff9fe3e90330152b0ebaa560384de33d013f994c56fad47677726875"}},{"ruleId":"D1","level":"warning","message":{"text":"mpr.func_mpr_contact_from_centers (cyclomatic 42): mpr.func_mpr_contact_from_centers has cyclomatic complexity 42 (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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ace82ec1e2a1cc445eac5e9b51a9c2f2938cdbb7d896f4c60131eecc5ea6675"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_hessian_direct_batch (cyclomatic 42): solver.func_hessian_direct_batch has cyclomatic complexity 42 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2589}}}],"partialFingerprints":{"codehealthFindingId/v1":"b639532e094f26b990df4e1ed0f1f0bba5c88cc3e49adfa658781c2a5c2df463"}},{"ruleId":"D1","level":"warning","message":{"text":"contact.func_clamp_prune_contacts (cyclomatic 41): contact.func_clamp_prune_contacts 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1144}}}],"partialFingerprints":{"codehealthFindingId/v1":"f94b03a700cadf6eee5cdce71a06c636c06713d161b6344bc458a5300199a04e"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_shared (cyclomatic 40): forward_dynamics.func_factor_mass_tree_shared has cyclomatic complexity 40 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":856}}}],"partialFingerprints":{"codehealthFindingId/v1":"9643adb5aba05c60a542d7c7d8a20831d3a981811e7855017ce1a42811136d94"}},{"ruleId":"D1","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_scene_editor (cyclomatic 40): ImGuiOverlayPlugin._render_scene_editor has cyclomatic complexity 40 (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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":867}}}],"partialFingerprints":{"codehealthFindingId/v1":"3317ef736e0829de9d90c88c7e07c8a76e2648edb5c031abfb96d0aca3b20c51"}},{"ruleId":"D1","level":"warning","message":{"text":"point_cloud_tactile._kernel_point_cloud_proximity_taxel_bvh (cyclomatic 39): point_cloud_tactile._kernel_point_cloud_proximity_taxel_bvh has cyclomatic complexity 39 (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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c93fdc0b9d65a8fbf450b41b1d86da6db07c3ce9a2e933c8c9b059d7f41762c"}},{"ruleId":"D1","level":"warning","message":{"text":"epa.func_safe_epa (cyclomatic 39): epa.func_safe_epa has cyclomatic complexity 39 (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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":960}}}],"partialFingerprints":{"codehealthFindingId/v1":"ede4a0cdab799136046608080581025f12cdbefbb9b51cd346e7b8019d37d2af"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_narrowphase_contact0 (cyclomatic 39): narrowphase.func_narrowphase_contact0 has cyclomatic complexity 39 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3959}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8077740439602ee8f582a4723cdbff5965156dd72c056b2bad6c04c6b222892"}},{"ruleId":"D1","level":"warning","message":{"text":"gltf.parse_glb_material (cyclomatic 38): gltf.parse_glb_material has cyclomatic complexity 38 (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":"genesis/utils/gltf.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"b49cc90cf4b24dbc568d89589b745cc0d8ce71ec9698e21dc464b0d05e3ab2b9"}},{"ruleId":"D1","level":"warning","message":{"text":"serialization._load_value (cyclomatic 38): serialization._load_value has cyclomatic complexity 38 (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":"genesis/utils/serialization.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"214a1e2abbccd5454bc456fae5b0c33a4ad02b5f604797a525bf693a2d9be788"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_collision.apply_collision_filtering (cyclomatic 38): usd_collision.apply_collision_filtering has cyclomatic complexity 38 (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":"genesis/utils/usd/usd_collision.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"0727462811d72ea7d3b6718af03a46897f200967fe40e1d870ac5cc2b5eaae50"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_integrate (cyclomatic 37): forward_dynamics.func_integrate 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2163}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6c5a735e7a4770e30ba22e2d808fa9fa97186b5b155c0092c3b6d87209fcb16"}},{"ruleId":"D1","level":"warning","message":{"text":"island.func_build_islands (cyclomatic 37): island.func_build_islands 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":295}}}],"partialFingerprints":{"codehealthFindingId/v1":"5643cb69c02fb2b9f52dc0b7dfd3fa09acecb97f6f16cb676e69e37202071ede"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.set_base_links_quat (cyclomatic 37): RigidSolver.set_base_links_quat 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2132}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9f714cbe3aa9933053d2e59ba63cd1720681ff00382cdb56c479df4765962e9"}},{"ruleId":"D1","level":"warning","message":{"text":"mjcf.build_model (cyclomatic 37): mjcf.build_model 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":"genesis/utils/mjcf.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"db10ae658389c1956172e4669300903e4c45313bada178ad9e1fac08cc21d35c"}},{"ruleId":"D1","level":"warning","message":{"text":"IPCCoupler._add_rigid_geoms_to_ipc (cyclomatic 36): IPCCoupler._add_rigid_geoms_to_ipc has cyclomatic complexity 36 (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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"ede39bccc8e5a8d48c438e8968b19a80557b55086d891b2fe703a67fcf8ed8f4"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_torque_and_passive_force (cyclomatic 36): forward_dynamics.func_torque_and_passive_force has cyclomatic complexity 36 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1538}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c4150de1aeb2a375000a43fbcd37f2952ad04751e3201c334487392de5ed295"}},{"ruleId":"D1","level":"warning","message":{"text":"Raytracer.build (cyclomatic 36): Raytracer.build has cyclomatic complexity 36 (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":"genesis/vis/raytracer.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c640ac61299de9b65f1bb059ccb3951e893757571d86927d23d903293b3c6af"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_contact_mpr_terrain (cyclomatic 35): narrowphase.func_contact_mpr_terrain has cyclomatic complexity 35 (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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1274}}}],"partialFingerprints":{"codehealthFindingId/v1":"20d80c7187940f26e1b5286c00f5d0d7207364adec87964b03fda955739366a6"}},{"ruleId":"D1","level":"warning","message":{"text":"island.func_reorder_island_dofs (cyclomatic 35): island.func_reorder_island_dofs has cyclomatic complexity 35 (threshold 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":797}}}],"partialFingerprints":{"codehealthFindingId/v1":"682bf8a88a7ce92c24c4e26c262cdf540071cca5f210c1c6078024d0a6656b52"}},{"ruleId":"D1","level":"warning","message":{"text":"solver._add_friction_constraint (cyclomatic 34): solver._add_friction_constraint has cyclomatic complexity 34 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"871cfdf6065f47a3e371741b25b6e5c25ad7cb1d7740a3dd9ec647157949d5f7"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_island_hessian_assemble_block (cyclomatic 34): solver.func_island_hessian_assemble_block has cyclomatic complexity 34 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3084}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e8e85afad232bc98250fb1f225e46a91845658521c8ac8d327a3e29149a669f"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.set_base_links_pos (cyclomatic 34): RigidSolver.set_base_links_pos has cyclomatic complexity 34 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2008}}}],"partialFingerprints":{"codehealthFindingId/v1":"e79830bcd4311b9d2c6b85958ffc11eee45eb00ce9bd13fd3a9703046d710095"}},{"ruleId":"D1","level":"warning","message":{"text":"Renderer._get_primitive_program (cyclomatic 34): Renderer._get_primitive_program has cyclomatic complexity 34 (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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":749}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e0d3d74a336de60fd698f436cc049d10e82a5de4f9daada610072cdc91acc78"}},{"ruleId":"D1","level":"warning","message":{"text":"Viewer._render (cyclomatic 34): Viewer._render has cyclomatic complexity 34 (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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1057}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc889ee7f4137e42d8e8f6e0e2c226b68fd077182a649dce74b21e860bee9558"}},{"ruleId":"D1","level":"warning","message":{"text":"multi_contact.func_clip_polygon (cyclomatic 33): multi_contact.func_clip_polygon 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":891}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f163246c9b3d84862325290fec951a3d34ff4ddb153364786dae2859a5f5832"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_solve_init (cyclomatic 33): solver.func_solve_init 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5565}}}],"partialFingerprints":{"codehealthFindingId/v1":"258ed55870ea4dbe4b437d0e1fbf5df8c8a78c61e9e944ea804fb59e427c6efb"}},{"ruleId":"D1","level":"warning","message":{"text":"gltf.parse_mesh_glb (cyclomatic 33): gltf.parse_mesh_glb 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":"genesis/utils/gltf.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"89ca2770e5d6f7ce53c4b5fe34c67e555cd75f86cab02286cefb6cae55a0f85a"}},{"ruleId":"D1","level":"warning","message":{"text":"mjcf.parse_geom (cyclomatic 33): mjcf.parse_geom 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":"genesis/utils/mjcf.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fda12a1bcae889a35296b67f1e511cbedb1e0083fe81f98c6cb293615b8336a"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver._jacobi_mass_spread_bound (cyclomatic 32): RigidSolver._jacobi_mass_spread_bound 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":783}}}],"partialFingerprints":{"codehealthFindingId/v1":"094fd46b85dbb172a1f2120ad9de0ea56882c388327f2b70020d4bde3bd9343e"}},{"ruleId":"D1","level":"warning","message":{"text":"_trimesh_patch.load_obj (cyclomatic 32): _trimesh_patch.load_obj 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"b082d7c106d9a1f45f8d5cfef19bd888c3975f8317111766848508e0b376e4d3"}},{"ruleId":"D1","level":"warning","message":{"text":"TrajectoryFileWriter.build (cyclomatic 32): TrajectoryFileWriter.build 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":"genesis/recorders/trajectory.py"},"region":{"startLine":510}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c90cfed0248acd7aec18faa002f7bdb6f3321af119419ec2e8aef2fcde48cac"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntityDescription._load_heterogeneous_morphs (cyclomatic 31): KinematicEntityDescription._load_heterogeneous_morphs 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"649e9ca85381ebfbae20891a14f60abda397ada70fd0863eb4d1d42f3ba6fbde"}},{"ruleId":"D1","level":"warning","message":{"text":"diff_gjk.func_gjk_contact (cyclomatic 31): diff_gjk.func_gjk_contact 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"c26035e6a46146bcad08551f5b513f515031cae2967b7b6baab55d0b397cd2db"}},{"ruleId":"D1","level":"warning","message":{"text":"gjk.func_gjk_contact (cyclomatic 31): gjk.func_gjk_contact 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cc9b31b0751712dda4aac0e92ddf3659cdd00f0268b0a852dceb4fbee7dc2b0"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver._set_links_info (cyclomatic 31): RigidSolver._set_links_info 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2263}}}],"partialFingerprints":{"codehealthFindingId/v1":"b664d79206c53b615711856c0ee7ebbed6fc26b012151455b1e082414c71d845"}},{"ruleId":"D1","level":"warning","message":{"text":"JITRenderer.set_primitive (cyclomatic 31): JITRenderer.set_primitive 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"21e7ab7e9146d574472592db5947593e8a6f73ba1bf1add1fbe5713cd562dfb5"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_midpoint_free_body (cyclomatic 30): forward_dynamics.func_midpoint_free_body 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1949}}}],"partialFingerprints":{"codehealthFindingId/v1":"512ce4caba60f13e7dcfb4fc8278c95f0ad3ceaf8af87ba546eb8284ca99aaec"}},{"ruleId":"D1","level":"warning","message":{"text":"linesearch.func_ls_state_advance (cyclomatic 30): linesearch.func_ls_state_advance 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":383}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0caecbaca0b9307713a1f40c5128b2781402b5b385bb5886a32cbc2e3ebd497"}},{"ruleId":"D1","level":"warning","message":{"text":"Viewer.start (cyclomatic 30): Viewer.start 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1153}}}],"partialFingerprints":{"codehealthFindingId/v1":"f83683d07062cede3a8bb95a27ecb51eab0769af91ff775459ba5ed718fbe084"}},{"ruleId":"D1","level":"warning","message":{"text":"misc.indices_to_mask (cyclomatic 30): misc.indices_to_mask 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":"genesis/utils/misc.py"},"region":{"startLine":605}}}],"partialFingerprints":{"codehealthFindingId/v1":"3abb4a9851c14ba390303af44d9d82afd68806f9b0dcd73764e60d8b354bc618"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidEntityDescription._describe_link (cyclomatic 29): RigidEntityDescription._describe_link 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1674}}}],"partialFingerprints":{"codehealthFindingId/v1":"d512746ce00b34c49eabaf264ae2b43a75cefcde1b5b279f209b4e088c36ed18"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntity._get_global_idx (cyclomatic 29): KinematicEntity._get_global_idx 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":568}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ea463d4de6761bb5df06e5a02da9cf60c900af1686186d4b5fcc16a62eebeff"}},{"ruleId":"D1","level":"warning","message":{"text":"noslip.func_noslip_update_row (cyclomatic 29): noslip.func_noslip_update_row 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"88d8280c9acdbbfc03aeffd87db23f5238e2d65a3860e95e1f7c351d0244a2d7"}},{"ruleId":"D1","level":"warning","message":{"text":"_trimesh_patch.export_obj (cyclomatic 29): _trimesh_patch.export_obj 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":756}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8077c0f143c667f82b4410498d9be3f193c3db11eaa33ec49d827a2bbec5273"}},{"ruleId":"D1","level":"warning","message":{"text":"Renderer.render (cyclomatic 29): Renderer.render 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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d08fcfd109b31ca6e88abf499e8cbcf1108305da7d155376dd57cb7782159cb"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_material.parse_preview_surface (cyclomatic 29): usd_material.parse_preview_surface 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":"genesis/utils/usd/usd_material.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a55eb89bf21e692016ed6549baea14dcabe8ac1fd20a1ef13e195b82b535860"}},{"ruleId":"D1","level":"warning","message":{"text":"Raytracer.update_scene (cyclomatic 29): Raytracer.update_scene 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":"genesis/vis/raytracer.py"},"region":{"startLine":675}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f3651f69cdeb151f6dc8ad38adebb96ca8e43b05e229ae7bb77e6fbf572d173"}},{"ruleId":"D1","level":"warning","message":{"text":"Mesh.from_trimesh (cyclomatic 28): Mesh.from_trimesh has cyclomatic complexity 28 (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":"genesis/engine/mesh.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b56f2663a796309fc840920724fbf750bc029ba66cfc65104e25c56f3a3b50a"}},{"ruleId":"D1","level":"warning","message":{"text":"gjk.func_safe_gjk (cyclomatic 28): gjk.func_safe_gjk has cyclomatic complexity 28 (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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1143}}}],"partialFingerprints":{"codehealthFindingId/v1":"108b89755e6f96b709d02d5cc06eb21b5d04c5db6159fa1422bf3e7d2c3963cb"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntityDescription._align_free_roots (cyclomatic 27): KinematicEntityDescription._align_free_roots 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1199}}}],"partialFingerprints":{"codehealthFindingId/v1":"03a8db7040970bed6404c4dfd7c3d129a10ff54bd98be9215fe26d872b28dbca"}},{"ruleId":"D1","level":"warning","message":{"text":"Scene.add_entity (cyclomatic 27): Scene.add_entity 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":"genesis/engine/scene.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"3893cf5b71610d5630a7165d0a025095c8abb2a6ae18882da88bb1256d63ae5a"}},{"ruleId":"D1","level":"warning","message":{"text":"point_cloud_tactile._kernel_elastomer_surface_state_via_global_bvh (cyclomatic 27): point_cloud_tactile._kernel_elastomer_surface_state_via_global_bvh 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1493}}}],"partialFingerprints":{"codehealthFindingId/v1":"6849322acd55a62d205ec3357ba6b921dc1543debbdcae753d92b594f230e8c1"}},{"ruleId":"D1","level":"warning","message":{"text":"multi_contact.func_potential_box_normals (cyclomatic 27): multi_contact.func_potential_box_normals 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfee1fa44d1c1f99b48aa58f91d5191f4b016f5804b71bd90122d6250682f6a4"}},{"ruleId":"D1","level":"warning","message":{"text":"misc.sanitize_index (cyclomatic 27): misc.sanitize_index 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":"genesis/utils/misc.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"69c06a7948d6cb5a69263a2943927e295e6e10ef3cb633b6ed14a542689f2de1"}},{"ruleId":"D1","level":"warning","message":{"text":"watertighten._quadric_decimate_loop (cyclomatic 27): watertighten._quadric_decimate_loop 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":"genesis/utils/watertighten.py"},"region":{"startLine":749}}}],"partialFingerprints":{"codehealthFindingId/v1":"37f8d7d5af4e09056c3090086a082e6d8e2b20e5d4194501acfa934bdb91ab87"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntity.inverse_kinematics_multilink (cyclomatic 26): KinematicEntity.inverse_kinematics_multilink has cyclomatic complexity 26 (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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1553}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc3bf0535d58829f47025a49faeb786decea50d756d2a72726b651c50fae8bb1"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_tiled (cyclomatic 26): forward_dynamics.func_factor_mass_tree_tiled 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc3514a8962df4ef4dd2978d49b14183e6bb2cf8bd9c5de06a8b2853318f3287"}},{"ruleId":"D1","level":"warning","message":{"text":"diff_gjk.func_extended_epa (cyclomatic 26): diff_gjk.func_extended_epa 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"05f04f5f73401662d6d48660c348c9463e563f27ec266dad298cdf75bfad7a76"}},{"ruleId":"D1","level":"warning","message":{"text":"epa.func_epa (cyclomatic 26): epa.func_epa 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc7bb3e586462d33a6c09c8d2f5bc38f10abea26a984ee63a825192a9923c995"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.build (cyclomatic 26): RigidSolver.build 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":311}}}],"partialFingerprints":{"codehealthFindingId/v1":"db34d3495aaa5f7f85c78003f5b9b5cb9986be42b8983677aae5e0810ccf5543"}},{"ruleId":"D1","level":"warning","message":{"text":"Primitive._add_to_context (cyclomatic 26): Primitive._add_to_context 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":"genesis/ext/pyrender/primitive.py"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f93171925f9a00dd85ef7b26be32c76d351fce113c532c7754407d9bd64fa84"}},{"ruleId":"D1","level":"warning","message":{"text":"mjcf.parse_geoms (cyclomatic 26): mjcf.parse_geoms has cyclomatic complexity 26 (threshold 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":"genesis/utils/mjcf.py"},"region":{"startLine":745}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bc6b83aaca519a7b1c052b6abb5499c25942401ed24c3286426b16f40013ad9"}},{"ruleId":"D1","level":"warning","message":{"text":"point_cloud_tactile._kernel_elastomer_surface_state_bvh (cyclomatic 25): point_cloud_tactile._kernel_elastomer_surface_state_bvh 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1335}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7dae07f9b65b6914b233f4a04cf2a7d57fba77e6a4c66fb4f806e935261faf2"}},{"ruleId":"D1","level":"warning","message":{"text":"linesearch.func_row_alpha_terms (cyclomatic 25): linesearch.func_row_alpha_terms 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3539376a4c4dbefc1737062969a4b6305411c95464698bdfc063445bacef98a"}},{"ruleId":"D1","level":"warning","message":{"text":"solver._sort_contacts_and_build_islands (cyclomatic 25): solver._sort_contacts_and_build_islands 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1506}}}],"partialFingerprints":{"codehealthFindingId/v1":"87330a5d0de047ec522ba93ecdb5058db0626757c38980077f6743ae947df5d0"}},{"ruleId":"D1","level":"warning","message":{"text":"RRTConnect.plan (cyclomatic 25): RRTConnect.plan 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":"genesis/utils/path_planning.py"},"region":{"startLine":895}}}],"partialFingerprints":{"codehealthFindingId/v1":"e106fadb55b8192309752afdcda9fe46d93beea74e8ecaf42afcea2d9d2e7563"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicSolver.build (cyclomatic 24): KinematicSolver.build 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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5fa63446467dceb2878f4b76cdb4b107e5308faa88e79e97848b9cf9ff34253"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicSolver.set_dofs_velocity (cyclomatic 24): KinematicSolver.set_dofs_velocity 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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1240}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2d3fbbfbc7dbe04e4be5f7b03352d35b06ad335ee6779ee52a8b2f0060ff6b2"}},{"ruleId":"D1","level":"warning","message":{"text":"epa.func_epa_init_polytope_3d (cyclomatic 24): epa.func_epa_init_polytope_3d 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad2e1a8fdb8255c768f2a48aad935d2cd515b841fd98b255ca9d8504d1c4f4ab"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_add_dynamic_constraint_rows_batch (cyclomatic 24): solver.func_add_dynamic_constraint_rows_batch 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1838}}}],"partialFingerprints":{"codehealthFindingId/v1":"25ba8c6a6c1b89f175d294e6e9c9042e83a8564cacdab63f874bcbec09d1810c"}},{"ruleId":"D1","level":"warning","message":{"text":"Renderer._bind_and_draw_primitive (cyclomatic 24): Renderer._bind_and_draw_primitive 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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"556146895910fa111e65f022b86ea769641ba0de904dfe320174b5fa87a0fc14"}},{"ruleId":"D1","level":"warning","message":{"text":"LegacyCoupler.mpm_grid_op (cyclomatic 23): LegacyCoupler.mpm_grid_op 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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"86ab851ae478c2da197d4b86ed6843c653b6ea95f40ceeb6cc503811131b5b44"}},{"ruleId":"D1","level":"warning","message":{"text":"SAPCoupler.build (cyclomatic 23): SAPCoupler.build 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"366447986a5636da7ce9b992ff32cf275512681d3f8fa09c10a808f0f9ff3247"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_global (cyclomatic 23): forward_dynamics.func_factor_mass_tree_global 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":705}}}],"partialFingerprints":{"codehealthFindingId/v1":"582a3ebaf6886c6d38c203f4852a6976b84b7722fa33ec9bd75f501ccde614fc"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_kinematics.func_sweep_links_by_level (cyclomatic 23): forward_kinematics.func_sweep_links_by_level 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"d28106904e2674d1fc965076df9967aa06639fe8f641008b77f6356383c11782"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase._func_multicontact_run_detection (cyclomatic 23): narrowphase._func_multicontact_run_detection 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3015}}}],"partialFingerprints":{"codehealthFindingId/v1":"e709c4c39c2109ec72d37e1068369321374be307bd7aa66894fffac10e2aadbc"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_narrow_phase_nonconvex_vs_nonterrain (cyclomatic 23): narrowphase.func_narrow_phase_nonconvex_vs_nonterrain 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4533}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aff2ed6b5c34006464cb19733913d54abfbd429246c27404678d75ad98312e0"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.set_state (cyclomatic 23): RigidSolver.set_state 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1785}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf9faa4a5f41f4d4fe7b0a3cbe506965c95cce87649c0a2057aa126d5878d63c"}},{"ruleId":"D1","level":"warning","message":{"text":"array_class.get_constraint_state (cyclomatic 23): array_class.get_constraint_state has cyclomatic complexity 23 (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":"genesis/utils/array_class.py"},"region":{"startLine":1041}}}],"partialFingerprints":{"codehealthFindingId/v1":"040811a954b28fb25e542397f90e873f7dc7f13f926ac76b3b040f3200e464aa"}},{"ruleId":"D1","level":"warning","message":{"text":"misc.broadcast_tensor (cyclomatic 23): misc.broadcast_tensor 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":"genesis/utils/misc.py"},"region":{"startLine":996}}}],"partialFingerprints":{"codehealthFindingId/v1":"519548408e65d0d227ee271425f92512b7d7a3d92166310b593c98590a067b46"}},{"ruleId":"D1","level":"warning","message":{"text":"RRT.plan (cyclomatic 23): RRT.plan 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":"genesis/utils/path_planning.py"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"99fa80cfe98355b05ed29ed8ee4bfd59303e45d1c6b315b23bbd587f0d302f4e"}},{"ruleId":"D1","level":"warning","message":{"text":"terrain.parse_terrain (cyclomatic 23): terrain.parse_terrain 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":"genesis/utils/terrain.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf5bdf7689577c05ad7e925cd4f6aa3855db169764b5e1f2fbe3875c221c95fa"}},{"ruleId":"D1","level":"warning","message":{"text":"UsdContext.find_all_materials (cyclomatic 23): UsdContext.find_all_materials 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":"genesis/utils/usd/usd_context.py"},"region":{"startLine":338}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb34b54d57d5d27f3369109a863d600b11579919acf9b64f0fa951df781445fd"}},{"ruleId":"D1","level":"warning","message":{"text":"LegacyCoupler.fem_surface_force (cyclomatic 22): LegacyCoupler.fem_surface_force has cyclomatic complexity 22 (threshold 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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f35b9614bf3be2794660c76023f885a05c1fc4742bc5993aa052182c772ac3a"}},{"ruleId":"D1","level":"warning","message":{"text":"manual_bw.func_forward_kinematics_link_bw (cyclomatic 22): manual_bw.func_forward_kinematics_link_bw has cyclomatic complexity 22 (threshold 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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"29eae11a2db6763e337b5c83fc40d7ceacccab41d7a6401130637951304981ba"}},{"ruleId":"D1","level":"warning","message":{"text":"linesearch.func_search_single_island (cyclomatic 22): linesearch.func_search_single_island 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":762}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdcfec1c3abf4de62dc8a708bdc74c898e512084a0a0a17bc9584b1d93e4f96a"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver._set_dofs_info (cyclomatic 22): RigidSolver._set_dofs_info has cyclomatic complexity 22 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2593}}}],"partialFingerprints":{"codehealthFindingId/v1":"f119cbcde405a606a4585f6e8dca25ce71356e5b805388d07b67650872f595dc"}},{"ruleId":"D1","level":"warning","message":{"text":"JITRenderer.update_context (cyclomatic 22): JITRenderer.update_context has cyclomatic complexity 22 (threshold 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48bfd2e1a9d1cf87510586b767fcc5f3ae748c9a9081405be7bc75976d545d7"}},{"ruleId":"D1","level":"warning","message":{"text":"Mesh._get_trimesh_props (cyclomatic 22): Mesh._get_trimesh_props 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":"genesis/ext/pyrender/mesh.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0e442b854288017983790768ce76f7d7fa08659f6fc164eef6a016ad15c81f6"}},{"ruleId":"D1","level":"warning","message":{"text":"OffscreenRenderer.render (cyclomatic 22): OffscreenRenderer.render has cyclomatic complexity 22 (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":"genesis/ext/pyrender/offscreen.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"7815c5de2603366713d8539d157b5fc32a75dec533411cae0f0a6a0c0ea8b91d"}},{"ruleId":"D1","level":"warning","message":{"text":"utils.format_texture_source (cyclomatic 22): utils.format_texture_source 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":"genesis/ext/pyrender/utils.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6ffb54f522194644a3e485173bd62c258ec1d0b2ee5bb3073e1c8f15e2b5813"}},{"ruleId":"D1","level":"warning","message":{"text":"MPLLinePlotter._update_plot (cyclomatic 22): MPLLinePlotter._update_plot 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":"genesis/recorders/plotters.py"},"region":{"startLine":567}}}],"partialFingerprints":{"codehealthFindingId/v1":"905e459256a2d24a06f96adf9379f6f910b868b80a8e05148e760a6cc0526db1"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_rigid_entity.parse_usd_rigid_entity (cyclomatic 22): usd_rigid_entity.parse_usd_rigid_entity 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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c314cc1946820776a9186674155d1fed811b1c33d6538b3731e4917bda0e5a5"}},{"ruleId":"D1","level":"warning","message":{"text":"MPMSolver.p2g (cyclomatic 21): MPMSolver.p2g 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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"e04308f947d36303d5d2444e11475938bf7b0cfcc39e52ba8250b5ece4a46554"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_kinematics.func_forward_kinematics_link (cyclomatic 21): forward_kinematics.func_forward_kinematics_link 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc8346d0efc905271e962c5bee7cf354924c057820c6b601d9e1f4ec7533d508"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_kinematics.func_update_cartesian_space (cyclomatic 21): forward_kinematics.func_update_cartesian_space 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":1141}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a3c27ed67b8cf429264fd3ea3f8c2feb4d81f15c44484124cf4de97db5b0198"}},{"ruleId":"D1","level":"warning","message":{"text":"contact.func_collider_clear_env (cyclomatic 21): contact.func_collider_clear_env 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"a08a306f76bc53fc6c608d73dc6623331d139d445bd6a95313a24d758f36ca6f"}},{"ruleId":"D1","level":"warning","message":{"text":"gjk.func_gjk (cyclomatic 21): gjk.func_gjk 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"d054e14a1cd8816e72f883d7b276f21a8edf014eee0b3721c9d4667f5c32008e"}},{"ruleId":"D1","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_file_browser (cyclomatic 21): ImGuiOverlayPlugin._render_file_browser 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":786}}}],"partialFingerprints":{"codehealthFindingId/v1":"28207437b2786fffa4c6f61afc5022f9cb76a5a4bc0a68b7ba1a29667c449c86"}},{"ruleId":"D1","level":"warning","message":{"text":"surfaces._make_rgba (cyclomatic 21): surfaces._make_rgba 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":"genesis/options/surfaces.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"125945eba9985f88e46410e3c61d57f590fa60f303885f71d09455a5ea288426"}},{"ruleId":"D1","level":"warning","message":{"text":"misc.get_gpu_shared_tile_sizes (cyclomatic 21): misc.get_gpu_shared_tile_sizes 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":"genesis/utils/misc.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"90e6f7585e7869bb21b17a3e366696137ef661c9e76ef7f7232a146d555ec0ce"}},{"ruleId":"D1","level":"warning","message":{"text":"GenesisGeomRetriever.retrieve_rigid_meshes_static (cyclomatic 21): GenesisGeomRetriever.retrieve_rigid_meshes_static 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":"genesis/vis/batch_renderer.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"764715c8311441bcb32b266f80475648203d76df5f0026eb6708d28ad51278d7"}},{"ruleId":"D1","level":"warning","message":{"text":"RasterizerContext.update_rigid (cyclomatic 21): RasterizerContext.update_rigid 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c0d14aefc8084cedb9b0a304a0ea41759155ed7e8cb85b802d661c8fc56fce1"}},{"ruleId":"D1","level":"warning","message":{"text":"InteractiveScene._apply_rebuild (cyclomatic 20): InteractiveScene._apply_rebuild 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":"genesis/engine/interactive_scene.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"5187d162ed08080f52bbcd9278cdd317247aed2ebbf68402dfca8c1afcad3ec8"}},{"ruleId":"D1","level":"warning","message":{"text":"Simulator.build (cyclomatic 20): Simulator.build 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":"genesis/engine/simulator.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2b0b77b8a940a08677bd71046618ed7300025293cc81a3c27f3e96d15b9455f"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_refresh_links_invweight_and_meaninertia (cyclomatic 20): forward_dynamics.func_refresh_links_invweight_and_meaninertia 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1393}}}],"partialFingerprints":{"codehealthFindingId/v1":"216bb2e83c492cda9b13327b1020e2b69b1c30fc4d5ebe0dd458ba6f2a1bf5c5"}},{"ruleId":"D1","level":"warning","message":{"text":"backward.kernel_manual_add_collision_constraints_bw (cyclomatic 20): backward.kernel_manual_add_collision_constraints_bw 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ba8a42a56850f2bc2e598ba5a3737e60494581b3adf58cb0fe64832110b965f"}},{"ruleId":"D1","level":"warning","message":{"text":"noslip.func_refresh_qacc_batch (cyclomatic 20): noslip.func_refresh_qacc_batch 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9eaa45b82323deeaddd75829fca43f0f0aaa7f289f961ac39e8e5bd51af1d49"}},{"ruleId":"D1","level":"warning","message":{"text":"solver._func_contact_row_direction (cyclomatic 20): solver._func_contact_row_direction 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":638}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc141ac0890e6634dbc31c305585606caba7c1448b2eb68cc2f4fa22f5a0942c"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_equality_links (cyclomatic 20): solver.func_equality_links 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1164}}}],"partialFingerprints":{"codehealthFindingId/v1":"070df06e3207826705dcbefba5c513337dd5a3a21c02787bae95d8981958f306"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_cholesky_solve_batch (cyclomatic 20): solver.func_cholesky_solve_batch has cyclomatic complexity 20 (threshold 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4224}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dcc1d984975024363b2d0f8c18bf51dde7c5b1ef198ad87abfd55e2e642b05c"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.set_qpos (cyclomatic 20): RigidSolver.set_qpos 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2445}}}],"partialFingerprints":{"codehealthFindingId/v1":"a648bc5791c50d8bbb2fcb18c3d9e368a4353ba86d48d88e97a51c2972886090"}},{"ruleId":"D1","level":"warning","message":{"text":"Scene.add_node (cyclomatic 20): Scene.add_node 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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":381}}}],"partialFingerprints":{"codehealthFindingId/v1":"b034ee0b67885fa54a8e73fc9e7a5c063e025bc982c1df3848b36ccb93aead5d"}},{"ruleId":"D1","level":"warning","message":{"text":"URDF.animate (cyclomatic 20): URDF.animate 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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3400}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdaef17e05ca22ce6e3b724e9c8cb6a75bad7834e3aa9d1e6f9d92720eafe036"}},{"ruleId":"D1","level":"warning","message":{"text":"Options._validation_error (cyclomatic 20): Options._validation_error 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":"genesis/options/options.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"94580b9c7f856917f0e4edeca197e327f26273c737427b7db139de646b08663c"}},{"ruleId":"D1","level":"warning","message":{"text":"Trajectory.__init__ (cyclomatic 20): Trajectory.__init__ 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":"genesis/recorders/trajectory.py"},"region":{"startLine":1034}}}],"partialFingerprints":{"codehealthFindingId/v1":"bab987fab42228483e7a670839220d6f3692a428c2821fd601dd4fd63fa16dab"}},{"ruleId":"D1","level":"warning","message":{"text":"serialization._export_value (cyclomatic 20): serialization._export_value 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":"genesis/utils/serialization.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce76a08c7a3b12c79ec9eeb56b1d09e167284b606fd1c6cd0230a9bf4bb87456"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_stage._find_connected_components (cyclomatic 20): usd_stage._find_connected_components 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":"genesis/utils/usd/usd_stage.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e9e31d9720d5cc8667594b23f1dc91bd7be8e85c2fe1748d803d89f2c4b2dc6"}},{"ruleId":"D1","level":"warning","message":{"text":"Camera.render (cyclomatic 20): Camera.render 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":"genesis/vis/camera.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"13e547d38e0ea77f4e16ed8913884d51fd8e3bce19675f5432565748d9028ec4"}},{"ruleId":"D1","level":"warning","message":{"text":"SensorManager._resolve_sensor_cls (cyclomatic 19): SensorManager._resolve_sensor_cls 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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ca76d5770c0b8ba6f870965486bf9f8075d59e4b6da2e77a5d62498e5cf1875"}},{"ruleId":"D1","level":"warning","message":{"text":"SensorManager.build (cyclomatic 19): SensorManager.build 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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"a408e4998103550f442d0e59cc74a55ef085168d73e5813e2bf743f4b7898b4b"}},{"ruleId":"D1","level":"warning","message":{"text":"TemperatureGridSensor.build (cyclomatic 19): TemperatureGridSensor.build 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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"f007e181a21af2c6591748c889a6c47ad30ba04c50fe38f42eac497cf90d5926"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_init_dofs_invweight (cyclomatic 19): forward_dynamics.func_init_dofs_invweight 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1331}}}],"partialFingerprints":{"codehealthFindingId/v1":"9108e4a96e4d6252eaf4e54e1f3ff027fbff93a8b5dca8142b2fa01bb26b245c"}},{"ruleId":"D1","level":"warning","message":{"text":"manual_bw.func_forward_velocity_link_bw (cyclomatic 19): manual_bw.func_forward_velocity_link_bw has cyclomatic complexity 19 (threshold 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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd25a13ae7aa269cd603683a4b6dabd21727b951542c5f233846da05810b226e"}},{"ruleId":"D1","level":"warning","message":{"text":"gjk.func_gjk_subdistance (cyclomatic 19): gjk.func_gjk_subdistance 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":819}}}],"partialFingerprints":{"codehealthFindingId/v1":"66dd6b50cbe76dcc00499178990867e005873a5058bd94df4a96827c4c688d70"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_factor_island_incremental_or_direct (cyclomatic 19): solver.func_factor_island_incremental_or_direct 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4068}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf49ee20ee32ba449ce94d636172db0003d16d302081b2f6d39a5555009a859b"}},{"ruleId":"D1","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_sim_controls (cyclomatic 19): ImGuiOverlayPlugin._render_sim_controls has cyclomatic complexity 19 (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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":504}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cb4c3c77eca377626096ea1cff6650297f2d99a51836d97c10bc9a7a30a3b27"}},{"ruleId":"D1","level":"warning","message":{"text":"Texture._add_to_context (cyclomatic 19): Texture._add_to_context has cyclomatic complexity 19 (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":"genesis/ext/pyrender/texture.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffd04096ca74f5d68dcade0187e67d33a3e83cedc1456dd614ce6d9dcca832b9"}},{"ruleId":"D1","level":"warning","message":{"text":"TrajectoryFileWriter._compress_frames (cyclomatic 19): TrajectoryFileWriter._compress_frames 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":"genesis/recorders/trajectory.py"},"region":{"startLine":799}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc1fac41bec79ad1fc728a0adfe1baa27be63e0ba561e4cf446d1e91f6d27fb5"}},{"ruleId":"D1","level":"warning","message":{"text":"usd_rigid_entity._parse_articulation_structure (cyclomatic 19): usd_rigid_entity._parse_articulation_structure 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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"097d42341ff3973e54f5a33b3def80f265aaf7c2b804c1da688e7b26f0c8a45d"}},{"ruleId":"D1","level":"warning","message":{"text":"FEMSelfTetContactHandler.compute_pairs (cyclomatic 18): FEMSelfTetContactHandler.compute_pairs 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. This shape REPEATS in the file: one other method here (RigidRigidTetContactHandler.compute_pairs) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2843}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d89e8fea0531767c20b89fde64df9835d6e3d28966d64357bb8d7dcf1e0bca6"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidRigidTetContactHandler.compute_pairs (cyclomatic 18): RigidRigidTetContactHandler.compute_pairs 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. This shape REPEATS in the file: one other method here (FEMSelfTetContactHandler.compute_pairs) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3850}}}],"partialFingerprints":{"codehealthFindingId/v1":"a047f958f58320613201ab7fb5d8d1278efe99c7d16dce963180107ee41f0c8e"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntityDescription._resolve_geoms (cyclomatic 18): KinematicEntityDescription._resolve_geoms has cyclomatic complexity 18 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function so the top-level body reads as a short sequence of named decisions."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1387}}}],"partialFingerprints":{"codehealthFindingId/v1":"72ca0ada389cf3f43d36ff0ac124263000ce6f46451ce738ecb9166472df2f8d"}},{"ruleId":"D1","level":"warning","message":{"text":"KinematicEntity.process_input_grad (cyclomatic 18): KinematicEntity.process_input_grad 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":497}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b9676bf9beea99dad51958cf7d138f989d2edb52d10903797fe208bbadcde1f"}},{"ruleId":"D1","level":"warning","message":{"text":"surface_distance_probe._kernel_surface_distance_probe_bvh (cyclomatic 18): surface_distance_probe._kernel_surface_distance_probe_bvh 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":"genesis/engine/sensors/surface_distance_probe.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6c9e9a9d8798bbd5f22d461045e1f8fd122905e5db0078928ae580016924cc7"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.kernel_refresh_invweight_and_meaninertia (cyclomatic 18): forward_dynamics.kernel_refresh_invweight_and_meaninertia 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1469}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0812a221d88f27527c845e698ec27b46b0e0c48e791e9e4b34f94c708db3f48"}},{"ruleId":"D1","level":"warning","message":{"text":"broadphase.func_check_collision_valid (cyclomatic 18): broadphase.func_check_collision_valid 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd04cf750e5fdd149a7975a2d323bd65d8bbfa1f25ab958b80569ddc73003111"}},{"ruleId":"D1","level":"warning","message":{"text":"epa.func_epa_init_polytope_2d (cyclomatic 18): epa.func_epa_init_polytope_2d 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":432}}}],"partialFingerprints":{"codehealthFindingId/v1":"941cd37147e56b99ad49f43945c150fca32bd3bcfbb8f9acf52d704b980d2205"}},{"ruleId":"D1","level":"warning","message":{"text":"linesearch.func_exit_islands_coop (cyclomatic 18): linesearch.func_exit_islands_coop 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1562}}}],"partialFingerprints":{"codehealthFindingId/v1":"c767d2b2b80d2abc45c76b1d50470ecc5613f8e9f6d71b2dd5be65299d80a624"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_cone_rank_update_island (cyclomatic 18): solver.func_cone_rank_update_island has cyclomatic complexity 18 (threshold 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3893}}}],"partialFingerprints":{"codehealthFindingId/v1":"687a3b2c2eadf74f1ad48ad2ab2541e0522aa2528ce20027786b61f10949fd33"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_update_constraint_batch (cyclomatic 18): solver.func_update_constraint_batch 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5047}}}],"partialFingerprints":{"codehealthFindingId/v1":"e208252cc27753ab973837f6d33d20e351b663a705e073f3813617c08cf80b32"}},{"ruleId":"D1","level":"warning","message":{"text":"Viewer.on_close (cyclomatic 18): Viewer.on_close 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"82168a58cfef6fd04475f78fe1dc2341d1598da8d844a463cb620213c1d5c05a"}},{"ruleId":"D1","level":"warning","message":{"text":"URDF.link_fk (cyclomatic 18): URDF.link_fk 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. This shape REPEATS in the file: one other method here (URDF.link_fk_batch) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2965}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b516b2730a483c4dffe472a424c62d83588d9d71f110fda973507e49f4e76f7"}},{"ruleId":"D1","level":"warning","message":{"text":"URDF.link_fk_batch (cyclomatic 18): URDF.link_fk_batch 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. This shape REPEATS in the file: one other method here (URDF.link_fk) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3051}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ff07b7af2be0408305fb24c2585beca1bd5eb4c7ad0dec78cc6283dc56e8876"}},{"ruleId":"D1","level":"warning","message":{"text":"ImageTexture._validate_and_load (cyclomatic 18): ImageTexture._validate_and_load 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":"genesis/options/textures.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f414dad603f2afd9fcaca47091717f5c9fa81012e26992fe5d5da38eb951725"}},{"ruleId":"D1","level":"warning","message":{"text":"array_class.iter_data (cyclomatic 18): array_class.iter_data 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":"genesis/utils/array_class.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e60fedd4b3e6410a469c0d624f6d88af03698d20ce8280948d243bd2e811301"}},{"ruleId":"D1","level":"warning","message":{"text":"FrameImageExporter.export_frame_single_camera (cyclomatic 18): FrameImageExporter.export_frame_single_camera 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":"genesis/utils/image_exporter.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cb7e0e30259c184641f94713cbea84ee791a9bc96a46c0cd0faacb7f13dda98"}},{"ruleId":"D1","level":"warning","message":{"text":"RRTConnect._kernel_rrt_connect_step1 (cyclomatic 18): RRTConnect._kernel_rrt_connect_step1 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":"genesis/utils/path_planning.py"},"region":{"startLine":726}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3fcda81f5b3031e0d8605895dc8d12ee7ca5fcc8a5c5329f5d7578c91a815eb"}},{"ruleId":"D1","level":"warning","message":{"text":"watertighten._collapse_safe (cyclomatic 18): watertighten._collapse_safe 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":"genesis/utils/watertighten.py"},"region":{"startLine":593}}}],"partialFingerprints":{"codehealthFindingId/v1":"29f84ec05cc32d17b50e02b291154ccb11d8fb5b7a6b926a621db26ccba04626"}},{"ruleId":"D1","level":"warning","message":{"text":"Camera.build (cyclomatic 18): Camera.build 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":"genesis/vis/camera.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aa76593dcf11c979e15537e0b1c4cd1fe6a96cae405ee8625d4081d339840d2"}},{"ruleId":"D1","level":"warning","message":{"text":"IPCCoupler._add_articulation_entities_to_ipc (cyclomatic 17): IPCCoupler._add_articulation_entities_to_ipc 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"94f4a8165425a1720e4681ec0ce6c74afcf263e6ad8899dd0f572faf5ec11234"}},{"ruleId":"D1","level":"warning","message":{"text":"FEMFloorTetContactHandler.detection (cyclomatic 17): FEMFloorTetContactHandler.detection 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2579}}}],"partialFingerprints":{"codehealthFindingId/v1":"60a21c1d49e606b890fa6cc75515ac97a86bbc437e9d72786911b07a5aa968ff"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidFemTriTetContactHandler.compute_pairs (cyclomatic 17): RigidFemTriTetContactHandler.compute_pairs 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3501}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3851d99f87a0cb774725b6f4fe291633cde6ae72a47ea849832804843d5e33c"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidJointDescription.__post_init__ (cyclomatic 17): RigidJointDescription.__post_init__ 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b38f091c57295817bc2ac13cb671d685d03b4ae22200f60b60578957a35db15"}},{"ruleId":"D1","level":"warning","message":{"text":"Sensor.__init_subclass__ (cyclomatic 17): Sensor.__init_subclass__ 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":"genesis/engine/sensors/base_sensor.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"a68db70e6e1da465194be5910e504a0dfd6cc34d293b625be54129b75b3d0bff"}},{"ruleId":"D1","level":"warning","message":{"text":"contact.func_contact_is_after (cyclomatic 17): contact.func_contact_is_after 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f06585006f4c4a647b08c611a42792d06cc55a5c8d3fac8dbcfdf38457a8944"}},{"ruleId":"D1","level":"warning","message":{"text":"island.func_group_constraints_by_island_coop (cyclomatic 17): island.func_group_constraints_by_island_coop 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"144f967076d011ceb4732fb7b2aa2a6e8c467ef6f1d18b2170b6feabdeb732b0"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_apply_staged_rank_updates_island (cyclomatic 17): solver.func_apply_staged_rank_updates_island 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3717}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a79bb9a37f07d31a2cacddc8f56ec46829857a4580f586870628b9cd0eb47e0"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_cone_rank_update_whole_env (cyclomatic 17): solver.func_cone_rank_update_whole_env has cyclomatic complexity 17 (threshold 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3989}}}],"partialFingerprints":{"codehealthFindingId/v1":"e609b6b24ae9ce0869f8efd01bebda96d8bd846bed76462ef2bb3c693057ded9"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidSolver.__init__ (cyclomatic 17): RigidSolver.__init__ 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"11b40b100f7bb154983aec4794d18bad35ac4b7f3c2d42f4b1f5d35372b34c4d"}},{"ruleId":"D1","level":"warning","message":{"text":"_trimesh_patch._parse_vertices (cyclomatic 17): _trimesh_patch._parse_vertices 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":539}}}],"partialFingerprints":{"codehealthFindingId/v1":"16dbfb3799f666f7f88dcac28631ab43ee19c49f7397243b55c3023fc8949e71"}},{"ruleId":"D1","level":"warning","message":{"text":"Scene._remove_node (cyclomatic 17): Scene._remove_node 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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":552}}}],"partialFingerprints":{"codehealthFindingId/v1":"5efb9f1221e4282e7eeba8a8c2ac5e693e0290673c13d075c7c3e0a00e0dd980"}},{"ruleId":"D1","level":"warning","message":{"text":"TrajectoryFileWriter._get_frame (cyclomatic 17): TrajectoryFileWriter._get_frame 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":"genesis/recorders/trajectory.py"},"region":{"startLine":728}}}],"partialFingerprints":{"codehealthFindingId/v1":"4060a444bd7d8d60d864bfe6c10b62ba42e61ef7f8ee2f7583b8d8c620b0c10c"}},{"ruleId":"D1","level":"warning","message":{"text":"geom.trans_R_to_T (cyclomatic 17): geom.trans_R_to_T 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":"genesis/utils/geom.py"},"region":{"startLine":1149}}}],"partialFingerprints":{"codehealthFindingId/v1":"d62a8bb505583b97abc36051be8b52fcf34ca64803ea29f5a61a1ba45cd8f596"}},{"ruleId":"D1","level":"warning","message":{"text":"serialization.load (cyclomatic 17): serialization.load 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":"genesis/utils/serialization.py"},"region":{"startLine":596}}}],"partialFingerprints":{"codehealthFindingId/v1":"71cececda7662714c16a03849490fcee0fe8b8be802f22b88532842e400012c4"}},{"ruleId":"D1","level":"warning","message":{"text":"Alarm.fetch_wandb_data (cyclomatic 16): Alarm.fetch_wandb_data 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":".github/workflows/scripts/alarm.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e273150e22bb43cedca95e920174f8b29d22e3e9de1397c37cb4ebaf8473e0e"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidFloorTetContactHandler.detection (cyclomatic 16): RigidFloorTetContactHandler.detection 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3280}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bd11df41b024bd6efca6a906693e16afd0d9b9abb9479115d0b79ed939fe52f"}},{"ruleId":"D1","level":"warning","message":{"text":"Emitter.emit (cyclomatic 16): Emitter.emit 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":"genesis/engine/entities/emitter.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6594b7c5dfa5295bc5b577e2f19e1953677fb15892d46a35bebe9f72fd7e647"}},{"ruleId":"D1","level":"warning","message":{"text":"RigidJoint.dofs_length (cyclomatic 16): RigidJoint.dofs_length 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":"genesis/engine/entities/rigid_entity/rigid_joint.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1d0daa4c31864da26a3b77f296ec140cfbfaf2f92589d2fb91dc6d1d102a0dd"}},{"ruleId":"D1","level":"warning","message":{"text":"RaycastContext.activate (cyclomatic 16): RaycastContext.activate 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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"579a804dbe99988d9ca7a31e57f8f65dc2f83e7c28eed773ea995484d8e3f412"}},{"ruleId":"D1","level":"warning","message":{"text":"FEMSolver.accumulate_vertex_force_preconditioner (cyclomatic 16): FEMSolver.accumulate_vertex_force_preconditioner has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fe21168cd8361ced13b9639e533cca64767774ab196096308caad6402880d29"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_init_link_invweight (cyclomatic 16): forward_dynamics.func_init_link_invweight has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1262}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb814e7d5117e929aeb59ae9fc28b3fd59c8d51861663a5e013f39e14758cef0"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_dynamics.func_implicit_damping (cyclomatic 16): forward_dynamics.func_implicit_damping 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2360}}}],"partialFingerprints":{"codehealthFindingId/v1":"96caa2949d7cd52c7f990d38d755f75a85548e0e77bcd44d1d0abfc053b3ceb4"}},{"ruleId":"D1","level":"warning","message":{"text":"forward_kinematics.func_forward_velocity_link (cyclomatic 16): forward_kinematics.func_forward_velocity_link 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"3650228f510176cdf93fc032c3d77eb6d17cff16126be2abe1e088986c384e9a"}},{"ruleId":"D1","level":"warning","message":{"text":"inverse_kinematics.func_get_jacobian (cyclomatic 16): inverse_kinematics.func_get_jacobian has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"aed3b28543c1cf36917bb2904d1f9d7dedd2adadd025e2ce444708323916bdb5"}},{"ruleId":"D1","level":"warning","message":{"text":"mpr.mpr_find_pos (cyclomatic 16): mpr.mpr_find_pos has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a5b5446c124fff5dbe50562fdcab599f9ea7fc790b9e5a894889f6cd41428ac"}},{"ruleId":"D1","level":"warning","message":{"text":"narrowphase.func_contact_convex_convex_sdf (cyclomatic 16): narrowphase.func_contact_convex_convex_sdf 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1135}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b7067d725f947f498a77a4a555c232be3ff253705944e22ad1c9f1785f96563"}},{"ruleId":"D1","level":"warning","message":{"text":"backward.kernel_compute_gradients (cyclomatic 16): backward.kernel_compute_gradients has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"be7fa585c9346055990126f3ee7c8bdf511d42b6f54767a81b6777e7264c8ec9"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_add_relative_motion_rows (cyclomatic 16): solver.func_add_relative_motion_rows has cyclomatic complexity 16 (threshold 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1767}}}],"partialFingerprints":{"codehealthFindingId/v1":"66abc8da47b0f11cc48bd17cbe3e8fe87047d60d3da9bb518e1edc01777ee466"}},{"ruleId":"D1","level":"warning","message":{"text":"solver.func_cholesky_factor_direct_batch (cyclomatic 16): solver.func_cholesky_factor_direct_batch 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3499}}}],"partialFingerprints":{"codehealthFindingId/v1":"4613b8fd11b909eea70380e9ebe56b6d001a1880b943928b2a15452124390566"}},{"ruleId":"D1","level":"warning","message":{"text":"jit_render.bind_lighting (cyclomatic 16): jit_render.bind_lighting 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"f93f384f16f3c0c5c398499ca21ba102b96f40ee09188147745b8da16e60964e"}},{"ruleId":"D1","level":"warning","message":{"text":"PathPlanner._func_check_collision (cyclomatic 16): PathPlanner._func_check_collision 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":"genesis/utils/path_planning.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"18998ae3b7669366ce94be91ad3c32d44d68cc2faae8419b283e7fc4aecc8dc9"}},{"ruleId":"D1","level":"warning","message":{"text":"MouseInteractionPlugin.on_draw (cyclomatic 16): MouseInteractionPlugin.on_draw 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":"genesis/vis/viewer_plugins/plugins/mouse_interaction.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"234650272af3ca97960f2aa9a97365e51eed9d5e0bf29fca3ff7b860df079242"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_contact_overlap_axes (cognitive 558): narrowphase.func_contact_overlap_axes has cognitive complexity 558 (threshold 15). Drivers by points: if/else 63 (276 pts), loops 44 (220 pts), ternaries 12 (44 pts), boolean chains 18 (nesting depth added 421). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1931}}}],"partialFingerprints":{"codehealthFindingId/v1":"42fa474c1bceb6bf30bdca6714a334d06a1cced3d66301e059c57852f01a0e54"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_add_polytope_vertex_contacts_sdf (cognitive 406): narrowphase.func_add_polytope_vertex_contacts_sdf has cognitive complexity 406 (threshold 15). Drivers by points: if/else 60 (294 pts), loops 20 (97 pts), boolean chains 14, ternaries 1 (nesting depth added 311). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"cffe563c3823d04d078186902b2e67ec6ff1e6a52650dce22ae36e32d3ff3db8"}},{"ruleId":"D2","level":"warning","message":{"text":"box_contact.func_box_box_contact (cognitive 388): box_contact.func_box_box_contact has cognitive complexity 388 (threshold 15). Drivers by points: if/else 56 (218 pts), loops 25 (92 pts), ternaries 18 (68 pts), boolean chains 10 (nesting depth added 279). 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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b62300150d169dd54926385b39e1f64c7bd0230ae11c37c5058c8fb30eca4f9"}},{"ruleId":"D2","level":"warning","message":{"text":"broadphase._func_broad_phase_sap (cognitive 284): broadphase._func_broad_phase_sap has cognitive complexity 284 (threshold 15). Drivers by points: if/else 38 (188 pts), loops 19 (86 pts), ternaries 2 (7 pts), boolean chains 3 (nesting depth added 222). 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d1291edd7b361924cce092a602cb46e804178b65a34beba9e47d2e98be4eef0"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_linesearch_islands_coop (cognitive 266): linesearch.func_linesearch_islands_coop has cognitive complexity 266 (threshold 15). Drivers by points: if/else 39 (151 pts), loops 30 (113 pts), boolean chains 2 (nesting depth added 195). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1191}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7e80034f46d5e179cd946dfa583e72363298fe8852e9701d12bcc6e5ee00030"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_add_polytope_vertex_contacts_sdf_shell (cognitive 264): narrowphase.func_add_polytope_vertex_contacts_sdf_shell has cognitive complexity 264 (threshold 15). Drivers by points: if/else 40 (172 pts), loops 10 (50 pts), ternaries 5 (33 pts), boolean chains 9 (nesting depth added 200). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":597}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a44e059a6e5623909eb0b81c868e22b7b123286f5e5a5665d147c40b37f9861"}},{"ruleId":"D2","level":"warning","message":{"text":"backward.kernel_manual_add_equality_constraints_bw (cognitive 253): backward.kernel_manual_add_equality_constraints_bw has cognitive complexity 253 (threshold 15). Drivers by points: loops 24 (115 pts), if/else 20 (84 pts), ternaries 11 (54 pts) (nesting depth added 198). 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":784}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c8c4c7c0af989a21af34de3d9c8cee5eeb63f1d9b17d86736177943fe33f7d9"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_clamp_prune_contacts_coop (cognitive 249): contact.func_clamp_prune_contacts_coop has cognitive complexity 249 (threshold 15). Drivers by points: if/else 29 (153 pts), loops 20 (88 pts), boolean chains 8 (nesting depth added 192). 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1446}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a9515f16a6f8c832a52dd94c8368a4853fab6976eb4ec96efc0d787c199e7af"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_convex_convex_contact (cognitive 245): narrowphase.func_convex_convex_contact has cognitive complexity 245 (threshold 15). Drivers by points: if/else 40 (188 pts), loops 6 (35 pts), boolean chains 15, ternaries 2 (7 pts) (nesting depth added 182). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2475}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2195e4960e5b96b83b193824cdf6bcc5d2679f7e43f7b5ac3b7607f6b7a9009"}},{"ruleId":"D2","level":"warning","message":{"text":"inverse_kinematics.func_inverse_kinematics (cognitive 213): inverse_kinematics.func_inverse_kinematics has cognitive complexity 213 (threshold 15). Drivers by points: loops 28 (119 pts), if/else 16 (68 pts), ternaries 3 (20 pts), boolean chains 6 (nesting depth added 160). 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":363}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdcaaf6edc77e21ab8cc81f5e849d4296d3a059314a37e27fdd65c80475bd17b"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_island_assemble_factor_solve_tiled (cognitive 213): solver.func_island_assemble_factor_solve_tiled has cognitive complexity 213 (threshold 15). Drivers by points: if/else 31 (106 pts), loops 32 (105 pts), boolean chains 2 (nesting depth added 148). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2764}}}],"partialFingerprints":{"codehealthFindingId/v1":"a080bd70ef9b774c5618205365e0f010dcf00072c1be11c480994859098ec06c"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrowphase_multicontact (cognitive 210): narrowphase.func_narrowphase_multicontact has cognitive complexity 210 (threshold 15). Drivers by points: if/else 28 (133 pts), loops 10 (59 pts), ternaries 2 (10 pts), boolean chains 8 (nesting depth added 162). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3734}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc0150e01450626a79cb1ac03b570c20e43ec9d153a17add9288f58da5ba9db5"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_clamp_prune_contacts (cognitive 206): contact.func_clamp_prune_contacts has cognitive complexity 206 (threshold 15). Drivers by points: if/else 20 (122 pts), loops 15 (80 pts), boolean chains 4 (nesting depth added 167). 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1144}}}],"partialFingerprints":{"codehealthFindingId/v1":"17dbd6077304e06c7ba72f6110e10dc7750c80196ba4f129ba5725ec469daf2b"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_geometry.parse_prim_geoms (cognitive 200): usd_geometry.parse_prim_geoms has cognitive complexity 200 (threshold 15). Drivers by points: if/else 48 (139 pts), loops 11 (38 pts), boolean chains 19, ternaries 1 (4 pts) (nesting depth added 121). 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":"genesis/utils/usd/usd_geometry.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"22f0db8863860815f112d2396fd09fb75cae7f4b89b5b2113de3147150ddff8e"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._parse_scene (cognitive 198): KinematicEntityDescription._parse_scene has cognitive complexity 198 (threshold 15). Drivers by points: if/else 46 (109 pts), loops 24 (59 pts), boolean chains 23, ternaries 2 (5 pts), error handling 1 (2 pts) (nesting depth added 102). 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a1b6a5e52435b04736a08189f94f1d75390a6bee691c072340f79c452f17f5d"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_shared (cognitive 193): forward_dynamics.func_factor_mass_tree_shared has cognitive complexity 193 (threshold 15). Drivers by points: if/else 25 (117 pts), loops 14 (68 pts), ternaries 1 (7 pts), boolean chains 1 (nesting depth added 152). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":856}}}],"partialFingerprints":{"codehealthFindingId/v1":"907ab6a9192e5398a0555e3a463bb817244b8b4ca2fe09c63055dd83183c87e9"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_recompute_perturbed_contact (cognitive 185): narrowphase.func_recompute_perturbed_contact has cognitive complexity 185 (threshold 15). Drivers by points: if/else 39 (126 pts), ternaries 6 (32 pts), loops 5 (14 pts), boolean chains 13 (nesting depth added 122). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1543}}}],"partialFingerprints":{"codehealthFindingId/v1":"64a75302112195ad2edc4d9459bede3a85c79001e26c6cd44a121f4a1d0ec0ad"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_contact_mpr_terrain (cognitive 183): narrowphase.func_contact_mpr_terrain has cognitive complexity 183 (threshold 15). Drivers by points: if/else 17 (116 pts), loops 8 (41 pts), ternaries 3 (19 pts), boolean chains 7 (nesting depth added 148). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1274}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30dba9e37389a242bf0ba05722a29f077fc4d1650dc6dd7b48549032f9f53fb"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._add_collision_constraints_per_contact (cognitive 176): solver._add_collision_constraints_per_contact has cognitive complexity 176 (threshold 15). Drivers by points: if/else 23 (113 pts), loops 10 (37 pts), ternaries 6 (22 pts), boolean chains 4 (nesting depth added 133). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":916}}}],"partialFingerprints":{"codehealthFindingId/v1":"66defc7e9e8df6198ac8c7f9eb59e51ee917b1099ae195c05d453a063bd2502a"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_rigid_entity._parse_link (cognitive 167): usd_rigid_entity._parse_link has cognitive complexity 167 (threshold 15). Drivers by points: if/else 40 (108 pts), ternaries 8 (38 pts), loops 5 (14 pts), boolean chains 7 (nesting depth added 107). 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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"43712d3b45ab7646b5b6eee4f4f86125939f5a9868de285a68c4be6e616059be"}},{"ruleId":"D2","level":"warning","message":{"text":"multi_contact.func_multi_contact (cognitive 166): multi_contact.func_multi_contact has cognitive complexity 166 (threshold 15). Drivers by points: ternaries 28 (88 pts), if/else 29 (63 pts), loops 5 (10 pts), boolean chains 5 (nesting depth added 99). 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"8598ee9e9ce78e12a934bd51352edac2185a0336b718835885d50db6b60e52ed"}},{"ruleId":"D2","level":"warning","message":{"text":"Collider.get_contacts (cognitive 151): Collider.get_contacts has cognitive complexity 151 (threshold 15). Drivers by points: if/else 43 (91 pts), ternaries 11 (45 pts), boolean chains 13, loops 1 (2 pts) (nesting depth added 83). 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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":881}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4921ab46df6e8125bb273ab046e271813fe2dd0e45cccd23be101e1f799514f"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase._func_multicontact_detect (cognitive 147): narrowphase._func_multicontact_detect has cognitive complexity 147 (threshold 15). Drivers by points: if/else 33 (104 pts), loops 6 (25 pts), boolean chains 10, ternaries 2 (8 pts) (nesting depth added 96). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3163}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef632d38bb0b102f011722e884eddf7479265d37e7106b782c56f5f92094564f"}},{"ruleId":"D2","level":"warning","message":{"text":"point_cloud_tactile._kernel_point_cloud_proximity_taxel_bvh (cognitive 136): point_cloud_tactile._kernel_point_cloud_proximity_taxel_bvh has cognitive complexity 136 (threshold 15). Drivers by points: if/else 16 (68 pts), loops 20 (65 pts), boolean chains 3 (nesting depth added 97). 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfe901694d80064b92f51bf08f364e8fe33493a1488297d7731b9167678a20de"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_build_islands_coop (cognitive 136): island.func_build_islands_coop has cognitive complexity 136 (threshold 15). Drivers by points: if/else 36 (98 pts), loops 17 (33 pts), boolean chains 5 (nesting depth added 78). 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":514}}}],"partialFingerprints":{"codehealthFindingId/v1":"aab024d7cec10048c15fe6ad97f989f570d812f87247ae204dfb97ce801749d2"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_entity_browser (cognitive 136): ImGuiOverlayPlugin._render_entity_browser has cognitive complexity 136 (threshold 15). Drivers by points: if/else 29 (97 pts), loops 7 (24 pts), ternaries 3 (9 pts), boolean chains 6 (nesting depth added 91). 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":1059}}}],"partialFingerprints":{"codehealthFindingId/v1":"7096b45394b8b11997b6bed1eb19432523bd8d3cc4c745c9cff01d09818b37e8"}},{"ruleId":"D2","level":"warning","message":{"text":"mesh._postprocess_collision_geoms_impl (cognitive 130): mesh._postprocess_collision_geoms_impl has cognitive complexity 130 (threshold 15). Drivers by points: if/else 36 (88 pts), loops 10 (22 pts), boolean chains 20 (nesting depth added 64). 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":"genesis/utils/mesh.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"45e8b69871bc4f46886e62dc3b29a7684001cc0b42066bf36ea3c3690d87aa64"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_hessian_direct_batch (cognitive 128): solver.func_hessian_direct_batch has cognitive complexity 128 (threshold 15). Drivers by points: if/else 21 (69 pts), loops 18 (55 pts), boolean chains 2, ternaries 1 (2 pts) (nesting depth added 86). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2589}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c339ccb97644fa7ed015e409b802ee3df5f0e1e33fb8d075bdf717bd2058612"}},{"ruleId":"D2","level":"warning","message":{"text":"urdf.parse_urdf (cognitive 127): urdf.parse_urdf has cognitive complexity 127 (threshold 15). Drivers by points: if/else 32 (79 pts), ternaries 7 (24 pts), loops 9 (16 pts), boolean chains 6, error handling 1 (2 pts) (nesting depth added 72). 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":"genesis/utils/urdf.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"934496d1033c71ce344d52a02f87ff63b298a2e9a54f345d663fa9e86d61a3ff"}},{"ruleId":"D2","level":"warning","message":{"text":"bvh.func_build_bvh (cognitive 118): bvh.func_build_bvh has cognitive complexity 118 (threshold 15). Drivers by points: loops 27 (62 pts), if/else 18 (47 pts), ternaries 4 (9 pts) (nesting depth added 69). 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":"genesis/engine/bvh.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d3f21c495cdc4385bb23e6f0f679a84466d47ebd80e8bf9c1f3d73cd53d48d4"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_island_hessian_assemble_block (cognitive 116): solver.func_island_hessian_assemble_block has cognitive complexity 116 (threshold 15). Drivers by points: if/else 21 (74 pts), loops 13 (42 pts) (nesting depth added 82). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3084}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c77d140bdcba956dbd99f587e512d861101203fc191192ee0a1984fff2916ab"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_tiled (cognitive 112): forward_dynamics.func_factor_mass_tree_tiled has cognitive complexity 112 (threshold 15). Drivers by points: loops 11 (53 pts), if/else 12 (51 pts), ternaries 1 (7 pts), boolean chains 1 (nesting depth added 87). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7bbeb85755840f02cc069f92c1a769f3f0296039fa335e53f245b80292ddb70"}},{"ruleId":"D2","level":"warning","message":{"text":"Collider._compute_collision_pair_idx (cognitive 112): Collider._compute_collision_pair_idx has cognitive complexity 112 (threshold 15). Drivers by points: if/else 30 (71 pts), loops 10 (26 pts), ternaries 3 (10 pts), boolean chains 5 (nesting depth added 64). 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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"704601205c938f9b465508437170316d6f178ac7ea266cf55c785153552d0035"}},{"ruleId":"D2","level":"warning","message":{"text":"mpr.func_mpr_contact_from_centers (cognitive 109): mpr.func_mpr_contact_from_centers has cognitive complexity 109 (threshold 15). Drivers by points: if/else 37 (93 pts), ternaries 2 (10 pts), boolean chains 5, loops 1 (nesting depth added 64). 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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"388331f4c0e808f5e1d09c1a262375e254d0c20b449f03914156c2aa8b798816"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_integrate (cognitive 106): forward_dynamics.func_integrate has cognitive complexity 106 (threshold 15). Drivers by points: if/else 20 (58 pts), loops 9 (27 pts), ternaries 4 (17 pts), boolean chains 4 (nesting depth added 69). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2163}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f8012aed961a0383d72589d86810b1a18773568414f6a002f30eb52cc10ab44"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._add_rigid_geoms_to_ipc (cognitive 105): IPCCoupler._add_rigid_geoms_to_ipc has cognitive complexity 105 (threshold 15). Drivers by points: if/else 21 (73 pts), loops 5 (11 pts), ternaries 2 (8 pts), boolean chains 7, error handling 1 (6 pts) (nesting depth added 69). 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad2ebf9d198ec428961efed0efbe108fac4a730e09199cc458789f60fa5b635e"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrowphase_contact0 (cognitive 101): narrowphase.func_narrowphase_contact0 has cognitive complexity 101 (threshold 15). Drivers by points: if/else 20 (78 pts), boolean chains 11, loops 4 (9 pts), ternaries 1 (3 pts) (nesting depth added 65). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3959}}}],"partialFingerprints":{"codehealthFindingId/v1":"2689522d8d8f6d7850a241cb9f211ce3bf16a5ed6a01e61a87d9a0b9ddb1e626"}},{"ruleId":"D2","level":"warning","message":{"text":"LegacyCoupler.mpm_grid_op (cognitive 100): LegacyCoupler.mpm_grid_op has cognitive complexity 100 (threshold 15). Drivers by points: if/else 12 (56 pts), loops 10 (44 pts) (nesting depth added 78). 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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"882e96db58a58d33a39a19edee87a66a11f651d2c5cd2d113993c25dc33d6079"}},{"ruleId":"D2","level":"warning","message":{"text":"LegacyCoupler.fem_surface_force (cognitive 100): LegacyCoupler.fem_surface_force has cognitive complexity 100 (threshold 15). Drivers by points: loops 11 (51 pts), if/else 10 (49 pts) (nesting depth added 79). 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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1bc0961e5f32cd115df314f5f9f4b8df43afcdb43cfc72c084a29efe830d8bd"}},{"ruleId":"D2","level":"warning","message":{"text":"point_cloud_tactile._kernel_elastomer_surface_state_via_global_bvh (cognitive 100): point_cloud_tactile._kernel_elastomer_surface_state_via_global_bvh has cognitive complexity 100 (threshold 15). Drivers by points: if/else 13 (52 pts), loops 11 (33 pts), ternaries 3 (15 pts) (nesting depth added 73). 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1493}}}],"partialFingerprints":{"codehealthFindingId/v1":"07d0e317d7e55d319780205288f6221bf7250b3f5dccde717af5afb16d7d6578"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree_global (cognitive 99): forward_dynamics.func_factor_mass_tree_global has cognitive complexity 99 (threshold 15). Drivers by points: if/else 13 (58 pts), loops 7 (33 pts), ternaries 1 (7 pts), boolean chains 1 (nesting depth added 77). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":705}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b1318f7e6f9499394159187d45e72a42d2cdbd4143398562276ffdefc43ac1a"}},{"ruleId":"D2","level":"warning","message":{"text":"gltf.parse_mesh_glb (cognitive 99): gltf.parse_mesh_glb has cognitive complexity 99 (threshold 15). Drivers by points: if/else 19 (58 pts), ternaries 6 (21 pts), loops 7 (17 pts), boolean chains 3 (nesting depth added 64). 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":"genesis/utils/gltf.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"e57ab54e76018840ed9713426a61e05108cb9a505e7e832abb9dceeb36536fd4"}},{"ruleId":"D2","level":"warning","message":{"text":"mjcf.build_model (cognitive 98): mjcf.build_model has cognitive complexity 98 (threshold 15). Drivers by points: if/else 17 (42 pts), loops 11 (33 pts), ternaries 5 (16 pts), boolean chains 4, error handling 1 (3 pts) (nesting depth added 60). 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":"genesis/utils/mjcf.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"40c29a7b06115b5f8f8ebd5bedf3e8271f3651e0830225206ce46e95566cb48e"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._load_heterogeneous_morphs (cognitive 94): KinematicEntityDescription._load_heterogeneous_morphs has cognitive complexity 94 (threshold 15). Drivers by points: if/else 17 (51 pts), loops 7 (21 pts), ternaries 7 (21 pts), boolean chains 1 (nesting depth added 62). 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"7388ff9891289d4e74e0905e66b0b4094887d5b195c64eaaaf106b0a718081b4"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver._build_static_config (cognitive 94): RigidSolver._build_static_config has cognitive complexity 94 (threshold 15). Drivers by points: if/else 21 (43 pts), boolean chains 27, ternaries 6 (15 pts), loops 5 (9 pts) (nesting depth added 35). 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"053af0d4b4acbac00a81b1e22f85ab1b9ddbd1b0fb4c8d4f55e180877375b3bf"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_contact_support_hull (cognitive 92): contact.func_contact_support_hull has cognitive complexity 92 (threshold 15). Drivers by points: if/else 13 (37 pts), loops 14 (36 pts), boolean chains 12, ternaries 3 (7 pts) (nesting depth added 50). 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":953}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef796296f4214d3fc9287677c71177e98535cb60102215528e0dcceec94be7b5"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_torque_and_passive_force (cognitive 91): forward_dynamics.func_torque_and_passive_force has cognitive complexity 91 (threshold 15). Drivers by points: if/else 13 (40 pts), ternaries 8 (30 pts), loops 6 (15 pts), boolean chains 6 (nesting depth added 58). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1538}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c7f23502f9d4cc0c4f57648c56f4c55b578c2d08d5385cf290f9f6c8a11e48e"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver._jacobi_mass_spread_bound (cognitive 91): RigidSolver._jacobi_mass_spread_bound has cognitive complexity 91 (threshold 15). Drivers by points: if/else 15 (48 pts), loops 10 (30 pts), boolean chains 7, ternaries 1 (6 pts) (nesting depth added 58). 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":783}}}],"partialFingerprints":{"codehealthFindingId/v1":"beed1be616ac699e1113999279be92fefc3ed1044a65c1a4aab3d3a42510a2a0"}},{"ruleId":"D2","level":"warning","message":{"text":"point_cloud_tactile._kernel_elastomer_surface_state_bvh (cognitive 89): point_cloud_tactile._kernel_elastomer_surface_state_bvh has cognitive complexity 89 (threshold 15). Drivers by points: if/else 11 (41 pts), loops 11 (33 pts), ternaries 3 (15 pts) (nesting depth added 64). 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1335}}}],"partialFingerprints":{"codehealthFindingId/v1":"21530ee0c8c239288f19e03cf1d5f900a9416c03c93558ec7d90eb509912f4f2"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.indices_to_mask (cognitive 89): misc.indices_to_mask has cognitive complexity 89 (threshold 15). Drivers by points: if/else 18 (56 pts), ternaries 4 (21 pts), boolean chains 5, error handling 1 (4 pts), loops 2 (3 pts) (nesting depth added 59). 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":"genesis/utils/misc.py"},"region":{"startLine":605}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea6cc0105f18be2a2aac7aa7296a0fa36ded8ed0a18594069413799b44066a66"}},{"ruleId":"D2","level":"warning","message":{"text":"mjcf.parse_link (cognitive 89): mjcf.parse_link has cognitive complexity 89 (threshold 15). Drivers by points: if/else 30 (62 pts), ternaries 8 (17 pts), loops 3 (5 pts), boolean chains 3, 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":"genesis/utils/mjcf.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"67265bf0ddaeb51bf367208eb3eae568ba09f4076b6093a883116fd662ebbac2"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrow_phase_nonconvex_vs_nonterrain (cognitive 88): narrowphase.func_narrow_phase_nonconvex_vs_nonterrain has cognitive complexity 88 (threshold 15). Drivers by points: if/else 12 (59 pts), loops 5 (19 pts), ternaries 1 (6 pts), boolean chains 4 (nesting depth added 66). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4533}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cfa750b02e2d64f7dafe027080fe2c20e0f35f5b64f89d579691ffb81b6796"}},{"ruleId":"D2","level":"warning","message":{"text":"diff_gjk.func_gjk_contact (cognitive 84): diff_gjk.func_gjk_contact has cognitive complexity 84 (threshold 15). Drivers by points: if/else 26 (74 pts), loops 4 (8 pts), boolean chains 2 (nesting depth added 52). 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"179017aadc9f20175547851b9f5ce80016e710547a769d3d8098a72e709c7ea7"}},{"ruleId":"D2","level":"warning","message":{"text":"noslip.func_noslip_update_row (cognitive 84): noslip.func_noslip_update_row has cognitive complexity 84 (threshold 15). Drivers by points: if/else 19 (57 pts), loops 6 (22 pts), boolean chains 5 (nesting depth added 54). 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"728f88acae95b8188bd5d2057b26d0b5036f89470317caeae8a4087a6843f24e"}},{"ruleId":"D2","level":"warning","message":{"text":"multi_contact.func_clip_polygon (cognitive 83): multi_contact.func_clip_polygon has cognitive complexity 83 (threshold 15). Drivers by points: if/else 14 (42 pts), loops 9 (30 pts), ternaries 4 (6 pts), boolean chains 5 (nesting depth added 51). 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":891}}}],"partialFingerprints":{"codehealthFindingId/v1":"a119dc061c191861e1816a305324aed4cbe185174aceb9620898ba08baff63bb"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_collision.apply_collision_filtering (cognitive 83): usd_collision.apply_collision_filtering has cognitive complexity 83 (threshold 15). Drivers by points: if/else 19 (45 pts), loops 14 (32 pts), boolean chains 4, ternaries 1 (2 pts) (nesting depth added 45). 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":"genesis/utils/usd/usd_collision.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"2640925461ffbeb0b27c1d437481c331133789726073e25292eef59d940f1218"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_safe_epa (cognitive 81): epa.func_safe_epa has cognitive complexity 81 (threshold 15). Drivers by points: if/else 26 (62 pts), loops 5 (9 pts), boolean chains 7, ternaries 1 (3 pts) (nesting depth added 42). 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":960}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b6bfc4b1346317c9a15595012090be720aea104d12aab1dc475590bdd22e7c7"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntity.attach (cognitive 80): KinematicEntity.attach has cognitive complexity 80 (threshold 15). Drivers by points: if/else 26 (52 pts), loops 6 (10 pts), ternaries 3 (10 pts), boolean chains 8 (nesting depth added 37). 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fc906769e124c90190c8ec82c38a17f0fd2b2f820eee55e546de952fd4a81fe"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_gjk_contact (cognitive 79): gjk.func_gjk_contact has cognitive complexity 79 (threshold 15). Drivers by points: if/else 19 (65 pts), boolean chains 5, ternaries 4 (5 pts), loops 2 (4 pts) (nesting depth added 49). 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"15c2841ed802be05a210daa37ee3400a0359398b8bc18976cc17b0a552df8944"}},{"ruleId":"D2","level":"warning","message":{"text":"MPMSolver.p2g (cognitive 78): MPMSolver.p2g has cognitive complexity 78 (threshold 15). Drivers by points: if/else 13 (57 pts), loops 6 (19 pts), boolean chains 2 (nesting depth added 57). 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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"c28055e804680164b1a6e4df016309f7e2a9b37774ea91cbab0372f7aa924fb9"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_cone_rank_update_whole_env (cognitive 78): solver.func_cone_rank_update_whole_env has cognitive complexity 78 (threshold 15). Drivers by points: loops 9 (48 pts), if/else 6 (29 pts), boolean chains 1 (nesting depth added 62). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3989}}}],"partialFingerprints":{"codehealthFindingId/v1":"02f3a2e5c1575caae2419a28fa49ae3ccb85aed3fb9114643200cb830388f879"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._align_free_roots (cognitive 77): KinematicEntityDescription._align_free_roots has cognitive complexity 77 (threshold 15). Drivers by points: if/else 15 (46 pts), loops 9 (26 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 50). 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1199}}}],"partialFingerprints":{"codehealthFindingId/v1":"3428e6287e1466f9f106a0517337bea13e54aed347750e65452ffd26d072ff55"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_reorder_island_dofs (cognitive 77): island.func_reorder_island_dofs has cognitive complexity 77 (threshold 15). Drivers by points: loops 16 (39 pts), if/else 9 (30 pts), boolean chains 8 (nesting depth added 44). 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":797}}}],"partialFingerprints":{"codehealthFindingId/v1":"db3e7b6750b06531498b241561fa625f5ccbd906a28882d575f58b46f497cb32"}},{"ruleId":"D2","level":"warning","message":{"text":"Raytracer.build (cognitive 77): Raytracer.build has cognitive complexity 77 (threshold 15). Drivers by points: loops 15 (36 pts), if/else 19 (33 pts), ternaries 2 (8 pts) (nesting depth added 41). 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":"genesis/vis/raytracer.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef9ecd196d41d5b63297146fd997d5f50799b900a72ac35d9aed12fca64af18d"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_sweep_links_by_level (cognitive 76): forward_kinematics.func_sweep_links_by_level has cognitive complexity 76 (threshold 15). Drivers by points: if/else 20 (62 pts), loops 4 (14 pts) (nesting depth added 52). 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"57fb54f28d43310ac88abf41c8070d7b3c3d96c13e01d9c8a2dbb226f9619ae3"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_build_islands (cognitive 74): island.func_build_islands has cognitive complexity 74 (threshold 15). Drivers by points: if/else 19 (47 pts), loops 14 (23 pts), boolean chains 4 (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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":295}}}],"partialFingerprints":{"codehealthFindingId/v1":"640cc7c589ada09db1bf960fad202f5faf340bc80c01dae0b571274bdc87d93a"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_solve_init (cognitive 73): solver.func_solve_init has cognitive complexity 73 (threshold 15). Drivers by points: if/else 23 (47 pts), loops 8 (17 pts), boolean chains 6, ternaries 2 (3 pts) (nesting depth added 34). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5565}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab14175cb869838a9f2d7d74a02357e995b35a4f2f7a49c63149bcf70e5367e4"}},{"ruleId":"D2","level":"warning","message":{"text":"backward.kernel_manual_add_collision_constraints_bw (cognitive 72): backward.kernel_manual_add_collision_constraints_bw has cognitive complexity 72 (threshold 15). Drivers by points: if/else 10 (26 pts), loops 7 (26 pts), ternaries 5 (20 pts) (nesting depth added 50). 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"588ef9814218620153550b85ca43ae8c3667d4f2611e6a9c17f343a2a6179f27"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._add_friction_constraint (cognitive 72): solver._add_friction_constraint has cognitive complexity 72 (threshold 15). Drivers by points: if/else 24 (54 pts), ternaries 7 (13 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 37). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"8902c4502b4294becd59078f3ea5a58fe01295998ab891c0c0c77b75368e2221"}},{"ruleId":"D2","level":"warning","message":{"text":"genesis.init (cognitive 70): genesis.init has cognitive complexity 70 (threshold 15). Drivers by points: if/else 31 (40 pts), boolean chains 18, loops 5, ternaries 3 (5 pts), error handling 1 (2 pts) (nesting depth added 12). 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":"genesis/__init__.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"b41a2314c5ff98e8d44bbdc049b61e967ce383a589675d9f838eac57f4c513aa"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_safe_gjk (cognitive 70): gjk.func_safe_gjk has cognitive complexity 70 (threshold 15). Drivers by points: if/else 20 (54 pts), loops 3 (7 pts), ternaries 2 (7 pts), boolean chains 2 (nesting depth added 43). 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1143}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6436226720759ca76609271786ddf6e02556dfcf47217ddf0a911afc105559e"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.update_rigid (cognitive 69): RasterizerContext.update_rigid has cognitive complexity 69 (threshold 15). Drivers by points: if/else 9 (40 pts), loops 9 (28 pts), boolean chains 1 (nesting depth added 50). 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"d441fce95c87d898307f590c51e8f1957d23b2cf929fd22d87eac97ce1773b75"}},{"ruleId":"D2","level":"warning","message":{"text":"mjcf.parse_geoms (cognitive 68): mjcf.parse_geoms has cognitive complexity 68 (threshold 15). Drivers by points: loops 12 (35 pts), if/else 11 (30 pts), boolean chains 3 (nesting depth added 42). 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":"genesis/utils/mjcf.py"},"region":{"startLine":745}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab32b9741a0d5e81652bb23769b4041a2638a7fbbbad35125f61b2390f5aabe"}},{"ruleId":"D2","level":"warning","message":{"text":"Camera.set_pose (cognitive 67): Camera.set_pose has cognitive complexity 67 (threshold 15). Drivers by points: if/else 30 (46 pts), boolean chains 10, ternaries 4 (9 pts), loops 1 (2 pts) (nesting depth added 22). 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":"genesis/vis/camera.py"},"region":{"startLine":592}}}],"partialFingerprints":{"codehealthFindingId/v1":"920efb2b46ad3b53bb6f799d5825c337119c61fac2f0931b1a8e516c54d9d122"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_search_single_island (cognitive 66): linesearch.func_search_single_island has cognitive complexity 66 (threshold 15). Drivers by points: if/else 15 (44 pts), loops 7 (22 pts) (nesting depth added 44). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":762}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c281ca0ce6ed4862730faa3ddd744985b4f9b3ed8070e601edc7ed9934d60bb"}},{"ruleId":"D2","level":"warning","message":{"text":"gltf.parse_glb_material (cognitive 66): gltf.parse_glb_material has cognitive complexity 66 (threshold 15). Drivers by points: if/else 31 (63 pts), boolean chains 2, loops 1 (nesting depth added 32). 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":"genesis/utils/gltf.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd668ed613bbac7d235b76669fdb9d0606c336073ad2f1485d1aa9dd5477004b"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.set_base_links_quat (cognitive 65): RigidSolver.set_base_links_quat has cognitive complexity 65 (threshold 15). Drivers by points: if/else 25 (46 pts), boolean chains 15, ternaries 2 (4 pts) (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2132}}}],"partialFingerprints":{"codehealthFindingId/v1":"47a37bdbf5f15e2d10dd963dea4f3868d74c5a5d6973c11b55a2beaa6bbd9a7e"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_scene_editor (cognitive 65): ImGuiOverlayPlugin._render_scene_editor has cognitive complexity 65 (threshold 15). Drivers by points: if/else 20 (46 pts), boolean chains 10, ternaries 2 (5 pts), loops 2 (4 pts) (nesting depth added 31). 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":867}}}],"partialFingerprints":{"codehealthFindingId/v1":"e36fd06bdb4c56a64012a88a0a903c11b5722101d310764a4a36f6596b4f814f"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_cone_rank_update_island (cognitive 64): solver.func_cone_rank_update_island has cognitive complexity 64 (threshold 15). Drivers by points: loops 8 (34 pts), if/else 7 (28 pts), boolean chains 2 (nesting depth added 47). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3893}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd5d7af16a5f120fa2f5a820b9269edb07e581500d614cd5549d76f617afdfe7"}},{"ruleId":"D2","level":"warning","message":{"text":"Viewer.start (cognitive 62): Viewer.start has cognitive complexity 62 (threshold 15). Drivers by points: if/else 17 (34 pts), error handling 9 (21 pts), boolean chains 4, loops 2 (3 pts) (nesting depth added 30). 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1153}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6264480cc5771fbc75d9f3739ba63da1e5c81a61569286eb357e4d4721f7d94"}},{"ruleId":"D2","level":"warning","message":{"text":"_trimesh_patch.load_obj (cognitive 61): _trimesh_patch.load_obj has cognitive complexity 61 (threshold 15). Drivers by points: if/else 23 (42 pts), error handling 5 (13 pts), boolean chains 5, loops 1 (nesting depth added 27). 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"31cddb2e13b777bca4f66590b084fcf734e0edd4ca7b4fd35476b3b9890b0379"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_init_dofs_invweight (cognitive 60): forward_dynamics.func_init_dofs_invweight has cognitive complexity 60 (threshold 15). Drivers by points: loops 6 (24 pts), if/else 5 (20 pts), ternaries 4 (14 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1331}}}],"partialFingerprints":{"codehealthFindingId/v1":"428ed12ea3ed4512f89d463114fe91c87f7d87769d8ea409903b0981726430b7"}},{"ruleId":"D2","level":"warning","message":{"text":"multi_contact.func_potential_box_normals (cognitive 60): multi_contact.func_potential_box_normals has cognitive complexity 60 (threshold 15). Drivers by points: if/else 12 (32 pts), ternaries 4 (14 pts), loops 5 (12 pts), boolean chains 2 (nesting depth added 37). 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"85fa1b04731caabe2af89351cca808797640d40d1556c45f10d5df5ff74f7a26"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._sort_contacts_and_build_islands (cognitive 60): solver._sort_contacts_and_build_islands has cognitive complexity 60 (threshold 15). Drivers by points: if/else 16 (42 pts), loops 5 (14 pts), boolean chains 4 (nesting depth added 35). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1506}}}],"partialFingerprints":{"codehealthFindingId/v1":"93bc3ecee05696312a596729f140f6dc18d0812a77cb486a65aa5d512f9f4c12"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.set_base_links_pos (cognitive 60): RigidSolver.set_base_links_pos has cognitive complexity 60 (threshold 15). Drivers by points: if/else 24 (43 pts), boolean chains 13, ternaries 2 (4 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2008}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2a17d5fc5ce9c4af5b914e3823af863ed4d9546954ae68fc88a7cc51d254809"}},{"ruleId":"D2","level":"warning","message":{"text":"serialization._load_value (cognitive 60): serialization._load_value has cognitive complexity 60 (threshold 15). Drivers by points: if/else 21 (34 pts), boolean chains 11, ternaries 4 (8 pts), error handling 1 (4 pts), loops 1 (3 pts) (nesting depth added 22). 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":"genesis/utils/serialization.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"11c77a051082277ab10145fc5e4bada88f2181338dfc6014efa31285ac7f634c"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._quadric_decimate_loop (cognitive 60): watertighten._quadric_decimate_loop has cognitive complexity 60 (threshold 15). Drivers by points: if/else 18 (50 pts), boolean chains 5, loops 3 (5 pts) (nesting depth added 34). 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":"genesis/utils/watertighten.py"},"region":{"startLine":749}}}],"partialFingerprints":{"codehealthFindingId/v1":"811906983c43554385473615f98bc6dd8e41fd8833c5cae4a49a9bf1786e22cc"}},{"ruleId":"D2","level":"warning","message":{"text":"RRTConnect._kernel_rrt_connect_step1 (cognitive 59): RRTConnect._kernel_rrt_connect_step1 has cognitive complexity 59 (threshold 15). Drivers by points: if/else 11 (35 pts), loops 5 (15 pts), ternaries 2 (9 pts) (nesting depth added 41). 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":"genesis/utils/path_planning.py"},"region":{"startLine":726}}}],"partialFingerprints":{"codehealthFindingId/v1":"76852449e1eed5f2229ab733a968754810607e292b7e8c62bc3e1ff9b9f05484"}},{"ruleId":"D2","level":"warning","message":{"text":"surface_distance_probe._kernel_surface_distance_probe_bvh (cognitive 58): surface_distance_probe._kernel_surface_distance_probe_bvh has cognitive complexity 58 (threshold 15). Drivers by points: if/else 10 (39 pts), loops 6 (16 pts), boolean chains 3 (nesting depth added 39). 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":"genesis/engine/sensors/surface_distance_probe.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"07e886eab916840f84f2f92bcf46e3da46304987435b2a411ccce69860ec3147"}},{"ruleId":"D2","level":"warning","message":{"text":"Raytracer.update_scene (cognitive 58): Raytracer.update_scene has cognitive complexity 58 (threshold 15). Drivers by points: if/else 13 (23 pts), loops 9 (19 pts), ternaries 4 (15 pts), boolean chains 1 (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":"genesis/vis/raytracer.py"},"region":{"startLine":675}}}],"partialFingerprints":{"codehealthFindingId/v1":"df169f5b6a28fbb0bba0242bac64a9d92be12650c75b4a944240caf2980c97db"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_add_dynamic_constraint_rows_batch (cognitive 57): solver.func_add_dynamic_constraint_rows_batch has cognitive complexity 57 (threshold 15). Drivers by points: if/else 11 (35 pts), ternaries 4 (12 pts), boolean chains 5, loops 3 (5 pts) (nesting depth added 34). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1838}}}],"partialFingerprints":{"codehealthFindingId/v1":"4743d76cd7d4b5dbe3169cba45aac7964d0bfc898a381d06ee5bf98818ee7e45"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_exit_islands_coop (cognitive 56): linesearch.func_exit_islands_coop has cognitive complexity 56 (threshold 15). Drivers by points: if/else 13 (41 pts), loops 6 (15 pts) (nesting depth added 37). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1562}}}],"partialFingerprints":{"codehealthFindingId/v1":"e432001856a3822d8387becd7d07efbc41ccd0bc4887996faf2d9d47294d3f99"}},{"ruleId":"D2","level":"warning","message":{"text":"Mesh.from_trimesh (cognitive 55): Mesh.from_trimesh has cognitive complexity 55 (threshold 15). Drivers by points: if/else 21 (47 pts), boolean chains 6, ternaries 1 (2 pts) (nesting depth added 27). 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":"genesis/engine/mesh.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"09ef13ae14e372fceac88330f4e5e689901356a4fc490b53021e08137e852110"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_row_alpha_terms (cognitive 55): linesearch.func_row_alpha_terms has cognitive complexity 55 (threshold 15). Drivers by points: if/else 15 (38 pts), loops 4 (12 pts), boolean chains 5 (nesting depth added 31). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7f06c42d7ff053265bf2e20acfe7600c6c335a97857d195eb1d6ce52f02f3f7"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_collider_clear_env (cognitive 53): contact.func_collider_clear_env has cognitive complexity 53 (threshold 15). Drivers by points: if/else 10 (26 pts), loops 6 (16 pts), ternaries 2 (8 pts), boolean chains 3 (nesting depth added 32). 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"16fab8fde554cf2eb775f9047baf0a4911a568d50a23bbec3403b3e6d768ffda"}},{"ruleId":"D2","level":"warning","message":{"text":"diff_gjk.func_extended_epa (cognitive 53): diff_gjk.func_extended_epa has cognitive complexity 53 (threshold 15). Drivers by points: if/else 20 (40 pts), loops 4 (8 pts), ternaries 1 (3 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fa234ec88540b0531bbebe76d48192c0ead48bcafce19ddd30d59ac833dd07c"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_ls_state_advance (cognitive 53): linesearch.func_ls_state_advance has cognitive complexity 53 (threshold 15). Drivers by points: if/else 23 (44 pts), boolean chains 6, loops 2 (3 pts) (nesting depth added 22). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":383}}}],"partialFingerprints":{"codehealthFindingId/v1":"0df21eb242bb753f331e3ff5d322e3193fc445b849942790ed1a357ec1dee9fc"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._func_contact_row_direction (cognitive 53): solver._func_contact_row_direction has cognitive complexity 53 (threshold 15). Drivers by points: if/else 15 (40 pts), ternaries 3 (12 pts), boolean chains 1 (nesting depth added 34). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":638}}}],"partialFingerprints":{"codehealthFindingId/v1":"911118f51248ae768673e5a2514871bea76cc1df9a17b520db89dc2e4c3e63f1"}},{"ruleId":"D2","level":"warning","message":{"text":"_trimesh_patch.export_obj (cognitive 53): _trimesh_patch.export_obj has cognitive complexity 53 (threshold 15). Drivers by points: if/else 21 (38 pts), error handling 2 (6 pts), loops 3 (6 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":756}}}],"partialFingerprints":{"codehealthFindingId/v1":"83a79d216672fb540a127fd0104af2e8c83dba3c953fd9038fc898cc1f6fd4b1"}},{"ruleId":"D2","level":"warning","message":{"text":"Renderer.render (cognitive 53): Renderer.render has cognitive complexity 53 (threshold 15). Drivers by points: if/else 18 (35 pts), boolean chains 8, loops 3 (8 pts), ternaries 1 (2 pts) (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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"7804ac533bb4f6cab18991e7435e2be70b63e611c093ab2e5c5fdbfff9aa7c01"}},{"ruleId":"D2","level":"warning","message":{"text":"RRTConnect._kernel_rrt_connect_step2 (cognitive 53): RRTConnect._kernel_rrt_connect_step2 has cognitive complexity 53 (threshold 15). Drivers by points: if/else 12 (43 pts), loops 3 (10 pts) (nesting depth added 38). 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":"genesis/utils/path_planning.py"},"region":{"startLine":832}}}],"partialFingerprints":{"codehealthFindingId/v1":"93698fd0cec1bce0f67ea2a06c27c824dc0df09808b51bc791a226f3fb15133e"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_midpoint_free_body (cognitive 52): forward_dynamics.func_midpoint_free_body has cognitive complexity 52 (threshold 15). Drivers by points: if/else 16 (29 pts), loops 8 (13 pts), ternaries 4 (7 pts), boolean chains 3 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1949}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac19c5d3a4ce2351e98e064cc9d1130ca0f0b899e312942f506cf19a61f72ef9"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_epa (cognitive 52): epa.func_epa has cognitive complexity 52 (threshold 15). Drivers by points: if/else 17 (37 pts), loops 4 (8 pts), boolean chains 4, ternaries 1 (3 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"0329d6136aad8a6af5064b08918cdb67dd2b2f13d207ddda4b8511bcf9f13685"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase._func_multicontact_run_detection (cognitive 52): narrowphase._func_multicontact_run_detection has cognitive complexity 52 (threshold 15). Drivers by points: if/else 13 (42 pts), boolean chains 6, loops 1 (4 pts) (nesting depth added 32). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3015}}}],"partialFingerprints":{"codehealthFindingId/v1":"17194901c8583091493eb96e0fb2319018cc792504f57e95fbd16933a92adb15"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver._set_links_info (cognitive 52): RigidSolver._set_links_info has cognitive complexity 52 (threshold 15). Drivers by points: if/else 15 (31 pts), boolean chains 7, loops 3 (7 pts), ternaries 3 (7 pts) (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2263}}}],"partialFingerprints":{"codehealthFindingId/v1":"893b57bd38f29ee3a768dc75bb07a73156146ef1c1b964f0059cb0aba5ed5c1b"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_linesearch_islands_serial (cognitive 49): linesearch.func_linesearch_islands_serial has cognitive complexity 49 (threshold 15). Drivers by points: loops 7 (29 pts), if/else 9 (20 pts) (nesting depth added 33). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":962}}}],"partialFingerprints":{"codehealthFindingId/v1":"d31f2378766d8566bf68c0feb3105e3300b098a6e4d1df065fdf4034dd3cb227"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.set_state (cognitive 49): RigidSolver.set_state has cognitive complexity 49 (threshold 15). Drivers by points: if/else 24 (45 pts), boolean chains 4 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1785}}}],"partialFingerprints":{"codehealthFindingId/v1":"34cb403fff17179c0d085fdd6ad77c54a74284eb49938085c79e6893bf38ec9b"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidEntityDescription._describe_link (cognitive 48): RigidEntityDescription._describe_link has cognitive complexity 48 (threshold 15). Drivers by points: if/else 13 (30 pts), boolean chains 9, ternaries 5 (7 pts), loops 1 (2 pts) (nesting depth added 20). 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1674}}}],"partialFingerprints":{"codehealthFindingId/v1":"f47bf980e7a027f225799cd9e25178a6b921f6743ecb15cfd8bd8211db5c43f4"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntity._get_global_idx (cognitive 48): KinematicEntity._get_global_idx has cognitive complexity 48 (threshold 15). Drivers by points: if/else 20 (37 pts), ternaries 2 (5 pts), boolean chains 4, error handling 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":568}}}],"partialFingerprints":{"codehealthFindingId/v1":"af454d0acb5bf1598cad78dec3969bfa7e80c335dbba83bcf84c95e4adb62881"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicSolver.set_dofs_velocity (cognitive 48): KinematicSolver.set_dofs_velocity has cognitive complexity 48 (threshold 15). Drivers by points: if/else 20 (36 pts), boolean chains 9, ternaries 1 (3 pts) (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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1240}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0d693e51b002c1b98535afd666bf16422655ff0fb6efbd9a4e37aeeb293e0a0"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_mass_mat_assemble_tree_cooperative (cognitive 48): forward_dynamics.func_mass_mat_assemble_tree_cooperative has cognitive complexity 48 (threshold 15). Drivers by points: if/else 8 (28 pts), loops 5 (20 pts) (nesting depth added 35). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d0987dfea3ac6412930d86d7423d43098b55e6a3a79866ffa299452a12175e0"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_add_cone_hessian_block_island (cognitive 48): solver.func_add_cone_hessian_block_island has cognitive complexity 48 (threshold 15). Drivers by points: if/else 6 (27 pts), loops 5 (20 pts), boolean chains 1 (nesting depth added 36). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2457}}}],"partialFingerprints":{"codehealthFindingId/v1":"2807f759cba3be28b10ae77bba188cb4b813bfa394106dabc22ff7671fafae72"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_factor_island_incremental_or_direct (cognitive 48): solver.func_factor_island_incremental_or_direct has cognitive complexity 48 (threshold 15). Drivers by points: if/else 15 (40 pts), loops 3 (6 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4068}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b0239a6ede8ff485e50e91cef69f14e46f109cf61c44d058db5e79d1b761a30"}},{"ruleId":"D2","level":"warning","message":{"text":"mjcf.parse_geom (cognitive 48): mjcf.parse_geom has cognitive complexity 48 (threshold 15). Drivers by points: if/else 23 (38 pts), boolean chains 6, ternaries 3 (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":"genesis/utils/mjcf.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1d4879e1d123f11f1e1360c09ab5c8db30be176ce5c79c2e8651acdb3a099df"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_cholesky_solve_batch (cognitive 47): solver.func_cholesky_solve_batch has cognitive complexity 47 (threshold 15). Drivers by points: loops 10 (26 pts), if/else 10 (21 pts) (nesting depth added 27). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4224}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2cdd263491bbc66707abee5c76f29b933f971c9721a0dd2fb87078c6ba51fd9"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.build (cognitive 47): RigidSolver.build has cognitive complexity 47 (threshold 15). Drivers by points: if/else 17 (32 pts), ternaries 3 (7 pts), boolean chains 4, loops 3 (4 pts) (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":311}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fd1ea9cccbe8dd1035a27159c17b861b70bf2b24ce2c0269432eb03e67bba29"}},{"ruleId":"D2","level":"warning","message":{"text":"JITRenderer.set_primitive (cognitive 47): JITRenderer.set_primitive has cognitive complexity 47 (threshold 15). Drivers by points: if/else 19 (34 pts), boolean chains 7, ternaries 2 (4 pts), loops 2 (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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"25a12e260c156af3d7b980d2d4e09ee18cf3c7d9f947921e99d45a43cb28f4ef"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._add_fem_entities_to_ipc (cognitive 46): IPCCoupler._add_fem_entities_to_ipc has cognitive complexity 46 (threshold 15). Drivers by points: if/else 13 (40 pts), loops 2 (3 pts), ternaries 1 (3 pts) (nesting depth added 30). 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b9a1ac4c3e5e3f88ef0bb27bcfcfbda8e365fc07ce2d7b58972238cf8968b38"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_refresh_links_invweight_and_meaninertia (cognitive 45): forward_dynamics.func_refresh_links_invweight_and_meaninertia has cognitive complexity 45 (threshold 15). Drivers by points: if/else 7 (21 pts), ternaries 6 (14 pts), loops 4 (8 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1393}}}],"partialFingerprints":{"codehealthFindingId/v1":"480e6b1d624639e7b377720450c7c722a039912f0d6c4c9c2e1a26d29fcf3901"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.broadcast_tensor (cognitive 45): misc.broadcast_tensor has cognitive complexity 45 (threshold 15). Drivers by points: if/else 15 (32 pts), loops 3 (7 pts), boolean chains 5, 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":"genesis/utils/misc.py"},"region":{"startLine":996}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc47bd936a9bb2b62dcffc2ae368537fd4d791d9dd43ee516241810cee284682"}},{"ruleId":"D2","level":"warning","message":{"text":"RaycastContext.activate (cognitive 44): RaycastContext.activate has cognitive complexity 44 (threshold 15). Drivers by points: if/else 11 (24 pts), ternaries 3 (14 pts), loops 2 (4 pts), boolean chains 2 (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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"107c15518a20aa2041e2f8160eaa230071dfbbbc33b34220ce0a46ddbea1dee4"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_update_cartesian_space (cognitive 44): forward_kinematics.func_update_cartesian_space has cognitive complexity 44 (threshold 15). Drivers by points: if/else 8 (20 pts), loops 7 (14 pts), ternaries 3 (8 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":1141}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fe6be4df000dca59d7c0a47b1c1ca368910ade50ffcfdd7771c3d3770145276"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.add_limit_constraints (cognitive 44): solver.add_limit_constraints has cognitive complexity 44 (threshold 15). Drivers by points: if/else 7 (22 pts), loops 5 (16 pts), ternaries 1 (5 pts), boolean chains 1 (nesting depth added 30). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1969}}}],"partialFingerprints":{"codehealthFindingId/v1":"e81045d99df58847defd74215616c13a843b7d48de9810f0a97a6fd246c23ff2"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_apply_staged_rank_updates_island (cognitive 44): solver.func_apply_staged_rank_updates_island has cognitive complexity 44 (threshold 15). Drivers by points: if/else 11 (32 pts), loops 5 (11 pts), boolean chains 1 (nesting depth added 27). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3717}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a682afc92a9eed8718a1534976b3968a071c715878129402787e9c94033467e"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_material.parse_preview_surface (cognitive 44): usd_material.parse_preview_surface has cognitive complexity 44 (threshold 15). Drivers by points: if/else 18 (37 pts), boolean chains 7 (nesting depth added 19). 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":"genesis/utils/usd/usd_material.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5b928b082655d9b9dd0963f0d95115fb619eea78e12ce529263e1ed2e54a509"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._gaussian_axis (cognitive 44): watertighten._gaussian_axis has cognitive complexity 44 (threshold 15). Drivers by points: loops 12 (42 pts), if/else 2 (nesting depth added 30). 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":"genesis/utils/watertighten.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"b039b1494b24c6f0c1624db78831174fd554c6a1acadde0b4a7181a4bfbb176e"}},{"ruleId":"D2","level":"warning","message":{"text":"GenesisGeomRetriever.retrieve_rigid_meshes_static (cognitive 44): GenesisGeomRetriever.retrieve_rigid_meshes_static has cognitive complexity 44 (threshold 15). Drivers by points: if/else 12 (26 pts), loops 6 (9 pts), ternaries 4 (8 pts), boolean chains 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":"genesis/vis/batch_renderer.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"7013588f6160275ef277e57ef8f79347f5dce803c5e684cd6295a7ecd2e7afe4"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_init_link_invweight (cognitive 43): forward_dynamics.func_init_link_invweight has cognitive complexity 43 (threshold 15). Drivers by points: loops 7 (22 pts), if/else 5 (12 pts), ternaries 3 (8 pts), boolean chains 1 (nesting depth added 27). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1262}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d747677152cc1847639509736c68979638bfb6220cd854c74d8113388019e3c"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_file_browser (cognitive 43): ImGuiOverlayPlugin._render_file_browser has cognitive complexity 43 (threshold 15). Drivers by points: if/else 14 (32 pts), boolean chains 6, loops 1 (3 pts), error handling 1 (2 pts) (nesting depth added 21). 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":786}}}],"partialFingerprints":{"codehealthFindingId/v1":"39e9703c0a0eb1e08af90f73b09b0c5fecff66e9c32d24d16ae42abe9af67f36"}},{"ruleId":"D2","level":"warning","message":{"text":"Primitive._add_to_context (cognitive 43): Primitive._add_to_context has cognitive complexity 43 (threshold 15). Drivers by points: if/else 20 (25 pts), ternaries 7 (15 pts), loops 2 (3 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":"genesis/ext/pyrender/primitive.py"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"44b3a97d791886dea481058a9560132dbbca9c86437c6b74ebbb86f2069ed4b1"}},{"ruleId":"D2","level":"warning","message":{"text":"Viewer._render (cognitive 43): Viewer._render has cognitive complexity 43 (threshold 15). Drivers by points: if/else 27 (35 pts), boolean chains 4, loops 2 (4 pts) (nesting depth added 10). 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1057}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbeaf47179a8245f0add26c7d48bc61074ebeec7fd2d4d6962f3298d76a2c0a8"}},{"ruleId":"D2","level":"warning","message":{"text":"TrajectoryFileWriter.build (cognitive 43): TrajectoryFileWriter.build has cognitive complexity 43 (threshold 15). Drivers by points: if/else 16 (20 pts), ternaries 7 (13 pts), loops 4 (6 pts), boolean chains 4 (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":"genesis/recorders/trajectory.py"},"region":{"startLine":510}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d3dd6cdfee3b4512b848302c6d9f378e05cc0726819a62193569719862810bd"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_implicit_damping (cognitive 42): forward_dynamics.func_implicit_damping has cognitive complexity 42 (threshold 15). Drivers by points: if/else 10 (28 pts), loops 4 (10 pts), ternaries 1 (3 pts), boolean chains 1 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2360}}}],"partialFingerprints":{"codehealthFindingId/v1":"696cba0fb745c3625d127edd5670ff321040c3eb9d936bb589a23827f951a03d"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_gjk_subdistance (cognitive 42): gjk.func_gjk_subdistance has cognitive complexity 42 (threshold 15). Drivers by points: if/else 14 (35 pts), loops 2 (4 pts), boolean chains 3 (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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":819}}}],"partialFingerprints":{"codehealthFindingId/v1":"38b0abdc9c8af183ef4a2ca5767e78cfdb6632a006208afa6ab82437439f78f7"}},{"ruleId":"D2","level":"warning","message":{"text":"Renderer._get_primitive_program (cognitive 42): Renderer._get_primitive_program has cognitive complexity 42 (threshold 15). Drivers by points: if/else 29 (41 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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":749}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ce1250fdd4844fb2de1a3bb89bfaa9fcf6efde953087b5fa9c68f617bbe7e3c"}},{"ruleId":"D2","level":"warning","message":{"text":"MPLLinePlotter._update_plot (cognitive 42): MPLLinePlotter._update_plot has cognitive complexity 42 (threshold 15). Drivers by points: if/else 11 (27 pts), loops 4 (8 pts), boolean chains 7 (nesting depth added 20). 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":"genesis/recorders/plotters.py"},"region":{"startLine":567}}}],"partialFingerprints":{"codehealthFindingId/v1":"d534c8817e14466133c6045ec7ef88b7fcf229f7ba78c9772e29766183cc5a38"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSelfTetContactHandler.compute_pairs (cognitive 41): FEMSelfTetContactHandler.compute_pairs has cognitive complexity 41 (threshold 15). Drivers by points: if/else 9 (24 pts), loops 8 (17 pts) (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. This shape REPEATS in the file: one other method here (RigidRigidTetContactHandler.compute_pairs) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2843}}}],"partialFingerprints":{"codehealthFindingId/v1":"d28cd0680510166b9608538845814066b0b065a9e058052c63efc00ab07600aa"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidRigidTetContactHandler.compute_pairs (cognitive 41): RigidRigidTetContactHandler.compute_pairs has cognitive complexity 41 (threshold 15). Drivers by points: if/else 9 (24 pts), loops 8 (17 pts) (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. This shape REPEATS in the file: one other method here (FEMSelfTetContactHandler.compute_pairs) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3850}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bbd6c70d2be3efcb1622793bcde3d75c96276e720086a9ec7427af608ec0357"}},{"ruleId":"D2","level":"warning","message":{"text":"kinematic_tactile._kernel_build_sensor_geom_idx (cognitive 41): kinematic_tactile._kernel_build_sensor_geom_idx has cognitive complexity 41 (threshold 15). Drivers by points: if/else 3 (15 pts), ternaries 3 (13 pts), loops 4 (11 pts), boolean chains 2 (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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e2d9ff88b97d05e9d950f47a685f97b3aacd9e06588afb4732ef27409053e0d"}},{"ruleId":"D2","level":"warning","message":{"text":"SensorManager._resolve_sensor_cls (cognitive 41): SensorManager._resolve_sensor_cls has cognitive complexity 41 (threshold 15). Drivers by points: if/else 10 (24 pts), loops 3 (7 pts), error handling 1 (6 pts), boolean chains 4 (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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"b75b772f471eabf3e85750012d54ccfaea36aad383d35b02f9a52bff94dda3cc"}},{"ruleId":"D2","level":"warning","message":{"text":"PBDSolver._kernel_solve_density (cognitive 41): PBDSolver._kernel_solve_density has cognitive complexity 41 (threshold 15). Drivers by points: loops 8 (25 pts), if/else 4 (15 pts), boolean chains 1 (nesting depth added 28). 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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":598}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd912704146bee58f282df49705f51d17b0b63e2f82d3c6caf9df4170bf5caad"}},{"ruleId":"D2","level":"warning","message":{"text":"noslip.func_refresh_qacc_batch (cognitive 41): noslip.func_refresh_qacc_batch has cognitive complexity 41 (threshold 15). Drivers by points: if/else 11 (25 pts), loops 7 (15 pts), ternaries 1 (nesting depth added 22). 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"11d480cbb613765e2e827f0915c0f793ea7690ebed5cbd662d0aae25bd4c6d56"}},{"ruleId":"D2","level":"warning","message":{"text":"Mesh._get_trimesh_props (cognitive 41): Mesh._get_trimesh_props has cognitive complexity 41 (threshold 15). Drivers by points: if/else 14 (28 pts), ternaries 3 (10 pts), boolean chains 3 (nesting depth added 21). 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":"genesis/ext/pyrender/mesh.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc6844f3cb5f76441d190f5450755b8f4669816d2dcab81c40f47daf52af0375"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.get_gpu_shared_tile_sizes (cognitive 41): misc.get_gpu_shared_tile_sizes has cognitive complexity 41 (threshold 15). Drivers by points: if/else 10 (19 pts), loops 7 (13 pts), ternaries 3 (8 pts), boolean chains 1 (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":"genesis/utils/misc.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"885483137aa01e07204ee33310f4e70efe61a5302350f3f5b6c4d51ba7e753ac"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidFemTriTetContactHandler.compute_pairs (cognitive 40): RigidFemTriTetContactHandler.compute_pairs has cognitive complexity 40 (threshold 15). Drivers by points: if/else 9 (22 pts), loops 8 (17 pts), boolean chains 1 (nesting depth added 22). 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3501}}}],"partialFingerprints":{"codehealthFindingId/v1":"252632a9f5421bc855e5fd1aacb2cbdc12da5372c6175d53a613718a36e8ae12"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_epa_init_polytope_3d (cognitive 40): epa.func_epa_init_polytope_3d has cognitive complexity 40 (threshold 15). Drivers by points: if/else 8 (16 pts), ternaries 5 (13 pts), loops 6 (10 pts), boolean chains 1 (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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"983881aade50ac2ef0242da5856bc8621a306ac57df6ce50b2c51476c4cb63f9"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_gjk (cognitive 40): gjk.func_gjk has cognitive complexity 40 (threshold 15). Drivers by points: if/else 17 (34 pts), loops 3 (5 pts), boolean chains 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"14ea7cadc7fdcec8be3c4e3b5bb43a7ae287c7a61fa20e263b7d73b720fd59d4"}},{"ruleId":"D2","level":"warning","message":{"text":"Renderer._bind_and_draw_primitive (cognitive 40): Renderer._bind_and_draw_primitive has cognitive complexity 40 (threshold 15). Drivers by points: if/else 23 (36 pts), boolean chains 4 (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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ad21ca1b2e762e5d56b7139abea247ad0c53cc8438e17fa3232b47b85f1cbb5"}},{"ruleId":"D2","level":"warning","message":{"text":"RRT._kernel_rrt_step1 (cognitive 40): RRT._kernel_rrt_step1 has cognitive complexity 40 (threshold 15). Drivers by points: if/else 5 (16 pts), loops 5 (15 pts), ternaries 2 (9 pts) (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":"genesis/utils/path_planning.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4fcc5701191dc9f1dd8a3be18040b28aa26b042738a56d3250ece372c5c662c"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_contact_convex_convex_sdf (cognitive 39): narrowphase.func_contact_convex_convex_sdf has cognitive complexity 39 (threshold 15). Drivers by points: if/else 10 (27 pts), loops 4 (10 pts), boolean chains 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1135}}}],"partialFingerprints":{"codehealthFindingId/v1":"6666f84d5664f5af249d38feb8ae096d5df8e54a1dbd534b2471495743595336"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_exit_single_island (cognitive 39): linesearch.func_exit_single_island has cognitive complexity 39 (threshold 15). Drivers by points: if/else 11 (27 pts), loops 3 (9 pts), ternaries 1 (3 pts) (nesting depth added 24). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":901}}}],"partialFingerprints":{"codehealthFindingId/v1":"52b52bb81dcd555a26f9825b41bd4d2a04bf78a8d5595b65e4018cf2102d87c4"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_exit_islands_serial (cognitive 39): linesearch.func_exit_islands_serial has cognitive complexity 39 (threshold 15). Drivers by points: if/else 9 (27 pts), loops 3 (12 pts) (nesting depth added 27). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1105}}}],"partialFingerprints":{"codehealthFindingId/v1":"29df645c298ef87c3687be0c39c9eba990348daed0a305450f5de2eabd4b3d3c"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_island_tiled_factor_solve_all (cognitive 39): solver.func_island_tiled_factor_solve_all has cognitive complexity 39 (threshold 15). Drivers by points: if/else 7 (26 pts), ternaries 1 (7 pts), loops 2 (4 pts), boolean chains 2 (nesting depth added 27). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3426}}}],"partialFingerprints":{"codehealthFindingId/v1":"75f84085bb8491ad1fe640d886ad2f7d6503be04edbdf164ea4fe0bf2b7591be"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_update_contact_force (cognitive 39): solver.func_update_contact_force has cognitive complexity 39 (threshold 15). Drivers by points: loops 6 (18 pts), if/else 5 (15 pts), ternaries 1 (6 pts) (nesting depth added 27). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5926}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a88c6bdace66b35c8ea9e76250ec227497f1a1b89d7a81bcbbb683b41679bb5"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.set_qpos (cognitive 39): RigidSolver.set_qpos has cognitive complexity 39 (threshold 15). Drivers by points: if/else 18 (31 pts), boolean chains 5, ternaries 1 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2445}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e3b0c369fad60e5b20494752bf715a08da026f1c365513e16b01e245ec8da66"}},{"ruleId":"D2","level":"warning","message":{"text":"TrajectoryFileWriter._compress_frames (cognitive 39): TrajectoryFileWriter._compress_frames has cognitive complexity 39 (threshold 15). Drivers by points: if/else 11 (22 pts), error handling 3 (10 pts), boolean chains 3, ternaries 1 (3 pts), loops 1 (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":"genesis/recorders/trajectory.py"},"region":{"startLine":799}}}],"partialFingerprints":{"codehealthFindingId/v1":"0782f32cdb8142f407d775f85609a70a43cd3bdb157b5b8b5bc6ed8e9d0b2b7a"}},{"ruleId":"D2","level":"warning","message":{"text":"PathPlanner._func_check_collision (cognitive 39): PathPlanner._func_check_collision has cognitive complexity 39 (threshold 15). Drivers by points: if/else 8 (30 pts), boolean chains 5, loops 2 (4 pts) (nesting depth added 24). 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":"genesis/utils/path_planning.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"09e9e5575a405218e52d8049b22a222bd5be39465a290749f92fc80ab9cb864f"}},{"ruleId":"D2","level":"warning","message":{"text":"inverse_kinematics.func_jacobian_scratch (cognitive 38): inverse_kinematics.func_jacobian_scratch has cognitive complexity 38 (threshold 15). Drivers by points: loops 8 (25 pts), ternaries 3 (10 pts), if/else 1 (3 pts) (nesting depth added 26). 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"c694680b752f29555e2e7e894c1f7c8244167468f1bf7b625389184419f4e605"}},{"ruleId":"D2","level":"warning","message":{"text":"inverse_kinematics.func_get_jacobian (cognitive 38): inverse_kinematics.func_get_jacobian has cognitive complexity 38 (threshold 15). Drivers by points: loops 8 (25 pts), ternaries 3 (10 pts), if/else 1 (3 pts) (nesting depth added 26). 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"fef0dafa6e041d608a4d540ce2f6cf942c204549f5cfe1d779dd376b15bc9c1a"}},{"ruleId":"D2","level":"warning","message":{"text":"manual_bw.func_forward_kinematics_link_bw (cognitive 37): manual_bw.func_forward_kinematics_link_bw has cognitive complexity 37 (threshold 15). Drivers by points: loops 11 (26 pts), if/else 4 (5 pts), ternaries 3 (5 pts), boolean chains 1 (nesting depth added 18). 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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad771993bb53c2bd704151c36f877c741b9520da648f7833d1bcbc668a39f8ba"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.add_frictionloss_constraints (cognitive 37): solver.add_frictionloss_constraints has cognitive complexity 37 (threshold 15). Drivers by points: if/else 3 (12 pts), loops 5 (12 pts), ternaries 3 (12 pts), boolean chains 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2064}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fa8663950997c412657cc90a2f667160550a5187b92311c14f988e86fd374fd"}},{"ruleId":"D2","level":"warning","message":{"text":"RRTConnect.plan (cognitive 37): RRTConnect.plan has cognitive complexity 37 (threshold 15). Drivers by points: if/else 18 (27 pts), ternaries 3 (5 pts), loops 3, boolean chains 2 (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":"genesis/utils/path_planning.py"},"region":{"startLine":895}}}],"partialFingerprints":{"codehealthFindingId/v1":"29f8f4093d05c1569d50608a940727a6742c1b81d0e547a6031e58b5d7f18bf1"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_rigid_entity._parse_articulation_structure (cognitive 37): usd_rigid_entity._parse_articulation_structure has cognitive complexity 37 (threshold 15). Drivers by points: if/else 10 (20 pts), ternaries 5 (11 pts), loops 4 (6 pts) (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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"43d6b0257c09b5607a68b9e20d0148bc46833bb57e82012d8982a1d9c265819d"}},{"ruleId":"D2","level":"warning","message":{"text":"Alarm.build_table (cognitive 36): Alarm.build_table has cognitive complexity 36 (threshold 15). Drivers by points: ternaries 5 (19 pts), if/else 7 (14 pts), loops 2, boolean chains 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":".github/workflows/scripts/alarm.py"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"e99f94b35532045e709c29744c9ab6c52c8f9f4c17750bf8d3cc5808e71a186d"}},{"ruleId":"D2","level":"warning","message":{"text":"TemperatureGridSensor.build (cognitive 36): TemperatureGridSensor.build has cognitive complexity 36 (threshold 15). Drivers by points: if/else 13 (25 pts), loops 3 (8 pts), ternaries 2, boolean chains 1 (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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"beba93534f0ee19cd595eed72da6900ca0d70903e7bd067021bc845132b33a71"}},{"ruleId":"D2","level":"warning","message":{"text":"multi_contact.func_approximate_polygon_with_quad (cognitive 36): multi_contact.func_approximate_polygon_with_quad has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (25 pts), loops 4 (11 pts) (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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":1102}}}],"partialFingerprints":{"codehealthFindingId/v1":"07b930a0faa51f61ffef1c0bb59a7b0fe2df6bacb18c8e2cfaa10a76c5eaaa3b"}},{"ruleId":"D2","level":"warning","message":{"text":"backward.kernel_manual_add_joint_limit_constraints_bw (cognitive 36): backward.kernel_manual_add_joint_limit_constraints_bw has cognitive complexity 36 (threshold 15). Drivers by points: if/else 4 (17 pts), ternaries 3 (12 pts), loops 3 (6 pts), boolean chains 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"6795710da1414cd0603866fd9f6053cf3a9fd49d534cd984d8df92c70ef0ff26"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_group_constraints_by_island_coop (cognitive 36): island.func_group_constraints_by_island_coop has cognitive complexity 36 (threshold 15). Drivers by points: if/else 10 (24 pts), loops 6 (11 pts), boolean chains 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"12e3fdbf80771e4afab32a8a30a13e7180ef0b7257d548f7e36c2a8ec534bbab"}},{"ruleId":"D2","level":"warning","message":{"text":"RRT.plan (cognitive 36): RRT.plan has cognitive complexity 36 (threshold 15). Drivers by points: if/else 18 (27 pts), ternaries 3 (5 pts), boolean chains 2, loops 2 (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":"genesis/utils/path_planning.py"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"aab1a1b93e5752cadc791542e7fffe80a71aec97e54ef1710914b90479a29994"}},{"ruleId":"D2","level":"warning","message":{"text":"temperature._kernel_compute_contact_areas (cognitive 35): temperature._kernel_compute_contact_areas has cognitive complexity 35 (threshold 15). Drivers by points: loops 7 (18 pts), if/else 5 (15 pts), boolean chains 2 (nesting depth added 21). 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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ed2dc0215d15239d8c703470d331e7f0c86dc96ce9eacc2f331b036f5b45c01"}},{"ruleId":"D2","level":"warning","message":{"text":"manual_bw.func_forward_velocity_link_bw (cognitive 35): manual_bw.func_forward_velocity_link_bw has cognitive complexity 35 (threshold 15). Drivers by points: loops 12 (25 pts), if/else 3 (5 pts), ternaries 3 (5 pts) (nesting depth added 17). 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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"2882cf548c70573abce64f3d16555f4e3bfed96df6c228d75ac497cb64f9260f"}},{"ruleId":"D2","level":"warning","message":{"text":"broadphase.func_check_collision_valid (cognitive 35): broadphase.func_check_collision_valid has cognitive complexity 35 (threshold 15). Drivers by points: if/else 6 (17 pts), boolean chains 8, ternaries 2 (8 pts), loops 1 (2 pts) (nesting depth added 18). 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"737d2a6afccfae6641bd80096919a755f1b19b944405fd24ff1133b3eaa1e523"}},{"ruleId":"D2","level":"warning","message":{"text":"Camera.render (cognitive 35): Camera.render has cognitive complexity 35 (threshold 15). Drivers by points: if/else 13 (26 pts), boolean chains 4, ternaries 2 (3 pts), 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":"genesis/vis/camera.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e6dafafd32eac03b3eb71babfd7f3a33bd3cb38a546e8d9ff0f31b3a860ab4c"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._add_articulation_entities_to_ipc (cognitive 34): IPCCoupler._add_articulation_entities_to_ipc has cognitive complexity 34 (threshold 15). Drivers by points: if/else 8 (19 pts), loops 4 (8 pts), ternaries 2 (6 pts), boolean chains 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b33f32cb8d169e6e3adc7150ccb6619c6553b24c8ad4be988b3d8f7659c1c5d"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMFloorTetContactHandler.detection (cognitive 34): FEMFloorTetContactHandler.detection has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 5 (8 pts), boolean chains 3 (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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2579}}}],"partialFingerprints":{"codehealthFindingId/v1":"588d242c10af0dcbc7b13ab7b0f51201e9563b0287dd3dd2270a111c821b9cf4"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidJoint.dofs_length (cognitive 34): RigidJoint.dofs_length has cognitive complexity 34 (threshold 15). Drivers by points: if/else 9 (18 pts), loops 5 (14 pts), ternaries 2 (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":"genesis/engine/entities/rigid_entity/rigid_joint.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6802f718fdbece4add8640ba65da12844e1b79e0b9225c2e6f79c5ffcfdf9ad"}},{"ruleId":"D2","level":"warning","message":{"text":"Scene.add_entity (cognitive 34): Scene.add_entity has cognitive complexity 34 (threshold 15). Drivers by points: if/else 20 (32 pts), boolean chains 1, ternaries 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":"genesis/engine/scene.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8cb1bba1b3d13c5b51f0dd18907d985ed0e299e048af011ced83b234fe8b3a5"}},{"ruleId":"D2","level":"warning","message":{"text":"SensorManager.build (cognitive 34): SensorManager.build has cognitive complexity 34 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 9 (12 pts), ternaries 2 (6 pts), boolean chains 2 (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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"52da8dddcd2ba1fa6e149f5a7322a70afcd201f44dc977dd7f0c4030f6317f5e"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_factor_mass_tree (cognitive 34): forward_dynamics.func_factor_mass_tree has cognitive complexity 34 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 5 (14 pts), ternaries 1 (4 pts) (nesting depth added 22). 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee9b3e3833ec1364db6a0f2dfd17d90dde47aa07a3e1667227c80510f847ce3c"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_forward_velocity_link (cognitive 34): forward_kinematics.func_forward_velocity_link has cognitive complexity 34 (threshold 15). Drivers by points: loops 6 (16 pts), if/else 5 (10 pts), ternaries 5 (8 pts) (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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"88ebf7f4942f6b3ea270c132c385fa1123e04d488ba3c38c4cf08f0438f5e47a"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_contact_is_after (cognitive 34): contact.func_contact_is_after has cognitive complexity 34 (threshold 15). Drivers by points: if/else 8 (20 pts), loops 6 (14 pts) (nesting depth added 20). 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"934c047d7face4a090395c74c17c918c6b480d90723304962db045f1439e2d7f"}},{"ruleId":"D2","level":"warning","message":{"text":"noslip.func_noslip_batch (cognitive 34): noslip.func_noslip_batch has cognitive complexity 34 (threshold 15). Drivers by points: if/else 7 (27 pts), loops 3 (6 pts), ternaries 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":438}}}],"partialFingerprints":{"codehealthFindingId/v1":"213324b49f25ffee9a7f458be7d2d7fb4b0d6e92060fbc76f840570599d6c02e"}},{"ruleId":"D2","level":"warning","message":{"text":"ImageTexture._validate_and_load (cognitive 34): ImageTexture._validate_and_load has cognitive complexity 34 (threshold 15). Drivers by points: if/else 19 (34 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":"genesis/options/textures.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"2454a486b74605fa366a4515dc18bee35b3d52a039fa8be1e8d971729dabf0f2"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_rigid_entity.parse_usd_rigid_entity (cognitive 34): usd_rigid_entity.parse_usd_rigid_entity has cognitive complexity 34 (threshold 15). Drivers by points: if/else 13 (21 pts), loops 6 (9 pts), boolean chains 4 (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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"facde6d7e2fe5a2a2819b642c0af552b54875418b1b610c300001b5817219b7f"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidFloorTetContactHandler.detection (cognitive 33): RigidFloorTetContactHandler.detection has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 5 (8 pts), boolean chains 2 (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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3280}}}],"partialFingerprints":{"codehealthFindingId/v1":"1684cca529e36b04cdd58fedd087ff046cc3d1dc4b25f8ee2c1ed754bcc7c328"}},{"ruleId":"D2","level":"warning","message":{"text":"RaycastContext.update (cognitive 33): RaycastContext.update has cognitive complexity 33 (threshold 15). Drivers by points: if/else 14 (30 pts), boolean chains 2, loops 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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9a2e32023b021e0e79b3a3979521e1b3e33c093231c22f4ef6ce6fa671f620c"}},{"ruleId":"D2","level":"warning","message":{"text":"accessor.kernel_set_dofs_position (cognitive 33): accessor.kernel_set_dofs_position has cognitive complexity 33 (threshold 15). Drivers by points: loops 7 (20 pts), if/else 3 (7 pts), ternaries 2 (6 pts) (nesting depth added 21). 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":903}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5ad64cb0932e53bd368d16d76d2b9320e61496752a908b1811882b7292ae92e"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.func_hibernate_island_if_settled (cognitive 33): misc.func_hibernate_island_if_settled has cognitive complexity 33 (threshold 15). Drivers by points: loops 4 (12 pts), if/else 4 (11 pts), ternaries 2 (9 pts), boolean chains 1 (nesting depth added 22). 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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad257c3eb78f6347df3921763aa7fd681bb92d6d25ed1588f4fa940ca34bc56d"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_prefer_gjk_refinement (cognitive 33): narrowphase.func_prefer_gjk_refinement has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (24 pts), loops 3 (7 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1843}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6730b33342a337d9b7ffc0c1acb7ae0ef11e113d4545e025280c27e35226a75"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_island_hessian_assemble_all (cognitive 33): solver.func_island_hessian_assemble_all has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (28 pts), boolean chains 2, ternaries 1 (2 pts), loops 1 (nesting depth added 19). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3337}}}],"partialFingerprints":{"codehealthFindingId/v1":"c338a1617578785123ec0ebcd3f2e0d0da771c32fd7e450187ffcc7ea11bdfa5"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_cholesky_factor_direct_batch (cognitive 33): solver.func_cholesky_factor_direct_batch has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (20 pts), loops 4 (9 pts), boolean chains 4 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3499}}}],"partialFingerprints":{"codehealthFindingId/v1":"90a8ea1018e6ebeb2c93be94be84c4e2f6f080c9533b7cb58c795ae25c26350b"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._kernel_solve_monolith (cognitive 33): solver._kernel_solve_monolith has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (21 pts), loops 3 (8 pts), boolean chains 4 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5850}}}],"partialFingerprints":{"codehealthFindingId/v1":"9078e4486627917a9d99b0919dc692bea09ccd019645507aa1248bf57ddf308c"}},{"ruleId":"D2","level":"warning","message":{"text":"jit_render.bind_lighting (cognitive 33): jit_render.bind_lighting has cognitive complexity 33 (threshold 15). Drivers by points: if/else 11 (28 pts), loops 3 (5 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"17bea2bc9c5011371f37f5254be36b246f4ada72dbefd872e7ad4461c8ecc8f4"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF._process_cfgs (cognitive 33): URDF._process_cfgs has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (20 pts), loops 5 (13 pts) (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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3841}}}],"partialFingerprints":{"codehealthFindingId/v1":"a18826623b3c51c4ba29e9dc06d92885cbc8eb600005e701447fbac431a4ee7b"}},{"ruleId":"D2","level":"warning","message":{"text":"Trajectory.__init__ (cognitive 33): Trajectory.__init__ has cognitive complexity 33 (threshold 15). Drivers by points: if/else 14 (29 pts), boolean chains 3, loops 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":"genesis/recorders/trajectory.py"},"region":{"startLine":1034}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b4e0be84f23d5135c3c46e75195eb759374ca03f435eba8772754cbb456c775"}},{"ruleId":"D2","level":"warning","message":{"text":"Camera.build (cognitive 33): Camera.build has cognitive complexity 33 (threshold 15). Drivers by points: if/else 17 (29 pts), boolean chains 4 (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":"genesis/vis/camera.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbc93634b9b02afa61f6c7ea870a655164e43210142599e655ab10049cf739d8"}},{"ruleId":"D2","level":"warning","message":{"text":"SAPCoupler.build (cognitive 32): SAPCoupler.build has cognitive complexity 32 (threshold 15). Drivers by points: if/else 15 (26 pts), boolean chains 5, 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e6c2b2012ff298c1fa74fcd4fdb10bfa5975ff3b458a7cb3c139660a845b159"}},{"ruleId":"D2","level":"warning","message":{"text":"tactile_shared.normalize_grid_probe_layout (cognitive 32): tactile_shared.normalize_grid_probe_layout has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (23 pts), ternaries 1 (5 pts), boolean chains 4 (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":"genesis/engine/sensors/tactile_shared.py"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d3628779985d9169a7615336d4431778fb8ae7bdbacd8761869d169b8d0710a"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSolver.accumulate_vertex_force_preconditioner (cognitive 32): FEMSolver.accumulate_vertex_force_preconditioner has cognitive complexity 32 (threshold 15). Drivers by points: loops 11 (24 pts), if/else 4 (8 pts) (nesting depth added 17). 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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"169342dad9f65826b679a077453467609d07e6e0df4550fad0495ef2ac0322b3"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.kernel_refresh_invweight_and_meaninertia (cognitive 32): forward_dynamics.kernel_refresh_invweight_and_meaninertia has cognitive complexity 32 (threshold 15). Drivers by points: if/else 7 (15 pts), ternaries 4 (8 pts), loops 4 (7 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1469}}}],"partialFingerprints":{"codehealthFindingId/v1":"c92cf51ea45387617e92990367163cd6a25bb8f7f61f6a4cc42971d7232d3f56"}},{"ruleId":"D2","level":"warning","message":{"text":"solver_breakdown._func_update_constraint_forces (cognitive 32): solver_breakdown._func_update_constraint_forces has cognitive complexity 32 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 4 (10 pts), boolean chains 3, ternaries 1 (2 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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ff65a4afeb59ac6ba0bc2cbf87b9a157a704f231367885389e1a031cd6b976c"}},{"ruleId":"D2","level":"warning","message":{"text":"raycast_qd.closest_point_on_triangle (cognitive 32): raycast_qd.closest_point_on_triangle has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (26 pts), boolean chains 6 (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":"genesis/utils/raycast_qd.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"23eca67d68f7ee70c3af360c84622b9a9ed79cf831f02999703a9c94331408b9"}},{"ruleId":"D2","level":"warning","message":{"text":"UsdContext.find_all_materials (cognitive 32): UsdContext.find_all_materials has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (20 pts), loops 4 (6 pts), boolean chains 3, ternaries 2, error handling 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":"genesis/utils/usd/usd_context.py"},"region":{"startLine":338}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fa98e0a776f6f27cc21e8036d6ced6fc04f7bc7aa2b1be2fe676171fb5b6c12"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._collapse_safe (cognitive 32): watertighten._collapse_safe has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (20 pts), loops 4 (6 pts), boolean chains 4, ternaries 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":"genesis/utils/watertighten.py"},"region":{"startLine":593}}}],"partialFingerprints":{"codehealthFindingId/v1":"f673f24fe03bc55de1a01102352d4b91615cd7f2bd4c01d35fe3d0231cc829ba"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicSolver.build (cognitive 31): KinematicSolver.build has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (13 pts), loops 7 (9 pts), boolean chains 6, ternaries 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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"041061788591e699282d15819629c6b2c7708f168e98166b6e5c2970187e57c9"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_safe_gjk_support (cognitive 31): gjk.func_safe_gjk_support has cognitive complexity 31 (threshold 15). Drivers by points: if/else 8 (16 pts), ternaries 4 (12 pts), loops 2 (3 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1586}}}],"partialFingerprints":{"codehealthFindingId/v1":"f59cd541d3dc19a6e0e4b6bce409ea1f576cd03dc51b4a0649ac53906fed131f"}},{"ruleId":"D2","level":"warning","message":{"text":"mpr.mpr_find_pos (cognitive 31): mpr.mpr_find_pos has cognitive complexity 31 (threshold 15). Drivers by points: loops 6 (15 pts), if/else 7 (14 pts), boolean chains 2 (nesting depth added 16). 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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"effde68cf7397267ea064d722173b8bbe85bee673c41e7724455dadd9b5adda7"}},{"ruleId":"D2","level":"warning","message":{"text":"backward.kernel_compute_gradients (cognitive 31): backward.kernel_compute_gradients has cognitive complexity 31 (threshold 15). Drivers by points: loops 14 (28 pts), if/else 1 (3 pts) (nesting depth added 16). 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a13aa4efd082f54b4ea7bae7815085db7302b81a185fe2294d7f4e308e712bf"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_add_relative_motion_rows (cognitive 31): solver.func_add_relative_motion_rows has cognitive complexity 31 (threshold 15). Drivers by points: loops 7 (15 pts), if/else 3 (9 pts), ternaries 3 (5 pts), boolean chains 2 (nesting depth added 16). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1767}}}],"partialFingerprints":{"codehealthFindingId/v1":"c429aab78b0f39c21ecf6dbc8e4825ae6e41d3813a9b71fe33da652717df6719"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_update_constraint_batch (cognitive 31): solver.func_update_constraint_batch has cognitive complexity 31 (threshold 15). Drivers by points: loops 6 (15 pts), if/else 8 (14 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5047}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d0151d4f4086971c873793970fe2ae6ab3e6af043d795cfb26e65330da12fe3"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.update_contact (cognitive 31): RasterizerContext.update_contact has cognitive complexity 31 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 5 (14 pts), boolean chains 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":621}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29373f591886516f88f38857d342d82445ac91042b18b8b367d86ea9895c3cc"}},{"ruleId":"D2","level":"warning","message":{"text":"temperature._kernel_contact_heat (cognitive 30): temperature._kernel_contact_heat has cognitive complexity 30 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 4 (8 pts), ternaries 1 (3 pts), boolean chains 2 (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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7c8a454b10c8101729c652a9e1d110396516dac5415d84544f03566ae80f727"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicSolver.set_qpos (cognitive 30): KinematicSolver.set_qpos has cognitive complexity 30 (threshold 15). Drivers by points: if/else 14 (23 pts), boolean chains 4, ternaries 1 (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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1194}}}],"partialFingerprints":{"codehealthFindingId/v1":"dec2c21aa023b9a044077e5ffb80b2cd6efbc07ecb41586033ea92a481f8bab0"}},{"ruleId":"D2","level":"warning","message":{"text":"accessor.kernel_set_sol_params (cognitive 30): accessor.kernel_set_sol_params has cognitive complexity 30 (threshold 15). Drivers by points: loops 8 (24 pts), if/else 5 (6 pts) (nesting depth added 17). 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":633}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4b8106a81ae3026b1729afc1b6deaa93f7d80d3e3f1229be79afffbcf2a7993"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_update_force (cognitive 30): forward_dynamics.func_update_force has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 3 (7 pts), ternaries 1 (5 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1724}}}],"partialFingerprints":{"codehealthFindingId/v1":"17a37049641551b084d018d925b16a490344d7fb99504615d6e19524cec535fb"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_add_cone_hessian_block (cognitive 30): solver.func_add_cone_hessian_block has cognitive complexity 30 (threshold 15). Drivers by points: loops 5 (16 pts), if/else 4 (14 pts) (nesting depth added 21). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2293}}}],"partialFingerprints":{"codehealthFindingId/v1":"a10df9d200364f5140890afb896d3095a99881cd62626c2619af175e7b572124"}},{"ruleId":"D2","level":"warning","message":{"text":"Scene.add_node (cognitive 30): Scene.add_node has cognitive complexity 30 (threshold 15). Drivers by points: if/else 15 (28 pts), loops 2 (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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":381}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeefde4cefe65726b97dc738a443a78344ab2d201a105198cae11235add88944"}},{"ruleId":"D2","level":"warning","message":{"text":"utils.format_texture_source (cognitive 30): utils.format_texture_source has cognitive complexity 30 (threshold 15). Drivers by points: if/else 17 (29 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":"genesis/ext/pyrender/utils.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"51e2664d83d7a3c5aa8e1260d31739731233c5b597f7ebb8b8612f69b7dfa5bf"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF.link_fk (cognitive 30): URDF.link_fk has cognitive complexity 30 (threshold 15). Drivers by points: if/else 13 (25 pts), loops 3 (5 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. This shape REPEATS in the file: one other method here (URDF.link_fk_batch) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2965}}}],"partialFingerprints":{"codehealthFindingId/v1":"42abefc62d61e85b2dfd525eec48440d25df2d5f2ce3e3921e1429ec71c2162f"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF.link_fk_batch (cognitive 30): URDF.link_fk_batch has cognitive complexity 30 (threshold 15). Drivers by points: if/else 13 (25 pts), loops 3 (5 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. This shape REPEATS in the file: one other method here (URDF.link_fk) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3051}}}],"partialFingerprints":{"codehealthFindingId/v1":"7293db8bcde4c35aa20b73c06570d8d9560478107bb09587d08f806d7c4d152a"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF.animate (cognitive 30): URDF.animate has cognitive complexity 30 (threshold 15). Drivers by points: if/else 12 (20 pts), loops 5 (8 pts), boolean chains 2 (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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3400}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dc940c783adbc3cd116975b3390071f3dd55eb1d542769be287528e6d363f83"}},{"ruleId":"D2","level":"warning","message":{"text":"surfaces._make_rgba (cognitive 30): surfaces._make_rgba has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (17 pts), ternaries 4 (6 pts), boolean chains 5, loops 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":"genesis/options/surfaces.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"6532dc65208800301cfe342ae3c0ba127ff3160a97c09dcbd487403143bc9d7c"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._resolve_geoms (cognitive 29): KinematicEntityDescription._resolve_geoms has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 6 (11 pts), boolean chains 5 (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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1387}}}],"partialFingerprints":{"codehealthFindingId/v1":"23666fe34a503538da0e00f1ab9f5bdc05c9188ffb6c4aa561fa40008b02db04"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_forward_kinematics_link (cognitive 29): forward_kinematics.func_forward_kinematics_link has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (11 pts), ternaries 6 (10 pts), loops 3 (7 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"287d1884e3a02d90b5f80cecae6376b9fefee4b839702662eb8a0cafb6714efc"}},{"ruleId":"D2","level":"warning","message":{"text":"inverse_kinematics.func_forward_kinematics_scratch (cognitive 29): inverse_kinematics.func_forward_kinematics_scratch has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (17 pts), ternaries 3 (8 pts), loops 2 (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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb75534ba53fc38cb441582c3765b1234afa40a27aa73f075e3b9cd351e43bd5"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_contact_heapsort (cognitive 29): contact.func_contact_heapsort has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (21 pts), loops 3 (6 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":755}}}],"partialFingerprints":{"codehealthFindingId/v1":"11d6dd8bbcac943b7b00deeae038d0e0408b839752c4c64f5562dd7c6b578123"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_equality_links (cognitive 29): solver.func_equality_links has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 7 (13 pts), ternaries 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1164}}}],"partialFingerprints":{"codehealthFindingId/v1":"ced7ecee46163c8a8a7d46f55c82a11fb50ef01be1e17dfc0acf6e68fdf61307"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_island_hessian_patch_block (cognitive 29): solver.func_island_hessian_patch_block has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (21 pts), loops 4 (8 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3257}}}],"partialFingerprints":{"codehealthFindingId/v1":"337b4619831e4c93b96fc9edbbe4591bb9ab9212cf28ecda8d65bc6100760322"}},{"ruleId":"D2","level":"warning","message":{"text":"Scene._remove_node (cognitive 29): Scene._remove_node has cognitive complexity 29 (threshold 15). Drivers by points: if/else 15 (27 pts), loops 2 (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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":552}}}],"partialFingerprints":{"codehealthFindingId/v1":"5330849f25ab5df417567edb579acd953a86c021e070d03ad15be17cdef5e091"}},{"ruleId":"D2","level":"warning","message":{"text":"Options._validation_error (cognitive 29): Options._validation_error has cognitive complexity 29 (threshold 15). Drivers by points: if/else 11 (22 pts), boolean chains 3, loops 2, 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":"genesis/options/options.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"e643dfe37ba49f695c5104e6a9f36f9f01ebc024b3ac04dfdda4aaf2f09ec620"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.sanitize_index (cognitive 29): misc.sanitize_index has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (17 pts), ternaries 3 (6 pts), boolean chains 5, error handling 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":"genesis/utils/misc.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5ebab167a16f20759aa42fb403f71facbc8960089a058a05b18a742d7daf2cd"}},{"ruleId":"D2","level":"warning","message":{"text":"MouseInteractionPlugin.on_draw (cognitive 29): MouseInteractionPlugin.on_draw has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (19 pts), loops 2 (5 pts), boolean chains 3, ternaries 1 (2 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":"genesis/vis/viewer_plugins/plugins/mouse_interaction.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"7aef51e9294c92944bb5fb385742930a68db31915a9b2db09736949dfb17a3bc"}},{"ruleId":"D2","level":"warning","message":{"text":"HybridEntity.__init__ (cognitive 28): HybridEntity.__init__ has cognitive complexity 28 (threshold 15). Drivers by points: if/else 17 (27 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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"73d1efa83721e51ee32f18207f11f002e781a6f5ba6e71e9d9f2905a17954ee0"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._load_mesh (cognitive 28): KinematicEntityDescription._load_mesh has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (20 pts), loops 3 (7 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":797}}}],"partialFingerprints":{"codehealthFindingId/v1":"b344e720370d930319a6e7df5c58225d5d24bc0811114294f6c1e3792bec284d"}},{"ruleId":"D2","level":"warning","message":{"text":"diff.func_integrate_dq_entity (cognitive 28): diff.func_integrate_dq_entity has cognitive complexity 28 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 4 (9 pts), ternaries 3 (9 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":"genesis/engine/solvers/rigid/abd/diff.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"14c38300a01c541b40b22bbc6081406cc61b41f722e4502f1ac08400059e58e2"}},{"ruleId":"D2","level":"warning","message":{"text":"inverse_kinematics.func_integrate_dq_scratch (cognitive 28): inverse_kinematics.func_integrate_dq_scratch has cognitive complexity 28 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 4 (9 pts), ternaries 3 (9 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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"1372bcd20cc54dfe7ca6f5e96e916c2ba44290c588ea5a1d0450c03dcc396615"}},{"ruleId":"D2","level":"warning","message":{"text":"backward.kernel_manual_add_frictionloss_constraints_bw (cognitive 28): backward.kernel_manual_add_frictionloss_constraints_bw has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 3 (12 pts), loops 4 (10 pts), if/else 1 (5 pts), boolean chains 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"72b6802dc27364b22d79d6ea6c1e6b75bf09cd16df47f9414d0e5a225cb375d5"}},{"ruleId":"D2","level":"warning","message":{"text":"Alarm.fetch_wandb_data (cognitive 27): Alarm.fetch_wandb_data has cognitive complexity 27 (threshold 15). Drivers by points: if/else 9 (19 pts), error handling 2 (4 pts), boolean chains 3, loops 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":".github/workflows/scripts/alarm.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd6494637aa8feae50f5a158ea0f1e1f28a006696afb60e18d2ff2034a821d07"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntity.process_input_grad (cognitive 27): KinematicEntity.process_input_grad has cognitive complexity 27 (threshold 15). Drivers by points: if/else 5 (16 pts), boolean chains 5, loops 2 (4 pts), match/switch 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":497}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc3349589e58286ef833cbcbc1728748ec33afd376ed9ba5b13099aeea16b48f"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_compute_mass_matrix (cognitive 27): forward_dynamics.func_compute_mass_matrix has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 7 (11 pts), ternaries 2 (5 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"86fe240e523ab1486d21e0515ed40a04abec0fd4f5b411091a28cb3f55abba19"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_epa_horizon (cognitive 27): epa.func_epa_horizon has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 2 (4 pts), boolean chains 3, ternaries 1 (3 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c82c6ed6a9ed48486a8e3ba9996d4a8b1b9a2df7bbaf5d27ca55a2fff3f7a92"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._func_update_efc_force (cognitive 27): solver._func_update_efc_force has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 4 (9 pts), ternaries 2 (4 pts), boolean chains 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5199}}}],"partialFingerprints":{"codehealthFindingId/v1":"c794d157941e7d74311e7c967a35cf804f4b9ecc66b9660b14b8a7ba5a669209"}},{"ruleId":"D2","level":"warning","message":{"text":"array_class.iter_data (cognitive 27): array_class.iter_data has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 5, loops 2 (5 pts), ternaries 1 (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":"genesis/utils/array_class.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cf8a8359636670ce00fa9a7aec453be79a3c2590b088e90ecc4c03e53dd50b9"}},{"ruleId":"D2","level":"warning","message":{"text":"FrameImageExporter.export_frame_single_camera (cognitive 27): FrameImageExporter.export_frame_single_camera has cognitive complexity 27 (threshold 15). Drivers by points: if/else 12 (19 pts), ternaries 2 (4 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":"genesis/utils/image_exporter.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e990c3e54004565ecc1f6f097ea92bc75f8bf496156bebb7ba80234866fae14"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.qd_to_torch (cognitive 27): misc.qd_to_torch has cognitive complexity 27 (threshold 15). Drivers by points: if/else 9 (17 pts), error handling 2 (5 pts), ternaries 2 (5 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":"genesis/utils/misc.py"},"region":{"startLine":734}}}],"partialFingerprints":{"codehealthFindingId/v1":"29f3f5710d3d87ced577a1a26c5a618811c7ffa87a66c62aa80efab1ddb63933"}},{"ruleId":"D2","level":"warning","message":{"text":"mjcf.parse_equalities (cognitive 27): mjcf.parse_equalities has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (14 pts), loops 3 (6 pts), ternaries 2 (6 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":"genesis/utils/mjcf.py"},"region":{"startLine":825}}}],"partialFingerprints":{"codehealthFindingId/v1":"73453826b34a8c0886d29f593ff256b0835cd3cbaacf34555c6e0703f56e1ad9"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntity.inverse_kinematics_multilink (cognitive 26): KinematicEntity.inverse_kinematics_multilink has cognitive complexity 26 (threshold 15). Drivers by points: if/else 11 (14 pts), ternaries 7 (9 pts), loops 2, boolean chains 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1553}}}],"partialFingerprints":{"codehealthFindingId/v1":"7919187abee16f7207c13965f7546b445339d56b4131ef04eb1cc6c04234732c"}},{"ruleId":"D2","level":"warning","message":{"text":"InteractiveScene._apply_rebuild (cognitive 26): InteractiveScene._apply_rebuild has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (14 pts), loops 4 (6 pts), ternaries 3 (4 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":"genesis/engine/interactive_scene.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fc72f0fd7e388d7f05226b05b72452895a4a841c6dd2593ec48f445c0166321"}},{"ruleId":"D2","level":"warning","message":{"text":"Sensor.__init_subclass__ (cognitive 26): Sensor.__init_subclass__ has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 7, 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":"genesis/engine/sensors/base_sensor.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"fddcf6683088a7d1ed9f41db2d549780f3af2d65deded694f99bf6a4e5bb016d"}},{"ruleId":"D2","level":"warning","message":{"text":"contact_force._kernel_get_contacts_forces (cognitive 26): contact_force._kernel_get_contacts_forces has cognitive complexity 26 (threshold 15). Drivers by points: loops 5 (15 pts), if/else 3 (8 pts), boolean chains 3 (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":"genesis/engine/sensors/contact_force.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d7866c77c7922e97d81bb9d2af500730ecca93c9b6fbc242eba1218bb8d30dd"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_midpoint_eligible (cognitive 26): forward_dynamics.func_midpoint_eligible has cognitive complexity 26 (threshold 15). Drivers by points: if/else 5 (12 pts), ternaries 3 (7 pts), boolean chains 4, loops 1 (3 pts) (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1863}}}],"partialFingerprints":{"codehealthFindingId/v1":"efa777da33c73068b1e46bc0b91cd2ac0d4ef8e496770cc1f2bc49638dc4893d"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_compute_island_envelope (cognitive 26): solver.func_compute_island_envelope has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 8 (11 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2226}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d9efaae3cce8f315e270391ff4d9b4a64791cd068da03007112601659609d51"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_add_cone_hessian_block_coop (cognitive 26): solver.func_add_cone_hessian_block_coop has cognitive complexity 26 (threshold 15). Drivers by points: if/else 4 (16 pts), loops 3 (9 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2353}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a9012ac51507abb5f5fb0d5870da442e65bb2aad92b0818048608a2fb8d3a64"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_hessian_and_cholesky_factor_incremental_batch (cognitive 26): solver.func_hessian_and_cholesky_factor_incremental_batch has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (20 pts), loops 2 (4 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4170}}}],"partialFingerprints":{"codehealthFindingId/v1":"33c80e13fd9c1fbd3448418d17d4153ea3e3af0ffe43a5c06db6e7d5e620f352"}},{"ruleId":"D2","level":"warning","message":{"text":"OffscreenRenderer.render (cognitive 26): OffscreenRenderer.render has cognitive complexity 26 (threshold 15). Drivers by points: if/else 18 (20 pts), boolean chains 6 (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":"genesis/ext/pyrender/offscreen.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ebd0e9bcfd9e1149689243276c9beb85fa1e0ec2201dc8d1b039f2e03abeab6"}},{"ruleId":"D2","level":"warning","message":{"text":"linalg.mat_inverse (cognitive 26): linalg.mat_inverse has cognitive complexity 26 (threshold 15). Drivers by points: loops 10 (22 pts), if/else 2 (4 pts) (nesting depth added 14). 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":"genesis/utils/linalg.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eae667dd5977ceb3528cda72662d8ddd9178efcf9a25243c035b1b42acefc96"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.assign_indexed_tensor (cognitive 26): misc.assign_indexed_tensor has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (20 pts), boolean chains 3, ternaries 1 (2 pts), error handling 1 (nesting depth added 13). 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":"genesis/utils/misc.py"},"region":{"startLine":1128}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3c9a1a5520fb89f83ce30b9bb5b3adfcf064346c847b728d1a52dfdfcc8d066"}},{"ruleId":"D2","level":"warning","message":{"text":"terrain.parse_terrain (cognitive 26): terrain.parse_terrain has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (19 pts), boolean chains 2, error handling 1 (2 pts), loops 1 (2 pts), ternaries 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":"genesis/utils/terrain.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"76192389811f376cab14c954376e8c33e03565f62c1189a160e733f9d8f36540"}},{"ruleId":"D2","level":"warning","message":{"text":"Rasterizer.destroy (cognitive 26): Rasterizer.destroy has cognitive complexity 26 (threshold 15). Drivers by points: error handling 3 (10 pts), if/else 5 (10 pts), loops 3 (6 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":"genesis/vis/rasterizer.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"255f65a31788347790408790b916fb5171b61701cfff27cea32ccaa1903a7d05"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.update_pbd (cognitive 26): RasterizerContext.update_pbd has cognitive complexity 26 (threshold 15). Drivers by points: if/else 5 (21 pts), loops 2 (5 pts) (nesting depth added 19). 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":872}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2bc5e596baddae9b8cc833f58763b5bc4ea242c7c8c2a3deaa3d1be3eab40fb"}},{"ruleId":"D2","level":"warning","message":{"text":"Viewer.build (cognitive 26): Viewer.build has cognitive complexity 26 (threshold 15). Drivers by points: if/else 12 (21 pts), error handling 1 (2 pts), ternaries 2, 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":"genesis/vis/viewer.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7eed20886fe5c7f52e853bcb442592267e59c022bec79336e9f0b4d495e03d1"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSelfTetContactHandler.compute_candidates (cognitive 25): FEMSelfTetContactHandler.compute_candidates has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 3 (5 pts), boolean chains 3 (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. This shape REPEATS in the file: one other method here (RigidRigidTetContactHandler.compute_candidates) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2772}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb166f8c05c7c43ecb21dc65d24e2481cab2c2992e1350648431c60ab3b8afb2"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidRigidTetContactHandler.compute_candidates (cognitive 25): RigidRigidTetContactHandler.compute_candidates has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 3 (5 pts), boolean chains 3 (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. This shape REPEATS in the file: one other method here (FEMSelfTetContactHandler.compute_candidates) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3780}}}],"partialFingerprints":{"codehealthFindingId/v1":"e62228910d3981367cbf0897b3824249b02fbfe34acb509e2f6fe182ff798463"}},{"ruleId":"D2","level":"warning","message":{"text":"Simulator.build (cognitive 25): Simulator.build has cognitive complexity 25 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 5, loops 4 (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":"genesis/engine/simulator.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1148361a020c1ae0f3fe2e88702ab04bc7c059da15eb47670914a7e2c09dfc9"}},{"ruleId":"D2","level":"warning","message":{"text":"JITRenderer.update_context (cognitive 25): JITRenderer.update_context has cognitive complexity 25 (threshold 15). Drivers by points: loops 11 (14 pts), if/else 4 (7 pts), boolean chains 4 (nesting depth added 6). 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff1aad8b77e409f87b6515ca3048e3c93aa08972fff431a7a2da50217cad1373"}},{"ruleId":"D2","level":"warning","message":{"text":"LinePlotHelper.process (cognitive 25): LinePlotHelper.process has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 5 (10 pts), error handling 1 (4 pts) (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":"genesis/recorders/plotters.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"86a2df5e2a9d6214b98aa3ca3814eb2575727cf1400d32948ddd60716dd21e1f"}},{"ruleId":"D2","level":"warning","message":{"text":"serialization.load (cognitive 25): serialization.load has cognitive complexity 25 (threshold 15). Drivers by points: if/else 9 (17 pts), error handling 4, 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":"genesis/utils/serialization.py"},"region":{"startLine":596}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce11921be57cb60a9157a0fcbe2d81a98eecccb55223918b1e441ae5db5fa316"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_stage._find_connected_components (cognitive 25): usd_stage._find_connected_components has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 5, ternaries 2 (4 pts), loops 3 (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":"genesis/utils/usd/usd_stage.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dec586e5dd5b2a4d0272f4cb86b60768d141d67c6442f7ece05eb7a2a0b5efd"}},{"ruleId":"D2","level":"warning","message":{"text":"bvh.func_bvh_query_aabb (cognitive 24): bvh.func_bvh_query_aabb has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (20 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 14). 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":"genesis/engine/bvh.py"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"e959be8e3eaf88e7c30810057d879833300ae0321a1fb0219a4bf20a39e155e3"}},{"ruleId":"D2","level":"warning","message":{"text":"kinematic_tactile._kernel_kinematic_taxel_bvh (cognitive 24): kinematic_tactile._kernel_kinematic_taxel_bvh has cognitive complexity 24 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 5 (10 pts), ternaries 1 (2 pts) (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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":791}}}],"partialFingerprints":{"codehealthFindingId/v1":"63bd517878df7d7b7758690d7c8a383f30097d70f743b8aa917c8c5063cc71bf"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_compute_mass_matrix_masked (cognitive 24): forward_dynamics.func_compute_mass_matrix_masked has cognitive complexity 24 (threshold 15). Drivers by points: loops 7 (10 pts), if/else 5 (9 pts), ternaries 2 (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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"10e3512e1eb8d247d6a946a2dba084df6d215fe57c74965e0c2dc8f3136b220f"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_gjk_intersect (cognitive 24): gjk.func_gjk_intersect has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 5 (9 pts) (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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":663}}}],"partialFingerprints":{"codehealthFindingId/v1":"53853154c17c0b372e80d908f8a1c838ce38c10d89f70ef95325b6e4648a50a6"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_search_valid_simplex_vertex (cognitive 24): gjk.func_search_valid_simplex_vertex has cognitive complexity 24 (threshold 15). Drivers by points: ternaries 5 (14 pts), if/else 3 (6 pts), loops 3 (4 pts) (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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1448}}}],"partialFingerprints":{"codehealthFindingId/v1":"95436277cbb0eb995f27181a0f6e656dab01d33c64166452c2d1db2fef222861"}},{"ruleId":"D2","level":"warning","message":{"text":"trajectory._encode_frames (cognitive 24): trajectory._encode_frames has cognitive complexity 24 (threshold 15). Drivers by points: loops 5 (15 pts), if/else 1 (4 pts), ternaries 2 (4 pts), boolean chains 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":"genesis/recorders/trajectory.py"},"region":{"startLine":382}}}],"partialFingerprints":{"codehealthFindingId/v1":"a94ceca7fa6f7564b2a6fb2e8dfb4efbe5075af28fbd6fe359d7fec6b4c5c935"}},{"ruleId":"D2","level":"warning","message":{"text":"geom.z_to_quat (cognitive 24): geom.z_to_quat has cognitive complexity 24 (threshold 15). Drivers by points: if/else 10 (21 pts), boolean chains 2, 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":"genesis/utils/geom.py"},"region":{"startLine":2114}}}],"partialFingerprints":{"codehealthFindingId/v1":"48ce6652d0ced434712408db222f2a7ba28e0b0d2a205d810acc3eac61b11eea"}},{"ruleId":"D2","level":"warning","message":{"text":"serialization._export_value (cognitive 24): serialization._export_value has cognitive complexity 24 (threshold 15). Drivers by points: if/else 13 (16 pts), boolean chains 4, ternaries 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":"genesis/utils/serialization.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ccf36767751f774e78ab484b1fb7c83c1f904503eed3af519584180a10883c"}},{"ruleId":"D2","level":"warning","message":{"text":"serialization._redact_paths (cognitive 24): serialization._redact_paths has cognitive complexity 24 (threshold 15). Drivers by points: if/else 5 (9 pts), ternaries 2 (6 pts), loops 2 (5 pts), boolean chains 2, error handling 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":"genesis/utils/serialization.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"d18424b1e1f7806e60458358480805f693e13af36ad60f5983bf6297532b3f59"}},{"ruleId":"D2","level":"warning","message":{"text":"gjk.func_gjk_subdistance_2d (cognitive 23): gjk.func_gjk_subdistance_2d has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 4 (9 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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":940}}}],"partialFingerprints":{"codehealthFindingId/v1":"aba01b76ed205043187402970319096ee222c895389044224dcdd19d60a08481"}},{"ruleId":"D2","level":"warning","message":{"text":"geom.trans_R_to_T (cognitive 23): geom.trans_R_to_T has cognitive complexity 23 (threshold 15). Drivers by points: if/else 12 (15 pts), ternaries 4 (6 pts), boolean chains 2 (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":"genesis/utils/geom.py"},"region":{"startLine":1149}}}],"partialFingerprints":{"codehealthFindingId/v1":"106a55049423a1005d9a60f0aef721e31a0b7ae342635874b8e81f9cd640f197"}},{"ruleId":"D2","level":"warning","message":{"text":"geom._tc_polar (cognitive 23): geom._tc_polar has cognitive complexity 23 (threshold 15). Drivers by points: if/else 12 (18 pts), ternaries 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":"genesis/utils/geom.py"},"region":{"startLine":1455}}}],"partialFingerprints":{"codehealthFindingId/v1":"92eefd2d07b7ca142f62ccc7e7f520bf732859851c782e7e2b01ce8f586b19b4"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.qd_to_numpy (cognitive 23): misc.qd_to_numpy has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (12 pts), error handling 2 (5 pts), ternaries 2 (5 pts), boolean chains 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":"genesis/utils/misc.py"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb0abfceb52c7b4e2a20796ea594db64534b8e5ec90b7e5ec500bce258137513"}},{"ruleId":"D2","level":"warning","message":{"text":"RRT._kernel_rrt_step2 (cognitive 23): RRT._kernel_rrt_step2 has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (18 pts), loops 2 (5 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":"genesis/utils/path_planning.py"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb53d340fa39a7776ebd22090b2be121b4fefb050eea7a694fdda18887132629"}},{"ruleId":"D2","level":"warning","message":{"text":"urdf.merge_fixed_links (cognitive 23): urdf.merge_fixed_links has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 5 (8 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":"genesis/utils/urdf.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"65b778c4f186a839c1a008aa68dd4adc47deae56eced7cc0ead2c8048edf2d7d"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._build_edge_component_table (cognitive 23): watertighten._build_edge_component_table has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (18 pts), loops 3 (5 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":"genesis/utils/watertighten.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7515cdbc9571f71b9fbac06588fc2c02b4a677f179031d88ae0c1ece2a39425"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidFemTriTetContactHandler.compute_candidates (cognitive 22): RigidFemTriTetContactHandler.compute_candidates has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 3 (5 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3441}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4dcfadc8ab2d90a13ef4fb722b028f883f99c7c04c13c037acff29e2a77e0f4"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidJointDescription.__post_init__ (cognitive 22): RigidJointDescription.__post_init__ has cognitive complexity 22 (threshold 15). Drivers by points: if/else 14 (16 pts), ternaries 2 (6 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a3f93193eaca29838947dd88cd69f0415560f15a0636185d296210a3bcee1b"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidEntity._build (cognitive 22): RigidEntity._build has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 2, 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1928}}}],"partialFingerprints":{"codehealthFindingId/v1":"82a59711998b5fb9f751d6435dd1890d6230689376fce86c4887a41d860038ab"}},{"ruleId":"D2","level":"warning","message":{"text":"PBDSolver._kernel_solve_collision (cognitive 22): PBDSolver._kernel_solve_collision has cognitive complexity 22 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 4 (9 pts), boolean chains 4 (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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcd74d82c8fabe6e1151cb1c61afceb3898a34147da5f4c645005068c11d1cfd"}},{"ruleId":"D2","level":"warning","message":{"text":"manual_bw.kernel_manual_compute_qacc_bw (cognitive 22): manual_bw.kernel_manual_compute_qacc_bw has cognitive complexity 22 (threshold 15). Drivers by points: loops 10 (22 pts) (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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"4237825a30e4aa708d8398de0ee3597f942b3ffb433728550249e52dc7a8f5fb"}},{"ruleId":"D2","level":"warning","message":{"text":"multi_contact.func_potential_mesh_normals (cognitive 22): multi_contact.func_potential_mesh_normals has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (15 pts), boolean chains 4, loops 2 (3 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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5bdb48d08dce125106a8bc31724dcfeaee0deaf53e84f72c920452182e2b61c"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_group_constraints_by_island (cognitive 22): island.func_group_constraints_by_island has cognitive complexity 22 (threshold 15). Drivers by points: loops 6 (11 pts), if/else 5 (10 pts), boolean chains 1 (nesting depth added 10). 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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"cde1c91ce21533a9723b406eaacdb792d504146167577a90712174456dc705b9"}},{"ruleId":"D2","level":"warning","message":{"text":"ConstraintSolver.get_weld_constraints (cognitive 22): ConstraintSolver.get_weld_constraints has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 4 (9 pts), ternaries 1 (2 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b0a4317e8f84c90750012225e86fe61279f06ea9aeb5ae4989050975b42d047"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_sim_controls (cognitive 22): ImGuiOverlayPlugin._render_sim_controls has cognitive complexity 22 (threshold 15). Drivers by points: if/else 13 (14 pts), ternaries 5 (7 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":504}}}],"partialFingerprints":{"codehealthFindingId/v1":"901a603e34e7d5f0d45ce8d18e95a450b45edf736a0ba009894943472a0a7376"}},{"ruleId":"D2","level":"warning","message":{"text":"types.build_entity_joint_data (cognitive 22): types.build_entity_joint_data has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 2 (4 pts), ternaries 1 (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":"genesis/ext/pyrender/overlay/types.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"bda06eda69e909c4e5bb889e4ee9c52dcf368f9e0e0719ccf582a5b153bff8e7"}},{"ruleId":"D2","level":"warning","message":{"text":"Viewer.on_close (cognitive 22): Viewer.on_close has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (12 pts), error handling 6 (7 pts), loops 2 (3 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"e50e3cc9a676aed4467f1ebf79160955a3e2372dbb47a1386b2d3660b8cf7b2a"}},{"ruleId":"D2","level":"warning","message":{"text":"Recorder.sync (cognitive 22): Recorder.sync has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (15 pts), ternaries 2 (4 pts), loops 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":"genesis/recorders/base_recorder.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc9c2dbc16568d2529e48f50328d3cccbbd9f57470be6c8a56f6e5ea53fd0851"}},{"ruleId":"D2","level":"warning","message":{"text":"array_class.get_constraint_state (cognitive 22): array_class.get_constraint_state has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 18, boolean chains 2, if/else 1, loops 1. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. 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":"genesis/utils/array_class.py"},"region":{"startLine":1041}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2edd0af65e913a911a7d9b9ae91dbf639c16c96b6d2e71db5bba8f7e27937bc"}},{"ruleId":"D2","level":"warning","message":{"text":"urdf.principal_axes_rot (cognitive 22): urdf.principal_axes_rot has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (13 pts), loops 5 (8 pts), 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":"genesis/utils/urdf.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a8bb4e4e890b8886cc35c313a678f54c9844dbeadf3f767b4b8eb44a4c99450"}},{"ruleId":"D2","level":"warning","message":{"text":"UsdContext.replace_asset_symlinks (cognitive 22): UsdContext.replace_asset_symlinks has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 4 (8 pts) (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":"genesis/utils/usd/usd_context.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"a833eb51a78a7b1d275d452b55adc5f711244aa742ef0fdb622f14e4adb8e0aa"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._setup_coupling_config (cognitive 21): IPCCoupler._setup_coupling_config has cognitive complexity 21 (threshold 15). Drivers by points: if/else 8 (19 pts), loops 2 (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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab7959e99edfe2f76b508433c795c61c6ed374c3a83b8cf056cc03025e0b588"}},{"ruleId":"D2","level":"warning","message":{"text":"Emitter.emit (cognitive 21): Emitter.emit has cognitive complexity 21 (threshold 15). Drivers by points: if/else 14 (19 pts), boolean chains 1, 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":"genesis/engine/entities/emitter.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"ded849aaa3643e1d479f1b9e7d632eeac721944a34e970466ed6d1eb5779eb28"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription.resolve (cognitive 21): KinematicEntityDescription.resolve has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (19 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"cffb1964558dfafb44eb2a87aacbe3ab33330a3582a825b15e61b78c3384c0d8"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidEntity.attach (cognitive 21): RigidEntity.attach has cognitive complexity 21 (threshold 15). Drivers by points: if/else 3 (8 pts), loops 3 (8 pts), ternaries 1 (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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1847}}}],"partialFingerprints":{"codehealthFindingId/v1":"c22fdb9529e2d92a7f3b8b1ee7a1e074014a13a2087dab34e39c01f300e68576"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSolver.one_pcg_iter (cognitive 21): FEMSolver.one_pcg_iter has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 7 (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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":790}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b99d304a0c94a1bce69bd1a4457dadfc2cf0390d1124c6d1534c004a0432899"}},{"ruleId":"D2","level":"warning","message":{"text":"MPMSolver.g2p (cognitive 21): MPMSolver.g2p has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (12 pts), loops 3 (8 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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ed641784ba4d5d65364e2cd9d20dbe5f6f335cc4c88be269ce2993cae4819a0"}},{"ruleId":"D2","level":"warning","message":{"text":"PBDSolver._kernel_solve_viscosity (cognitive 21): PBDSolver._kernel_solve_viscosity has cognitive complexity 21 (threshold 15). Drivers by points: loops 5 (14 pts), if/else 2 (6 pts), boolean chains 1 (nesting depth added 13). 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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":666}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e8d654dda6de162d6ab170afe7a5ffb2c07684bf61bd4285c70409770e0dab2"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_update_verts_for_geom (cognitive 21): forward_kinematics.func_update_verts_for_geom has cognitive complexity 21 (threshold 15). Drivers by points: loops 3 (11 pts), if/else 5 (10 pts) (nesting depth added 13). 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":830}}}],"partialFingerprints":{"codehealthFindingId/v1":"0174e9501271a8691b4794eeee893fc42f2be0a4de41ee9a59b4b2bab75cbfee"}},{"ruleId":"D2","level":"warning","message":{"text":"box_contact.func_plane_box_contact (cognitive 21): box_contact.func_plane_box_contact has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (18 pts), loops 1 (3 pts) (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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"458b12000683d54d683dd916e58423951af642bcdd592c7f67dec682e7725af7"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_safe_attach_face_to_polytope (cognitive 21): epa.func_safe_attach_face_to_polytope has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 2 (4 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":1327}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c5f00fe99e8fa1f4f54975dd5a4e0a95a280c56724190e4a58ef1378519af7b"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase._func_multicontact_accept (cognitive 21): narrowphase._func_multicontact_accept has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 1 (2 pts) (nesting depth added 14). 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3534}}}],"partialFingerprints":{"codehealthFindingId/v1":"c63da430169ba7934f71c6797d60b30e30707694a9a4fa57e6570862b3a3ec87"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver._set_dofs_info (cognitive 21): RigidSolver._set_dofs_info has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 2 (5 pts), loops 2 (4 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2593}}}],"partialFingerprints":{"codehealthFindingId/v1":"070a04617bacb20b2459831d7e59bf99a356ff90753d4a31e67e8bc3b43927ee"}},{"ruleId":"D2","level":"warning","message":{"text":"_trimesh_patch.parse_mtl (cognitive 21): _trimesh_patch.parse_mtl has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (14 pts), error handling 2 (6 pts), loops 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"032f3db08aade0c654fc1529ac55d6ebbe9699b1de8aa4a2aef585ba5815a2eb"}},{"ruleId":"D2","level":"warning","message":{"text":"_trimesh_patch._parse_vertices (cognitive 21): _trimesh_patch._parse_vertices has cognitive complexity 21 (threshold 15). Drivers by points: if/else 12 (15 pts), error handling 1 (3 pts), boolean chains 2, loops 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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":539}}}],"partialFingerprints":{"codehealthFindingId/v1":"3121ffada337e8a93525808ce3693f0d5e09fb3ed3dc057071db1f77d7ee0bff"}},{"ruleId":"D2","level":"warning","message":{"text":"JITRenderer.set_light (cognitive 21): JITRenderer.set_light has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (20 pts), 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"79f7d193d63f39adefdfbe3d996056b68ad373966538ceb3f94e6daf56a00fb2"}},{"ruleId":"D2","level":"warning","message":{"text":"Renderer._forward_pass (cognitive 21): Renderer._forward_pass has cognitive complexity 21 (threshold 15). Drivers by points: if/else 13 (17 pts), loops 1 (2 pts), boolean chains 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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"586038cbf18f5761e18556e7d9e39dd243a81317570274b732c03698f3f73808"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF._validate_graph (cognitive 21): URDF._validate_graph has cognitive complexity 21 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 6 (10 pts) (nesting depth added 10). 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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3770}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc6c789ad3924fe756b1933df9827db45fda91082db4d4981779228abca22664"}},{"ruleId":"D2","level":"warning","message":{"text":"BatchTexture.from_images (cognitive 21): BatchTexture.from_images has cognitive complexity 21 (threshold 15). Drivers by points: if/else 13 (17 pts), loops 2 (4 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":"genesis/options/textures.py"},"region":{"startLine":298}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5aaacbbd85a430305e2401b89204b9ae2fce92bc1c5cd0f77a0905675440a65"}},{"ruleId":"D2","level":"warning","message":{"text":"_main.launch (cognitive 20): _main.launch has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 2 (4 pts), ternaries 1 (3 pts), 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":"genesis/_main.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2d239026ca0746cce9d523d396d1c8d7288a353fbd16ad8508a2490565a0ae9"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_tower._auto_smooth (cognitive 20): generate_tower._auto_smooth has cognitive complexity 20 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 3 (9 pts) (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":"genesis/assets/tower/generate_tower.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"216617fac757ac5fac4d3b2032bc52b1f77af5de5ab40abe6d7134c2fca23f85"}},{"ruleId":"D2","level":"warning","message":{"text":"RaycasterSensor._update_raw_data (cognitive 20): RaycasterSensor._update_raw_data has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 4 (5 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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"26fe7478d3a5336ed387cfa9d0a2d1f4caa61a2b6be472b214e3b08038b8413c"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.kernel_init_link_fields (cognitive 20): misc.kernel_init_link_fields has cognitive complexity 20 (threshold 15). Drivers by points: loops 7 (14 pts), if/else 2 (3 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 9). 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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b39ddb2e30d804fda1b322c205b8890cf7f0d95ea1cbc3ed705aac0b55c2bec"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_cone_head_kinks (cognitive 20): linesearch.func_cone_head_kinks has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 4 (6 pts), ternaries 1 (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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dba2138305e5cbe4ae2c78f481f59a0de130f46b1d17766f6165a5a514b3b1e"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_wrap_cone_hessian (cognitive 20): solver.func_wrap_cone_hessian has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 2 (6 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2409}}}],"partialFingerprints":{"codehealthFindingId/v1":"1133bb86e464577a803ec4e0215e551c937ec9ee545249006fabed08fd30390c"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_update_cone_free_hessian_flip (cognitive 20): solver.func_update_cone_free_hessian_flip has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 2 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2549}}}],"partialFingerprints":{"codehealthFindingId/v1":"c18926bba119a8c830e43b348841d67814846eaa8fe36ce3573a8074192b27c3"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_solve_iter (cognitive 20): solver.func_solve_iter has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 1 (4 pts) (nesting depth added 13). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5760}}}],"partialFingerprints":{"codehealthFindingId/v1":"7847429ac5b6f9dd4b0bf9616f1c234d487d9b8c194aa4063a6a0637e42d99e7"}},{"ruleId":"D2","level":"warning","message":{"text":"solver_breakdown._func_update_qfrc_constraint_per_dof (cognitive 20): solver_breakdown._func_update_qfrc_constraint_per_dof has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (13 pts), loops 2 (5 pts), boolean chains 1, ternaries 1 (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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"3953cc30e2cf59070bcd1800282ce46d69f0a55f7d450583df7e71136790411e"}},{"ruleId":"D2","level":"warning","message":{"text":"solver_breakdown._func_islands_linesearch_and_apply (cognitive 20): solver_breakdown._func_islands_linesearch_and_apply has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (13 pts), ternaries 1 (4 pts), boolean chains 2, loops 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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d577cff340445c695624981da382a320b228cd3195590baaf3083819a70d642"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_visualization (cognitive 20): ImGuiOverlayPlugin._render_visualization has cognitive complexity 20 (threshold 15). Drivers by points: if/else 11 (13 pts), ternaries 3 (6 pts), boolean chains 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a279f19804f1f5e659923035aabf76f6f2b1baa8d0345be5abf35750e32d08f"}},{"ruleId":"D2","level":"warning","message":{"text":"Scene.__init__ (cognitive 20): Scene.__init__ has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (13 pts), loops 3 (7 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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"71b77b228c5a57febafb2e469bddc23699da83a019abf0022f8a0d2fe5d2af8f"}},{"ruleId":"D2","level":"warning","message":{"text":"array_class.check_data (cognitive 20): array_class.check_data has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (14 pts), ternaries 1 (3 pts), boolean chains 2, 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":"genesis/utils/array_class.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"7225a85729453580f4bac04bf27f3c0e09d4e2c98885c37329e8374d7959ef93"}},{"ruleId":"D2","level":"warning","message":{"text":"cache.get_hashkey (cognitive 20): cache.get_hashkey has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (10 pts), error handling 1 (3 pts), ternaries 1 (3 pts), boolean chains 2, loops 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":"genesis/utils/cache.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3a859b34fc588599427dc0162263ff5b1ac4d13e763833367f9b4a145d57958"}},{"ruleId":"D2","level":"warning","message":{"text":"mesh.surface_uvs_to_trimesh_visual (cognitive 20): mesh.surface_uvs_to_trimesh_visual has cognitive complexity 20 (threshold 15). Drivers by points: if/else 12 (18 pts), boolean chains 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":"genesis/utils/mesh.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"27626b892e8b4332820b52f93921bbc0e8f2d5be85674c73fcaff0c832bd38d2"}},{"ruleId":"D2","level":"warning","message":{"text":"serialization.declared_schema (cognitive 20): serialization.declared_schema has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (11 pts), loops 3 (7 pts), boolean chains 2 (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":"genesis/utils/serialization.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"f28e11c21fad6f773d1bdb7ab12a01e962d15acf9022abccf18f401b84e05ffd"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._neighbors (cognitive 20): watertighten._neighbors has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (14 pts), loops 3 (6 pts) (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":"genesis/utils/watertighten.py"},"region":{"startLine":569}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8b39ab62609c698e3c9f28c3cd64ca6a4485a9c3e9cfc0d585fbca60788c2ba"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._glue_manifold_corners (cognitive 20): watertighten._glue_manifold_corners has cognitive complexity 20 (threshold 15). Drivers by points: loops 4 (7 pts), if/else 2 (6 pts), ternaries 2 (6 pts), boolean chains 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":"genesis/utils/watertighten.py"},"region":{"startLine":1143}}}],"partialFingerprints":{"codehealthFindingId/v1":"d50f177ee216527b71766db45c195bb5e89b03b1fd564e9e33c942d4ba77acad"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.on_pbd (cognitive 20): RasterizerContext.on_pbd has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (15 pts), loops 2 (5 pts) (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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":807}}}],"partialFingerprints":{"codehealthFindingId/v1":"69afb3902372ce764b3cd2dc182293180726d4b343b12d78d597b46a18bf2cda"}},{"ruleId":"D2","level":"warning","message":{"text":"List.__repr__colorized__ (cognitive 19): List.__repr__colorized__ has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 3 (6 pts), error handling 1 (2 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":"genesis/datatypes.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4fa0c7b879a5db5ead2f812e85f5aeef72f3e9b1c2a96f5cd179e948ac4170e"}},{"ruleId":"D2","level":"warning","message":{"text":"SAPCoupler.rigid_solve_pcg (cognitive 19): SAPCoupler.rigid_solve_pcg has cognitive complexity 19 (threshold 15). Drivers by points: loops 7 (13 pts), if/else 3 (6 pts) (nesting depth added 9). 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1141}}}],"partialFingerprints":{"codehealthFindingId/v1":"d88fdad0821293e12ddf72c0a65a2d2c3c198d6b71e9fd54f82fc96addc80092"}},{"ruleId":"D2","level":"warning","message":{"text":"kinematic_tactile._func_query_contact_depth (cognitive 19): kinematic_tactile._func_query_contact_depth has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (13 pts), boolean chains 5, 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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c1b03e6e9edafa4ef46994a06c0f0c95e7327e9e9725779df6e12df67e8e236"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSolver._func_compute_ele_energy (cognitive 19): FEMSolver._func_compute_ele_energy has cognitive complexity 19 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 3 (7 pts) (nesting depth added 11). 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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e4e0019df70c4ce35a9bfc3b93e5e576815c2ec261c37879ce9322ece872ca1"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicSolver._init_tree_fields (cognitive 19): KinematicSolver._init_tree_fields has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (12 pts), loops 2 (5 pts), boolean chains 2 (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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"7708a3c0d4363c20719c38cc9769d3af632dbc8cd54160d1c767c1d27d53b9b7"}},{"ruleId":"D2","level":"warning","message":{"text":"box_contact.func_sphere_box_contact (cognitive 19): box_contact.func_sphere_box_contact has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), ternaries 3 (9 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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"8582019ffd8485e9b0c09ecc39e01dfccec3e94131d1bae6b53952f0d1011791"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_contact_is_before (cognitive 19): contact.func_contact_is_before has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 3 (4 pts), boolean chains 2 (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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":808}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a5b0bce07f2f865ba07abb8a78a1580d7406f95ec375e66b984f1ad81e1b040"}},{"ruleId":"D2","level":"warning","message":{"text":"contact.func_contact_group_by_normal (cognitive 19): contact.func_contact_group_by_normal has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (12 pts), loops 5 (7 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":896}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6bb4f4a8282ca34dd360f7ebc1df1c52a28348a610a133b3b6662e6798d89fd"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver._init_tree_fields (cognitive 19): RigidSolver._init_tree_fields has cognitive complexity 19 (threshold 15). Drivers by points: loops 6 (12 pts), if/else 2 (6 pts), boolean chains 1 (nesting depth added 10). 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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":953}}}],"partialFingerprints":{"codehealthFindingId/v1":"15aad789cc38a9865acab4e99b704f6e7ffefbadf085ebd412290c3e05a6f21f"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_joints_euler_mode (cognitive 19): ImGuiOverlayPlugin._render_joints_euler_mode has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (15 pts), loops 2 (3 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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":1213}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfc9b5e63455ff916b1a57e8e4d791989ca119dd79d66d8bf75babf727feef25"}},{"ruleId":"D2","level":"warning","message":{"text":"CSVFileWriter.process (cognitive 19): CSVFileWriter.process has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 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":"genesis/recorders/file_writers.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9a8b13aaab568b3e208fb1d8b6136457d719143d217340d55afe6db731b09d8"}},{"ruleId":"D2","level":"warning","message":{"text":"TrajectoryFileWriter.cleanup (cognitive 19): TrajectoryFileWriter.cleanup has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (17 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":"genesis/recorders/trajectory.py"},"region":{"startLine":957}}}],"partialFingerprints":{"codehealthFindingId/v1":"11f774345809f0b89bbab9a6de81564378ad316abf6ee47dc25787572ade470a"}},{"ruleId":"D2","level":"warning","message":{"text":"hybrid.reduce_graph (cognitive 19): hybrid.reduce_graph has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 4 (5 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":"genesis/utils/hybrid.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"81a639e287a9b2c6ec088ff9ad997ce95f75915a549d2f20fa62752331f2f87b"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.get_device (cognitive 19): misc.get_device has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 3 (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":"genesis/utils/misc.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"76e7782cba27c1c001656bf67aa1f94bbab1d147621fd4a73eeb3ed6a46f704a"}},{"ruleId":"D2","level":"warning","message":{"text":"BatchRenderer.render (cognitive 19): BatchRenderer.render has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 3, ternaries 2 (3 pts), loops 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":"genesis/vis/batch_renderer.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"628335f96c12347b1731c66c0c73249b1b2813a707807cec72bcc1682378596a"}},{"ruleId":"D2","level":"warning","message":{"text":"Camera.update_following (cognitive 19): Camera.update_following has cognitive complexity 19 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 2, loops 1, ternaries 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":"genesis/vis/camera.py"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f4b2e76dfe77635953da9fcfbccf0602446e62c94acf5ce22df31367094b645"}},{"ruleId":"D2","level":"warning","message":{"text":"Rasterizer.render_camera (cognitive 19): Rasterizer.render_camera has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 4, 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":"genesis/vis/rasterizer.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cad732474518a287788287fb06041d02062d27727bb747724b24bf4e13d6c83"}},{"ruleId":"D2","level":"warning","message":{"text":"Raycaster.__init__ (cognitive 19): Raycaster.__init__ has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 3 (4 pts), ternaries 2 (3 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":"genesis/vis/viewer_plugins/raycast.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fe67a5ea403580c162565fe0640dfe5fc20c15679f834b02e5c3521cc03e2a1"}},{"ruleId":"D2","level":"warning","message":{"text":"Visualizer.__init__ (cognitive 19): Visualizer.__init__ has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (15 pts), error handling 2 (3 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":"genesis/vis/visualizer.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"05bca4e570a88b8eac90841ae86737da0c19ea6d11bbabd36ce2c3850cda13f8"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._post_advance_external_articulation (cognitive 18): IPCCoupler._post_advance_external_articulation has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 3 (5 pts), ternaries 1 (2 pts) (nesting depth added 9). 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":959}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a62bbd4e5ba3738a5ac9373272566ddf08bb7df421aa45f197fb5a3234e16a"}},{"ruleId":"D2","level":"warning","message":{"text":"ParticleEntity.sample (cognitive 18): ParticleEntity.sample has cognitive complexity 18 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 1 (2 pts), boolean chains 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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcc81f46bd52ea754b8b7c2de9a580cf8bcf623532617250ac1d670e33bf654d"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicEntityDescription._resolve_inertial (cognitive 18): KinematicEntityDescription._resolve_inertial has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (12 pts), ternaries 1 (4 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1471}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fb14344374e6ff19660767d34985d070fb43e2530694e378f2eacca60d55f5d"}},{"ruleId":"D2","level":"warning","message":{"text":"point_cloud_tactile._kernel_elastomer_dilate_accumulate (cognitive 18): point_cloud_tactile._kernel_elastomer_dilate_accumulate has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 3 (7 pts) (nesting depth added 10). 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1260}}}],"partialFingerprints":{"codehealthFindingId/v1":"7827c52ab0c837cbd9e5b6f23f4024a827060b03b4d8a457afebbc5b6320439d"}},{"ruleId":"D2","level":"warning","message":{"text":"RaycastContext._static_entry_groups (cognitive 18): RaycastContext._static_entry_groups has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (13 pts), 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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbbdb14557d42fd56e8de6d3d3f5b42ebfa3bfb50cd61f81baedcb935be370b4"}},{"ruleId":"D2","level":"warning","message":{"text":"SensorManager.read_sensors (cognitive 18): SensorManager.read_sensors has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), ternaries 2 (6 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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":424}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1c87fe2d624fad11307f5a90da6435577f196ef6709592b77e6ebc759a0a4fe"}},{"ruleId":"D2","level":"warning","message":{"text":"temperature._qd_polygon_area_from_points_3d (cognitive 18): temperature._qd_polygon_area_from_points_3d has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 3 (4 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 8). 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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"3561eeeec252ca4d29c981565c433a6f71b2e70371681f117d751fc918db73b5"}},{"ruleId":"D2","level":"warning","message":{"text":"Simulator._add_entity (cognitive 18): Simulator._add_entity has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 3, loops 1 (2 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":"genesis/engine/simulator.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbde3d62e127ae9925d9a0d1017323a9493042f7d8babcce760df022608d40cd"}},{"ruleId":"D2","level":"warning","message":{"text":"KinematicSolver._init_link_fields (cognitive 18): KinematicSolver._init_link_fields has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 3 (7 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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":614}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e7f4244a3aa60d956c61f08aeb451d2eea39d38485b6dd139aeab8606e1e446"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_update_geoms (cognitive 18): forward_kinematics.func_update_geoms has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 3 (8 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":535}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca19ea8e8976e6f5a6c7db27643188710fadfda536fc415c3066d045cf73f6a"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_forward_velocity (cognitive 18): forward_kinematics.func_forward_velocity has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 3 (8 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"211da18c5b8933b7b211296b2e66e756e94fce14c09c54a36e933f79748ffd9b"}},{"ruleId":"D2","level":"warning","message":{"text":"epa.func_epa_init_polytope_2d (cognitive 18): epa.func_epa_init_polytope_2d has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (12 pts), loops 5 (6 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":432}}}],"partialFingerprints":{"codehealthFindingId/v1":"467e3e45094b0054c0c7ae4019d2b4d5dc2e1e1f9395f88ef13689d036685807"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrow_phase_diff_convex_vs_convex (cognitive 18): narrowphase.func_narrow_phase_diff_convex_vs_convex has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 2, 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4287}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d288e14e2aa563382f8e242b4ac2c9290ed6daf44bc736574f42a8ef4048869"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrow_phase_convex_specializations (cognitive 18): narrowphase.func_narrow_phase_convex_specializations has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (13 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4429}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf2048c234c0d903f94a8192ee6d7ed7114af1f89a0c8bee5b1ae82913918b6"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.kernel_get_equality_constraints (cognitive 18): solver.kernel_get_equality_constraints has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (10 pts), if/else 4 (8 pts) (nesting depth added 9). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d53609830fe453bdc0a5b831afab618c7be2547bdd3e8b5eaa5b0ef7963445b"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_rank_batch_update_island (cognitive 18): solver.func_rank_batch_update_island has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 2 (4 pts), ternaries 1 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3803}}}],"partialFingerprints":{"codehealthFindingId/v1":"e85044d8a6c6eefc5e27c23483c29ed9f5cbd5efcfdef26896d5453047975237"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_factor_island_incremental_batch (cognitive 18): solver.func_factor_island_incremental_batch has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 3 (4 pts), 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3847}}}],"partialFingerprints":{"codehealthFindingId/v1":"33c0b68f39cca1ea1fe511aa7ab6e2cfc5308fcbc87a6c3468528c44d6928e10"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._func_update_cost_coop (cognitive 18): solver._func_update_cost_coop has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 3 (5 pts), boolean chains 3 (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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5275}}}],"partialFingerprints":{"codehealthFindingId/v1":"16c7f1921438646640f9c9d396f0fb83e57d827afdc42bc724a629443a716fe8"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._initialize_Jaref_parallel (cognitive 18): solver._initialize_Jaref_parallel has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 3 (7 pts), ternaries 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5504}}}],"partialFingerprints":{"codehealthFindingId/v1":"2308994b5ca8cb0f7808f482b24ead846c361c517d0c42898a80018deffa582f"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.__init__ (cognitive 18): RigidSolver.__init__ has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (9 pts), ternaries 3 (5 pts), boolean chains 4 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5cdb3234e11a1a983a188f77646901f5d0f20ba520a1a765d8401c02d902b49"}},{"ruleId":"D2","level":"warning","message":{"text":"Renderer._normal_pass (cognitive 18): Renderer._normal_pass has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 2 (3 pts), ternaries 1 (3 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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7d992389a98910b95dabadd4a5f54dc546c5c88251ab1b225b00bd702666dd3"}},{"ruleId":"D2","level":"warning","message":{"text":"Joint.get_child_pose (cognitive 18): Joint.get_child_pose has cognitive complexity 18 (threshold 15). Drivers by points: if/else 12 (18 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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2292}}}],"partialFingerprints":{"codehealthFindingId/v1":"c72463c621165242f9e3bd5ca941fc5e968403c2495a2fb4b766471c2bedca1f"}},{"ruleId":"D2","level":"warning","message":{"text":"Link.collision_mesh (cognitive 18): Link.collision_mesh has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 2 (5 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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2588}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c03c38f86d73bec1758d8d930096886413584c6b7819470a4ec2c67916c3bc6"}},{"ruleId":"D2","level":"warning","message":{"text":"Tensor.__torch_function__ (cognitive 18): Tensor.__torch_function__ has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 2, error handling 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":"genesis/grad/tensor.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3dcf43dbfd4ce13265aed038e9f2b33a7f9927965312333900a30d78cb9f281"}},{"ruleId":"D2","level":"warning","message":{"text":"raycaster._generate_uniform_angles (cognitive 18): raycaster._generate_uniform_angles has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (13 pts), ternaries 1 (4 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":"genesis/options/sensors/raycaster.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"d97dcf467b71e5fc6a836cd0aed26309592749fb7a399acaec1d06ad538bb178"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.update_fem (cognitive 18): RasterizerContext.update_fem has cognitive complexity 18 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 3 (9 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":950}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4de08aa55e2348e476ce6caa95868e9083858f6110cfacca4b63dacc70d0362"}},{"ruleId":"D2","level":"warning","message":{"text":"Raytracer.add_surface (cognitive 18): Raytracer.add_surface has cognitive complexity 18 (threshold 15). Drivers by points: if/else 12 (13 pts), ternaries 3 (5 pts) (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":"genesis/vis/raytracer.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7f2147d4c18dcba023dfc045a6ead505bac725207a54b87a3b135068cff1bd6"}},{"ruleId":"D2","level":"warning","message":{"text":"Visualizer.update_visual_states (cognitive 18): Visualizer.update_visual_states has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (14 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":"genesis/vis/visualizer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"05626332673907dc27135de505d938512047b984d98c7c4d840bcbd36739ddf8"}},{"ruleId":"D2","level":"warning","message":{"text":"SAPCoupler.compute_fem_matrix_vector_product (cognitive 17): SAPCoupler.compute_fem_matrix_vector_product has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 4 (7 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1059}}}],"partialFingerprints":{"codehealthFindingId/v1":"500bab96bfedfdf43fdf402b5b401680c3ca319949483b4f7dd5f77547dd8405"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidRigidContactHandler.compute_jacobian (cognitive 17): RigidRigidContactHandler.compute_jacobian has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (11 pts), ternaries 2 (6 pts) (nesting depth added 10). 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2375}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2e030b768c8cd263a1b9d62d8f32f9431c9210999f68388dcdd17ebf88af3b6"}},{"ruleId":"D2","level":"warning","message":{"text":"Mesh.__init__ (cognitive 17): Mesh.__init__ has cognitive complexity 17 (threshold 15). Drivers by points: if/else 11 (15 pts), boolean chains 2 (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":"genesis/engine/mesh.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ee88091417aa818dbf6478c0090c7492344dc17d0568b37e4cc41ddc26048ca"}},{"ruleId":"D2","level":"warning","message":{"text":"ProbeSensorMixin.build (cognitive 17): ProbeSensorMixin.build has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (12 pts), ternaries 5 (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":"genesis/engine/sensors/probe.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"ded837486fdbce5d5f4dda4c3b46ddcaa8593ef73da39d1e7962760c79903bfe"}},{"ruleId":"D2","level":"warning","message":{"text":"kinematic_solver._fill_base_link_geom_offsets (cognitive 17): kinematic_solver._fill_base_link_geom_offsets has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (12 pts), ternaries 1 (3 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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e175dde5ff47c5a4ce881145367303152d99929b1f12df44e320945c28eab75"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_kinematics.func_COM_root (cognitive 17): forward_kinematics.func_COM_root has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (7 pts), ternaries 2 (6 pts), loops 2 (4 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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f84dff992fe21b1ae8c8c190a23bca6e502f5d1dbdef61d965a3a82092cf073"}},{"ruleId":"D2","level":"warning","message":{"text":"island.func_sort_contacts_coop (cognitive 17): island.func_sort_contacts_coop has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 3 (4 pts), boolean chains 3 (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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":946}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e1358cd7355170e94f513c3ba76b79ecb205f4261726a34dc7463a07efe60ec"}},{"ruleId":"D2","level":"warning","message":{"text":"linesearch.func_mv_jv_islands (cognitive 17): linesearch.func_mv_jv_islands has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (15 pts), if/else 1 (2 pts) (nesting depth added 11). 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce4ba160dead7c196ae3782d8357f9ad4d1a3390261dc9991972f8dc7cff5c06"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._func_disc_middle (cognitive 17): solver._func_disc_middle has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (13 pts), if/else 3 (4 pts) (nesting depth added 9). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4502}}}],"partialFingerprints":{"codehealthFindingId/v1":"05052da4bb3a8d57cd5073fb262997173398de0dc8aaf7387eb757235c9c8570"}},{"ruleId":"D2","level":"warning","message":{"text":"solver._func_cone_block_chol (cognitive 17): solver._func_cone_block_chol has cognitive complexity 17 (threshold 15). Drivers by points: loops 4 (12 pts), if/else 3 (5 pts) (nesting depth added 10). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4629}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffb55700d273ae1fa82a79d9f87d63b82e0608fbba46c4f47281c1e586388cf1"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidSolver.substep (cognitive 17): RigidSolver.substep has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 3 (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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1261}}}],"partialFingerprints":{"codehealthFindingId/v1":"799646bf366c68fa4254e7694fab1f307e44f915fac4ada201532935292a8f83"}},{"ruleId":"D2","level":"warning","message":{"text":"JITRenderer.update (cognitive 17): JITRenderer.update has cognitive complexity 17 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 4 (7 pts) (nesting depth added 9). 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a6e760107fb67c1baf4085540696a44a97d8f236b2e643d0b29f83c6a95c40d"}},{"ruleId":"D2","level":"warning","message":{"text":"EGLPlatform.init_context (cognitive 17): EGLPlatform.init_context has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 3, error handling 1 (2 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":"genesis/ext/pyrender/platforms/egl.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"31ab8cb144fb7ab31648a77f5a2b11ebf1373fe29d0be5354da0ac75b0105768"}},{"ruleId":"D2","level":"warning","message":{"text":"URDF.__init__ (cognitive 17): URDF.__init__ has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 6 (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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2692}}}],"partialFingerprints":{"codehealthFindingId/v1":"af59b7d79c5ad618386f1fbb08371ddc0c5e3c0139f3dd640488f339f5632a87"}},{"ruleId":"D2","level":"warning","message":{"text":"LinePlotHelper.__init__ (cognitive 17): LinePlotHelper.__init__ has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (8 pts), loops 2 (6 pts), ternaries 1 (3 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":"genesis/recorders/plotters.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"a45cc12924a2b535b7c2851ea3a6d5ba684be0a623e7c8bada05fe329b0cc319"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.qd_zero_grad (cognitive 17): misc.qd_zero_grad has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (10 pts), error handling 2 (6 pts), loops 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":"genesis/utils/misc.py"},"region":{"startLine":860}}}],"partialFingerprints":{"codehealthFindingId/v1":"67414d8a926a746643f496d3179539fe2cd4c26e3bcb253f717296131a350d65"}},{"ruleId":"D2","level":"warning","message":{"text":"raycast_qd.write_ray_hit (cognitive 17): raycast_qd.write_ray_hit has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (15 pts), boolean chains 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":"genesis/utils/raycast_qd.py"},"region":{"startLine":687}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc2e83027aa65a76b6b2454d0c755d17553656a65d7fc21c2085cf4bf7ba5f44"}},{"ruleId":"D2","level":"warning","message":{"text":"terrain.convert_heightfield_to_watertight_trimesh (cognitive 17): terrain.convert_heightfield_to_watertight_trimesh has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (9 pts), loops 7 (8 pts) (nesting depth added 2). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. 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":"genesis/utils/terrain.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5e7a20fec03e58722a903827357ef553d37258c0f57624729af5734695aff35"}},{"ruleId":"D2","level":"warning","message":{"text":"usd_rigid_entity._compute_joint_prim_paths (cognitive 17): usd_rigid_entity._compute_joint_prim_paths has cognitive complexity 17 (threshold 15). Drivers by points: ternaries 4 (8 pts), boolean chains 4, if/else 3 (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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c0f42eca654323c2004071e9a8c8319ec181d5cc62c0ef02de5041d0036ec5d"}},{"ruleId":"D2","level":"warning","message":{"text":"VideoEncoder.close (cognitive 17): VideoEncoder.close has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (7 pts), loops 2 (5 pts), error handling 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":"genesis/utils/video_encoder.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"599f6ec68018136e50b49cf4fcd0993b111f575693f2c840b19158d598b00e82"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.on_fem (cognitive 17): RasterizerContext.on_fem has cognitive complexity 17 (threshold 15). Drivers by points: loops 3 (9 pts), if/else 2 (4 pts), ternaries 1 (4 pts) (nesting depth added 11). 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":927}}}],"partialFingerprints":{"codehealthFindingId/v1":"218838f582eef260808013d6733008ed2cf27a8c876a92585f4f92e00efba8ca"}},{"ruleId":"D2","level":"warning","message":{"text":"IPCCoupler._pre_advance_external_articulation (cognitive 16): IPCCoupler._pre_advance_external_articulation has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 3 (7 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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":914}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a12442a75ccdd99b4e030edf97423d0b8b3423a60b5a462cebac13ee8942e15"}},{"ruleId":"D2","level":"warning","message":{"text":"RigidEntity.get_contacts (cognitive 16): RigidEntity.get_contacts has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 3, ternaries 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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":3126}}}],"partialFingerprints":{"codehealthFindingId/v1":"f497fe5549202c2038619036c5a4235d7d8da60f213695acb81f993bc1041772"}},{"ruleId":"D2","level":"warning","message":{"text":"Scene._reject_unexportable (cognitive 16): Scene._reject_unexportable has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (7 pts), ternaries 2 (6 pts), boolean chains 2, 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":"genesis/engine/scene.py"},"region":{"startLine":1575}}}],"partialFingerprints":{"codehealthFindingId/v1":"2412733dcaf388280d462ea77c7b7d7b64c4eac78dc38f4a60bc7f9c1a0b6533"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSolver.one_linesearch_iter (cognitive 16): FEMSolver.one_linesearch_iter has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 4 (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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":871}}}],"partialFingerprints":{"codehealthFindingId/v1":"26f0bb2e138202142449a875138211f72e73912af0dad219a19d327bcf51c9e5"}},{"ruleId":"D2","level":"warning","message":{"text":"FEMSolver._kernel_add_elements (cognitive 16): FEMSolver._kernel_add_elements has cognitive complexity 16 (threshold 15). Drivers by points: loops 10 (14 pts), if/else 1 (2 pts) (nesting depth added 5). 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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1142}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0ac90748e4cb3a2974ea877268c6d0718a8e410a2a6111e4fc695f694d77bd5"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_update_acc (cognitive 16): forward_dynamics.func_update_acc has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (6 pts), loops 2 (5 pts), ternaries 1 (4 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1684}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5907a1a8d2b38785044d01d44b3cfab66fe9632bf5b11adade66fc3f502ad41"}},{"ruleId":"D2","level":"warning","message":{"text":"forward_dynamics.func_compute_qacc (cognitive 16): forward_dynamics.func_compute_qacc has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (6 pts), loops 3 (6 pts), ternaries 1 (3 pts), 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1834}}}],"partialFingerprints":{"codehealthFindingId/v1":"b935ed6f21fc342bacf3b7191350562a3ee280002956c8a5486cd419b58cd60b"}},{"ruleId":"D2","level":"warning","message":{"text":"misc.func_apply_link_external_wrench (cognitive 16): misc.func_apply_link_external_wrench has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (16 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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":895}}}],"partialFingerprints":{"codehealthFindingId/v1":"f24d0822957a1e7bf842aa71095ab49146a170555af7177dcf30cebd442c1ef3"}},{"ruleId":"D2","level":"warning","message":{"text":"narrowphase.func_narrow_phase_convex_vs_convex (cognitive 16): narrowphase.func_narrow_phase_convex_vs_convex has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (10 pts), boolean chains 3, loops 2 (3 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4227}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff6100e58e0aa06be5be774df0ab50ed486a92a7eff1cb8a73ffc1d41a60ef33"}},{"ruleId":"D2","level":"warning","message":{"text":"noslip.func_noslip (cognitive 16): noslip.func_noslip has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 1, ternaries 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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":549}}}],"partialFingerprints":{"codehealthFindingId/v1":"0492adcd03ee809f92c447c1970be31ce05e8e3340be8e7f9647d24ba6eb2f47"}},{"ruleId":"D2","level":"warning","message":{"text":"solver.func_qfrc_scatter_sparse (cognitive 16): solver.func_qfrc_scatter_sparse has cognitive complexity 16 (threshold 15). Drivers by points: loops 4 (11 pts), if/else 3 (5 pts) (nesting depth added 9). 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":4993}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5774c295ade5887ccfcbb966b2cb57de2fe1f554adec9a98d826c06ac928c2"}},{"ruleId":"D2","level":"warning","message":{"text":"solver_breakdown._func_islands_update_search_direction (cognitive 16): solver_breakdown._func_islands_update_search_direction has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (13 pts), boolean chains 2, 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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cffc6b0c367e422257b42d3158a632946fcaa0de99b7d66ac85677378c11810"}},{"ruleId":"D2","level":"warning","message":{"text":"ImGuiOverlayPlugin._render_control_panel (cognitive 16): ImGuiOverlayPlugin._render_control_panel has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 3 (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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"35e06a77ec553f5e0b170726f627c06db4191b3688bb0aa5cc7937496e329871"}},{"ruleId":"D2","level":"warning","message":{"text":"Texture._add_to_context (cognitive 16): Texture._add_to_context has cognitive complexity 16 (threshold 15). Drivers by points: if/else 13, boolean chains 3. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. 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":"genesis/ext/pyrender/texture.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"957d4da794cd70f6c735a3708a856ebde2722a5f71e5419face54b7336f3fcc0"}},{"ruleId":"D2","level":"warning","message":{"text":"Viewer._setup_main_camera (cognitive 16): Viewer._setup_main_camera has cognitive complexity 16 (threshold 15). Drivers by points: if/else 12 (15 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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":434}}}],"partialFingerprints":{"codehealthFindingId/v1":"2787d1019540b4726e7081bdeb469b927b0aa7b0c35689fb3730101042bdc4e8"}},{"ruleId":"D2","level":"warning","message":{"text":"MPLVectorFieldPlotter.build (cognitive 16): MPLVectorFieldPlotter.build has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (5 pts), loops 3 (5 pts), ternaries 3 (4 pts), boolean chains 2 (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":"genesis/recorders/plotters.py"},"region":{"startLine":726}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0d02b33c5222c945089896f37b1d3a6c746055a1d544658b98ddea7b37e5e26"}},{"ruleId":"D2","level":"warning","message":{"text":"Trajectory.play (cognitive 16): Trajectory.play has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 4, loops 2 (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":"genesis/recorders/trajectory.py"},"region":{"startLine":1257}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dcc4e2ccc6d7f8f498de6adbcb30429a782820d4ad868ff37b41d3fad65c251"}},{"ruleId":"D2","level":"warning","message":{"text":"collision.solve_contype_conaffinity (cognitive 16): collision.solve_contype_conaffinity has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (7 pts), loops 3 (6 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":"genesis/utils/collision.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b926e41728476991a5bb10e83b7d23354afc62cd768073c8d51e24b6560524c"}},{"ruleId":"D2","level":"warning","message":{"text":"mesh.create_box (cognitive 16): mesh.create_box has cognitive complexity 16 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 4 (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":"genesis/utils/mesh.py"},"region":{"startLine":1149}}}],"partialFingerprints":{"codehealthFindingId/v1":"89b913ac51cf46f99ed228229e0b5c8468124b7c8277c8f7d1fd5a3c0a2de7d6"}},{"ruleId":"D2","level":"warning","message":{"text":"particle.particles_to_mesh (cognitive 16): particle.particles_to_mesh has cognitive complexity 16 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 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":"genesis/utils/particle.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d3b026ba102aa9d15c00c5a2982587b3da4c5c69dab0304b4868494fdc8b42a"}},{"ruleId":"D2","level":"warning","message":{"text":"PathPlanner.interpolate_path (cognitive 16): PathPlanner.interpolate_path has cognitive complexity 16 (threshold 15). Drivers by points: loops 6 (14 pts), if/else 1 (2 pts) (nesting depth added 9). 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":"genesis/utils/path_planning.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"8701bfbb621c4ade757f8e363ebfa62969a84df6aa4f1581c32b24b10bfeb1b9"}},{"ruleId":"D2","level":"warning","message":{"text":"watertighten._extract_dual_contour_mesh (cognitive 16): watertighten._extract_dual_contour_mesh has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (10 pts), loops 3 (6 pts) (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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/watertighten.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"a56b11bbc849b0ab1efc8e8645d513b7e12fa925d38ba8c93fe909f41b4e268f"}},{"ruleId":"D2","level":"warning","message":{"text":"RasterizerContext.on_rigid (cognitive 16): RasterizerContext.on_rigid has cognitive complexity 16 (threshold 15). Drivers by points: if/else 2 (7 pts), loops 3 (6 pts), ternaries 1 (3 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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":516}}}],"partialFingerprints":{"codehealthFindingId/v1":"efa9720b8aaa43ba1b6eb7732d297aed003e0c23618571002bafcfd398eb3e6e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: constraint/solver.py: FileTooLong \u2014 4413 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 3913 over it, 8.83\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"32381c7a9bb82de552894d8aeec54d3e8d3ce2fc4edfbd210a7023298b90c96f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/narrowphase.py: FileTooLong \u2014 3658 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 3158 over it, 7.32\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbf7d0fae1e5b2d2a7ada42360b19028232883ec5167981a6d42362c0cbd9926"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: couplers/sap_coupler.py: FileTooLong \u2014 3161 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 2661 over it, 6.32\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8805506ad84a4d13cab6021bbc91138814d9e8ed08e26f2eb08bd6c6d6f74354"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: rigid/rigid_solver.py: FileTooLong \u2014 2623 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 2123 over it, 5.25\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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0f9ce3bb1e3c93ccb1fbd97975086a06f18ba4b75c65c5971f9491ed516261b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/array_class.py: FileTooLong \u2014 2248 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1748 over it, 4.50\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":"genesis/utils/array_class.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"437a6bd5f37bbe98170a5c3356f8cf1a15f5cbeeefc42bc9aa73eb972277c9ce"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: RigidSolver: TooManyMethods \u2014 126 methods. The bar is 30 methods; this is 96 over it, 4.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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"e50286aa8092268afb0d560800c9a714620986bcc10ad3c660409d549f6128ec"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: urdfpy/urdf.py: FileTooLong \u2014 2099 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1599 over it, 4.20\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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f17bff22cf9220629f65d197dc16f07e9028dbbb966ee39c6eb790ea27df29a8"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SAPCoupler: TooManyMethods \u2014 113 methods. The bar is 30 methods; this is 83 over it, 3.77\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"920eb37bd03d8f5de0df7008f3764829851e328764be46b64a6e766121345006"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: sensors/point_cloud_tactile.py: FileTooLong \u2014 1797 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1297 over it, 3.59\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b87501b65632326f0e162846bfdc01065c034615abb9ee21b1615fca0f2237a0"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: abd/forward_dynamics.py: FileTooLong \u2014 1783 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1283 over it, 3.57\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5527f8f1b19789ca092c52c84a9f74f7e85c528bad3284669858f6d7d0f6117f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/geom.py: FileTooLong \u2014 1571 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1071 over it, 3.14\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":"genesis/utils/geom.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"08c55d3c0bff592d6b54697829e22b6a022b258f62806ec38a11361cfc442443"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: rigid_entity/rigid_entity.py: FileTooLong \u2014 1568 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1068 over it, 3.14\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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf158e21c0b56e66eab595006d475475220a4d00358ea2800dc991dec323a69c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: solvers/kinematic_solver.py: FileTooLong \u2014 1353 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 853 over it, 2.71\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbc9574ff5345f73e89faec007fda401c4e559e9e657779e17fe0dd9ea108acd"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: constraint/linesearch.py: FileTooLong \u2014 1314 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 814 over it, 2.63\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f6d48956703fdc0f7e9b2c5529d5c0749155653f6f19168552743c9a69ac2ea"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: FEMSolver: TooManyMethods \u2014 76 methods. The bar is 30 methods; this is 46 over it, 2.53\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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"a45d16bf83b327d950115ac13a7d2b55b7a164836303d3d2438a1cce6feaf3d9"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/contact.py: FileTooLong \u2014 1262 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 762 over it, 2.52\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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ef87354f232b576046030a2a2ce315ef6d7b7fe5ac8d514039d7cdd10c6669f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: RigidEntity: TooManyMethods \u2014 75 methods. The bar is 30 methods; this is 45 over it, 2.50\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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1738}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc0f9a73849dabf59c84be087ff5ee90553610a1f92fe788a7807bcffda23a5b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pyrender/jit_render.py: FileTooLong \u2014 1193 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 693 over it, 2.39\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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f920ffbd54bf2c9e858a656c5e8dec2c864a6f1525ca604b86a9f8b2c8fbf27"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: rigid_entity/description.py: FileTooLong \u2014 1183 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 683 over it, 2.37\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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8982c3d931220dd478e68ca9da68fb9fb8f24f146033d3949f7e8d832eb6c4c7"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: solvers/fem_solver.py: FileTooLong \u2014 1177 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 677 over it, 2.35\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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"17f1c4b974330a2023f3601b8e9f7ae289fa16663979bbb10b530ca717d2e37b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/gjk.py: FileTooLong \u2014 1136 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 636 over it, 2.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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5b902a20d3c7b45c81efd7b4adf855adf67b2c2a9209d178197bfc5332ad0c0"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: MPMSolver: TooManyMethods \u2014 67 methods. The bar is 30 methods; this is 37 over it, 2.23\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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3cc4aa41a4554097c36ea2b2ac9cb1ad7beffff3a0d7e941167e017e919407f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: RasterizerContext: TooManyMethods \u2014 67 methods. The bar is 30 methods; this is 37 over it, 2.23\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0317d8535c2fe70a36061fe0ca3d6f0a809b6374aa2ad4a8452b4ca4020eafe"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: abd/accessor.py: FileTooLong \u2014 1115 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 615 over it, 2.23\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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b214544bf2f4ba88a37574b74b097591fc652809aa8803da08ba299deb01be4b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: sensors/kinematic_tactile.py: FileTooLong \u2014 1079 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 579 over it, 2.16\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1addc48e2b20ba92cdd542bfb1e681658bc5b1b38be60a9e9e50fc1d1c5baad7"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: KinematicSolver: TooManyMethods \u2014 63 methods. The bar is 30 methods; this is 33 over it, 2.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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaaa7ea11829bfaba2cef55a1b07d2ff2d24ba27d352ed997740c1540c2d236f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SPHSolver: TooManyMethods \u2014 61 methods. The bar is 30 methods; this is 31 over it, 2.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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8157684cda9b6b165553ccd72db59bf20f763873ddf6976108b5c174c9d2419"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: solvers/mpm_solver.py: FileTooLong \u2014 1002 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 502 over it, 2.00\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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c57dd0a23bed2deea3276c7053856ccb8e4edf89a69a3cb45dcd25dad20e73da"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Scene: TooManyMethods \u2014 60 methods. The bar is 30 methods; this is 30 over it, 2.00\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":"genesis/engine/scene.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"b83520ed7ba17484c06e0732e6273b18b586914f69243323f1d3c37f7ba46d4f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/collider.py: FileTooLong \u2014 994 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 494 over it, 1.99\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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b350c686ba619070049c4e0a9b238736203a4d476a7cdf55cf4edd2e6f9e8d29"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/mesh.py: FileTooLong \u2014 980 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 480 over it, 1.96\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":"genesis/utils/mesh.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2eceec37cba346fc87482774de8754ed4eceb0f495e652518848bff14a34397"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/epa.py: FileTooLong \u2014 969 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 469 over it, 1.94\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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6498c32b6d9ecd609aaa4b824f9f013003dd1f1bf96875f4aff021ec7b0524e2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: vis/rasterizer_context.py: FileTooLong \u2014 960 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 460 over it, 1.92\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a81a31bf8b9d26ec1dc58ea75809d6f07c7dea051e440047ada3b531201e04d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: abd/forward_kinematics.py: FileTooLong \u2014 956 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 456 over it, 1.91\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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"135ecfe75fa9639520de4e02d630ab552f075e872615f5838538a4fdeb4da560"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pyrender/viewer.py: FileTooLong \u2014 937 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 437 over it, 1.87\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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e25bf71ae20779772c799d2dd1fcb211aac02334f75e427ced39e555d590ee14"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: engine/scene.py: FileTooLong \u2014 917 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 417 over it, 1.83\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":"genesis/engine/scene.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9120c0cee040f4c364b69bbbd6d9e726830fbc7ebc76725329c26726247f1a46"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/watertighten.py: FileTooLong \u2014 916 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 416 over it, 1.83\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":"genesis/utils/watertighten.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21d2dcb5cc5aac1f4abed2685403285d6714e94f49e6c716342ce945449aea6c"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: PBDSolver: TooManyMethods \u2014 54 methods. The bar is 30 methods; this is 24 over it, 1.80\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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"1214755ea1309291c7b2c7fdc2ccf46cf44f98f4f2fd4865480e027aa1a190ad"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: overlay/plugin.py: FileTooLong \u2014 898 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 398 over it, 1.80\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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e78a81d245e1983935babf15c1593ecee6d23ac73c5daca20a9ea6ae4990c256"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/path_planning.py: FileTooLong \u2014 869 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 369 over it, 1.74\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":"genesis/utils/path_planning.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"42dfe9c0c5b1efc3ca5b23e99826c656c77853aa8bb00632545f74ade7b7ae89"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: recorders/trajectory.py: FileTooLong \u2014 865 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 365 over it, 1.73\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":"genesis/recorders/trajectory.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a5c055ab501c059ec823671c5124cf1d075128ec6ce85b9a10a1ee613f78a1d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: solvers/pbd_solver.py: FileTooLong \u2014 810 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 310 over it, 1.62\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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"31560b73a6f5cb2a93f77cade46ed2ab36072b204440e896d8cd3987093bf46b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: constraint/island.py: FileTooLong \u2014 800 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 300 over it, 1.60\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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"27fc8f7c7ed9ab38fd801802a36c2c0e127bb8680911fe44a2c62894abb463ff"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: abd/misc.py: FileTooLong \u2014 787 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 287 over it, 1.57\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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5102eea4d4c63211ffd92018fa4d377d69063970e045b74b85f18fce7c4c07b9"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: KinematicEntity: TooManyMethods \u2014 47 methods. The bar is 30 methods; this is 17 over it, 1.57\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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b163914c039cc5864068feefe46bef6ffc61ede26d12c34b370dc26803c252f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/misc.py: FileTooLong \u2014 780 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 280 over it, 1.56\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":"genesis/utils/misc.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"23bc9aad3a686c35ed3ab24119a43d86402e0c4a16a68b54445a14906dcf5289"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Viewer: TooManyMethods \u2014 46 methods. The bar is 30 methods; this is 16 over it, 1.53\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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bb123527486b46458316cac7b5ee75714ca9c957410f5c79c64a128ddb9f514"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ToolEntity: TooManyMethods \u2014 45 methods. The bar is 30 methods; this is 15 over it, 1.50\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":"genesis/engine/entities/tool_entity/tool_entity.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d722033701e115f1186e5e1f9cbe0678cc59377bb960367d7a0018149867326"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/multi_contact.py: FileTooLong \u2014 741 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 241 over it, 1.48\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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"71518055effba8f170c449507a616016d1e7bd69edefa2478b34215f0c1a64df"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: ipc_coupler/coupler.py: FileTooLong \u2014 708 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 208 over it, 1.42\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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b84423c0b2dc9e6c55491411d4314a31d3f5cbcb5d04802c56c90186f3d772c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pyrender/renderer.py: FileTooLong \u2014 704 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 204 over it, 1.41\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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48ae4d18245d428672965f2777ff9b66cc49dfb04ea92f5751461e5803cff8fc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: sensors/temperature.py: FileTooLong \u2014 697 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 197 over it, 1.39\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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a4233b4aa646b3c06213e3ad7e6cc3625e1d38dcb1c65bd860d2fcd6639471f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: couplers/legacy_coupler.py: FileTooLong \u2014 694 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 194 over it, 1.39\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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c933b9b202792997d97da2433997f0d56cc3215c4e77e5ccaabed0a76b1a58af"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: solvers/sph_solver.py: FileTooLong \u2014 685 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 185 over it, 1.37\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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa0ea141f71b3acf1bcb4e547b0a0289dafa1eda7d1f7b076174eb6aad713ed2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/raycast_qd.py: FileTooLong \u2014 670 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 170 over it, 1.34\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":"genesis/utils/raycast_qd.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c62fbc702eae3290745cc24daec80ac0f6587ceea320bbf0cadd5e4c5cec408b"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: FEMEntity: TooManyMethods \u2014 40 methods. The bar is 30 methods; this is 10 over it, 1.33\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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9bea478a17214b1586bd28ef3f25eb9d8d4a837bb11e206ea2662c26f87b458"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: engine/mesh.py: FileTooLong \u2014 665 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 165 over it, 1.33\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":"genesis/engine/mesh.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"79353f708221d485812a27d23d5f48a2bf9a1196f7d4e729c75eb9913234be52"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/diff_gjk.py: FileTooLong \u2014 647 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 147 over it, 1.29\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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"285d58cfdde4021c318bb0c75851ebca15571977caffda1b635f6b4dc768126e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: vis/raytracer.py: FileTooLong \u2014 641 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 141 over it, 1.28\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":"genesis/vis/raytracer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1231feeb14676e441f1f05556e73e0925a8add4f21baf7922d175531726f81f9"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/box_contact.py: FileTooLong \u2014 638 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 138 over it, 1.28\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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"df95753f47c75b6f6bcb4848d55bcc6af837cd8a5c18e79552641bd06cd944a7"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: MPMEntity: TooManyMethods \u2014 38 methods. The bar is 30 methods; this is 8 over it, 1.27\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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"99c11af81d865616ab5be78b368015fd3ae45c861880d57731a70e7d79f554b7"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: abd/inverse_kinematics.py: FileTooLong \u2014 628 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 128 over it, 1.26\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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01566a1c34ed31070298af7f39a206aac41830e2493f752be133222b598e2bbc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: constraint/backward.py: FileTooLong \u2014 625 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 125 over it, 1.25\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"237db27b318963004539ebd8f970577db86f99a93ed27544c6d3a26ac230564e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: utils/mjcf.py: FileTooLong \u2014 625 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 125 over it, 1.25\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":"genesis/utils/mjcf.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b41871989249f24a313bc3c9cea29501c52ec8cceef9faff8444592e0a6a1835"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: vis/camera.py: FileTooLong \u2014 620 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 120 over it, 1.24\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":"genesis/vis/camera.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6002269b0752889ae21cae99a70b1fdd606d69815edb28c916543059e824c277"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: entities/fem_entity.py: FileTooLong \u2014 618 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 118 over it, 1.24\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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"61517a2ab9fd0a47f47142e9d25f16967e10a22b5102146e4e8d41c0a9d778f3"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ParticleEntity: TooManyMethods \u2014 37 methods. The bar is 30 methods; this is 7 over it, 1.23\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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"c24542f720e934895d063daf1db9079674b02c2528dd01ea15235aa5b60d8d72"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: recorders/plotters.py: FileTooLong \u2014 599 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 99 over it, 1.20\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":"genesis/recorders/plotters.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3aefa78799ea9cdba401ba83b371b0c907ef31a9fdf4d47f265c3911ddd6383c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: collider/mpr.py: FileTooLong \u2014 595 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 95 over it, 1.19\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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d63b718ac7077604a387775072d96d1fdc6ec5a2d6a97937aac9c8ad786166e3"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Renderer: TooManyMethods \u2014 34 methods. The bar is 30 methods; this is 4 over it, 1.13\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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"8edbac082b1b87c937bb3949620049cff029be5c38016955012d0858303c5401"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Simulator: TooManyMethods \u2014 32 methods. The bar is 30 methods; this is 2 over it, 1.07\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":"genesis/engine/simulator.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"79cbee154c873946116d15b2baabdcefeb79034be24fdbe75b0e2cd833a2f88c"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ImGuiOverlayPlugin: TooManyMethods \u2014 32 methods. The bar is 30 methods; this is 2 over it, 1.07\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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"a34e08c9451ef9661c51bf9c8413e3d1f93e5f8ffe056f53c895cbce6c1087ce"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: usd/usd_rigid_entity.py: FileTooLong \u2014 516 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 16 over it, 1.03\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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7810e93174bae602b63bdae2dce22573101a437e1d500c116a6685d1d3b9da9d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: sensors/camera.py: FileTooLong \u2014 514 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 14 over it, 1.03\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":"genesis/engine/sensors/camera.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb1708747d7781267ecbdd23d3f2f69ebee6105b8e56bde9758041b680eb791a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: sensors/tactile_shared.py: FileTooLong \u2014 512 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 12 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":"genesis/engine/sensors/tactile_shared.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f99efb97394dc4b9b3a6143dc0d0e8213da2ea637ae651ac8fc8312fe51d865b"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (3 members, 34 shared lines): genesis/engine/solvers/rigid/collider/diff_gjk.py:362-550 | genesis/engine/solvers/rigid/collider/epa.py:45-221 | genesis/engine/solvers/rigid/collider/epa.py:976-1212 \u2014 These 3 members are variants of one another: a block of 34 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 3 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1c0c685ee4c8514bb5cfecf76377364405dcb81b91cb590cea807722a6b981"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (3 members, 33 shared lines): genesis/engine/couplers/sap_coupler.py:2844-2975 | genesis/engine/couplers/sap_coupler.py:3509-3620 | genesis/engine/couplers/sap_coupler.py:3851-3985 \u2014 These 3 members are variants of one another: a block of 33 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 3 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2844}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a99b7697cf1c89d567d52c03a7a62a0ddd177785ccdbcb57b4d2880805e697"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (134 shared lines): genesis/engine/solvers/rigid/collider/contact.py:1153-1442 | genesis/engine/solvers/rigid/collider/contact.py:1453-1776 \u2014 These two members are variants of one another: 134 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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1153}}}],"partialFingerprints":{"codehealthFindingId/v1":"56b3e1b5e9e954c5432bad6ffde8a3708482a155a3e4f667aa1a0c8d343a3258"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (85 shared lines): genesis/engine/solvers/rigid/collider/narrowphase.py:101-593 | genesis/engine/solvers/rigid/collider/narrowphase.py:617-995 \u2014 These two members are variants of one another: 85 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"8968e89042e3626201ed0327a246b80421c56b643de6a409eba92e87f8eba4ef"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (83 shared lines): genesis/utils/path_planning.py:526-661 | genesis/utils/path_planning.py:909-1062 \u2014 These two members are variants of one another: 83 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":"genesis/utils/path_planning.py"},"region":{"startLine":526}}}],"partialFingerprints":{"codehealthFindingId/v1":"47df198c297d5a38fbc5ba6c0182387335a824ad899a80ae19ae0d527c5500a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (64 shared lines): genesis/engine/solvers/rigid/collider/narrowphase.py:3040-3159 | genesis/engine/solvers/rigid/collider/narrowphase.py:3972-4223 \u2014 These two members are variants of one another: 64 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3040}}}],"partialFingerprints":{"codehealthFindingId/v1":"9501cff4e4402b878a04cd1bdeac4a709f8fb78061efb2bb27ec696b94dc1a49"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (62 shared lines): genesis/utils/path_planning.py:387-463 | genesis/utils/path_planning.py:737-829 \u2014 These two members are variants of one another: 62 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":"genesis/utils/path_planning.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5d0c66bf4f7bec3b0823ce592037187f96e051fb9ccf1ff723fa15215555d46"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (52 shared lines): genesis/engine/solvers/rigid/constraint/linesearch.py:773-897 | genesis/engine/solvers/rigid/constraint/linesearch.py:970-1101 \u2014 These two members are variants of one another: 52 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f802d7782a86a25d8f7d7a7a6aadd4cda1b80a91f7eb2bd7420b2f84f5f821b"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (24 shared lines): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1004-1058 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1070-1116 \u2014 These two members are variants of one another: 24 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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1004}}}],"partialFingerprints":{"codehealthFindingId/v1":"d691316d4bebaffa4e3b15ecec041669fbdf38a2b17a6f4b0f9555d2bdaa751c"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (45 corresponding lines): genesis/engine/sensors/kinematic_tactile.py:552-613 | genesis/engine/sensors/point_cloud_tactile.py:1077-1138 \u2014 These two members are one piece of code written twice and then edited apart: 45 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":552}}}],"partialFingerprints":{"codehealthFindingId/v1":"be74563cbbc90b955541c482a96249956aba2ac62d430b279099a370393bfe25"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (33 corresponding lines): genesis/utils/tools.py:78-110 | genesis/utils/tools.py:113-146 \u2014 These two members are one piece of code written twice and then edited apart: 33 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/tools.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"feb9c7893312702eca9d048ee042e8d5e21daf4674128125c3599b636069efcb"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (14 corresponding lines): genesis/engine/entities/rigid_entity/rigid_entity.py:857-889 | genesis/engine/entities/rigid_entity/rigid_link.py:171-192 \u2014 These two members are one piece of code written twice and then edited apart: 14 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":857}}}],"partialFingerprints":{"codehealthFindingId/v1":"657b2a2bd105bcb49f1314b385192febbd5148781109d1de588005b6ae8f96dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (15 corresponding lines): genesis/utils/path_planning.py:360-375 | genesis/utils/path_planning.py:707-723 \u2014 These two members are one piece of code written twice and then edited apart: 15 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/path_planning.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"1058049faecd3d2133fd4a9d25e3b7d375cc859e624e58dfd6b8082bb0f3b825"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (12 corresponding lines): genesis/engine/sensors/kinematic_tactile.py:990-1001 | genesis/engine/sensors/kinematic_tactile.py:1236-1268 \u2014 These two members are one piece of code written twice and then edited apart: 12 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1e3d2cf4c78e8aa97469a9d88057eccb95a4fd89aee030f1bb812f6f2658a75"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/abd/accessor.py:42-60 | genesis/engine/solvers/rigid/abd/accessor.py:74-92 | genesis/engine/solvers/rigid/abd/accessor.py:107-131 | genesis/engine/solvers/rigid/abd/accessor.py:147-175 | genesis/engine/solvers/rigid/abd/accessor.py:188-206 \u2014 These 5 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 5 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0855633f0a3556f5fb49b1da639c3ab479624ba4aafe743b108cbb709ffafa2"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/abd/forward_kinematics.py:543-566 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:775-810 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1149-1235 | genesis/engine/solvers/rigid/abd/manual_bw.py:245-267 | genesis/engine/solvers/rigid/abd/manual_bw.py:432-449 \u2014 These 5 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 5 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bac2581de2cd077644781247c84ae77567fa54e0929b73987e40ab0e6cddce0"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/constraint/backward.py:454-642 | genesis/engine/solvers/rigid/constraint/backward.py:791-1478 | genesis/engine/solvers/rigid/constraint/solver.py:710-867 | genesis/engine/solvers/rigid/constraint/solver.py:924-1089 | genesis/engine/solvers/rigid/constraint/solver.py:1782-1834 \u2014 These 5 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 5 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"b72df5445a4d6478ab6aff16ed2cb567fa65b610e61e89b5436466fc62767f9f"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/couplers/sap_coupler.py:2694-2702 | genesis/engine/couplers/sap_coupler.py:2706-2714 | genesis/engine/couplers/sap_coupler.py:3024-3044 | genesis/engine/couplers/sap_coupler.py:3048-3068 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2694}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d4298ec887392cb1d729d97fd91dd4e99632835c444a2721fcb79b877361705"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/couplers/sap_coupler.py:3193-3207 | genesis/engine/couplers/sap_coupler.py:3252-3277 | genesis/engine/couplers/sap_coupler.py:3407-3438 | genesis/engine/couplers/sap_coupler.py:3746-3777 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3193}}}],"partialFingerprints":{"codehealthFindingId/v1":"2146f657f98e8793928f02eaddb6d4f2f69d6cb7929670e84a5ee5a5fb0e494b"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/sensors/kinematic_tactile.py:326-431 | genesis/engine/sensors/kinematic_tactile.py:453-499 | genesis/engine/sensors/kinematic_tactile.py:722-787 | genesis/engine/sensors/kinematic_tactile.py:819-951 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"636f19b68c496f5c972c8b0272a6fa77fa859de2df6178b9cbc317e069db9b15"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/sensors/point_cloud_tactile.py:375-566 | genesis/engine/sensors/point_cloud_tactile.py:1358-1489 | genesis/engine/sensors/point_cloud_tactile.py:1522-1662 | genesis/engine/sensors/surface_distance_probe.py:188-298 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"19d23343ec61725953787e816435d657a7ce81d0ef806d4e55b131db937a4b94"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/abd/accessor.py:219-231 | genesis/engine/solvers/rigid/abd/accessor.py:336-350 | genesis/engine/solvers/rigid/abd/accessor.py:363-375 | genesis/engine/solvers/rigid/abd/accessor.py:388-402 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"50ce66893473587b5d5c74426fa40f89148b22d55b99b2975a16dfccb08763ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/collider/epa.py:448-574 | genesis/engine/solvers/rigid/collider/epa.py:593-718 | genesis/engine/solvers/rigid/collider/epa.py:725-803 | genesis/engine/solvers/rigid/collider/epa.py:1281-1323 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"011bfd42ad6b8bec356f7c8c42c85bfc6b2dcf319fb56e4bd4246d656763ec22"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/collider/narrowphase.py:4242-4283 | genesis/engine/solvers/rigid/collider/narrowphase.py:4440-4481 | genesis/engine/solvers/rigid/collider/narrowphase.py:4497-4529 | genesis/engine/solvers/rigid/collider/narrowphase.py:4544-4680 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4242}}}],"partialFingerprints":{"codehealthFindingId/v1":"047452ba81d180af65cc674e64d21081826d5ef4a5c0685cb8d615b379edaec5"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/engine/solvers/rigid/rigid_solver.py:1786-1923 | genesis/engine/solvers/rigid/rigid_solver.py:2009-2126 | genesis/engine/solvers/rigid/rigid_solver.py:2133-2260 | genesis/engine/solvers/rigid/rigid_solver.py:2446-2515 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1786}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cad7e7649a06d7f18c120fec1fd51dd83cc7836b391192efff1ae0bc4ac92a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): genesis/utils/mesh.py:1033-1038 | genesis/utils/mesh.py:1054-1059 | genesis/utils/mesh.py:1075-1080 | genesis/utils/mesh.py:1141-1146 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/mesh.py"},"region":{"startLine":1033}}}],"partialFingerprints":{"codehealthFindingId/v1":"b63b316931198df8a40b6ae85197b5058d83d9bbf2fbc9e4d3c2393622f9856c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (70\u201373 lines \u00D7 3): genesis/ext/pyrender/jit_render.py:893-965 | genesis/ext/pyrender/jit_render.py:1031-1102 | genesis/ext/pyrender/jit_render.py:1169-1238 \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 \u0060genesis/ext/pyrender/jit_render.py:893\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. 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":893}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac530bd4964e34c71a32f4e192b32edd8416a8e6e3de13e2ff233fb488eeaf96"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (47\u201354 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:814-867 | genesis/engine/solvers/rigid/constraint/solver.py:1043-1089 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"777a8db9cbea8198555901619f25b56a8bc026f28a1256f2fbed5cbe4caccb6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (53\u201354 lines \u00D7 2): genesis/utils/path_planning.py:609-661 | genesis/utils/path_planning.py:1009-1062 \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":"genesis/utils/path_planning.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d8238711bff22e15d7947c5c83e3b162fc2694944e1808ea3af81d6d65b252e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34\u201351 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:402-452 | genesis/engine/solvers/rigid/collider/narrowphase.py:741-774 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac636fbdc8bbb794a43a38821f4be7011183b8c5dbc04b82dab86ed711307496"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31\u201349 lines \u00D7 2): genesis/utils/raycast_qd.py:52-100 | genesis/utils/raycast_qd.py:408-438 \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":"genesis/utils/raycast_qd.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"c24b2896b8c73cd83f2ec37dc12a442b13f29ec19c4ee34688540c5890fae31b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44\u201346 lines \u00D7 2): genesis/engine/solvers/rigid/abd/inverse_kinematics.py:420-465 | genesis/engine/solvers/rigid/abd/inverse_kinematics.py:550-593 \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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"25a29745bfc00179c6609b83982f8ea3f94d863c69ec294e77d7d7ac2afdaf48"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (42 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2689-2730 | genesis/engine/solvers/rigid/collider/narrowphase.py:4132-4173 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2689}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cc60cbae40555c1f2a44780e7d8d8c7c25cb784bf8a50c320c5870207f0bd06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37\u201339 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1418-1456 | genesis/engine/sensors/point_cloud_tactile.py:1578-1614 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1418}}}],"partialFingerprints":{"codehealthFindingId/v1":"f84c01b8e49e8d977bd1fd5c99b4272deaba40a208ca10807627232089146a56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201334 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:360-393 | genesis/engine/solvers/rigid/collider/narrowphase.py:725-739 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f353fb6e2291a62331353dea63a2a5c2c7924c946c7db77dc896a044c817d27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32\u201333 lines \u00D7 3): genesis/engine/sensors/kinematic_tactile.py:569-601 | genesis/engine/sensors/kinematic_tactile.py:646-678 | genesis/engine/sensors/point_cloud_tactile.py:1095-1126 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/sensors/kinematic_tactile.py:642\u0060 calls \u0060qd_int\u0060, \u0060zero\u0060 and \u0060genesis/engine/sensors/kinematic_tactile.py:566\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":569}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac5eaf030b2308d38973b37d028bd4d0cc7e3df2a09835761ce4344717af47ed"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u201333 lines \u00D7 4): genesis/engine/sensors/point_cloud_tactile.py:1374-1406 | genesis/engine/sensors/point_cloud_tactile.py:1407-1408 | genesis/engine/sensors/point_cloud_tactile.py:1537-1566 | genesis/engine/sensors/point_cloud_tactile.py:1567-1568 \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 \u0060genesis/engine/sensors/point_cloud_tactile.py:1407\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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/sensors/point_cloud_tactile.py:1407\u0060 calls \u0060Vector\u0060, \u0060qd_float\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:1408\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1374}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d50c290844b6ac8ef8f02f252c3d296f1922ab940d6eac3fe71e3ca5626be17"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201333 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1388-1420 | genesis/engine/solvers/rigid/collider/contact.py:1725-1749 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1388}}}],"partialFingerprints":{"codehealthFindingId/v1":"26efbf8686b87e66eb267b3ed76239382f23abf12ef4aea6f1ab1f9dffed0df2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:837-869 | genesis/engine/solvers/rigid/constraint/linesearch.py:1047-1079 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":837}}}],"partialFingerprints":{"codehealthFindingId/v1":"03925ec7f16d141a68e6384744eb7242ef644824cc6a4576707c635d66dc2e12"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/linesearch.py:837-867 | genesis/engine/solvers/rigid/constraint/linesearch.py:1047-1077 | genesis/engine/solvers/rigid/constraint/linesearch.py:1477-1507 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":837}}}],"partialFingerprints":{"codehealthFindingId/v1":"34420593242cd74fe835a140f53b04443da634e933eaa5ca1055ba4577242eb4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29\u201330 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:453-482 | genesis/engine/sensors/kinematic_tactile.py:722-750 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/sensors/kinematic_tactile.py:720\u0060 calls \u0060template\u0060 and \u0060genesis/engine/sensors/kinematic_tactile.py:451\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf76c84d7ffb4f6c7b19c3644b47e2d2ad760aa138043fd5009e2f98dd0e62c7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1322-1351 | genesis/engine/solvers/rigid/collider/contact.py:1637-1666 \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 before the matched lines, \u0060genesis/engine/solvers/rigid/collider/contact.py:1634\u0060 calls \u0060qd_block_max\u0060 and \u0060genesis/engine/solvers/rigid/collider/contact.py:1320\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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1322}}}],"partialFingerprints":{"codehealthFindingId/v1":"e83bd5f113e53cbcad38546e04e32f09a97ece0c01f7b78b809a8ed2abf5d9c3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:341-369 | genesis/engine/sensors/kinematic_tactile.py:833-861 \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 \u0060genesis/engine/sensors/kinematic_tactile.py:341\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":341}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ef7bfec1e16a5fc4b79448cb207b71ebd21eb496072350f71b6425638101787"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201329 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:1048-1076 | genesis/engine/solvers/rigid/constraint/backward.py:1247-1270 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":1048}}}],"partialFingerprints":{"codehealthFindingId/v1":"196cb553ea59d1afb90dd547749d3d57e49027b8d08bc9561ea4c6b9376cb9e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): genesis/ext/pyrender/renderer.py:260-288 | genesis/ext/pyrender/renderer.py:294-322 \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":"genesis/ext/pyrender/renderer.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"a80ba11016b0751eb9317002d190f59a4df6156b3ec814a20b7465d24396c0bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28\u201329 lines \u00D7 2): genesis/utils/usd/usd_rigid_entity.py:289-317 | genesis/utils/usd/usd_rigid_entity.py:332-359 \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb99a73513db893ed1d1e04d0ff8cf5d912b35e02a697bde52162d04c7c0124b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2894-2921 | genesis/engine/couplers/sap_coupler.py:3898-3925 \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 \u0060genesis/engine/couplers/sap_coupler.py:2894\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2894}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cdff17db760994db7b3a2c2dd0d74ebbceec9fb9c14e7c70888f41536399f9a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1179-1206 | genesis/engine/sensors/point_cloud_tactile.py:1616-1643 \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 before the matched lines, \u0060genesis/engine/sensors/point_cloud_tactile.py:1612\u0060 calls \u0060qd_inv_transform_by_trans_quat\u0060, \u0060static\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:1177\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1179}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a01fa81b39ff2a1200b11c88873e4ec03a36045d7ea4fe2d7ac90205a169e7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): genesis/engine/solvers/rigid/collider/broadphase.py:178-205 | genesis/engine/solvers/rigid/collider/broadphase.py:237-264 \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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"f59c5b43f29da4ed1bdb845e8cbdb31bd15b3ce277a14f4d7a10a6f3ca92d7e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2933-2960 | genesis/engine/solvers/rigid/collider/narrowphase.py:3434-3461 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2933}}}],"partialFingerprints":{"codehealthFindingId/v1":"efaa5255fbe1df522481eaa91b28cecc58e1b927c4a21ab114fa029182b08c58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201328 lines \u00D7 2): genesis/utils/raycast_qd.py:824-851 | genesis/utils/raycast_qd.py:926-944 \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":"genesis/utils/raycast_qd.py"},"region":{"startLine":824}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b2b40b5f251498c189e1433198bbc035e63f8297e664f7cb9457ba638ef5a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): genesis/utils/tools.py:78-105 | genesis/utils/tools.py:114-141 \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 \u0060genesis/utils/tools.py:78\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":"genesis/utils/tools.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"29a08dc57b07f012fe9c4b11897185021ce9a28a71ec381ae4f8c897aa8fb18b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201327 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:2643-2669 | genesis/engine/solvers/rigid/collider/narrowphase.py:3071-3095 | genesis/engine/solvers/rigid/collider/narrowphase.py:4065-4089 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:2643\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. 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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2643}}}],"partialFingerprints":{"codehealthFindingId/v1":"296535dba2db04dd7f07665bd4f9c712ba48799e78d2829a6765fa2685c67497"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201326 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:2684-2707 | genesis/engine/solvers/rigid/collider/narrowphase.py:3105-3130 | genesis/engine/solvers/rigid/collider/narrowphase.py:4127-4150 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:3105\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2684}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c8cd855ecbb26a49995384b1bf8248952df0ee7bf207635084db56f12e55563"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): genesis/engine/entities/particle_entity.py:150-174 | genesis/engine/entities/sph_entity.py:42-66 \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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"280a4471c73b6c478516ad25a1b93af9ff502e01a4d4a1050fe95d2b75587586"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201325 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1282-1306 | genesis/engine/solvers/rigid/collider/contact.py:1597-1617 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1282}}}],"partialFingerprints":{"codehealthFindingId/v1":"abdf091671509f4f615bd55b99d0e6e5304fbba811aa82d4bad8850bf3246f7a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): genesis/utils/path_planning.py:439-463 | genesis/utils/path_planning.py:805-829 \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":"genesis/utils/path_planning.py"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8b99451bbacf664224d00fb5fd8c20df45917ef2f8f967b1f53f0ee7d7ab9cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:522-545 | genesis/engine/solvers/rigid/collider/box_contact.py:803-826 \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0e699918fa9b103a969c32cee2b29b8d9fd90aaaf942986bb4e1229f6f337c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): genesis/engine/solvers/rigid/collider/collider.py:1248-1271 | genesis/engine/solvers/rigid/collider/collider.py:1298-1321 \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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":1248}}}],"partialFingerprints":{"codehealthFindingId/v1":"81d60a980503da93a06da73177087595a9619f712acd6de4b169e291c240ff8f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:1048-1069 | genesis/engine/sensors/kinematic_tactile.py:1330-1351 \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 \u0060genesis/engine/sensors/kinematic_tactile.py:1048\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":1048}}}],"partialFingerprints":{"codehealthFindingId/v1":"c428d58feeaa3ce2adf32c5ae0a6bedfc5fccec25915dfe064a146fbd0b413cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201322 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1425-1446 | genesis/engine/solvers/rigid/rigid_solver.py:2927-2947 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/kinematic_solver.py:1425\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1425}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b8770af01510baf4fb16e79571df729d07ae2633d926141025337cfdfe41d58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): genesis/ext/urdfpy/urdf.py:2997-3018 | genesis/ext/urdfpy/urdf.py:3081-3102 \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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":2997}}}],"partialFingerprints":{"codehealthFindingId/v1":"5734e139e7b543cb30aa8fa483e7c6b0ed7f7f5472d15e00cab6063d5d86a899"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201321 lines \u00D7 3): genesis/engine/solvers/rigid/collider/broadphase.py:177-197 | genesis/engine/solvers/rigid/collider/broadphase.py:236-256 | genesis/engine/solvers/rigid/collider/broadphase.py:275-292 \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 \u0060genesis/engine/solvers/rigid/collider/broadphase.py:177\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. 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"eafac9f65606eefc5a51c282a4a3e5cee95341ded17f2427add1f1a1d01bf26b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201321 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3567-3586 | genesis/engine/couplers/sap_coupler.py:3923-3943 \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 \u0060genesis/engine/couplers/sap_coupler.py:3567\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. 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3567}}}],"partialFingerprints":{"codehealthFindingId/v1":"565ec3aec4cdf20cf3ef272bea59798e6e9a044b3df2a1654379aebfc90fbc45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): genesis/engine/entities/emitter.py:163-183 | genesis/engine/entities/emitter.py:230-250 \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":"genesis/engine/entities/emitter.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f4bacdc96d7a585021796dc5377519cc17ed58f5e24e0af3a210a91800def59"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201321 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1440-1460 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1512-1529 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1440}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdef01774932a2cbc68f0f5de194b73cdbff45909d03c25ac24bcbf8e0360e25"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201320 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:2915-2934 | genesis/engine/couplers/sap_coupler.py:3563-3581 | genesis/engine/couplers/sap_coupler.py:3919-3938 \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. 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2915}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae0b0a1d48f173ab4b91093287c0febe83ea1fb7ef543eb05edc852c2b90d262"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201320 lines \u00D7 3): genesis/engine/sensors/kinematic_tactile.py:410-429 | genesis/engine/sensors/kinematic_tactile.py:908-926 | genesis/engine/sensors/kinematic_tactile.py:933-951 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/sensors/kinematic_tactile.py:929\u0060 calls \u0060static\u0060 and \u0060genesis/engine/sensors/kinematic_tactile.py:430\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":410}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4c162d6c84a070275cbdacfbec0565fd388443c243d3964e8507a1150b1378b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 3): genesis/engine/solvers/rigid/collider/diff_gjk.py:473-492 | genesis/engine/solvers/rigid/collider/epa.py:159-178 | genesis/engine/solvers/rigid/collider/epa.py:1103-1122 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a19a6082220f131a260bbcc691e42c05aee2b42902d11f4e14944760a3150e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201320 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:116-124 | genesis/engine/solvers/rigid/collider/narrowphase.py:691-699 | genesis/engine/solvers/rigid/collider/narrowphase.py:1087-1106 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"79941abf0731a87f7129518bba08487a4e99757054ec6bfd622b01f8e95e2100"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2874-2893 | genesis/engine/couplers/sap_coupler.py:3878-3897 \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 \u0060genesis/engine/couplers/sap_coupler.py:2874\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2874}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab98985b676f2f10a2fba8b6348026e8f54d7f0eda8bd086d2ba6d2491524d7b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201320 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:104-121 | genesis/engine/sensors/kinematic_tactile.py:142-161 \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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a6457bb6ff1bb55287a8db92ad32c11aa1f623a80eb592c75c7c7a4357844b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201320 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1158-1177 | genesis/engine/sensors/point_cloud_tactile.py:1224-1242 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/sensors/point_cloud_tactile.py:1156\u0060 calls \u0060template\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:1222\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1158}}}],"partialFingerprints":{"codehealthFindingId/v1":"63fec3eb47ca0805d98dcb84266aab2e143109f10deaccc77bb063198e075969"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1470-1489 | genesis/engine/sensors/point_cloud_tactile.py:1643-1662 \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 before the matched lines, \u0060genesis/engine/sensors/point_cloud_tactile.py:1640\u0060 calls \u0060abs\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:1468\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1470}}}],"partialFingerprints":{"codehealthFindingId/v1":"cde982126cd81c6c475c1021b619b6908e7a99f2afd13ab8c5a73379bb68e7dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1153-1196 | genesis/engine/solvers/rigid/collider/contact.py:1453-1472 \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 before the matched lines, \u0060genesis/engine/solvers/rigid/collider/contact.py:1149\u0060 calls \u0060template\u0060 and \u0060genesis/engine/solvers/rigid/collider/contact.py:1450\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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1153}}}],"partialFingerprints":{"codehealthFindingId/v1":"5df35c65ae95a35a180c85a3ecb3945378cf2e315460a08f380b491a0c2e9f57"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201320 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:505-524 | genesis/engine/solvers/rigid/collider/epa.py:635-653 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":505}}}],"partialFingerprints":{"codehealthFindingId/v1":"67394f6f9c7df0d78788b0eb2247b1374a99e37df2d5742eeab2c483d99d359c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:220-239 | genesis/engine/solvers/rigid/collider/narrowphase.py:318-337 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca27b3d996b048c81d46bd0cfcae8c530b5372ae42410a9d5290d2d7092b6bd9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201320 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:738-753 | genesis/engine/solvers/rigid/constraint/solver.py:957-976 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":738}}}],"partialFingerprints":{"codehealthFindingId/v1":"91f39099b110582a946faaaff406f969a70af5d09a43f4351763dd24aa3a7b59"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): genesis/utils/path_planning.py:387-406 | genesis/utils/path_planning.py:737-756 \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":"genesis/utils/path_planning.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"f327ad5cdf64c4c27b2dbf632f8ba49e98771a2e7c8d92ae93fd64df0af08ebd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201319 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1247-1265 | genesis/engine/solvers/rigid/collider/contact.py:1554-1570 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1247}}}],"partialFingerprints":{"codehealthFindingId/v1":"698858fd9bbd62cb26050dc856f586da312429ada878df0b08faeec1257d7792"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): genesis/engine/solvers/rigid/collider/gjk.py:1646-1664 | genesis/engine/solvers/rigid/collider/gjk_support.py:147-165 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/collider/gjk.py:1646\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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":1646}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c02a834a270963388a50f6adfaf9b2a75a5dc757a0f6ebd57b769f76809c039"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): genesis/ext/pyrender/jit_render.py:975-993 | genesis/ext/pyrender/jit_render.py:1112-1130 \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 \u0060genesis/ext/pyrender/jit_render.py:975\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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":975}}}],"partialFingerprints":{"codehealthFindingId/v1":"e68f0ecc4ec1d999fa59e26c3ef2a12c3a072c344321d421114a598f1e616244"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): genesis/ext/pyrender/jit_render.py:996-1014 | genesis/ext/pyrender/jit_render.py:1133-1151 \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 \u0060genesis/ext/pyrender/jit_render.py:996\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. 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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":996}}}],"partialFingerprints":{"codehealthFindingId/v1":"68295682893955b8bd4269204e331d9b24a136e9459d43f54b4c6329cced8576"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): genesis/ext/pyrender/jit_render.py:1397-1414 | genesis/ext/pyrender/jit_render.py:1422-1439 \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 \u0060genesis/ext/pyrender/jit_render.py:1397\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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":1397}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c9929d88a1dcb0e3e403512c7e1fa091746216218f3e06fb9635b8023c66aee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): genesis/utils/path_planning.py:476-493 | genesis/utils/path_planning.py:844-861 \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":"genesis/utils/path_planning.py"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"66fa4e3faf317bd4b93d817d6b4f69a6fd169427efc19cdf361b892c62113dd9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201317 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:488-504 | genesis/engine/solvers/rigid/collider/narrowphase.py:819-832 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2a0c7910f5baec53c802942e2b008373ab35ab19de52f2519f3ad1e522f3272"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201317 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:977-993 | genesis/engine/solvers/rigid/constraint/backward.py:1170-1185 \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 \u0060genesis/engine/solvers/rigid/constraint/backward.py:1170\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":977}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b63a6b76e415c41e3715005f7a1449035164c9822536c6640d90733550fcb90"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): genesis/utils/particle.py:246-262 | genesis/utils/particle.py:270-286 \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":"genesis/utils/particle.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"85d5f7dfc254972958c89b50e41ff1277b56259947db463ce104fa14175f8c22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 2): genesis/utils/raycast_qd.py:104-120 | genesis/utils/raycast_qd.py:441-455 \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":"genesis/utils/raycast_qd.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ca9ea0a18547c91e01663b7537eaf6d33907e37356ade800a1f6224b2ac4d77"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 3): genesis/engine/solvers/rigid/collider/capsule_contact.py:62-77 | genesis/engine/solvers/rigid/collider/capsule_contact.py:128-143 | genesis/engine/solvers/rigid/collider/capsule_contact.py:208-223 \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":"genesis/engine/solvers/rigid/collider/capsule_contact.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b287d2fc9ba8360c824be80cc42a83f18460d63fee7ab6bad1a9f51f4202a6d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): genesis/engine/solvers/rigid/collider/diff_gjk.py:450-465 | genesis/engine/solvers/rigid/collider/epa.py:1080-1095 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/collider/diff_gjk.py:450\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. 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":450}}}],"partialFingerprints":{"codehealthFindingId/v1":"5824cf31c2cfc87377f4d17cf4d2e46d4d5b01f127848fb388dd51c7186f902b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:141-156 | genesis/engine/solvers/rigid/collider/epa.py:1083-1098 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"741982f207e2d439e35f0576c9b8612d3f2bdfe12576d21c94468359f7d68b8c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201316 lines \u00D7 4): genesis/engine/solvers/rigid/constraint/backward.py:953-966 | genesis/engine/solvers/rigid/constraint/backward.py:1118-1133 | genesis/engine/solvers/rigid/constraint/solver.py:1187-1190 | genesis/engine/solvers/rigid/constraint/solver.py:1908-1911 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart. 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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":953}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a559e75769f59a35d148fc95670e1482167fb71da7e80fb646d27b487c8403f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5172-5186 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:39-54 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/constraint/solver.py:5172\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5172}}}],"partialFingerprints":{"codehealthFindingId/v1":"06373ffeffedfc893c55ba744f63d708e8f71e194eb3bc68a659381b9ea72545"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5200-5213 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:78-93 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/constraint/solver.py:5200\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5200}}}],"partialFingerprints":{"codehealthFindingId/v1":"3500f463934f1b25f25cc39e20bc6ae9c6b698f7b3fcd72b824619b34ac161cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): genesis/ext/pyrender/material.py:378-393 | genesis/ext/pyrender/material.py:587-602 \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, \u0060genesis/ext/pyrender/material.py:604\u0060 calls \u0060ones\u0060 and \u0060genesis/ext/pyrender/material.py:395\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":"genesis/ext/pyrender/material.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ef294b34dbf0eb8271f0b4e6e12c0462b65864153388c860ed76320f7d1dd4a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 4): genesis/engine/solvers/rigid/rigid_solver.py:1907-1921 | genesis/engine/solvers/rigid/rigid_solver.py:2112-2126 | genesis/engine/solvers/rigid/rigid_solver.py:2246-2260 | genesis/engine/solvers/rigid/rigid_solver.py:2503-2515 \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 \u0060genesis/engine/solvers/rigid/rigid_solver.py:1907\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/rigid_solver.py:2110\u0060 calls \u0060kernel_set_links_pos\u0060 and \u0060genesis/engine/solvers/rigid/rigid_solver.py:1906\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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1907}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2f60426b57057dd4dd8a59e7ac36dd7e220aa3f2f188049ef5b25624fac315d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:326-340 | genesis/engine/sensors/kinematic_tactile.py:819-832 \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 before the matched lines, \u0060genesis/engine/sensors/kinematic_tactile.py:817\u0060 calls \u0060template\u0060 and \u0060genesis/engine/sensors/kinematic_tactile.py:324\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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b97e46ba2f694e7b7b3e893de56a0aa66d54f4d3ec03114aeba8f120380844a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:527-541 | genesis/engine/sensors/point_cloud_tactile.py:543-555 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d2f2a9849adeeb88c37f0a745a32c4395341bca1d9d510b7d86fb1295393561"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201315 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:605-619 | genesis/engine/solvers/rigid/collider/diff_gjk.py:676-686 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":605}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb6bcca82fb7730ebdb4bfbe94ff749aeb7658cf6ac4cdc50b7415abec13e2f5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): genesis/engine/solvers/rigid/collider/diff_gjk.py:428-442 | genesis/engine/solvers/rigid/collider/epa.py:1059-1073 \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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":428}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe31075a24ca7f4e2d1cc7ec1bfda387ccde2f9387bbac01440c0e90506cdb67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2977-2990 | genesis/engine/solvers/rigid/collider/narrowphase.py:3574-3588 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2977}}}],"partialFingerprints":{"codehealthFindingId/v1":"d19d4751fbd33fe09f6411c3118ae15ee196db81520bea4d8cd7189d4d512293"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u201315 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:2638-2640 | genesis/engine/solvers/rigid/collider/narrowphase.py:3055-3069 | genesis/engine/solvers/rigid/collider/narrowphase.py:4048-4062 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:2638\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2638}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d9abe7143fc19a27f5995bdfaaf72182826859ced936dac20f165bd5e32a57e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:3475-3489 | genesis/engine/solvers/rigid/collider/narrowphase.py:3699-3713 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:3475\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3475}}}],"partialFingerprints":{"codehealthFindingId/v1":"63f3a702644baf2bd1bed6a21bc439e10392a89e12ee97246a57b3fc93f98724"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201315 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver_breakdown.py:184-198 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:247-256 \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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"98ca86dd15c1a91c312c2c2e27c075c2658d2efebf83096a96ea9e245bb2b456"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 2): genesis/utils/geom.py:884-898 | genesis/utils/geom.py:996-1009 \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":"genesis/utils/geom.py"},"region":{"startLine":884}}}],"partialFingerprints":{"codehealthFindingId/v1":"27731beeae0d9e498047c6232cae9c1f5a9076f296a0bb98234150e0a83cdc0c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 4): genesis/engine/sensors/kinematic_tactile.py:344-357 | genesis/engine/sensors/kinematic_tactile.py:464-477 | genesis/engine/sensors/kinematic_tactile.py:732-745 | genesis/engine/sensors/kinematic_tactile.py:836-849 \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. 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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1efafe02cb43d31488cd03a3acd24867047c1145cff0a73301112f4158fe28e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3): genesis/engine/solvers/rigid/collider/diff_gjk.py:451-466 | genesis/engine/solvers/rigid/collider/epa.py:141-154 | genesis/engine/solvers/rigid/collider/epa.py:1081-1096 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/collider/diff_gjk.py:451\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. 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":451}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c750257451f4271ffed4c67fc0900a98e2d831684d9d05e139d128a7f57cf2e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201314 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:531-541 | genesis/engine/solvers/rigid/constraint/backward.py:985-998 | genesis/engine/solvers/rigid/constraint/backward.py:1187-1196 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/constraint/backward.py:1197\u0060 calls \u0060qd_vec3\u0060 and \u0060genesis/engine/solvers/rigid/constraint/backward.py:542\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":531}}}],"partialFingerprints":{"codehealthFindingId/v1":"a525c00f8998805161395dbfdcffde4bf394ffa0883bb8564701db8636c10dd9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/engine/entities/mpm_entity.py:207-220 | genesis/engine/entities/mpm_entity.py:225-238 \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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4c19360efe6a4d8879a63aecd1c48d2341338e10eb313e885bf71536edd98ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:521-534 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:726-738 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbc9bee8f3851cf4d0f0ce75fd8755522f16694056dc4f19314be382482986b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1018-1031 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1077-1089 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:1018\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1018}}}],"partialFingerprints":{"codehealthFindingId/v1":"f751c71842e0b2b4a5e58f24013e47be6b9b2ab9e759781e419e0c4d80016df1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:66-79 | genesis/engine/solvers/rigid/collider/epa.py:1000-1013 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d27c415aa12ae25b9d98651a3e9de541933bf51e68f53a2c1d01ffe43082727"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201314 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2669-2682 | genesis/engine/solvers/rigid/collider/narrowphase.py:4117-4125 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2669}}}],"partialFingerprints":{"codehealthFindingId/v1":"1711592d317afa39b3b0031c7e1d90b0a6499a8eb92a7cbfee55ac2409fd6dab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:812-825 | genesis/engine/solvers/rigid/constraint/linesearch.py:1026-1037 \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 \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:812\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":812}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5d8c86aee5649f66f6104339a968de33d32ac0e139a8f87a89b71d029ca62f6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201314 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/noslip.py:53-66 | genesis/engine/solvers/rigid/constraint/noslip.py:91-97 \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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1cc87103d29a75870480d24f41c0c63c4d44cdcb3c56cd74d63ab3be942a34a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2233-2246 | genesis/engine/solvers/rigid/constraint/solver.py:2597-2612 \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, \u0060genesis/engine/solvers/rigid/constraint/solver.py:2616\u0060 calls \u0060static\u0060 and \u0060genesis/engine/solvers/rigid/constraint/solver.py:2248\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2233}}}],"partialFingerprints":{"codehealthFindingId/v1":"0438868afacb21d65d6e780459c873c0d3dcfe63b183ebc977cb0d5dee842296"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:2063-2076 | genesis/engine/solvers/rigid/rigid_solver.py:2188-2201 \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 \u0060genesis/engine/solvers/rigid/rigid_solver.py:2063\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/rigid_solver.py:2202\u0060 calls \u0060_select_links_offset\u0060, \u0060qd_to_torch\u0060 and \u0060genesis/engine/solvers/rigid/rigid_solver.py:2079\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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2063}}}],"partialFingerprints":{"codehealthFindingId/v1":"0208ab3ac031efce01dd1c10c8b22c8692c02544993165da092ab09b37ee4a06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/ext/isaacgym/terrain_utils.py:15-28 | genesis/utils/terrain.py:194-207 \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":"genesis/ext/isaacgym/terrain_utils.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"c57354f55a2e610694145bcfcc0dfdf9bb6eb610d282d3cd6624cc3c38ec8d9e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/ext/urdfpy/urdf.py:3020-3033 | genesis/ext/urdfpy/urdf.py:3104-3117 \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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":3020}}}],"partialFingerprints":{"codehealthFindingId/v1":"6105fc586a743337bdcd9890baccd2558ff149ead8a7f660850ea1643c8007ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 3): genesis/engine/solvers/rigid/collider/broadphase.py:199-210 | genesis/engine/solvers/rigid/collider/broadphase.py:258-269 | genesis/engine/solvers/rigid/collider/broadphase.py:295-307 \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 \u0060genesis/engine/solvers/rigid/collider/broadphase.py:199\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. 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"15da0dd3299331194bd3c74609016190af5f41df10a196cc5b5fb9ec09da81ec"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 3): genesis/engine/solvers/rigid/collider/broadphase.py:191-203 | genesis/engine/solvers/rigid/collider/broadphase.py:250-262 | genesis/engine/solvers/rigid/collider/broadphase.py:377-387 \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 \u0060genesis/engine/solvers/rigid/collider/broadphase.py:191\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. 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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bb1de61f506015f38b32c1e344b64c02481f574c7bc6b04e6f95955e1ae5033"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:1036-1048 | genesis/engine/solvers/rigid/constraint/backward.py:1235-1247 | genesis/engine/solvers/rigid/constraint/solver.py:1798-1810 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":1036}}}],"partialFingerprints":{"codehealthFindingId/v1":"f973a8b2982118d494cff6d0025f60aa8ad8911a8849723c6f996cde4c54bb75"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201313 lines \u00D7 3): genesis/ext/isaacgym/terrain_utils.py:378-387 | genesis/utils/terrain.py:282-294 | genesis/utils/terrain.py:320-329 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/isaacgym/terrain_utils.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"05cd412e1512319395df07a1744e6f393ee9f69c7f3841f582b3ec447960d20d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): genesis/engine/couplers/legacy_coupler.py:371-382 | genesis/engine/couplers/legacy_coupler.py:392-404 \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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"7485df39134addba714dfb271ba630bf25c7511fccfb5d463339cfe0aed7b3e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): genesis/engine/couplers/legacy_coupler.py:418-429 | genesis/engine/couplers/legacy_coupler.py:439-451 \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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"5537d5c4bc592f686ed1ee5224d7bd8899319374dc7d073d581f328b0afc1c37"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2788-2800 | genesis/engine/couplers/sap_coupler.py:3795-3807 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2788}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa57f5b2c4fdf03388d8ad299c6089c4da12b1fb8c36778fa664835574aa7155"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2818-2830 | genesis/engine/couplers/sap_coupler.py:3825-3837 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2818}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d1158b9168db5ddaf3bec25f95ea0afbe556a9ab58ff0182676f974ecf123b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): genesis/engine/entities/rigid_entity/description.py:770-782 | genesis/engine/entities/rigid_entity/description.py:1843-1853 \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 \u0060genesis/engine/entities/rigid_entity/description.py:770\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. 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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":770}}}],"partialFingerprints":{"codehealthFindingId/v1":"1150397ce3f58d39beaa3753ab358eabf2990afed1cef5424c40013d7af07f77"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1358-1370 | genesis/engine/sensors/point_cloud_tactile.py:1522-1534 \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 before the matched lines, \u0060genesis/engine/sensors/point_cloud_tactile.py:1519\u0060 calls \u0060template\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:1355\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1358}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c05ebc2aa5fc02b7abf8112347fc959ea50c403fd647e483bc10d057e689ee8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201313 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1124-1133 | genesis/engine/solvers/rigid/rigid_solver.py:2133-2145 \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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1124}}}],"partialFingerprints":{"codehealthFindingId/v1":"50cce0a2945a9bfcb2618c3f03c86f894f8f1db5cce59677e3729d35b478305e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1134-1146 | genesis/engine/solvers/rigid/rigid_solver.py:2195-2207 \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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1134}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f23cb3782a90c32b70f1a415c73cd93af5db2449cf2ecb9b1572f367cd754ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:366-377 | genesis/engine/solvers/sph_solver.py:198-210 \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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"e761f4eb32b26bd3dbd0f1da711fb2f4da1e34a6a8ea4b580b9e12915eb0c20a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1308-1320 | genesis/engine/solvers/rigid/collider/contact.py:1621-1631 \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, \u0060genesis/engine/solvers/rigid/collider/contact.py:1634\u0060 calls \u0060qd_block_max\u0060 and \u0060genesis/engine/solvers/rigid/collider/contact.py:1322\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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1308}}}],"partialFingerprints":{"codehealthFindingId/v1":"5db4f2d74c9e94fff3cd5c285a680b847bc807607249d66a10a031a6482412a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): genesis/engine/solvers/rigid/collider/diff_gjk.py:538-548 | genesis/engine/solvers/rigid/collider/epa.py:1200-1212 \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 \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. 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":538}}}],"partialFingerprints":{"codehealthFindingId/v1":"f73c8d7ca11b4f9619e89507dd2db621ac81855f7e7171bf3acbc987b13c8b80"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:126-136 | genesis/engine/solvers/rigid/collider/epa.py:1067-1079 \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 \u0060genesis/engine/solvers/rigid/collider/epa.py:126\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. 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. 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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"548f1725c0c07c05a652ddeaef893ed47dfbaf0c49505b605558f040e14d8f28"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:1455-1467 | genesis/engine/solvers/rigid/collider/narrowphase.py:4183-4195 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1455}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e8af36d59935093956b98dedd1b6f0d8ed8d72a9aeb973efcade30740059345"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2503-2515 | genesis/engine/solvers/rigid/collider/narrowphase.py:3216-3227 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:2503\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2503}}}],"partialFingerprints":{"codehealthFindingId/v1":"afbb9199173032d5753c08b8215162a67acecba2041f9eb0174d0516df0d0f7c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201313 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:673-682 | genesis/engine/solvers/rigid/constraint/solver.py:2071-2083 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":673}}}],"partialFingerprints":{"codehealthFindingId/v1":"f10de40df5895cb38f9f00f4d96678d2c3c8db0d8f79644722a729017241c9ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2970-2982 | genesis/engine/solvers/rigid/constraint/solver.py:2999-3011 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2970}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd5a6087fc626dec96f4532504d7e73440176b1a41fbb43e7bf5730779f8fc19"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:3941-3953 | genesis/engine/solvers/rigid/constraint/solver.py:4023-4035 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3941}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b21c8095a20b29daa0e54975182c8da42fc06306b37de0da407aff9f8a42971"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): genesis/engine/solvers/rigid/collider/epa.py:484-495 | genesis/engine/solvers/rigid/collider/epa.py:617-628 | genesis/engine/solvers/rigid/collider/epa.py:737-748 | genesis/engine/solvers/rigid/collider/epa.py:1289-1300 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":484}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee0b9e01ee6f689f9f2de3ebb42586260aea56563e979c7ff0c16e448ac4219a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): genesis/engine/solvers/rigid/collider/epa.py:533-544 | genesis/engine/solvers/rigid/collider/epa.py:685-696 | genesis/engine/solvers/rigid/collider/epa.py:753-764 | genesis/engine/solvers/rigid/collider/epa.py:1302-1313 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":533}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cfc11c6ffc9417ca90ebb9a0f54b40b6667184fe0f65ca09a5803c2a86f2920"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/entities/fem_entity.py:234-245 | genesis/engine/entities/particle_entity.py:121-132 \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 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bcb8812630c29451febad23ec4596d99c4a01c3506d7d6c3524a3c25a8b7071"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/force_fields.py:102-113 | genesis/engine/force_fields.py:294-305 \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":"genesis/engine/force_fields.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5fe2403ddb4f5f0a67065ab1bf719fe696a380d5c73d73f0a359b231455769e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1073-1084 | genesis/engine/solvers/rigid/rigid_solver.py:2070-2081 \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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1073}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3389ad1d6d4afc4047816a1d3e7efe271eb0c5b7a779eddb255809c4e872281"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:242-253 | genesis/engine/solvers/rigid/collider/epa.py:1261-1272 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bbddf58c256f7f3cbb02922d1db029924b00d4d561f589b9ff80d143b7e00fd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2566-2577 | genesis/engine/solvers/rigid/collider/narrowphase.py:3282-3292 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2566}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbf606635c777f876b00224f9f2a38ffa73256d41189ad1aa6e8b11a521a2af4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1377-1388 | genesis/engine/solvers/rigid/constraint/linesearch.py:1508-1519 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1377}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0d706859981a8d798d320c9c409aa4d9ce60830977edc2743a4f63393114a2b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2495-2506 | genesis/engine/solvers/rigid/constraint/solver.py:2706-2717 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2495}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ccbf6929701febfd0fd1a58985f7c5c9673683c5fd35cc2f6e2c5b42aea28c1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 2): genesis/utils/array_class.py:1863-1874 | genesis/utils/array_class.py:1913-1923 \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 \u0060genesis/utils/array_class.py:1863\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":"genesis/utils/array_class.py"},"region":{"startLine":1863}}}],"partialFingerprints":{"codehealthFindingId/v1":"db7da882d0fd8cfcd080487e48e9e6b507c5fe4551ac2565f675131d170fa2b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/utils/geom.py:939-950 | genesis/utils/geom.py:1931-1942 \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 \u0060genesis/utils/geom.py:939\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":"genesis/utils/geom.py"},"region":{"startLine":939}}}],"partialFingerprints":{"codehealthFindingId/v1":"db08af335bbc9a278e7d58e49e32f6e2851ab051f30ecf65678d816cc9bbf819"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 2): genesis/utils/geom.py:1161-1170 | genesis/utils/geom.py:1202-1213 \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":"genesis/utils/geom.py"},"region":{"startLine":1161}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b240b9838bf8c990f6482c95bffab6b25e6c35bb0d54923a59bb4f979450673"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/utils/path_planning.py:415-426 | genesis/utils/path_planning.py:778-789 \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":"genesis/utils/path_planning.py"},"region":{"startLine":415}}}],"partialFingerprints":{"codehealthFindingId/v1":"286cfdf795c9c75553184edc2164cf9f573209d5417b045a7d3ec9c4a0d02bf1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): genesis/utils/path_planning.py:536-547 | genesis/utils/path_planning.py:919-930 \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":"genesis/utils/path_planning.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad26cdcf170afd89eec8eb6abde7317a1eeef90a56e84040e1ad50ef9ca65ffa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:568-578 | genesis/engine/solvers/rigid/constraint/backward.py:1016-1025 | genesis/engine/solvers/rigid/constraint/backward.py:1224-1233 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":568}}}],"partialFingerprints":{"codehealthFindingId/v1":"0872275ff4a876222eb68ecc012c86ca9a3a587b93d2be177554ac932e775d34"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2335-2345 | genesis/engine/couplers/sap_coupler.py:3650-3660 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2335}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fb787494db87805fa1debee36b9b6cdb180f17b41810e29500b6884d638d26c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201311 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3358-3368 | genesis/engine/couplers/sap_coupler.py:3584-3591 \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 \u0060genesis/engine/couplers/sap_coupler.py:3358\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3358}}}],"partialFingerprints":{"codehealthFindingId/v1":"2769887088f5e0045f40d28e7aef8aa40bf3e89d7bb76de648d7d7b3ea9ac4ef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/entities/hybrid_entity.py:541-551 | genesis/engine/entities/hybrid_entity.py:628-638 \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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":541}}}],"partialFingerprints":{"codehealthFindingId/v1":"69d47cea6503b28cb1af6a8579160a5f62346fb1a27ac1db8e59f7dc2fc66a99"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:438-448 | genesis/engine/sensors/surface_distance_probe.py:229-239 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":438}}}],"partialFingerprints":{"codehealthFindingId/v1":"31902a0b0ae564898c2dade83b100eec7c43a30ee05fb19ec7cdd96a14210f6e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:1081-1091 | genesis/engine/solvers/mpm_solver.py:802-812 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/fem_solver.py:1081\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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1081}}}],"partialFingerprints":{"codehealthFindingId/v1":"a638d414e49c8ef60fdf1324c8ed7092b7b67709e0af714af08278dc3ed1484f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:653-663 | genesis/engine/solvers/pbd_solver.py:723-733 \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 \u0060genesis/engine/solvers/pbd_solver.py:653\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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":653}}}],"partialFingerprints":{"codehealthFindingId/v1":"03aff9b6f443302fb0b280ff20933d02f450ea444372c76c1f3ed4e4d7a57911"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1142-1152 | genesis/engine/solvers/rigid/constraint/noslip.py:22-32 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1142}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb106fec9bdd824ab9e317db4c4fcf0a705eddde216d58f21c5e97c8d4be15c0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (1\u201311 lines \u00D7 5): genesis/engine/solvers/rigid/abd/forward_kinematics.py:551-551 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1164-1166 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1222-1224 | genesis/engine/solvers/rigid/abd/manual_bw.py:245-260 | genesis/engine/solvers/rigid/abd/manual_bw.py:432-442 \u2014 there are 5 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 5 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:1164\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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":551}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7c940a186b21c77a7614d90232ddebe2a230dca60630d70e2e92fe7f10456c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): genesis/engine/solvers/rigid/collider/mpr.py:90-99 | genesis/engine/solvers/rigid/collider/utils.py:23-33 \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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e88e273799986db12e6809a2250da9adb23f7cad16ab9d3c26503f33df53238"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:579-588 | genesis/engine/solvers/rigid/constraint/solver.py:990-1000 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"d700b813989cf39ffbe8aa2f88fb32a5bb76204895c1e7782151ec849b54264a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:1003-1013 | genesis/engine/solvers/rigid/constraint/backward.py:1209-1219 \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 before the matched lines, \u0060genesis/engine/solvers/rigid/constraint/backward.py:1205\u0060 calls \u0060Vector\u0060 and \u0060genesis/engine/solvers/rigid/constraint/backward.py:1001\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":1003}}}],"partialFingerprints":{"codehealthFindingId/v1":"181c780c5f354f01221b6ff5084ab10528261527493cbd3f7f07cfa0590ddde5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/island.py:317-327 | genesis/engine/solvers/rigid/constraint/island.py:541-550 \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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":317}}}],"partialFingerprints":{"codehealthFindingId/v1":"da80deb51ae1bd3e57d0a2881f4d3c24d20eb0c8f7d6b0d1d921d42c626b0c3e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5217-5226 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:97-107 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5217}}}],"partialFingerprints":{"codehealthFindingId/v1":"07fd3c5075a7bb53ba6c189d69fbbc422a3b5b817464a724f883b2bd672dbd8c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): genesis/engine/states/entities.py:39-48 | genesis/engine/states/entities.py:96-106 \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":"genesis/engine/states/entities.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dfc4d667fd03ef91f113c13908eac720d310021e3b15c488bfdcf3b7fa748df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/ext/pyrender/overlay/plugin.py:1183-1193 | genesis/ext/pyrender/overlay/plugin.py:1277-1287 \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":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":1183}}}],"partialFingerprints":{"codehealthFindingId/v1":"714702976f5fe5b38fc77e929c36a5c64681235d5db4c27c6bd3f996a2dbfe96"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:2282-2291 | genesis/engine/couplers/sap_coupler.py:2383-2392 | genesis/engine/couplers/sap_coupler.py:2399-2408 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2282}}}],"partialFingerprints":{"codehealthFindingId/v1":"1035364c2b9d27ea740b77dbd3d2c2f784b04b54412a7c59ab8d36fa673d1f01"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): genesis/engine/solvers/rigid/rigid_solver.py:2042-2051 | genesis/engine/solvers/rigid/rigid_solver.py:2168-2177 | genesis/engine/solvers/rigid/rigid_solver.py:2461-2470 \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2042}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b49d3cfb780810d6a31a2f8bfd0bb1c352493cf491297656ef15cbd2f529dea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/entities/fem_entity.py:249-258 | genesis/engine/entities/particle_entity.py:138-147 \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 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"64c9a8a4660be44029cf30ef99095a659839b22fdfd70fa2a79fecb2f0644fa6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:604-612 | genesis/engine/sensors/kinematic_tactile.py:683-692 \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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":604}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccab4e0c0f8a93a251cd62f87983470ba8ebc58eff458894fd5074c5bb23ffb5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1089-1098 | genesis/engine/solvers/kinematic_solver.py:1158-1167 \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 \u0060genesis/engine/solvers/kinematic_solver.py:1089\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1089}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dd21ae7538db9ca1471b60046d9402e2c4c95386b0c4b32ec669358c45d5851"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1213-1222 | genesis/engine/solvers/rigid/rigid_solver.py:2476-2485 \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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1213}}}],"partialFingerprints":{"codehealthFindingId/v1":"49020d2fb70bf52077602a8c19f0a6b2d639d84f9fa5c1fc263935663d7e9059"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/mpm_solver.py:786-795 | genesis/engine/solvers/mpm_solver.py:809-818 \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 \u0060genesis/engine/solvers/mpm_solver.py:786\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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":786}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea71030ae643a8f3e619c1775e30541e962ad59ad0b65eb33767b3d61cc348d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/abd/accessor.py:43-52 | genesis/engine/solvers/rigid/abd/accessor.py:109-118 \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"1260d0d7ef872cb48f557ab7db06c6ddee9c61a4c5d2ec1db95e5431c2945877"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u201310 lines \u00D7 4): genesis/engine/solvers/rigid/abd/accessor.py:1208-1209 | genesis/engine/solvers/rigid/abd/accessor.py:1210-1211 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1579-1588 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1627-1636 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/abd/accessor.py:1210\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. 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":1208}}}],"partialFingerprints":{"codehealthFindingId/v1":"7110674efd3d3e68eb278ead81b83dff082fdf9a31bc5adf7134f022b8660890"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:446-454 | genesis/engine/solvers/rigid/collider/box_contact.py:717-726 \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5d4d3f81ba0bf1bf5bb9c4844ec9bc0a1a5ab4dd51f61161d135aafb5d12f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:1272-1281 | genesis/engine/solvers/rigid/collider/contact.py:1576-1585 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1272}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bc5619904f245123a2249d1972ccd944f0f2c4f25ff757ba62a1ec4bad96254"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u201310 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1286-1291 | genesis/engine/solvers/rigid/constraint/linesearch.py:1400-1409 \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. 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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1286}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfb104e5d33c93b0438addb6f7f3927495672ac7933aa1152234ffa0af3563cb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1310-1319 | genesis/engine/solvers/rigid/constraint/linesearch.py:1600-1609 \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 \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:1310\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1310}}}],"partialFingerprints":{"codehealthFindingId/v1":"586c668a6361042d279e6026d53c7392fad997444db7ad95e341f42f6359c0bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:3138-3145 | genesis/engine/solvers/rigid/constraint/solver.py:3195-3204 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3138}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c6ff2023a46276b113208004cc53ed4364dcd79d163888c3c5e7293cfba0ff9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5221-5230 | genesis/engine/solvers/rigid/constraint/solver.py:5515-5524 \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 \u0060genesis/engine/solvers/rigid/constraint/solver.py:5221\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5221}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0d65afc32a146cf5562159c66517b2d5948ce21728f5ad0fddf8bf63ce92b9f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:2759-2768 | genesis/engine/solvers/rigid/rigid_solver.py:2780-2789 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/rigid_solver.py:2777\u0060 calls \u0060qd_to_torch\u0060 and \u0060genesis/engine/solvers/rigid/rigid_solver.py:2757\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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2759}}}],"partialFingerprints":{"codehealthFindingId/v1":"73c63a41d3d8c5986f67cfbd6106060c0ef9c5dc984da0b0439579ed750f825b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:3097-3106 | genesis/engine/solvers/rigid/rigid_solver.py:3116-3125 \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":3097}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffed2c75cc1d6ad383c620fbb439e78d18344ed1543877708bb75118ac7c7498"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/ext/pyrender/jit_render.py:477-486 | genesis/ext/pyrender/jit_render.py:497-506 \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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":477}}}],"partialFingerprints":{"codehealthFindingId/v1":"105fe259b124187baf071c1ab47b659ec66f06f4e728b5fb39afff5447a798dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/ext/pyrender/scene.py:73-82 | genesis/ext/pyrender/scene.py:535-544 \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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30b9bc46c354beab0abc43893de05d81396df9c48b0da4156649f43a253e38b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): genesis/utils/path_planning.py:360-369 | genesis/utils/path_planning.py:707-715 \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":"genesis/utils/path_planning.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ca6364452b77b314d5702a17b3dd19df63d09fd21e27744d3e5094b888070c2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/utils/sdf.py:294-303 | genesis/utils/sdf.py:381-392 \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":"genesis/utils/sdf.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e8a7ef67ae375009583cbfdd7caf0282930ffadd5c54ba37886a31dcf53bcd4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/vis/rasterizer_context.py:1022-1031 | genesis/vis/rasterizer_context.py:1047-1056 \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":1022}}}],"partialFingerprints":{"codehealthFindingId/v1":"aece2dc883db88af8af907999897827804a01bc4d56cdbdeedc1b8fbb23623a1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:2878-2886 | genesis/engine/couplers/sap_coupler.py:3344-3352 | genesis/engine/couplers/sap_coupler.py:3882-3890 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2878}}}],"partialFingerprints":{"codehealthFindingId/v1":"d19bab0f71ad2870b9737020a1615634919fa473156aae9c87314efc64fe954c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): genesis/engine/sensors/point_cloud_tactile.py:450-458 | genesis/engine/sensors/point_cloud_tactile.py:1441-1449 | genesis/engine/sensors/point_cloud_tactile.py:1599-1607 \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. 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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":450}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6d67c3de00224adfd90e6764c1d1e577b34ea0203b0ed92671ce37a459e46c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:491-498 | genesis/engine/solvers/rigid/constraint/solver.py:721-729 | genesis/engine/solvers/rigid/constraint/solver.py:942-950 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2e0528eb8affa3065a4a49ea3f96cca906d1d71eb1c4b6cf4efb79b8ee9446e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/couplers/legacy_coupler.py:885-893 | genesis/engine/couplers/legacy_coupler.py:949-957 \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 \u0060genesis/engine/couplers/legacy_coupler.py:885\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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":885}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ec9800329624f1ee6c251df232baeb67fea4f98704d954b95d6ad98971d983a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:578-586 | genesis/engine/solvers/fem_solver.py:74-82 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb483d7c8576b9c0ac63f8d0f6e77a6165c8000701acc49ef72b437854093641"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2169-2177 | genesis/engine/couplers/sap_coupler.py:2214-2222 \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, \u0060genesis/engine/couplers/sap_coupler.py:2178\u0060 calls \u0060fill\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:2223\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2169}}}],"partialFingerprints":{"codehealthFindingId/v1":"53009c3d134a9fbb6eded2309df79609d0db7b973089da349383787c0626aa56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/entities/fem_entity.py:1141-1149 | genesis/engine/entities/particle_entity.py:737-745 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":1141}}}],"partialFingerprints":{"codehealthFindingId/v1":"3de9f31735ca97af5d9e2506e66d0c85646c5241c5fff8ac63bdf725e56ac458"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:992-1000 | genesis/engine/sensors/kinematic_tactile.py:1259-1267 \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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":992}}}],"partialFingerprints":{"codehealthFindingId/v1":"aea8db6a0f746bffb2f4c38199da50d153991f262367af4378b384e005c64e7e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20139 lines \u00D7 3): genesis/engine/solvers/rigid/abd/accessor.py:923-926 | genesis/engine/solvers/rigid/abd/diff.py:297-305 | genesis/engine/solvers/rigid/abd/inverse_kinematics.py:320-326 \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 all 3 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. 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":923}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dd140e2b59a221c23a95cf1f3e97ebe9f1144685cff2561e8837024d39a4148"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:968-976 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:983-991 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:968\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":968}}}],"partialFingerprints":{"codehealthFindingId/v1":"c23f69fab8cd365bfd8d3dc0d1016a7638487ae53bb6860a985de9756bcf7ec1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:1150-1158 | genesis/engine/solvers/rigid/collider/narrowphase.py:4029-4037 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1150}}}],"partialFingerprints":{"codehealthFindingId/v1":"893bb7c312b83f49b8af3107d2df37fb669d875a71f3af10b4935db19f653442"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1229-1237 | genesis/engine/solvers/rigid/constraint/linesearch.py:1583-1591 \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 \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:1229\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1229}}}],"partialFingerprints":{"codehealthFindingId/v1":"13740a227d7cf0ff8d8143ac05d1c9f4b301b552d0898acd7d3280eab3e53bc8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/noslip.py:197-205 | genesis/engine/solvers/rigid/constraint/noslip.py:486-494 \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 \u0060genesis/engine/solvers/rigid/constraint/noslip.py:197\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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"825d049b8dcda2fe8aa0422ccafde8f21b5ca30048c6b4347d9b54dcd0a83c89"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2311-2319 | genesis/engine/solvers/rigid/constraint/solver.py:2368-2376 \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 \u0060genesis/engine/solvers/rigid/constraint/solver.py:2311\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/constraint/solver.py:2320\u0060 calls \u0060static\u0060 and \u0060genesis/engine/solvers/rigid/constraint/solver.py:2377\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2311}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd1e7b8f52ca3397fdef097f0e52d2b6f8582d03ae110dceae41c069517739eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2374-2382 | genesis/engine/solvers/rigid/constraint/solver.py:2640-2648 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2374}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30b6099895df973a7707367754bd3ba4c8893e0b5822ac5272814f3c4000f5e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/ext/urdfpy/urdf.py:628-636 | genesis/ext/urdfpy/utils.py:258-266 \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":"genesis/ext/urdfpy/urdf.py"},"region":{"startLine":628}}}],"partialFingerprints":{"codehealthFindingId/v1":"88a17f780e3f88f98b451c59f9a9b3f94da5fb5eeb3705b4d7a43183cd3e6590"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): genesis/utils/usd/usd_rigid_entity.py:507-515 | genesis/utils/usd/usd_rigid_entity.py:610-617 \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":507}}}],"partialFingerprints":{"codehealthFindingId/v1":"c97c3b520c3145e332f9ef22995683a38ea6e254142a6c8d0d762a2118407c4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/vis/rasterizer_context.py:253-261 | genesis/vis/rasterizer_context.py:571-579 \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"e65aa0fac607cfe9194c5848b5fda8e5834581c186d8c2db1b7c26fba4de7162"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:2899-2906 | genesis/engine/couplers/sap_coupler.py:3554-3561 | genesis/engine/couplers/sap_coupler.py:3903-3910 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/couplers/sap_coupler.py:2898\u0060 calls \u0060zero\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:3552\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2899}}}],"partialFingerprints":{"codehealthFindingId/v1":"584aa3b65bf3ff9e64711e44ca2b3ba61505f007f42c19f7f8a9e6d456c399a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/solvers/fem_solver.py:559-566 | genesis/engine/solvers/fem_solver.py:573-580 | genesis/engine/solvers/fem_solver.py:613-620 \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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e0f46008104ed640ce2d058a3a61c4d3794fb7d985c97a15550352148c5452c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_dynamics.py:519-526 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:724-731 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:879-886 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:887\u0060 calls \u0060SharedArray\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:529\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":519}}}],"partialFingerprints":{"codehealthFindingId/v1":"06c1e2b2f4daffee45762203b551f200868201065ebeee19850b97464aeb9957"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_kinematics.py:523-530 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:755-763 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:976-983 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:519\u0060 calls \u0060template\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:751\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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":523}}}],"partialFingerprints":{"codehealthFindingId/v1":"079fb3c957e0135b409b0292fe619aca0c97a36d1a1bee290d3eb55d2727897b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:2241-2247 | genesis/engine/solvers/rigid/constraint/solver.py:2606-2613 | genesis/engine/solvers/rigid/constraint/solver.py:2802-2809 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/constraint/solver.py:2616\u0060 calls \u0060static\u0060 and \u0060genesis/engine/solvers/rigid/constraint/solver.py:2248\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2241}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc83413fe7a264c1537f455c429bdae21348dd3e4aa1c7d46109457550757970"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:2323-2330 | genesis/engine/solvers/rigid/constraint/solver.py:2489-2496 | genesis/engine/solvers/rigid/constraint/solver.py:2643-2650 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/constraint/solver.py:2320\u0060 calls \u0060static\u0060 and \u0060genesis/engine/solvers/rigid/constraint/solver.py:2642\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2323}}}],"partialFingerprints":{"codehealthFindingId/v1":"7da576ba2385bf24c8a55886280ae399177ccc6f721d651c1d2f8182b19fe1d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:2499-2506 | genesis/engine/solvers/rigid/constraint/solver.py:2577-2584 | genesis/engine/solvers/rigid/constraint/solver.py:2710-2717 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2499}}}],"partialFingerprints":{"codehealthFindingId/v1":"df4d51360886d31cf1c79e31454192f913556d5ee78f9ee547149940efae7034"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20138 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:3934-3941 | genesis/engine/solvers/rigid/constraint/solver.py:4016-4023 | genesis/engine/solvers/rigid/constraint/solver.py:4483-4488 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3934}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e866e32e60f70d5ef4d3ea39e48eb1bc4c395448bee316a0744672e3758f70b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:805-812 | genesis/engine/couplers/sap_coupler.py:3458-3465 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":805}}}],"partialFingerprints":{"codehealthFindingId/v1":"e869ab81eb207496a9b4afb99c0565060a4c62bdf8010628a6952c99022247cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2557-2564 | genesis/engine/couplers/sap_coupler.py:3256-3263 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2557}}}],"partialFingerprints":{"codehealthFindingId/v1":"b01ff9038e9dde50f3176095b4cc1843384e72782f701c9857c21aaf747e6694"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2828-2834 | genesis/engine/couplers/sap_coupler.py:3486-3493 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2828}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ffc398b86524467609c2ac23b785de54d102c460f10ec3de58435ab1dbfbee2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:375-382 | genesis/engine/sensors/surface_distance_probe.py:197-204 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"566f11e4875c5b92186acaf4e4bcaac65646c85913f1efa82316063ae977041f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:449-456 | genesis/engine/sensors/surface_distance_probe.py:242-249 \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, \u0060genesis/engine/sensors/surface_distance_probe.py:241\u0060 calls \u0060max\u0060 and \u0060genesis/engine/sensors/point_cloud_tactile.py:448\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":449}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cac31b61061d16fe26e141d88f11fe63f78631b7919771ed1b2093aab8ee452"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:245-252 | genesis/engine/solvers/pbd_solver.py:108-115 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/fem_solver.py:245\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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"e14d38163450eb7f4eabe273c74fe1f02c4a027e6e812d1891e6fce48e39bd37"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1204-1210 | genesis/engine/solvers/kinematic_solver.py:1259-1266 \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 \u0060genesis/engine/solvers/kinematic_solver.py:1259\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1204}}}],"partialFingerprints":{"codehealthFindingId/v1":"267be7646096d03ff4e1b6dbce566b13262248af87e98e160d78c6a2f864b67c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/mpm_solver.py:572-579 | genesis/engine/solvers/mpm_solver.py:583-590 \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 \u0060genesis/engine/solvers/mpm_solver.py:572\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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":572}}}],"partialFingerprints":{"codehealthFindingId/v1":"7131501e7ce0a5898bbe07c7eaa738265abbdad06a9919904704d8c26fe3f943"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:196-203 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1790-1796 \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, \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:204\u0060 calls \u0060func_add_safe_backward\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:1797\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"eda4692ca123b0c3c9a8d47b36dceda5769a4dbf899054c19fb334716835c597"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_kinematics.py:306-313 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1213-1220 \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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"73cf822b0b8c8332ef8ad29d631ddb9938af10ad17e278a4bb695593db718ec2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20138 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_kinematics.py:543-550 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:775-788 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1163-1166 \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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:539\u0060 calls \u0060template\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:771\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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f6ba7c34acad74a237a2b1c260ca3e7a6f0148f1a4ade46bcbb964f78a1292c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:469-476 | genesis/engine/solvers/rigid/collider/box_contact.py:760-767 \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 \u0060genesis/engine/solvers/rigid/collider/box_contact.py:469\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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":469}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0b33fa8d4e7f25a9230442b6f5cb92c1a90a26dc84523bf8d899e56f9b2b95d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:160-167 | genesis/engine/solvers/rigid/collider/narrowphase.py:709-716 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"349a0a9a627dd85619adba12762de65eb6c6734a24abdf2b125ca5c6b91a485c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:942-955 | genesis/engine/solvers/rigid/collider/narrowphase.py:960-967 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:942\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":942}}}],"partialFingerprints":{"codehealthFindingId/v1":"28f065391e6759ef50636f9959b8a5710104b6481d6c36bb1b669f23c8c72d1f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2579-2588 | genesis/engine/solvers/rigid/collider/narrowphase.py:3294-3301 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2579}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6cbf3c97ba33385fcbb305b4769181f6c4496fcaf7d8f9848f6ee6ae42eadd0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:837-844 | genesis/engine/solvers/rigid/constraint/solver.py:1396-1403 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":837}}}],"partialFingerprints":{"codehealthFindingId/v1":"a04bf56733f8ad06be9504981e3917b4c79d9e0bf3b2e0bf7c1e23616a862d03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:791-798 | genesis/engine/solvers/rigid/constraint/linesearch.py:920-927 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":791}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dc6032de4cefff1129cedc7b01b3230e8b61ff57233b5c4b448319b4e96d543"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/noslip.py:133-140 | genesis/engine/solvers/rigid/constraint/noslip.py:184-191 \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 \u0060genesis/engine/solvers/rigid/constraint/noslip.py:133\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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1ef2ee85a735cf6a30547caff59fccf2fad3e7797355123812bc358d0ab3c3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/noslip.py:211-218 | genesis/engine/solvers/rigid/constraint/noslip.py:226-232 \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 \u0060genesis/engine/solvers/rigid/constraint/noslip.py:211\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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a38130061b86400e325ed384b00e95d54d2cd32c751ba38fea163b8c044b16e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/ext/pyrender/camera.py:181-188 | genesis/ext/pyrender/camera.py:381-388 \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":"genesis/ext/pyrender/camera.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bc44c56bcd95753d2c74cfa94bd0a6787f1d568fa991787266010b033085311"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/options/solvers.py:796-803 | genesis/options/solvers.py:874-881 \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":"genesis/options/solvers.py"},"region":{"startLine":796}}}],"partialFingerprints":{"codehealthFindingId/v1":"d721870c97e9426b075bfd0c235d4e79bd849706a8a8e726fa295149d63d8732"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): genesis/utils/geom.py:658-665 | genesis/utils/geom.py:688-694 \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":"genesis/utils/geom.py"},"region":{"startLine":658}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf2ad6d989f25c6a1e8615663f0d3ffcb76f8bc9a37342bc7fcdc63bbc31bf5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/vis/raytracer.py:285-292 | genesis/vis/raytracer.py:299-306 \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":"genesis/vis/raytracer.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6babd3e3668a8a1bc2a076248bc70ebe8f797efb41b5e8665a1459da3a4212f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 5): genesis/engine/solvers/rigid/abd/accessor.py:42-48 | genesis/engine/solvers/rigid/abd/accessor.py:74-80 | genesis/engine/solvers/rigid/abd/accessor.py:108-114 | genesis/engine/solvers/rigid/abd/accessor.py:148-154 | genesis/engine/solvers/rigid/abd/accessor.py:188-194 \u2014 all 5 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f81ba3519ce17e98a547f9686d40dca3203dc775d2e7f6b4069da1a43e8a8b5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20137 lines \u00D7 4): genesis/engine/couplers/legacy_coupler.py:373-378 | genesis/engine/couplers/legacy_coupler.py:394-400 | genesis/engine/couplers/legacy_coupler.py:612-617 | genesis/engine/couplers/legacy_coupler.py:633-638 \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 \u0060genesis/engine/couplers/legacy_coupler.py:373\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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"2350fd03939728bea340bbb8979e9e205d5b46c0f18d3d6a04f0f2908c1c00ec"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): genesis/engine/couplers/sap_coupler.py:2533-2539 | genesis/engine/couplers/sap_coupler.py:3356-3362 | genesis/engine/couplers/sap_coupler.py:3582-3588 | genesis/engine/couplers/sap_coupler.py:3939-3945 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2533}}}],"partialFingerprints":{"codehealthFindingId/v1":"20c5eeefa19127bd36fde3a703dd7fa9644d8ec60028dc972874a3ed06009cb0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:1989-1995 | genesis/engine/solvers/rigid/constraint/solver.py:5223-5229 | genesis/engine/solvers/rigid/constraint/solver.py:5517-5523 \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 \u0060genesis/engine/solvers/rigid/constraint/solver.py:1989\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":1989}}}],"partialFingerprints":{"codehealthFindingId/v1":"b42099ffad90762263c2fa6a5318dc0544e71a49c3cc4157eefe334418b9a405"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:5008-5014 | genesis/engine/solvers/rigid/constraint/solver.py:5076-5082 | genesis/engine/solvers/rigid/constraint/solver.py:5121-5127 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5008}}}],"partialFingerprints":{"codehealthFindingId/v1":"692bf730b6e9c28362e17dbcd6de338ba45d8d62eb50b21ece30a794633d4fe9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20137 lines \u00D7 4): genesis/options/surfaces.py:415-418 | genesis/options/surfaces.py:499-505 | genesis/options/surfaces.py:589-595 | genesis/options/surfaces.py:686-692 \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. 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":"genesis/options/surfaces.py"},"region":{"startLine":415}}}],"partialFingerprints":{"codehealthFindingId/v1":"2659d9a75a000299dbba1b7cbfd277e442c5cdd069ff9e275f96fc782f8120b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5\u20137 lines \u00D7 3): genesis/vis/rasterizer_context.py:1023-1027 | genesis/vis/rasterizer_context.py:1048-1052 | genesis/vis/rasterizer_context.py:1067-1073 \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 \u0060genesis/vis/rasterizer_context.py:1023\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":1023}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0be206835d4fd336f32c66cee7d7f2753d4402c950d40e0fa34ff52bcc4bcd9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/bvh.py:332-338 | genesis/engine/bvh.py:348-354 \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 \u0060genesis/engine/bvh.py:332\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":"genesis/engine/bvh.py"},"region":{"startLine":332}}}],"partialFingerprints":{"codehealthFindingId/v1":"8638eb7b27b3bace80ad78533bd5a44a8e2eb82d19d90d83edc72c49684788a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2955-2961 | genesis/engine/couplers/sap_coupler.py:3604-3610 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2955}}}],"partialFingerprints":{"codehealthFindingId/v1":"de130af36fd2e32ddf4366fa248b848fac4dcb7d7c17b3c77b39ef09e2b881b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3161-3167 | genesis/engine/couplers/sap_coupler.py:3171-3177 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3161}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbe8fe192c41059afb8f6fdab6460020c275e5c2f972f5a518d5fd0d53ba7cc4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:283-289 | genesis/engine/sensors/surface_distance_probe.py:54-60 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"344bac7b0e369bcda26530030100be4c7a7345a4542c1a64e37038f12d7a0bea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:306-312 | genesis/engine/sensors/surface_distance_probe.py:104-110 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"be0310b152a27bac14eff02fde7a9ff63eb4041becd369bdcb06e7c840c15245"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:426-432 | genesis/engine/sensors/surface_distance_probe.py:221-227 \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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":426}}}],"partialFingerprints":{"codehealthFindingId/v1":"8adceaf75d68352ccafb171d3880744398a69624913972e2e9c87e249a2ee9bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:1162-1168 | genesis/engine/solvers/fem_solver.py:1240-1246 \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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1162}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4d0fe8e0af29929de54f3e4f4d57ebe61826337cae0ad5a9a60515512c61b5e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1197-1203 | genesis/engine/solvers/rigid/rigid_solver.py:2454-2460 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/rigid_solver.py:2453\u0060 calls \u0060qd_to_torch\u0060 and \u0060genesis/engine/solvers/kinematic_solver.py:1196\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1197}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9eaa28fb533c4a05a70cf3c243313599b50a9a756c78416b94f15f1cd9e0e50"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:222-228 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1813-1819 \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 before the matched lines, \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:1809\u0060 calls \u0060static\u0060, \u0060loop_config\u0060, \u0060ndrange\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:220\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"f72dda153212709d70e74c6d72a381f8e846ce8f1589ff9d43d82396910ab7ab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:604-613 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:945-951 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:604\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":604}}}],"partialFingerprints":{"codehealthFindingId/v1":"75efe91cf25b1bad7a092c2680f8e51f04483446fb73be741c543f92d02460a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:754-760 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:830-836 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:754\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":754}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfe623712fba11cf87e60106cc6ec9cbd1d3f3e5e34480a5bdb6b4fdd33e3d4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1411-1419 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1495-1501 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1411}}}],"partialFingerprints":{"codehealthFindingId/v1":"e71340b6d937a9f5cde0d66ea40cf6510673c154fbc2b222417f28caeae7c4fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/inverse_kinematics.py:780-786 | genesis/engine/solvers/rigid/abd/inverse_kinematics.py:800-806 \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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":780}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b11f742dae8811c890e9b0fdf3a22bc98cb8f6e087ba35d5dcb1a6659ff7da5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/collider/collider.py:832-838 | genesis/engine/solvers/rigid/constraint/solver.py:288-294 \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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":832}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa69a8495ee97a025913de7ff503ef32a5cc53bcefc6bac623ef73f9336a4269"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/collider/mpr.py:592-598 | genesis/engine/solvers/rigid/collider/mpr.py:638-644 \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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":592}}}],"partialFingerprints":{"codehealthFindingId/v1":"9353fd5ece60d5c293256ab19e8bdd64bad5bc0cdffcb724b04070b72d8aa5d5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2494-2504 | genesis/engine/solvers/rigid/collider/narrowphase.py:4016-4022 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:2494\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2494}}}],"partialFingerprints":{"codehealthFindingId/v1":"141024fd18f847c4d0619b5c90c3c164e5bd7f1a30e7376c5fae3f5945bef9da"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:238-244 | genesis/engine/solvers/rigid/constraint/solver.py:4718-4724 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"85c7dc325d6e815c1e3afe0e1858e0da640217ef505c5c0313c2420fe32169b5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:879-885 | genesis/engine/solvers/rigid/constraint/linesearch.py:1086-1092 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":879}}}],"partialFingerprints":{"codehealthFindingId/v1":"33783f9dca083cf50c665873be53081c5b7abb72fc82f1a7553aa8d4d5a1e7ab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1138-1144 | genesis/engine/solvers/rigid/constraint/linesearch.py:1622-1628 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1138}}}],"partialFingerprints":{"codehealthFindingId/v1":"57c7d1c0a7a5af784206359b2ad2f99a57571aedeba6c58ced8b60f0f48e3145"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:3050-3056 | genesis/engine/solvers/rigid/constraint/solver.py:3065-3071 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3050}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ae25578fac1d14ad2f01e22831cd05a16aa57f134f69f6b17a6e6a170abdbec"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:2083-2091 | genesis/engine/solvers/rigid/rigid_solver.py:2222-2228 \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2083}}}],"partialFingerprints":{"codehealthFindingId/v1":"990260ef4f4a9d0e45d25441df5be4fca0f1b9cb076cf45d99e9e679e9f9a1bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/sph_solver.py:488-496 | genesis/engine/solvers/sph_solver.py:596-602 \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 \u0060genesis/engine/solvers/sph_solver.py:488\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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbf673827f9fd82ed9de78884d624865754f3abc7451931578c4410df1162592"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/utils/urdf.py:346-354 | genesis/utils/urdf.py:358-364 \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 \u0060genesis/utils/urdf.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":"genesis/utils/urdf.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc80b7b92cdae78ec59b097a162053a9241078ceee00fb179720171950834bda"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/vis/rasterizer_context.py:928-934 | genesis/vis/rasterizer_context.py:951-957 \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":928}}}],"partialFingerprints":{"codehealthFindingId/v1":"73e3e8764b0237a611d160f8fd7dce1c4b5c5aaac336d800b27c35539da15bd9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/vis/raytracer.py:734-740 | genesis/vis/raytracer.py:753-759 \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 \u0060genesis/vis/raytracer.py:734\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":"genesis/vis/raytracer.py"},"region":{"startLine":734}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccc8f547114e1db7711891e24bfd5b6627d93b9bb559cfb39a7c74933f740f49"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): genesis/engine/solvers/rigid/abd/accessor.py:221-226 | genesis/engine/solvers/rigid/abd/accessor.py:338-343 | genesis/engine/solvers/rigid/abd/accessor.py:365-370 | genesis/engine/solvers/rigid/abd/accessor.py:390-395 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e875c7ecafce75b7702104e8005844b3c516ae0b3a44374be303d4ba22070c7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:2890-2895 | genesis/engine/couplers/sap_coupler.py:3546-3551 | genesis/engine/couplers/sap_coupler.py:3894-3899 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/couplers/sap_coupler.py:2898\u0060 calls \u0060zero\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:3554\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2890}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e8e9dd1d72061b0d0dcc87d386aaca02fd7b54b8186f2f7f9e10e388ea11576"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/engine/solvers/rigid/abd/diff.py:62-67 | genesis/engine/solvers/rigid/abd/diff.py:98-103 | genesis/engine/solvers/rigid/abd/diff.py:120-125 \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":"genesis/engine/solvers/rigid/abd/diff.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"9145574f831cb5e38a051119d4d788ff20cf7cc14ed91b21c12e7c0830554321"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:587-592 | genesis/engine/solvers/rigid/constraint/backward.py:1047-1052 | genesis/engine/solvers/rigid/constraint/backward.py:1246-1251 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ffd701c32eb48823a98d58a46bb10742bb9907f13a2ec47e44be150866c19d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/utils/geom.py:893-898 | genesis/utils/geom.py:1004-1009 | genesis/utils/geom.py:1079-1085 \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":"genesis/utils/geom.py"},"region":{"startLine":893}}}],"partialFingerprints":{"codehealthFindingId/v1":"438671c9cd2fe1e1ffaae0c3ddb5baca3cdd280818c7ad12ccc6990a29ce7db5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/utils/watertighten.py:100-105 | genesis/utils/watertighten.py:109-114 | genesis/utils/watertighten.py:118-123 \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":"genesis/utils/watertighten.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"20cd0726029dfff2974b5ca0e5f3c96fde636f4d39c1450f0eb5e1febe42e348"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1143-1148 | genesis/engine/couplers/sap_coupler.py:1162-1167 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1143}}}],"partialFingerprints":{"codehealthFindingId/v1":"729115f3fc51419ce14c160450f2a4266bef4a8c7092bdf70457b037239dc2cd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:89-94 | genesis/engine/entities/sph_entity.py:187-192 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"50139c89713f9490b80a6c95da7a7f3e436db4a33d8343c603c36b1af4d3c40e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): genesis/engine/entities/pbd_entity.py:234-237 | genesis/engine/entities/pbd_entity.py:624-629 | genesis/engine/entities/pbd_entity.py:697-702 \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":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"e44a7423ffe118e2490b9d3a1b396abf65d6aec892cf7c24185421fc2a31ecf8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/rigid_entity/description.py:1379-1384 | genesis/engine/entities/rigid_entity/description.py:1791-1796 \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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1379}}}],"partialFingerprints":{"codehealthFindingId/v1":"45fd322e42f16579181166a35b62df7fe7132d8cfde1e9e5d24dc3950ae42943"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:511-516 | genesis/engine/solvers/fem_solver.py:518-523 \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 \u0060genesis/engine/solvers/fem_solver.py:511\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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcb8ef9f5dab8e0c5e3cf8da8846c7d665f06dbdc4211efbfe44081a5202c0a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/mpm_solver.py:896-901 | genesis/engine/solvers/pbd_solver.py:897-902 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/mpm_solver.py:896\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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":896}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d3dda323a4729874d87aee1bcf9c51081886656a36d908353dee17bc4c02e52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:609-614 | genesis/engine/solvers/pbd_solver.py:686-691 \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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"dedd209e8962dc60167cbb751a3de2ac8ec03c0069fe990845e85ec8f4e6f03f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): genesis/engine/solvers/rigid/abd/accessor.py:995-998 | genesis/engine/solvers/rigid/abd/accessor.py:1013-1018 | genesis/engine/solvers/rigid/abd/accessor.py:1032-1037 \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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/abd/accessor.py:1013\u0060 calls \u0060ndrange\u0060 and \u0060genesis/engine/solvers/rigid/abd/accessor.py:995\u0060 does not \u2014 after which the two agree again for 5 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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":995}}}],"partialFingerprints":{"codehealthFindingId/v1":"e217d2fabc0fe938ab9f5a5577c63ff355e891b0d565dc77bfed15d562d8c7f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/accessor.py:1273-1278 | genesis/engine/solvers/rigid/abd/accessor.py:1344-1349 \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":1273}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b69413eccc1cd0bfc60936bd6834b588765e4e8c039cfd606ffd190bffd1267"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:49-54 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:70-75 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"d821b0d093be491a1242384bbdd6765762a2a4de8f0d2e101a04b8a5d771ae45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1040-1045 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1098-1103 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:1040\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1040}}}],"partialFingerprints":{"codehealthFindingId/v1":"961901ac7f43d842203ae2b9b04ceb75366cc94c51cf3a548a8e2866e4535d14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1195-1200 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1226-1231 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:1195\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1195}}}],"partialFingerprints":{"codehealthFindingId/v1":"db6bf5861c375f5f056d89c860456023cc7f9902ad632b335b346fa0c98b8863"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1656-1662 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:2198-2203 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1656}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea6b29bebf80cd7377c5f408e755fc0db55bb8317a503f6c4c511ef7f5baf7a7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:2180-2187 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:2263-2268 \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 \u0060genesis/engine/solvers/rigid/abd/forward_dynamics.py:2180\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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2180}}}],"partialFingerprints":{"codehealthFindingId/v1":"462ed65d9770770a1048193f0a0d3fad725436a37998f94444ce5ebf97925b5a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/manual_bw.py:261-266 | genesis/engine/solvers/rigid/abd/manual_bw.py:443-448 \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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"768721db991e6c88abd21c9458d2e1acdc1aa74482eaf71711ed00271dd353d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/misc.py:500-505 | genesis/engine/solvers/rigid/abd/misc.py:542-547 \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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":500}}}],"partialFingerprints":{"codehealthFindingId/v1":"51945b27368e9272539628ff3c04bf4a0b40a1db482ddf1bf5e52ed2e91410fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:459-464 | genesis/engine/solvers/rigid/collider/box_contact.py:747-756 \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 \u0060genesis/engine/solvers/rigid/collider/box_contact.py:459\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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":459}}}],"partialFingerprints":{"codehealthFindingId/v1":"775310ab76851ff66b14268607f5fbe0915af10a02f47de5593e92b000e84b82"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:631-636 | genesis/engine/solvers/rigid/collider/box_contact.py:646-651 \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 \u0060genesis/engine/solvers/rigid/collider/box_contact.py:631\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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":631}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba6543c6b91b61908076b00c6de271d1f051c2fd28742ba8c0364d9de3dfda27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:690-695 | genesis/engine/solvers/rigid/collider/box_contact.py:700-705 \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":690}}}],"partialFingerprints":{"codehealthFindingId/v1":"34ce656091ee3a4f71151a7959021d467ee7148d503ed92faa977a17c47861c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/collider/capsule_contact.py:43-50 | genesis/engine/solvers/rigid/collider/capsule_contact.py:182-187 \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":"genesis/engine/solvers/rigid/collider/capsule_contact.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"29dc41a98076913b50aaa9dd8a9eaf5fdfaddefd0357f75dea78360cebbb60a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:4029-4034 | genesis/engine/solvers/rigid/collider/narrowphase.py:4575-4589 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:4575\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4029}}}],"partialFingerprints":{"codehealthFindingId/v1":"d45c0a4d9242756363cc86b589bc91df2c7f24389b4729e8def5d3c3540a2119"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:850-855 | genesis/engine/solvers/rigid/constraint/solver.py:1406-1411 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":850}}}],"partialFingerprints":{"codehealthFindingId/v1":"725d5f6434a72c98de2a446f85178e043874269c9684aca78dcdc57df9e1118d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:693-698 | genesis/engine/solvers/rigid/constraint/linesearch.py:738-744 \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 \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:738\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":693}}}],"partialFingerprints":{"codehealthFindingId/v1":"51de9bdedc08d28685983415211176f820aadc7751651720b04d19ed102db114"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:1308-1313 | genesis/engine/solvers/rigid/constraint/linesearch.py:1434-1439 \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 \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:1308\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:1440\u0060 calls \u0060Vector\u0060 and \u0060genesis/engine/solvers/rigid/constraint/linesearch.py:1314\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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1308}}}],"partialFingerprints":{"codehealthFindingId/v1":"1514491ff1724a51ac0c9502bdc38aa5e753c243a2265c09461d4d113d8afbc6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:2337-2340 | genesis/engine/solvers/rigid/constraint/solver.py:2396-2401 | genesis/engine/solvers/rigid/constraint/solver.py:2510-2515 \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. 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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2337}}}],"partialFingerprints":{"codehealthFindingId/v1":"5543a70af403186955bb149fcd8e9e16640313712312497c05fcaf039bd70c69"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/solver.py:3117-3122 | genesis/engine/solvers/rigid/constraint/solver.py:3158-3161 | genesis/engine/solvers/rigid/constraint/solver.py:3241-3246 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3117}}}],"partialFingerprints":{"codehealthFindingId/v1":"85a7c07e720d68f49019d008b373890f6147eca8960f7b9eb635ce4a47756422"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5016-5021 | genesis/engine/solvers/rigid/constraint/solver.py:5129-5134 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5016}}}],"partialFingerprints":{"codehealthFindingId/v1":"1186a420eda251d2d20f71bb00003008ac5ed8df3fea0f4ee86d47648c33971b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:2057-2062 | genesis/engine/solvers/rigid/rigid_solver.py:2183-2188 \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 \u0060genesis/engine/solvers/rigid/rigid_solver.py:2057\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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2057}}}],"partialFingerprints":{"codehealthFindingId/v1":"4af247fbcb8b370c866a6e979774c9fb91f22d111f4c194eea29ab19c3185863"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/ext/isaacgym/terrain_utils.py:35-40 | genesis/utils/terrain.py:214-219 \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":"genesis/ext/isaacgym/terrain_utils.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"9641a4b18ee61a6dcbe8d5ff7b274622dec8240b74dc0f43ec8a67c731def2fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20136 lines \u00D7 3): genesis/utils/geom.py:209-214 | genesis/utils/geom.py:239-244 | genesis/utils/geom.py:1018-1019 \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":"genesis/utils/geom.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"987b70a85cede4ad46836afde68a15ab979f6b306ab65cf352ed8deb903d80dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/path_planning.py:530-535 | genesis/utils/path_planning.py:913-918 \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":"genesis/utils/path_planning.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"013b320478acac2b5fac88ccf23d89b1fe6462f69109eedb5b3c5bb17ffb6d83"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/path_planning.py:587-592 | genesis/utils/path_planning.py:977-982 \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":"genesis/utils/path_planning.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0d1ea12d774624f46b05882c3e5b44caa82e8a325311b7e13bd63f39f0c0c91"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/sdf.py:316-321 | genesis/utils/sdf.py:427-432 \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 \u0060genesis/utils/sdf.py:316\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/utils/sdf.py:315\u0060 calls \u0060qd_float\u0060 and \u0060genesis/utils/sdf.py:426\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":"genesis/utils/sdf.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"8adff764f8461a1975ab97117163a029f95f2a603d40f8477e17702c3f205402"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/urdf.py:333-339 | genesis/utils/urdf.py:351-356 \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":"genesis/utils/urdf.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"472635c6757404f78554bd2b36b511e42a2c4ad6d5bb7d6fe531b0b1de1e7396"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/vis/rasterizer_context.py:718-723 | genesis/vis/rasterizer_context.py:789-794 \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 \u0060genesis/vis/rasterizer_context.py:718\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/vis/rasterizer_context.py:716\u0060 calls \u0060qd_to_numpy\u0060 and \u0060genesis/vis/rasterizer_context.py:786\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":718}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2a7cd4f49050fa51ae05e616e0870ccb77f30e3fa37f3a943f24a7bd0dbbf42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): genesis/engine/solvers/rigid/constraint/backward.py:584-588 | genesis/engine/solvers/rigid/constraint/backward.py:1043-1048 | genesis/engine/solvers/rigid/constraint/backward.py:1242-1247 | genesis/engine/solvers/rigid/constraint/solver.py:995-1000 | genesis/engine/solvers/rigid/constraint/solver.py:1805-1810 \u2014 there are 5 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 5 sites; resolving a subset leaves the remainder to drift apart. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/constraint/backward.py:583\u0060 calls \u0060qd_float\u0060 and \u0060genesis/engine/solvers/rigid/constraint/backward.py:1042\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":584}}}],"partialFingerprints":{"codehealthFindingId/v1":"814413c7319cc7bc72a801432d434beb7856653be2108f528cb142514292c32f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): genesis/engine/solvers/pbd_solver.py:564-568 | genesis/engine/solvers/pbd_solver.py:609-613 | genesis/engine/solvers/pbd_solver.py:631-635 | genesis/engine/solvers/pbd_solver.py:686-690 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2439bb4a0f954e3491813f040326f0ea7a85d6f33364f0a805dc4f6d0b650da"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): genesis/engine/solvers/rigid/constraint/backward.py:587-591 | genesis/engine/solvers/rigid/constraint/backward.py:1047-1051 | genesis/engine/solvers/rigid/constraint/backward.py:1246-1250 | genesis/engine/solvers/rigid/constraint/solver.py:790-794 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e396359d6c3275abd27fb92aed7681cb3cff641ce86650006500853fd7d1867"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/couplers/sap_coupler.py:3025-3029 | genesis/engine/couplers/sap_coupler.py:3049-3053 | genesis/engine/couplers/sap_coupler.py:3074-3078 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3025}}}],"partialFingerprints":{"codehealthFindingId/v1":"af6f9c46e3dc2800fbe0ffb8aba750bd9de11f96ccd7eaeb90590a41d492c228"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/entities/tool_entity/mesh.py:97-101 | genesis/engine/solvers/sf_solver.py:196-200 | genesis/engine/solvers/sf_solver.py:219-223 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/tool_entity/mesh.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab3b1c88f8dd833387efd9016e5c17ad73bb4a8ef8a7d60806f755a57b0d4386"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/materials/FEM/elastic.py:185-189 | genesis/engine/materials/FEM/elastic.py:206-210 | genesis/engine/materials/FEM/elastic.py:217-221 \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":"genesis/engine/materials/FEM/elastic.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"237feca893b4a7ef10568aa92603db564d352b0f505ed171bb510bca8eb1933f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/abd/accessor.py:462-467 | genesis/engine/solvers/rigid/abd/accessor.py:507-511 | genesis/engine/solvers/rigid/abd/accessor.py:550-554 \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":462}}}],"partialFingerprints":{"codehealthFindingId/v1":"697dddc77fe57d92e361bf47e29e70009c1fe8f4638fa3cc1a71fc1c3e82e80f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1656-1660 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1813-1817 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:2198-2202 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1656}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea3f7f101c618c7f21abab14842bb8a739e286144e65d1a4eb2e3ce87383952c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_kinematics.py:559-563 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:805-809 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1192-1196 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:1197\u0060 calls \u0060func_forward_kinematics_link\u0060 and \u0060genesis/engine/solvers/rigid/abd/forward_kinematics.py:564\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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dd73c8db8db9f752617f667b2681a4ed8e793dbe76f2eb61dec1735705a8238"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:933-937 | genesis/engine/solvers/rigid/collider/narrowphase.py:954-958 | genesis/engine/solvers/rigid/collider/narrowphase.py:966-970 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":933}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0cffa5f1adfcb21e5cff9fa0f031037a022b5039e2c191d4bdb3815670ee72c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/collider/narrowphase.py:2499-2504 | genesis/engine/solvers/rigid/collider/narrowphase.py:3213-3217 | genesis/engine/solvers/rigid/collider/narrowphase.py:4018-4022 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:2499\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2499}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff32de01007ac6f2747eb5ee8c56c923445f775efb13572d1c6ad21a657dc2c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/backward.py:584-588 | genesis/engine/solvers/rigid/constraint/backward.py:1318-1323 | genesis/engine/solvers/rigid/constraint/solver.py:995-1000 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":584}}}],"partialFingerprints":{"codehealthFindingId/v1":"e64d44907e3e52a037c0c3861d0118ae332d8b6e6480fa36c6aa40917784b86d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/constraint/linesearch.py:1259-1263 | genesis/engine/solvers/rigid/constraint/linesearch.py:1383-1387 | genesis/engine/solvers/rigid/constraint/linesearch.py:1514-1518 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1259}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7333618d4a235cf665fbb48d50ce86ca898d65207d633b53699f7fd8e17d8b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/utils/watertighten.py:360-364 | genesis/utils/watertighten.py:372-376 | genesis/utils/watertighten.py:384-388 \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":"genesis/utils/watertighten.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2d783cc33a10e78cd855db6b13de2185c7301f38e524111d2972b9f7ed4cd0d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/vis/rasterizer_context.py:685-689 | genesis/vis/rasterizer_context.py:756-760 | genesis/vis/rasterizer_context.py:822-827 \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 \u0060genesis/vis/rasterizer_context.py:685\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":685}}}],"partialFingerprints":{"codehealthFindingId/v1":"48f52afed731df1dd4ea0af9ae1886f69813586ae79588991b4a7cde9dd56223"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/bvh.py:159-163 | genesis/engine/bvh.py:228-232 \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 \u0060genesis/engine/bvh.py:159\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":"genesis/engine/bvh.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"a49a2c25c4e2f0dd3e316f2f8f36b3facda1a69fbc5432633047ef6d7b241f66"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1078-1082 | genesis/engine/couplers/sap_coupler.py:1444-1449 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1078}}}],"partialFingerprints":{"codehealthFindingId/v1":"e829f5fe3971cc45eab784066880d39ec9e0f602c8622da325393f700fe1a647"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1084-1088 | genesis/engine/couplers/sap_coupler.py:1451-1455 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1084}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e1517030216410fa4ab46a110f74663bc1da4846581f20c607a230e306cee2e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1564-1568 | genesis/engine/couplers/sap_coupler.py:1585-1589 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1564}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdcb5ecc2da487c3638e6fc0c487e1b0c91a20f64145515b1630cf0acd7a91fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1574-1578 | genesis/engine/couplers/sap_coupler.py:1596-1600 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1574}}}],"partialFingerprints":{"codehealthFindingId/v1":"67c16a34a0fefe1c0e71b8e3512a4dc22cb7362826ac1089efeb286114968735"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20135 lines \u00D7 6): genesis/engine/couplers/sap_coupler.py:2694-2698 | genesis/engine/couplers/sap_coupler.py:2706-2710 | genesis/engine/couplers/sap_coupler.py:3032-3034 | genesis/engine/couplers/sap_coupler.py:3038-3041 | genesis/engine/couplers/sap_coupler.py:3055-3058 | genesis/engine/couplers/sap_coupler.py:3062-3065 \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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/couplers/sap_coupler.py:2698\u0060 calls \u0060static\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:3034\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2694}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e53a948dd5593be6537d4a6000ec10cd23dda83f2562783c92f8c7d0c1fdcd2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2810-2814 | genesis/engine/couplers/sap_coupler.py:2816-2820 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2810}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2698610cdb87828b582fd90c5b61081b7c2c6d3dcbded5e945cb329ce66ca5e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3027-3031 | genesis/engine/couplers/sap_coupler.py:3708-3714 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3027}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ee1cb13e57811e3acf4b985c0db55be4443d38615d856afaa1d51350136da24"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3264-3268 | genesis/engine/couplers/sap_coupler.py:3760-3764 \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 \u0060genesis/engine/couplers/sap_coupler.py:3264\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3264}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11d98ba42f3989a9e298032648d7318d2f3fdee82706a3ae18334cbcf14fa2b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20135 lines \u00D7 4): genesis/engine/couplers/sap_coupler.py:3204-3205 | genesis/engine/couplers/sap_coupler.py:3270-3274 | genesis/engine/couplers/sap_coupler.py:3435-3436 | genesis/engine/couplers/sap_coupler.py:3770-3774 \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 \u0060genesis/engine/couplers/sap_coupler.py:3270\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. 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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3204}}}],"partialFingerprints":{"codehealthFindingId/v1":"94736d39bd2a5f5dde81108018fe6b2fda9229ff72ab78f5b84b87d15fa176b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3706-3710 | genesis/engine/couplers/sap_coupler.py:3724-3728 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3706}}}],"partialFingerprints":{"codehealthFindingId/v1":"d144079d57630fa808ff1478f646c0f9766462391685d6656f0dbc4b3c911867"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:3817-3821 | genesis/engine/couplers/sap_coupler.py:3823-3827 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3817}}}],"partialFingerprints":{"codehealthFindingId/v1":"403b5b5d1ae02ca7d95a053689cd4c561bd97551a370f5a411a711faadb55850"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/fem_entity.py:288-292 | genesis/engine/entities/fem_entity.py:336-340 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b2764c357a335fbd2ef6afe39c4bab87e2c37be9ddacf653dcd50ce9c889775"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:50-54 | genesis/engine/entities/sph_entity.py:145-149 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6d120ecdfdeba8629cc5405ca2d469a9a4945a39aa8168610c78294ab30ca8b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:58-62 | genesis/engine/entities/sph_entity.py:153-157 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/entities/sph_entity.py:159\u0060 calls \u0060get_position\u0060, \u0060get_particles_pos\u0060 and \u0060genesis/engine/entities/pbd_entity.py:64\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":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a3ccb6ae7ac450a9b4ee7086fb5246786dcf5aabb3d54c336e0c9b0151e322f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:66-70 | genesis/engine/entities/sph_entity.py:164-168 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d0d6319566e255b25ab9bb41e127156898d08a0e5f85d6a74ed01affc8a1b87"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:74-78 | genesis/engine/entities/sph_entity.py:172-176 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5683793037adaa6c8fb982d0ec468c917bb7c43c3391af0d7a349e97501d97b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/rigid_entity/rigid_geom.py:279-283 | genesis/engine/entities/rigid_entity/rigid_link.py:514-518 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/entities/rigid_entity/rigid_geom.py:279\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. 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":"genesis/engine/entities/rigid_entity/rigid_geom.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"3500076d6c31355bbf13d3c77b10912ee796ae9616570b07b653b0726157422d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/sensors/point_cloud_tactile.py:1410-1414 | genesis/engine/sensors/point_cloud_tactile.py:1570-1574 \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 \u0060genesis/engine/sensors/point_cloud_tactile.py:1410\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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":1410}}}],"partialFingerprints":{"codehealthFindingId/v1":"699d0819374f27479359903dbfc97dd74d157557cc9674e45cc18d08ea553358"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:844-848 | genesis/engine/solvers/rigid/rigid_solver.py:1206-1210 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/kinematic_solver.py:844\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":844}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bade3606870304d6c447ec4e53e2c1c3a8d98568d512f86c47df7df0d576f12"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1147-1151 | genesis/engine/solvers/rigid/rigid_solver.py:2208-2217 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/kinematic_solver.py:1147\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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1147}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b013f331b370cad42b627cd5fca4e52e7d35bfb7ff25af1b6354550d50997f0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:399-403 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:458-462 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"2baa7c43096b9433e220efbef7687aeeead9aa3c0dd8c76e7884962c7772f86a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:571-575 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:593-597 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":571}}}],"partialFingerprints":{"codehealthFindingId/v1":"00da62b2fb880d74eecf37934d5f85467e0a5cf8cb72aa2d8ff8a78888c57ff2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1033-1037 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1091-1095 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1033}}}],"partialFingerprints":{"codehealthFindingId/v1":"1828d46a4833c7ae7b37dce614311e1ffd6fd990e13d3d202fff4d2b37ff77aa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1461-1465 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:1530-1534 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1461}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f0218136e57967ce2b664d18e74d598b2654d9130986e5b23530be99ac6155e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:2189-2193 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:2270-2274 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":2189}}}],"partialFingerprints":{"codehealthFindingId/v1":"b10780bff266149f9bd071c313f99b7dcf9e1b47ef160934695daef5e3ac7749"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:427-431 | genesis/engine/solvers/rigid/collider/box_contact.py:684-688 \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea263c628e840ce946547ffe32c18cb74af4f9f9a86591b62b3fd3dac5d0a399"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/box_contact.py:513-517 | genesis/engine/solvers/rigid/collider/box_contact.py:794-798 \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca1c992c8f47352909d6cc3039e1409c61c5c4a981312b3947bf42b4dac07b75"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/collider.py:990-995 | genesis/engine/solvers/rigid/constraint/solver.py:365-369 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/solvers/rigid/collider/collider.py:990\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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba1190d51db17e14511dba37b2301e750fe44977e270bd9af66512232aa5c7ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:702-706 | genesis/engine/solvers/rigid/collider/epa.py:764-768 \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 \u0060genesis/engine/solvers/rigid/collider/epa.py:702\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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":702}}}],"partialFingerprints":{"codehealthFindingId/v1":"d44b7d1447c0501d9c23f97c979b499afa3409dc65b36e2c60f8277eb9a77d08"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/mpr.py:617-621 | genesis/engine/solvers/rigid/collider/mpr.py:625-629 \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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"372a4fabbd34b8534b3c3caa2d5b94481268edfc65d6ffab5ebbafe987731753"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20135 lines \u00D7 4): genesis/engine/solvers/rigid/collider/narrowphase.py:4247-4251 | genesis/engine/solvers/rigid/collider/narrowphase.py:4444-4448 | genesis/engine/solvers/rigid/collider/narrowphase.py:4505-4507 | genesis/engine/solvers/rigid/collider/narrowphase.py:4548-4550 \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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:4246\u0060 calls \u0060min\u0060 and \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:4505\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4247}}}],"partialFingerprints":{"codehealthFindingId/v1":"aed64d100d303964472503a517949c7df0706c25fcc416e382952acc27c82431"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:4300-4304 | genesis/engine/solvers/rigid/collider/narrowphase.py:4349-4353 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":4300}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c2133a1e253e2e601050a2e4950a69de170b7fc0ddf585418de59fb59d9b976"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:952-956 | genesis/engine/solvers/rigid/constraint/linesearch.py:1151-1155 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":952}}}],"partialFingerprints":{"codehealthFindingId/v1":"d525301b4c4664170af47fde37ca27be0a42876c18e4f0c2e3614cdc2448db90"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2332-2336 | genesis/engine/solvers/rigid/constraint/solver.py:2390-2394 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2332}}}],"partialFingerprints":{"codehealthFindingId/v1":"c088d235016764c7e41cfc8cce7bb92a07aff0edeb895eeca4fe238eec7dd1e9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:2479-2483 | genesis/engine/solvers/rigid/constraint/solver.py:2638-2642 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2479}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e2efac5840f9704bc1be7ebc82bba2d5826c9b8208c47e6e32005f632de102d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5190-5194 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:56-60 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5190}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbcdf8b7f4b8b6f962a0b6498699eab9a7c980789aa5ff9742f04be277917fd3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5232-5236 | genesis/engine/solvers/rigid/constraint/solver.py:5526-5530 \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 \u0060genesis/engine/solvers/rigid/constraint/solver.py:5232\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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5232}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4b536a6377917a819700eab3ab87b7a4bc0af55a3e29d33832fc27eb0e78d8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/ext/isaacgym/terrain_utils.py:29-33 | genesis/utils/terrain.py:208-212 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/ext/isaacgym/terrain_utils.py:29\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":"genesis/ext/isaacgym/terrain_utils.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3326c3e8d5831479f3a0dc2499cee5e53942ce804fc5ea8589142bf8274fb80"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/ext/isaacgym/terrain_utils.py:365-369 | genesis/utils/terrain.py:271-275 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/ext/isaacgym/terrain_utils.py:365\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":"genesis/ext/isaacgym/terrain_utils.py"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"b26781bca81d2112c9205350f8f4aa35b5fd6d0fb736fec2b54d5b2236c3eeb5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/utils/geom.py:946-950 | genesis/utils/geom.py:2031-2035 \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":"genesis/utils/geom.py"},"region":{"startLine":946}}}],"partialFingerprints":{"codehealthFindingId/v1":"65868cc9ae1bbc0bb74bd7aa0c722056e8b356722c24fc57e71bc74fba3f4600"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/utils/path_planning.py:428-432 | genesis/utils/path_planning.py:791-795 \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":"genesis/utils/path_planning.py"},"region":{"startLine":428}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dbaf089b177c7b72b9e7126355d0141db0a9a4246789b04bb23173574892edf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/vis/camera.py:643-647 | genesis/vis/camera.py:649-653 | genesis/vis/camera.py:654-658 \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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060genesis/vis/camera.py:643\u0060 calls \u0060raise_exception\u0060 and \u0060genesis/vis/camera.py:654\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":"genesis/vis/camera.py"},"region":{"startLine":643}}}],"partialFingerprints":{"codehealthFindingId/v1":"202a2d292c160874fa02dffa1cd761d1968c2f0fcb7f4d2629b51c926383b1e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): genesis/engine/entities/fem_entity.py:628-641 | genesis/engine/entities/particle_entity.py:346-356 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":628}}}],"partialFingerprints":{"codehealthFindingId/v1":"d997f9516f0116fb077d715cbba3d8dce74b927591e0e162b0d4cfb87e3a9a61"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): genesis/engine/entities/fem_entity.py:676-691 | genesis/engine/entities/particle_entity.py:381-390 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":676}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef97493f49683c07fde32b297d96967c0bfb4b2ef7862ecb83525915af00557c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/particle_entity.py:475-480 | genesis/engine/entities/tool_entity/tool_entity.py:466-472 \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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"0815121770097d9ad8ac67a2b698b44c7dc9f2c462d9041a1e24e15f5eb3a0f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/pbd_entity.py:82-86 | genesis/engine/entities/sph_entity.py:180-184 \u2014 before extracting anything, compare \u0060genesis/engine/entities/pbd_entity.py\u0060 and \u0060genesis/engine/entities/sph_entity.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"6afed7374757e3987880f43ef03fa140821cbc4df7e1d224daa4dd9370392607"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/fem_entity.py:112-117 | genesis/engine/entities/mpm_entity.py:15-20 \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"c72bb96511433ff3cfe3775fde83da49d753fd1183df292310e56620a102647f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): genesis/engine/entities/rigid_entity/rigid_equality.py:27-33 | genesis/engine/entities/rigid_entity/rigid_geom.py:294-300 | genesis/engine/entities/rigid_entity/rigid_joint.py:88-94 \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 all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/rigid_equality.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb2027c7e671857739aac05ca41e7fb6671cf6ecae30d76635bdd6208bdb5715"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/engine/solvers/fem_solver.py:1106-1111 | genesis/engine/solvers/pbd_solver.py:840-845 | genesis/engine/solvers/sph_solver.py:794-799 \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 all 3 call sites, so a change lands once. 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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1106}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe004bcfa78622960dae54a8bbb58f2be34cd1df75326451d71526738e3ec9e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/kinematic_solver.py:1492-1498 | genesis/engine/solvers/rigid/rigid_solver.py:1248-1259 \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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1492}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd55a9c4c8c31164c56a3dc04076ca9b53f83711c59440e4f90afe579c6670cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/ext/pyrender/font.py:22-26 | genesis/ext/pyrender/shader_program.py:20-24 \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":"genesis/ext/pyrender/font.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"07992827c9a0f5d58b0e973b575b4c014d5eb7da4b5e4f9ba8373a6c41eb3800"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/ext/pyrender/font.py:45-50 | genesis/ext/pyrender/shader_program.py:68-73 \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":"genesis/ext/pyrender/font.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"edf4f54306723f96e2dfeb96bdb5cc908dd5dbc28da5246725fa7084351dfb68"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/legacy_coupler.py:543-547 | genesis/engine/couplers/legacy_coupler.py:597-601 \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, \u0060genesis/engine/couplers/legacy_coupler.py:606\u0060 calls \u0060pos_to_grid\u0060 and \u0060genesis/engine/couplers/legacy_coupler.py:550\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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"c47e3bc9dc9e425b2e5837fadaf389d01d77b7e55fc1f1cf102d0ec5d6629adc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:1364-1368 | genesis/engine/solvers/fem_solver.py:827-831 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1364}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f492cdcdbad149311332e45e66f6c9b4938099ed751ec8a1ec047b32592a901"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2205-2209 | genesis/engine/couplers/sap_coupler.py:2232-2236 \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 before the matched lines, \u0060genesis/engine/couplers/sap_coupler.py:2203\u0060 calls \u0060compute_contact_energy_gamma_G\u0060, \u0060compute_contact_gamma_G\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:2230\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2205}}}],"partialFingerprints":{"codehealthFindingId/v1":"31bc6da2601ceedbe5c3c80e14bff7c029c63a2dc11ca5851d1dec3272793be5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2354-2358 | genesis/engine/couplers/sap_coupler.py:2423-2427 \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, \u0060genesis/engine/couplers/sap_coupler.py:2428\u0060 calls \u0060Vector\u0060, \u0060dot\u0060 and \u0060genesis/engine/couplers/sap_coupler.py:2359\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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2354}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3631f2cccea4bf10550faae2da1f1392e4c475505a732d2dc8b076254331ac5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/couplers/sap_coupler.py:2629-2633 | genesis/engine/couplers/sap_coupler.py:3535-3539 \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2629}}}],"partialFingerprints":{"codehealthFindingId/v1":"96684b478e096a5511d80f512274016ea83ccc046e1a0e7c698a9948b2dd987f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/particle_entity.py:304-309 | genesis/engine/entities/particle_entity.py:331-336 \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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"f90f96963711254be567c0de31dc529eecd281a988661c0f45aec452895be0e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/entities/particle_entity.py:313-318 | genesis/engine/entities/pbd_entity.py:269-274 \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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f16e8390d0ca991bf22d1ead9e0676810b8a062717f91f19ab662403c9e2a80"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): genesis/engine/entities/pbd_entity.py:242-250 | genesis/engine/entities/pbd_entity.py:634-642 | genesis/engine/entities/pbd_entity.py:704-712 \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":"genesis/engine/entities/pbd_entity.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e52d6cc4bd2a7676f59da1d4ea5229c69d819ba01d04dc61bc83375da24d527"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/entities/rigid_entity/description.py:666-670 | genesis/engine/entities/tool_entity/tool_entity.py:38-42 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060genesis/engine/entities/rigid_entity/description.py:666\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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":666}}}],"partialFingerprints":{"codehealthFindingId/v1":"289e8ec6ae14302d5dc7bc25aff0e70a67f9119f93b459413671ce5a781b0d13"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/engine/entities/rigid_entity/rigid_entity.py:880-888 | genesis/engine/entities/rigid_entity/rigid_link.py:183-191 \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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":880}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d1839c73882ae07bb45943f63495e454176beba89ed0fd0f3e365bfb729b0be"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/materials/FEM/elastic.py:103-107 | genesis/engine/materials/FEM/elastic.py:130-134 \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":"genesis/engine/materials/FEM/elastic.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ac3c71b1dc2acef9484c0d45e7bb57c11dff5b0ceba9dae16c048740583b7c1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/materials/FEM/elastic.py:109-113 | genesis/engine/materials/FEM/elastic.py:192-196 \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":"genesis/engine/materials/FEM/elastic.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff19a4854ddb7f15030f8daf5700233a8abd80a1d82267da9983f01a7e2aeaa1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/sensors/camera.py:290-296 | genesis/engine/sensors/camera.py:658-664 \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":"genesis/engine/sensors/camera.py"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"2475c6ab489390d70e18f74654d1d23fff0e6e25e50a3e107f2255331d66bdfd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/sensors/kinematic_tactile.py:1387-1391 | genesis/engine/sensors/point_cloud_tactile.py:2404-2408 \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":"genesis/engine/sensors/kinematic_tactile.py"},"region":{"startLine":1387}}}],"partialFingerprints":{"codehealthFindingId/v1":"3aee6d0fead89ae9cd3f1898c567bf3b644f152855fbfd223c3b99e4df05521b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/sensors/tactile_shared.py:774-778 | genesis/engine/sensors/tactile_shared.py:783-787 \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":"genesis/engine/sensors/tactile_shared.py"},"region":{"startLine":774}}}],"partialFingerprints":{"codehealthFindingId/v1":"21a98e78e5ba461db894b164b55a85da16aaffd61e94821b8d951174ce760004"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:440-445 | genesis/engine/solvers/fem_solver.py:531-536 \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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":440}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4935768c71c598a7aa45cdb50fbfc29b57c6e6893f6d05b15970717cf78cdaf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): genesis/engine/solvers/fem_solver.py:630-643 | genesis/engine/solvers/fem_solver.py:683-696 \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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":630}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa09bd0d3050fba04f7d9c3e9d5be80ca72dc167fe01b305b0417ab57f6dccb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/mpm_solver.py:301-305 | genesis/engine/solvers/mpm_solver.py:334-338 \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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"cea700debe022033bd16661c00fe54577aed214bf0a4b581d85951af3b6f01e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:474-479 | genesis/engine/solvers/pbd_solver.py:514-519 \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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"b455c9636de1d003bca8c4318b7931302b7fcdcd1c07201872de097f732bd51a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:884-890 | genesis/engine/solvers/sph_solver.py:820-826 \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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":884}}}],"partialFingerprints":{"codehealthFindingId/v1":"1646936b28e0d8f2ac3b104aacf496e6b5928d0103e72dea72864cf1a4a53131"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/pbd_solver.py:912-916 | genesis/engine/solvers/sph_solver.py:869-873 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060genesis/engine/solvers/sph_solver.py:874\u0060 calls \u0060fill\u0060 and \u0060genesis/engine/solvers/pbd_solver.py:918\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":"genesis/engine/solvers/pbd_solver.py"},"region":{"startLine":912}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3f92bd07f856418aaf4f0555ae32e1bbef56adca1541e2e10c095e10591e59d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/accessor.py:55-60 | genesis/engine/solvers/rigid/abd/accessor.py:122-127 \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"f91800a8fbcc0e2ec0b84b07f39e150c3f18b607557df3362f13465086837c14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/accessor.py:248-252 | genesis/engine/solvers/rigid/abd/accessor.py:435-439 \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6661aa36420bff143550cfd5b7bee595e7dc3f8f10171cfef7fc0e1d7e31694"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:390-394 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:448-452 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"25ce40a597e1aaf64350d675af004775210c213bde504aa06ea552c71484b1e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1645-1650 | genesis/engine/solvers/rigid/abd/forward_dynamics.py:2172-2177 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1645}}}],"partialFingerprints":{"codehealthFindingId/v1":"db661f935b1210a9e8ecec19e8ca9c2d6be37dfe1fc71f0b4ca4015d06030c15"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_dynamics.py:1713-1717 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1167-1171 \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1713}}}],"partialFingerprints":{"codehealthFindingId/v1":"26ed969d2f301b06d070ffb9931ca95a330bd9c9d0a1226d37abc8f7ad468446"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/engine/solvers/rigid/abd/forward_kinematics.py:366-370 | genesis/engine/solvers/rigid/abd/inverse_kinematics.py:57-61 | genesis/engine/solvers/rigid/abd/manual_bw.py:42-46 \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 all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"0799a7313f26b40128ade0b3d78c68cf28f5bdc07f426796df47bb68f7c39b44"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/forward_kinematics.py:1206-1212 | genesis/engine/solvers/rigid/abd/forward_kinematics.py:1228-1234 \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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":1206}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d07bd302fde80877c37341b3e6a70d48e9ca235ce69868d8f2eb35bf1b67c81"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/abd/manual_bw.py:112-118 | genesis/engine/solvers/rigid/abd/manual_bw.py:135-141 \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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"04d5851fdd09ceb15f3d33d661e8818b776f57c8a1061618ae32298a90996555"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): genesis/engine/solvers/rigid/collider/contact.py:484-491 | genesis/engine/solvers/rigid/collider/diff_gjk.py:321-328 \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":484}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed27b035baab46ef009ceaf90273b567b370a4b3516d7036a14e3948ab225828"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): genesis/engine/solvers/rigid/collider/epa.py:230-235 | genesis/engine/solvers/rigid/collider/epa.py:1169-1174 | genesis/engine/solvers/rigid/collider/epa.py:1225-1230 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"c688479d0c3ddaace8c016a47e65fdf659df1db7f863f0d14f67fd6fd441769c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/collider/epa.py:902-908 | genesis/engine/solvers/rigid/collider/epa.py:1346-1352 \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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":902}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1ca5ebbd7dc544ab383c0ee00ff1eb618cf0890b442f0c13340518a270bc23d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:126-130 | genesis/engine/solvers/rigid/collider/narrowphase.py:701-705 \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 \u0060genesis/engine/solvers/rigid/collider/narrowphase.py:126\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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec375f073be6d1e62af23bc1b0bff6049b9dff959d3084f090c66ffa4edfa552"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/collider/narrowphase.py:2089-2095 | genesis/engine/solvers/rigid/collider/narrowphase.py:2111-2117 \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2089}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3ef1e609c1bb1b13c41c2378519646df3e559a644b6042c0e985c7a90c3f75a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:720-724 | genesis/engine/solvers/rigid/constraint/backward.py:771-775 \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, \u0060genesis/engine/solvers/rigid/constraint/backward.py:777\u0060 calls \u0060dot\u0060 and \u0060genesis/engine/solvers/rigid/constraint/backward.py:725\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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":720}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a8d4ca188db054e10b3f38c3de58b8b3711c1358d36b06b67ec12cc892be751"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:968-974 | genesis/engine/solvers/rigid/constraint/backward.py:1145-1151 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":968}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bef321c8a41e04fad97a368da2b47ca688f11dceafa2931de1c77807adf5e0d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/backward.py:1088-1092 | genesis/engine/solvers/rigid/constraint/backward.py:1472-1476 \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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":1088}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fcf29de95ab74b74d9ea4db73f284b8b4af4cd76064de06dcde3e1aa2e38f3d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/island.py:455-459 | genesis/engine/solvers/rigid/constraint/island.py:484-488 \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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":455}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae7bffe7044f3257d468ae3feb70373bba55ecef186682fa07db222a12d7119c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/linesearch.py:659-663 | genesis/engine/solvers/rigid/constraint/linesearch.py:1181-1185 \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":659}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d8f199802b3ef48ff3cf5c4c5e5f9a6e6f7a8b0b79c7d554c0cfac1c16b8bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:3146-3150 | genesis/engine/solvers/rigid/constraint/solver.py:3174-3178 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3146}}}],"partialFingerprints":{"codehealthFindingId/v1":"32787dc5adf8f74d47a07eef1155d4ff8cc6afe1fb4e365bbe5f662997f1bfac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/engine/solvers/rigid/constraint/solver.py:5434-5438 | genesis/engine/solvers/rigid/constraint/solver_breakdown.py:135-139 \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5434}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ef08994e93a075d8baaf1864bce3f4fc16c9f92276843059a9d0bb92cadc8c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): genesis/engine/solvers/rigid/rigid_solver.py:2794-2800 | genesis/engine/solvers/rigid/rigid_solver.py:2815-2821 \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2794}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3e145945926325ee66354ae6e3c100a415b451c9b5c884fbc34331ea8f08b72"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): genesis/utils/array_class.py:483-501 | genesis/utils/array_class.py:533-551 \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":"genesis/utils/array_class.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"17cbc0260b0f26d00702c39fdb9a10f03fe55bc2f03b2aee90f4f223ff7958f8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/utils/array_class.py:1635-1643 | genesis/utils/array_class.py:1649-1657 \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":"genesis/utils/array_class.py"},"region":{"startLine":1635}}}],"partialFingerprints":{"codehealthFindingId/v1":"9122eb6bbe7f8fe680c108f0f59d469af275005c09406bb74e0b675b4b3bdbaa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/utils/geom.py:1150-1154 | genesis/utils/geom.py:1191-1195 \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":"genesis/utils/geom.py"},"region":{"startLine":1150}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d38486ed70dede4cf7cf7d1e284ab38dab6aac0b2aec1912a80ed37b0063681"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): genesis/utils/mesh.py:1034-1038 | genesis/utils/mesh.py:1055-1059 | genesis/utils/mesh.py:1076-1080 | genesis/utils/mesh.py:1142-1146 \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. 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":"genesis/utils/mesh.py"},"region":{"startLine":1034}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8a25ced147688ed33b7e4e73e0186704d80808671303d62cbb7e82fa28334d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/path_planning.py:334-339 | genesis/utils/path_planning.py:679-684 \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 \u0060genesis/utils/path_planning.py:334\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":"genesis/utils/path_planning.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae66efc643d5b5558ec53461e993aaae4842055a00ad00bc6b07481cba737679"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/path_planning.py:601-606 | genesis/utils/path_planning.py:1001-1006 \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":"genesis/utils/path_planning.py"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"8003092c0d57dd37b1fbf704637587af822ed0cfc10028664696961751b95a6a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/utils/raycast_qd.py:530-534 | genesis/utils/raycast_qd.py:569-573 \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":"genesis/utils/raycast_qd.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa6984862888409722796aa3b96c4e7390542253f2acb4b984def7f36c995576"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): genesis/utils/usd/usd_rigid_entity.py:145-150 | genesis/utils/usd/usd_rigid_entity.py:153-158 \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"60e922fdf3c513e94e795332e1ce22b0c70bce50f289cf7c6e1c946ad175e0f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): genesis/vis/rasterizer_context.py:595-599 | genesis/vis/rasterizer_context.py:913-917 | genesis/vis/rasterizer_context.py:921-925 \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"642f5d4b2349fdd8e7597f726abf8422ed0004afa295cf453eae61c2453e0693"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): genesis/vis/rasterizer_context.py:726-734 | genesis/vis/rasterizer_context.py:797-805 \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 \u0060genesis/vis/rasterizer_context.py:726\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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":726}}}],"partialFingerprints":{"codehealthFindingId/v1":"c73ebc448e28226dc87f6ee2a0e59d1801c1e5652e0dd82f0474c9372ce46c53"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): genesis/vis/rasterizer_context.py:1015-1019 | genesis/vis/rasterizer_context.py:1034-1038 \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":1015}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cef19c62dfc433a9e153425fcc4cebe8065ae8a68b6c6327e3241cb2995f85c"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (3 members, 13 shared lines): examples/rigid/friction_breakaway.py:37-58 | examples/rigid/rolling_coast.py:22-43 | examples/rigid/torsional_grasp.py:23-44 \u2014 These 3 members are variants of one another: a block of 13 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 3 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/rigid/friction_breakaway.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c8c27e18cd6cc6b25adf3f02b4af061a0f543273829429db9739e2942bb9968"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (60 shared lines): examples/sap_coupling/franka_grasp_fem_sphere.py:8-92 | examples/sap_coupling/franka_grasp_rigid_cube.py:7-85 \u2014 These two members are variants of one another: 60 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":"examples/sap_coupling/franka_grasp_fem_sphere.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"e216411448eb1c00d26b9a86363dafa38e133c0c13ee584193f41689e53b37c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): examples/coupling/fem_cube_linked_with_arm.py:11-131 | examples/coupling/grasp_soft_cube.py:9-104 | examples/rigid/control_franka.py:9-110 | examples/rigid/grasp_bottle.py:9-115 | examples/rigid/suction_cup.py:7-129 | examples/sensors/imu_franka.py:12-137 \u2014 These 6 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 6 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/coupling/fem_cube_linked_with_arm.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"166500af4db03323d9ce5e1b339b19f8134d23c3d6b58c8d3002030bd6e2a2e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): examples/rigid/ik_custom_chain.py:9-35 | examples/rigid/ik_shadow_hand.py:9-35 \u2014 before extracting anything, compare \u0060examples/rigid/ik_custom_chain.py\u0060 and \u0060examples/rigid/ik_shadow_hand.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 66 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_custom_chain.py:9\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":"examples/rigid/ik_custom_chain.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"c17e12aefb57ec960f4cc0614f545638eea53c69dc4263e0462c9038b06d8220"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201326 lines \u00D7 2): examples/rigid/ik_custom_chain.py:25-50 | examples/rigid/ik_shadow_hand.py:46-70 \u2014 before extracting anything, compare \u0060examples/rigid/ik_custom_chain.py\u0060 and \u0060examples/rigid/ik_shadow_hand.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 66 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_custom_chain.py:25\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":"examples/rigid/ik_custom_chain.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"00a355333eeddd7c9d24b9658c0b4da8a56d9fc1a1e1100d0ed01c496de1d07d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): examples/sap_coupling/franka_grasp_fem_sphere.py:31-54 | examples/sap_coupling/franka_grasp_rigid_cube.py:26-49 \u2014 before extracting anything, compare \u0060examples/sap_coupling/franka_grasp_fem_sphere.py\u0060 and \u0060examples/sap_coupling/franka_grasp_rigid_cube.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sap_coupling/franka_grasp_fem_sphere.py:31\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":"examples/sap_coupling/franka_grasp_fem_sphere.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"127ae57540662971587759fc0e0eaf9a08ea66a6a04ee0c4e057c111c8332776"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22\u201323 lines \u00D7 2): examples/sensors/imu_franka.py:19-40 | examples/sensors/joint_torque_franka.py:35-57 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sensors/imu_franka.py:19\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":"examples/sensors/imu_franka.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3f8e99de9e2e7e4c3db55e2c2a3ae6facc68dc3d6183290db321c87a6f4efcd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201322 lines \u00D7 2): examples/coupling/fem_cube_linked_with_arm.py:22-43 | examples/deformable/fem_hard_and_soft_constraint.py:24-44 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/fem_cube_linked_with_arm.py:22\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":"examples/coupling/fem_cube_linked_with_arm.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"15ce9cea525673952e99fc938170db0e8c308472b531c002d9b3cc4d7b757362"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): examples/rigid/single_franka.py:17-37 | examples/rigid/single_franka_envs.py:28-48 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/single_franka.py:17\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":"examples/rigid/single_franka.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"813a9ba58687ae002e87fcd848f69726c3682dda847b7960b28a5d718af2c2fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): examples/rigid/terrain_height_field.py:13-33 | examples/rigid/terrain_subterrain.py:12-32 \u2014 before extracting anything, compare \u0060examples/rigid/terrain_height_field.py\u0060 and \u0060examples/rigid/terrain_subterrain.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 45 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 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, \u0060examples/rigid/terrain_height_field.py:34\u0060 calls \u0060zeros\u0060, \u0060arange\u0060, \u0060choice\u0060 and \u0060examples/rigid/terrain_subterrain.py:33\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":"examples/rigid/terrain_height_field.py"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8f0e646d38084f8d6aeed6cbcadbaa34b3f906f7a7ae14d77d6b41911d17c29"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): examples/sap_coupling/franka_grasp_fem_sphere.py:8-27 | examples/sap_coupling/franka_grasp_rigid_cube.py:7-26 \u2014 before extracting anything, compare \u0060examples/sap_coupling/franka_grasp_fem_sphere.py\u0060 and \u0060examples/sap_coupling/franka_grasp_rigid_cube.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sap_coupling/franka_grasp_fem_sphere.py:8\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":"examples/sap_coupling/franka_grasp_fem_sphere.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef538a3f3d5d5c07dfd2cb80c2c13900e0e74f8018737ce736a0031bc10265f5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): examples/kinematic/go2_kinematic.py:54-73 | examples/sensors/depth_camera_custom_vverts.py:137-155 \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":"examples/kinematic/go2_kinematic.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cdba1a71af8db5c487cfcf1ed60fcf445371cea6432a6fbd1c752d03ea521e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201319 lines \u00D7 2): examples/rigid/ik_franka.py:23-41 | examples/rigid/ik_franka_batched.py:29-46 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_franka.py:23\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":"examples/rigid/ik_franka.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"23ea6955c808f99222117bbcde94e9215907bce0ae3794d73d6fdc7081d632b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): examples/rigid/hibernation.py:102-118 | examples/rigid/wrecking_ball.py:223-239 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/hibernation.py:102\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":"examples/rigid/hibernation.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f0314dc59654c52b4130a5a1b8069843c894caadcbd4d51b4a5baef009fca3a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201317 lines \u00D7 2): examples/rigid/suction_cup.py:87-98 | examples/rigid/suction_cup.py:108-124 \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 \u0060examples/rigid/suction_cup.py:108\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":"examples/rigid/suction_cup.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"4722adfb7e8a6474ef9ab95bcd4a50f73bccff3eed9a9c81458e6ddd877d2a18"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): examples/drone/fly.py:17-32 | examples/rigid/control_franka.py:17-32 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/drone/fly.py:17\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":"examples/drone/fly.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8013f055683cc1f8b8a1169b258dba7ffde64d42b9c97b6420dbb481b547007"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201316 lines \u00D7 2): examples/ipc/ipc_momentum.py:30-45 | examples/sap_coupling/fem_sphere_and_cube.py:33-44 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/ipc/ipc_momentum.py:30\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":"examples/ipc/ipc_momentum.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee4b9277cc4f3a53af69bda3e37a562e183e6b05e8df87887767aa4f69e909a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201316 lines \u00D7 2): examples/rigid/diffik_controller.py:49-61 | examples/rigid/ik_franka.py:30-45 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_franka.py:30\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/rigid/diffik_controller.py:49\u0060 calls \u0060add_entity\u0060 and \u0060examples/rigid/ik_franka.py:30\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":"examples/rigid/diffik_controller.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"7afd5c96ff445d5a4699a912927a52db4b5c0fb4d5891ff3be888d4bfb54bc70"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4): examples/rigid/accelerometer_duck.py:7-21 | examples/rigid/control_franka.py:9-23 | examples/rigid/control_mesh.py:7-21 | examples/rigid/set_phys_attr.py:9-23 \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 all 4 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/accelerometer_duck.py:7\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":"examples/rigid/accelerometer_duck.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"245f924c5eb9b8bd72a246a40e28addfe017a64995e06f6836f83d53ac60c803"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): examples/coupling/flush_cubes.py:22-36 | examples/coupling/sand_wheel.py:24-38 \u2014 before extracting anything, compare \u0060examples/coupling/flush_cubes.py\u0060 and \u0060examples/coupling/sand_wheel.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 53 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/flush_cubes.py:22\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":"examples/coupling/flush_cubes.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"e230fc7038238391d93f6935230791a3321eb91463b0d09ba5e1d9cb39e86f86"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): examples/rigid/control_franka.py:15-29 | examples/rigid/grasp_bottle.py:17-31 \u2014 before extracting anything, compare \u0060examples/rigid/control_franka.py\u0060 and \u0060examples/rigid/grasp_bottle.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/control_franka.py:15\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/rigid/grasp_bottle.py:11\u0060 calls \u0060add_argument\u0060 and \u0060examples/rigid/control_franka.py:10\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":"examples/rigid/control_franka.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"173175ade1ba583d5498db2cadccc7f6f312e1977492699ddbc34102269f4d31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3): examples/rigid/gravity_compensation.py:10-23 | examples/rigid/nonconvex_mesh.py:10-23 | examples/rigid/single_franka.py:10-23 \u2014 before extracting anything, compare \u0060examples/rigid/gravity_compensation.py\u0060 and \u0060examples/rigid/nonconvex_mesh.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/gravity_compensation.py:10\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":"examples/rigid/gravity_compensation.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"b286a68bb0d3f2fec320fc1acb9ab9205d93feb4684e61210ef7163f1388c3d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): examples/coupling/sand_wheel.py:61-74 | examples/coupling/sand_wheel.py:85-98 \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 \u0060examples/coupling/sand_wheel.py:61\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":"examples/coupling/sand_wheel.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"24ff619820526e8ef6990d995491b0dac183f7b6a3ad746aea49bcdc11df7673"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): examples/sap_coupling/fem_fixed_constraint.py:44-57 | examples/sap_coupling/fem_sphere_and_cube.py:47-60 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sap_coupling/fem_fixed_constraint.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":"examples/sap_coupling/fem_fixed_constraint.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5c1644641e591398d087d5421b3228656e1e96aec8f7b9729de0150bd5a6e1a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): examples/drone/fly.py:17-29 | examples/rigid/control_franka.py:17-29 | examples/rigid/grasp_bottle.py:19-31 \u2014 before extracting anything, compare \u0060examples/rigid/control_franka.py\u0060 and \u0060examples/rigid/grasp_bottle.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/drone/fly.py:17\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":"examples/drone/fly.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b33a6f3987a5f9f9c5aede73cdb5be3e9cba6597e16a981e8fad8f44d9645df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 3): examples/rendering/moving_camera.py:15-26 | examples/rigid/single_franka.py:15-27 | examples/rigid/single_franka_envs.py:26-38 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/single_franka.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 35 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 \u0060examples/rendering/moving_camera.py:15\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. 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":"examples/rendering/moving_camera.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed42261e8b597a02a066c9052b0977faeddd7586eb563a639307aad57969dc69"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): examples/rigid/friction_breakaway.py:37-49 | examples/rigid/rolling_coast.py:22-34 | examples/rigid/torsional_grasp.py:23-35 \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 all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/rigid/friction_breakaway.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"89cac676c2b53eed657a7e48095dbbd1d490c42a1e439af6dcb1decfc7b7d4e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): examples/rigid/ik_custom_chain.py:15-27 | examples/rigid/ik_shadow_hand.py:15-27 | examples/rigid/nonconvex_mesh.py:14-26 \u2014 before extracting anything, compare \u0060examples/rigid/ik_custom_chain.py\u0060 and \u0060examples/rigid/ik_shadow_hand.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 66 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_custom_chain.py:15\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":"examples/rigid/ik_custom_chain.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"63fa9d7fd9140371452fccb818ee5b757ad9b78aa37ccc3c20b72bb290672d77"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201313 lines \u00D7 2): examples/coupling/cloth_attached_to_rigid.py:37-46 | examples/coupling/cloth_on_rigid.py:23-35 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cloth_attached_to_rigid.py:37\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. 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":"examples/coupling/cloth_attached_to_rigid.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"302b498efdd435d968b9d6c3ef0f0b3faefbbfb5697f9bbe7755aaadf9b12a4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): examples/coupling/cloth_on_rigid.py:19-31 | examples/coupling/water_wheel.py:31-43 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cloth_on_rigid.py:19\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":"examples/coupling/cloth_on_rigid.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"19f4ca3831dff16fe8b3e6f3dc9a48bf36e7f2c326645bb4d593d23cbb419044"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): examples/drone/hover_eval.py:47-59 | examples/locomotion/go2_eval.py:36-48 \u2014 before extracting anything, compare \u0060examples/drone/hover_eval.py\u0060 and \u0060examples/locomotion/go2_eval.py\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. 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 \u0060examples/drone/hover_eval.py:47\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":"examples/drone/hover_eval.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5a5e256daf48119e9bae4030308091a935783729c1e48fa81a4c7b0548221b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): examples/rigid/apply_external_wrench.py:8-20 | examples/rigid/merge_entities.py:18-30 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/apply_external_wrench.py:8\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/rigid/merge_entities.py:17\u0060 calls \u0060add_argument\u0060 and \u0060examples/rigid/apply_external_wrench.py:7\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":"examples/rigid/apply_external_wrench.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ae29baae217ca9fc58b986ebf871abfbb98092a37d49cd2ad9373af6f6631e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): examples/rigid/screw_constraint.py:28-40 | examples/tutorials/position_control_comparison.py:18-30 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/screw_constraint.py:28\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/rigid/screw_constraint.py:27\u0060 calls \u0060add_argument\u0060 and \u0060examples/tutorials/position_control_comparison.py:17\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":"examples/rigid/screw_constraint.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2822b5f0ce42a37814f270a362cd3de4b84fbc98f93ae2b77abb20859910dad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): examples/sap_coupling/fem_fixed_constraint.py:11-23 | examples/sap_coupling/fem_sphere_and_cube.py:8-20 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060examples/sap_coupling/fem_fixed_constraint.py:25\u0060 calls \u0060Elastic\u0060 and \u0060examples/sap_coupling/fem_sphere_and_cube.py:22\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":"examples/sap_coupling/fem_fixed_constraint.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"9483248523c66d07b3af9192e1e3f272e8dcf2f802ad2ae27d23d5ac443358a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): examples/rendering/moving_camera.py:14-25 | examples/rigid/gravity_compensation.py:14-25 | examples/rigid/single_franka.py:14-25 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/single_franka.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 35 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":"examples/rendering/moving_camera.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"353d14a997192837ff4d1348b5ccc3340aee4c5e9b05f65e6307c250395b542c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): examples/rigid/ik_duck.py:14-25 | examples/rigid/ik_franka.py:14-25 | examples/rigid/ik_franka_batched.py:15-26 \u2014 before extracting anything, compare \u0060examples/rigid/ik_duck.py\u0060 and \u0060examples/rigid/ik_franka.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 32 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_duck.py:14\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":"examples/rigid/ik_duck.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"b960e11850186e277fd50750bc9861c8e6701b9a293a95b065dee4a7b8abc1be"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/coupling/grasp_soft_cube.py:15-26 | examples/coupling/sand_wheel.py:16-27 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/grasp_soft_cube.py:15\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":"examples/coupling/grasp_soft_cube.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0245eafde96ac774820df76d43a34eb04168c05fbfd648e284e320000126a86"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/ipc/ipc_robot_cloth_teleop.py:101-112 | examples/ipc/ipc_robot_cloth_teleop.py:120-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 \u0060examples/ipc/ipc_robot_cloth_teleop.py:101\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":"examples/ipc/ipc_robot_cloth_teleop.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"e129a69147e66a0ee8bf7146ee4062d757e4d8c707fd3bfc1a23b41fa89e426c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/locomotion/go2_env.py:243-254 | examples/manipulation/grasp_env.py:238-249 \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":"examples/locomotion/go2_env.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"f46b6072790b5ea8f954e7f81090fed024386bfbbbe56ab625410fca3c11e354"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/rendering/demo.py:62-73 | examples/rendering/demo.py:110-121 \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 \u0060examples/rendering/demo.py:62\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":"examples/rendering/demo.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6ed57ce4c215dafa9b656b94d044ed8e097b3b2778fe31d70098207e97f6f58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 2): examples/rendering/moving_camera.py:12-23 | examples/rigid/closed_loop.py:26-36 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/closed_loop.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 44 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 \u0060examples/rendering/moving_camera.py:12\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":"examples/rendering/moving_camera.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4fd28339bc69e21c0c41436feab2ebc58b7a993e83d11f1518da252bd9c9541"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/rendering/moving_camera.py:17-28 | examples/rigid/franka_cube.py:23-34 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rendering/moving_camera.py:17\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":"examples/rendering/moving_camera.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ea74131e25eb379c4a00fb0a9dae15566c289a2edd7a81c3be1d4d45d4f4f5a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): examples/rigid/ik_franka_batched.py:35-46 | examples/rigid/ik_shadow_hand.py:32-44 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_franka_batched.py:35\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":"examples/rigid/ik_franka_batched.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a6945a3ad8f503c7b780b4612d3912d8ef5c8419adea2a4445617d88c2234fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 2): examples/rigid/merge_entities.py:23-34 | examples/rigid/screw_constraint.py:33-42 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/merge_entities.py:23\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. 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":"examples/rigid/merge_entities.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"70edc27f510e62e944354f5233134417d81088a95f75b17e92bb88a8484a9948"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): examples/coupling/cloth_attached_to_rigid.py:36-46 | examples/coupling/cloth_on_rigid.py:22-32 | examples/coupling/water_wheel.py:34-44 \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 all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cloth_attached_to_rigid.py:36\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":"examples/coupling/cloth_attached_to_rigid.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"7820202be3d09507ff183a6b74f37773ec9e79befe067cec66684d2724b2cad7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): examples/coupling/cut_dragon.py:9-19 | examples/coupling/flush_cubes.py:10-20 | examples/coupling/sand_wheel.py:12-22 \u2014 before extracting anything, compare \u0060examples/coupling/cut_dragon.py\u0060 and \u0060examples/coupling/flush_cubes.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 38 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cut_dragon.py:9\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":"examples/coupling/cut_dragon.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7759aa94209bb1bc35c71017e707fac86935fc2de9aca882413b3ae3ccf278d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): examples/rendering/demo.py:74-84 | examples/rendering/demo.py:86-96 | examples/rendering/demo.py:98-108 \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 \u0060examples/rendering/demo.py:74\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":"examples/rendering/demo.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"530df53242c2880de0e9a33c298ea90320b04c2c96e9a1b188433cf5086c07f8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): examples/rendering/moving_camera.py:10-20 | examples/rigid/closed_loop.py:24-34 | examples/usd/import_stage.py:50-60 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/closed_loop.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 44 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 \u0060examples/rendering/moving_camera.py:10\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/usd/import_stage.py:49\u0060 calls \u0060add_argument\u0060 and \u0060examples/rigid/closed_loop.py:23\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":"examples/rendering/moving_camera.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c57de48446150a5200a4a5c4dd99f0e12ddc9eb21004b217e47dddf1b04fdf5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): examples/coupling/cloth_on_rigid.py:55-64 | examples/deformable/differentiable_push.py:42-52 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cloth_on_rigid.py:55\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":"examples/coupling/cloth_on_rigid.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c1abe57d0f4bf7d8256c73d6947c0054647658d6f82462514764234648b0802"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): examples/rigid/apply_external_wrench.py:16-26 | examples/rigid/diffik_controller.py:24-34 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/apply_external_wrench.py:16\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":"examples/rigid/apply_external_wrench.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"53461741f46e6d038a0c9c6afe09c34e3158e0364ed20f241d7e30515589fa7c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): examples/sap_coupling/franka_grasp_fem_sphere.py:64-74 | examples/sap_coupling/franka_grasp_rigid_cube.py:57-67 \u2014 before extracting anything, compare \u0060examples/sap_coupling/franka_grasp_fem_sphere.py\u0060 and \u0060examples/sap_coupling/franka_grasp_rigid_cube.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sap_coupling/franka_grasp_fem_sphere.py:64\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":"examples/sap_coupling/franka_grasp_fem_sphere.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcbdf135582c890ef3f3564716b7b9b6c51a00bbcfa8e93100defb2e26a62d1d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u201311 lines \u00D7 3): examples/sensors/imu_franka.py:15-17 | examples/sensors/surface_distance_shadowhand.py:36-46 | examples/sensors/tactile_franka.py:187-197 \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 all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sensors/surface_distance_shadowhand.py:36\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/sensors/surface_distance_shadowhand.py:36\u0060 calls \u0060add_argument\u0060 and \u0060examples/sensors/imu_franka.py:15\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":"examples/sensors/imu_franka.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"874332fc96f844c994d30f9d6c7a0a885f8b46baa73ed06b3b94c856c896a887"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 5): examples/coupling/cut_dragon.py:9-18 | examples/coupling/flush_cubes.py:10-19 | examples/coupling/sand_wheel.py:12-21 | examples/coupling/sph_mpm.py:10-19 | examples/coupling/water_wheel.py:16-25 \u2014 before extracting anything, compare \u0060examples/coupling/cut_dragon.py\u0060 and \u0060examples/coupling/flush_cubes.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 38 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cut_dragon.py:9\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":"examples/coupling/cut_dragon.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"725d4ea385365d73b8d714913cd3ec603f3e1a453aca3ef8fab598874d61e374"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 4): examples/rendering/moving_camera.py:10-19 | examples/rigid/closed_loop.py:23-33 | examples/usd/import_stage.py:50-59 | examples/viewer_plugin/mouse_interaction.py:18-27 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/closed_loop.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 44 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 \u0060examples/rendering/moving_camera.py:10\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/usd/import_stage.py:49\u0060 calls \u0060add_argument\u0060, \u0060parse_args\u0060 and \u0060examples/rigid/closed_loop.py:23\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":"examples/rendering/moving_camera.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b7bafc73aca8c4a9de15ec5a2e9c8b54385d8054784a724997215189143237d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 4): examples/rigid/apply_external_wrench.py:12-21 | examples/rigid/merge_entities.py:22-31 | examples/rigid/screw_constraint.py:32-41 | examples/tutorials/position_control_comparison.py:22-31 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 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 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/apply_external_wrench.py:12\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/rigid/merge_entities.py:17\u0060 calls \u0060add_argument\u0060 and \u0060examples/rigid/apply_external_wrench.py:7\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":"examples/rigid/apply_external_wrench.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f5622089bfa4f9f7dfe32dba0a1bab1e5fd1148753f5632e767dbd0d812dd31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 4): examples/rigid/franka_cube.py:53-62 | examples/rigid/suction_cup.py:91-97 | examples/rigid/suction_cup.py:107-113 | examples/rigid/suction_cup.py:117-123 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/rigid/franka_cube.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1c5ff8750049fcbf75e4fa9ca438d6ee306ea4018a01a352604a8bde9b09663"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): examples/collision/contype.py:37-46 | examples/collision/contype.py:49-58 | examples/collision/contype.py:61-70 \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 \u0060examples/collision/contype.py:37\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":"examples/collision/contype.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e5eef363cab3269050defbaabdb139267aec982670a63e54fdaa5ff8d3bee94"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): examples/rendering/demo.py:36-47 | examples/rendering/demo.py:133-142 \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 \u0060examples/rendering/demo.py:36\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":"examples/rendering/demo.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf1e6fb67ed6df97f3dad3664a0bf76948785dfa6ad749795838700cdb9d1a67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): examples/rigid/ik_duck.py:41-50 | examples/rigid/ik_franka.py:38-47 \u2014 before extracting anything, compare \u0060examples/rigid/ik_duck.py\u0060 and \u0060examples/rigid/ik_franka.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 32 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/ik_duck.py:41\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":"examples/rigid/ik_duck.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2913c1bc4c4752a31af92666bcfb1a492508519ba1f29f42f35201acf4d8f0c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): examples/rigid/rolling_coast.py:47-56 | examples/rigid/torsional_grasp.py:48-57 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/rolling_coast.py:47\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":"examples/rigid/rolling_coast.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"4630293d4ea5f984728776fb12b5acc643f14e2f0eda8958a9f3a6c5ec08f6ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 7): examples/coupling/cut_dragon.py:8-16 | examples/coupling/flush_cubes.py:9-17 | examples/coupling/sand_wheel.py:11-19 | examples/coupling/sph_mpm.py:9-17 | examples/coupling/sph_rigid.py:9-17 | examples/coupling/water_wheel.py:15-23 | examples/deformable/differentiable_push.py:11-19 \u2014 before extracting anything, compare \u0060examples/coupling/cut_dragon.py\u0060 and \u0060examples/coupling/flush_cubes.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 38 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cut_dragon.py:8\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":"examples/coupling/cut_dragon.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0d23816763360f8aecac42fb0240ccc52ef3791b4b53b77f84f16b8e8d4b697"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 5): examples/rendering/moving_camera.py:14-23 | examples/rigid/closed_loop.py:28-36 | examples/rigid/gravity_compensation.py:14-23 | examples/rigid/nonconvex_mesh.py:14-23 | examples/rigid/single_franka.py:14-23 \u2014 before extracting anything, compare \u0060examples/rendering/moving_camera.py\u0060 and \u0060examples/rigid/closed_loop.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 44 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 \u0060examples/rendering/moving_camera.py:14\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":"examples/rendering/moving_camera.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"e36489572e1fcc7c487590391fd39b99c9cc54b41937106db700ca3ef149cee8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): examples/rigid/suction_cup.py:9-17 | examples/rigid/terrain_height_field.py:12-20 | examples/rigid/terrain_subterrain.py:11-19 | examples/tutorials/position_control_comparison.py:17-25 \u2014 before extracting anything, compare \u0060examples/rigid/terrain_height_field.py\u0060 and \u0060examples/rigid/terrain_subterrain.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 45 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/suction_cup.py:9\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":"examples/rigid/suction_cup.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"50314c749f4d20cc30df7cc715de3496dbfda211cf7a9f0ac87379b384106a6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): examples/rigid/diffik_controller.py:53-61 | examples/rigid/ik_duck.py:39-48 | examples/rigid/ik_franka.py:36-45 \u2014 before extracting anything, compare \u0060examples/rigid/ik_duck.py\u0060 and \u0060examples/rigid/ik_franka.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 32 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/rigid/diffik_controller.py:53\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":"examples/rigid/diffik_controller.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2459ee1a5d9e18a3fca180b6c4603733aedf3a3e6975def8ccef2a5d6b31d5d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): examples/deformable/pbd_liquid.py:10-18 | examples/rigid/domain_randomization.py:11-19 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/deformable/pbd_liquid.py:10\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":"examples/deformable/pbd_liquid.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3d0de7511ab72721ad33de71584f08663244876634b751c800b6d8a7e1a6eb8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): examples/ipc/ipc_momentum.py:222-230 | examples/ipc/ipc_momentum.py:233-241 \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":"examples/ipc/ipc_momentum.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"c36a392ca37d6be244e4377a99a52412657a434c8d9ce998b462131e9c8a406d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 9): examples/coupling/cut_dragon.py:8-15 | examples/coupling/flush_cubes.py:9-16 | examples/coupling/sand_wheel.py:11-18 | examples/coupling/sph_mpm.py:9-16 | examples/coupling/sph_rigid.py:9-16 | examples/coupling/water_wheel.py:15-22 | examples/deformable/differentiable_push.py:11-18 | examples/deformable/pbd_liquid.py:10-17 | examples/rigid/domain_randomization.py:11-18 \u2014 before extracting anything, compare \u0060examples/coupling/cut_dragon.py\u0060 and \u0060examples/coupling/flush_cubes.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 38 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/cut_dragon.py:8\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060examples/deformable/pbd_liquid.py:19\u0060 calls \u0060PBDOptions\u0060 and \u0060examples/deformable/differentiable_push.py:19\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":"examples/coupling/cut_dragon.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"8be149da4b9c73f6860ea712853701c9be2a5df41eb1969d4959a79990ce8d53"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): examples/coupling/rigid_mpm_attachment.py:18-25 | examples/rigid/suction_cup.py:9-16 | examples/rigid/terrain_height_field.py:12-19 | examples/rigid/terrain_subterrain.py:11-18 | examples/tutorials/position_control_comparison.py:17-24 \u2014 before extracting anything, compare \u0060examples/rigid/terrain_height_field.py\u0060 and \u0060examples/rigid/terrain_subterrain.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 45 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/rigid_mpm_attachment.py:18\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":"examples/coupling/rigid_mpm_attachment.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"43765ba9909bf905f674941e5e1f66c5f0a59a17cf5ad6cb0c57ca834bc0dedc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (1\u20138 lines \u00D7 3): examples/rigid/grasp_bottle.py:74-74 | examples/rigid/grasp_bottle.py:83-89 | examples/rigid/grasp_bottle.py:100-107 \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 \u0060examples/rigid/grasp_bottle.py:83\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":"examples/rigid/grasp_bottle.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a870e7f6b2dfc6d3aad644f4bbb4752e4308ea1b3e69658b3b55d21fc172e3a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 9): examples/coupling/rigid_mpm_attachment.py:17-23 | examples/rigid/gravity_compensation.py:8-14 | examples/rigid/nonconvex_mesh.py:8-14 | examples/rigid/single_franka.py:8-14 | examples/rigid/suction_cup.py:8-14 | examples/rigid/terrain_from_mesh.py:11-17 | examples/rigid/terrain_height_field.py:11-17 | examples/rigid/terrain_subterrain.py:10-16 | examples/tutorials/position_control_comparison.py:16-22 \u2014 before extracting anything, compare \u0060examples/rigid/gravity_compensation.py\u0060 and \u0060examples/rigid/nonconvex_mesh.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/rigid_mpm_attachment.py:17\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060examples/tutorials/position_control_comparison.py:23\u0060 calls \u0060SimOptions\u0060 and \u0060examples/rigid/terrain_from_mesh.py:18\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":"examples/coupling/rigid_mpm_attachment.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ae18c9dd95cacd8a17f83ef3babb67e50559b3952ec1ee9cc4fe324a5fa38e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20137 lines \u00D7 6): examples/coupling/fem_cube_linked_with_arm.py:83-89 | examples/coupling/grasp_soft_cube.py:64-70 | examples/rigid/control_franka.py:57-59 | examples/rigid/grasp_bottle.py:58-64 | examples/rigid/suction_cup.py:57-63 | examples/sensors/imu_franka.py:98-104 \u2014 before extracting anything, compare \u0060examples/rigid/control_franka.py\u0060 and \u0060examples/rigid/grasp_bottle.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/fem_cube_linked_with_arm.py:83\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060examples/coupling/fem_cube_linked_with_arm.py:89\u0060 calls \u0060set_dofs_force_range\u0060 and \u0060examples/rigid/control_franka.py:59\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":"examples/coupling/fem_cube_linked_with_arm.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"504bb9e9e743c42bf3b738eb172e26c9ef1e1c9386f2dd1524436d7a9f2b2515"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): examples/collision/pyramid.py:24-30 | examples/sap_coupling/franka_grasp_fem_sphere.py:14-21 | examples/sap_coupling/franka_grasp_rigid_cube.py:13-20 \u2014 before extracting anything, compare \u0060examples/sap_coupling/franka_grasp_fem_sphere.py\u0060 and \u0060examples/sap_coupling/franka_grasp_rigid_cube.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/collision/pyramid.py:24\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":"examples/collision/pyramid.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b0a8653f2b78a35abe03341455335b18417049ac5c99cc96dbfe2928f44cd32"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20137 lines \u00D7 6): examples/coupling/fem_cube_linked_with_arm.py:90-92 | examples/coupling/grasp_soft_cube.py:72-78 | examples/rigid/control_franka.py:59-60 | examples/rigid/grasp_bottle.py:66-73 | examples/rigid/suction_cup.py:64-66 | examples/sensors/imu_franka.py:105-107 \u2014 before extracting anything, compare \u0060examples/rigid/control_franka.py\u0060 and \u0060examples/rigid/grasp_bottle.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/coupling/fem_cube_linked_with_arm.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. 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/coupling/grasp_soft_cube.py:72\u0060 calls \u0060array\u0060 and \u0060examples/coupling/fem_cube_linked_with_arm.py:90\u0060 does not \u2014 after which the two agree again for 5 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":"examples/coupling/fem_cube_linked_with_arm.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a439d5a33be1d411ab9f7bb614226f0093bfcf74d2485a79a32f9e1510fad99"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): examples/drone/hover_eval.py:31-37 | examples/locomotion/go2_eval.py:26-32 \u2014 before extracting anything, compare \u0060examples/drone/hover_eval.py\u0060 and \u0060examples/locomotion/go2_eval.py\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. 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, \u0060examples/drone/hover_eval.py:30\u0060 calls \u0060add_argument\u0060 and \u0060examples/locomotion/go2_eval.py:25\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":"examples/drone/hover_eval.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"19d77ee2f7d9e54f1269b75707bae7d6f6c0b9836db1370519e527d3440564f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20136 lines \u00D7 3): examples/ipc/ipc_robot_grasp_cube.py:99-100 | examples/ipc/ipc_robot_grasp_cube.py:101-106 | examples/ipc/ipc_robot_grasp_cube.py:113-118 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060examples/ipc/ipc_robot_grasp_cube.py:100\u0060 calls \u0060control_dofs_position\u0060 and \u0060examples/ipc/ipc_robot_grasp_cube.py:99\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":"examples/ipc/ipc_robot_grasp_cube.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"576d18bda68e93fdd76aa679c5176652dddb87cf02fbbbc12ab9de34b4557c2b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): examples/rigid/set_phys_attr.py:173-178 | examples/rigid/set_phys_attr.py:183-189 \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 \u0060examples/rigid/set_phys_attr.py:173\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":"examples/rigid/set_phys_attr.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"8eeb738012d0d5b937847675e86890dc33fade4c86d597954c572455a6ee42a1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): examples/sap_coupling/franka_grasp_fem_sphere.py:84-89 | examples/sap_coupling/franka_grasp_rigid_cube.py:77-82 \u2014 before extracting anything, compare \u0060examples/sap_coupling/franka_grasp_fem_sphere.py\u0060 and \u0060examples/sap_coupling/franka_grasp_rigid_cube.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/sap_coupling/franka_grasp_fem_sphere.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"c45670bb407b40c2fa1527f21b54a29eb0fcde46926465a892f94a9f96e44064"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): examples/sensors/contact_force_go2.py:15-20 | examples/sensors/temperature_grid.py:40-45 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sensors/temperature_grid.py:40\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":"examples/sensors/contact_force_go2.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"58c71eab11f54c1d379d251a8cccdacaffa10eeb84a0db47cb5981906e2ce957"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): examples/sensors/lidar_teleop.py:150-156 | examples/sensors/surface_distance_shadowhand.py:138-144 | examples/sensors/temperature_grid.py:200-206 \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 all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/sensors/lidar_teleop.py:150\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060examples/sensors/temperature_grid.py:209\u0060 calls \u0060Keybind\u0060 and \u0060examples/sensors/surface_distance_shadowhand.py:147\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":"examples/sensors/lidar_teleop.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c4753e912dba26b3512f688b307c75acbe7517185e8a3bb3e5bc09bae5d633"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): examples/tutorials/position_control_comparison.py:77-81 | examples/tutorials/position_control_comparison.py:89-93 \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, \u0060examples/tutorials/position_control_comparison.py:94\u0060 calls \u0060cos\u0060 and \u0060examples/tutorials/position_control_comparison.py:83\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":"examples/tutorials/position_control_comparison.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11446b309260003c622a81bbc954700d7c9ebedf743a6fe7925c111587274d1"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: RigidEntity (LCOM4 59): RigidEntity\u0027s methods fall into 59 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 59 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":1738}}}],"partialFingerprints":{"codehealthFindingId/v1":"6afe0c33c017427d31368ac9c6c1b65a67b9a602c568b5a1dd2017c3a234445a"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: FEMSolver (LCOM4 21): FEMSolver\u0027s methods fall into 21 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 21 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"af7afca864196e5e90ce165fb16e9fc875d21047706ad6b89385face29c10b92"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: KinematicSolver (LCOM4 17): KinematicSolver\u0027s methods fall into 17 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 17 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"811293920a37208597c840325bd3926bce780553aae5f15888d8425e58997d4d"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: ToolEntity (LCOM4 16): ToolEntity\u0027s methods fall into 16 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 16 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/tool_entity/tool_entity.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdb8b2e3ae0f6913f32dbe104aaeff3be30a01eb46e02808823a7634cff13492"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: ParticleEntity (LCOM4 9): ParticleEntity\u0027s methods fall into 9 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 9 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"be408bc0d2dd0ea532d113c7aa73b54a952032a4d80f08f2c5b52554ea47b2c8"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: FEMEntity (LCOM4 6): FEMEntity\u0027s methods fall into 6 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 6 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"de36a11ed441be73190c3cb85ed12f61f10e33bcc89aaaff2dc5a310b178e22f"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: UsdContext (LCOM4 5): UsdContext\u0027s methods fall into 5 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 5 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee819cc9a598c2e2759830273c95d8cddc81ba6a31816c6e13bc2c9b54dd4d2e"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: KinematicEntity (LCOM4 4): KinematicEntity\u0027s methods fall into 4 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 4 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"8627e8d61c0caca8e52087ee5f1e984a780c5ec6b541b1918d8c558833ad9680"}},{"ruleId":"D14","level":"error","message":{"text":"Banned license: frozendict: \u0060frozendict\u0060 2.4.7 is published on PyPI under \u0060LGPL-3.0\u0060, which this policy bans, and it is in the SHIPPED closure of this repository \u2014 so it is installed by everything that depends on this repository, not just by its test environment. A distribution offering SEVERAL licences is a choice and is only charged when every one of them is banned. Replace the package, or record an accepted exception."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eabaddc5ace4df0a4a80aedb35b4fd43e6e12a49965a667944eb8cfdda09c895"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/narrowphase.py: genesis/engine/solvers/rigid/collider/narrowphase.py changed 25 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 133 in narrowphase.func_contact_overlap_axes at line 1931. 10 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/narrowphase.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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1931}}}],"partialFingerprints":{"codehealthFindingId/v1":"034378589f74b47a5c4e7f4cf5592d04fd3d5c2c15f91570b5b9d5e63bfe22f9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/rigid_solver.py: genesis/engine/solvers/rigid/rigid_solver.py changed 54 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 59 in RigidSolver._build_static_config at line 468. 15 of those changes were fix/bug commits, and the other 39 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/rigid_solver.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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1148fc4cd1a7bc22f3bfff76131b8fbdf9c1a865967da9a24b6e9ed762b9dd1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/solver.py: genesis/engine/solvers/rigid/constraint/solver.py changed 39 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 68 in solver.func_island_assemble_factor_solve_tiled at line 2764. 11 of those changes were fix/bug commits, and the other 28 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/solver.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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2764}}}],"partialFingerprints":{"codehealthFindingId/v1":"353a816c5522ebfc39171303ead0257563c27c0c070eb816d2610b781f0a7c78"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/collider.py: genesis/engine/solvers/rigid/collider/collider.py changed 24 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 60 in Collider.get_contacts at line 881. 2 of those changes were fix/bug commits, and the other 22 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/collider.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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":881}}}],"partialFingerprints":{"codehealthFindingId/v1":"60c69706aa6ef496051f023731e805d1e471b484dbdf96286d48e64fed8a6561"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/contact.py: genesis/engine/solvers/rigid/collider/contact.py changed 23 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 59 in contact.func_clamp_prune_contacts_coop at line 1446. 12 of those changes were fix/bug commits, so the churn is repair rather than feature work. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/contact.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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":1446}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a4a1110a5b874a559c24813796d6e8293c9d7ee1167395a6d89820ef766327e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/entities/rigid_entity/description.py: genesis/engine/entities/rigid_entity/description.py changed 11 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 96 in KinematicEntityDescription._parse_scene at line 892. 6 of those changes were fix/bug commits, so the churn is repair rather than feature work. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/entities/rigid_entity/description.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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f1f3459859e51ade441a41607c81159af283657d8f9f83bf5e2393b71ae1f9b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/entities/rigid_entity/rigid_entity.py: genesis/engine/entities/rigid_entity/rigid_entity.py changed 24 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 43 in KinematicEntity.attach at line 262. 10 of those changes were fix/bug commits, and the other 14 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/entities/rigid_entity/rigid_entity.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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"a37cfee4633b9476b860596e6d7a30e0fd22f5ac47c34a44ede41b9bbb0cb52d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/array_class.py: genesis/utils/array_class.py changed 43 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 23 in array_class.get_constraint_state at line 1041. 13 of those changes were fix/bug commits, and the other 30 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/array_class.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":"genesis/utils/array_class.py"},"region":{"startLine":1041}}}],"partialFingerprints":{"codehealthFindingId/v1":"703c8381a7bb00a2d7de956671e98e747c0efe062c3ec356e51227a2ca5572ca"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/__init__.py: genesis/__init__.py changed 14 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 62 in genesis.init at line 59. 4 of those changes were fix/bug commits, and the other 10 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/__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":"genesis/__init__.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd39c94ec41abab78a359496991616af3b1cf74ab5439b60e8659d51831783f3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/mesh.py: genesis/utils/mesh.py changed 12 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 66 in mesh._postprocess_collision_geoms_impl at line 456. 6 of those changes were fix/bug commits, and the other 6 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/mesh.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":"genesis/utils/mesh.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ba6ea8caccd5770e0e0a8319d6dcb5b9bf447c1f82df2c320dd687b4d15dabe"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/abd/forward_dynamics.py: genesis/engine/solvers/rigid/abd/forward_dynamics.py changed 19 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 40 in forward_dynamics.func_factor_mass_tree_shared at line 856. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/abd/forward_dynamics.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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":856}}}],"partialFingerprints":{"codehealthFindingId/v1":"e82c6eaac692979b72e18210f8f86169e2707279a53f33abd7b6d5e35c215821"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/linesearch.py: genesis/engine/solvers/rigid/constraint/linesearch.py changed 10 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 70 in linesearch.func_linesearch_islands_coop at line 1191. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/linesearch.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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":1191}}}],"partialFingerprints":{"codehealthFindingId/v1":"cec6aabba81fb03fdfd053c847f19d87b564c51cd036c899e67775cebbe16d13"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/island.py: genesis/engine/solvers/rigid/constraint/island.py changed 10 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 58 in island.func_build_islands_coop at line 514. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/island.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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":514}}}],"partialFingerprints":{"codehealthFindingId/v1":"f91370c95d92315a27e51b6d465aec0de91ed7dabeabc520465e56711c0e02f7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/mpr.py: genesis/engine/solvers/rigid/collider/mpr.py changed 13 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 42 in mpr.func_mpr_contact_from_centers at line 468. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/mpr.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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cb0c84e4c3a3879d4fafed018ee46ffbfac6972081682298c22344d5ab76d0f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/broadphase.py: genesis/engine/solvers/rigid/collider/broadphase.py changed 9 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 58 in broadphase._func_broad_phase_sap at line 78. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/broadphase.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":"genesis/engine/solvers/rigid/collider/broadphase.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"093a1637967767757abc11eed14037337d166f45488c0a6e0b18a53f9796979f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/urdf.py: genesis/utils/urdf.py changed 9 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 58 in urdf.parse_urdf at line 135. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/urdf.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":"genesis/utils/urdf.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9e8654522cd1afa8e69bbf4a9b2428ad5d9efae805b50fcb8358c20d6c2445d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/box_contact.py: genesis/engine/solvers/rigid/collider/box_contact.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 129 in box_contact.func_box_box_contact at line 189. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/box_contact.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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd062adb82e84ee2473d53b316559e73df775679125083d54173ae0a171d20c7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/misc.py: genesis/utils/misc.py changed 19 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 27 in misc.sanitize_index at line 907. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/misc.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":"genesis/utils/misc.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"af5ad578e475405371dd23bcb8736fe7ca96d8ad168fdb4f6026ccaa24f3b9a9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/scene.py: genesis/engine/scene.py changed 19 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 27 in Scene.add_entity at line 337. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/scene.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":"genesis/engine/scene.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"449b60d905e430521a0af7b61730a469c00c6a77dfc919728b4b7e95a8367593"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/mjcf.py: genesis/utils/mjcf.py changed 11 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 46 in mjcf.parse_link at line 287. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/mjcf.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":"genesis/utils/mjcf.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"6144bafb74ef4ccc0c4190ffda5a9f7a41974c555a567a5436fe239c8ab57a5d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/backward.py: genesis/engine/solvers/rigid/constraint/backward.py changed 9 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 54 in backward.kernel_manual_add_equality_constraints_bw at line 784. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/backward.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":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":784}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f920b6998cdbffe37b421b405998c89b79d30ebdc8e53b16c4cf3c712b70338"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/kinematic_solver.py: genesis/engine/solvers/kinematic_solver.py changed 20 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 24 in KinematicSolver.build at line 229. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/kinematic_solver.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":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"802e7a785907165f1a68de2c0cbcfc62e53867097c62380b816af8596115a9d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/vis/camera.py: genesis/vis/camera.py changed 10 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 43 in Camera.set_pose at line 592. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/vis/camera.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":"genesis/vis/camera.py"},"region":{"startLine":592}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d5ca992e43749a88e5c163e6fe92632c6e7833ec2f54fc58ad1e682d2c88d38"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/abd/forward_kinematics.py: genesis/engine/solvers/rigid/abd/forward_kinematics.py changed 19 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 21 in forward_kinematics.func_forward_kinematics_link at line 322. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/abd/forward_kinematics.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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c127803ead2050379d42c1d89a07cabe8b6a0816a90a5e5f0091ad94a412d65"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/epa.py: genesis/engine/solvers/rigid/collider/epa.py changed 8 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 39 in epa.func_safe_epa at line 960. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/epa.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":"genesis/engine/solvers/rigid/collider/epa.py"},"region":{"startLine":960}}}],"partialFingerprints":{"codehealthFindingId/v1":"30b337bfbb4888a0e3176b5419747863a0fb1b4aceb51f3569dbb9b0632994db"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/abd/inverse_kinematics.py: genesis/engine/solvers/rigid/abd/inverse_kinematics.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 52 in inverse_kinematics.func_inverse_kinematics at line 363. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/abd/inverse_kinematics.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":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":363}}}],"partialFingerprints":{"codehealthFindingId/v1":"304c1a1f3d1b0a1e1eea28e33206a66cb5a3becc2748d47c3e4ee83c88ff54f6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/usd/usd_geometry.py: genesis/utils/usd/usd_geometry.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 78 in usd_geometry.parse_prim_geoms at line 38. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/usd/usd_geometry.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":"genesis/utils/usd/usd_geometry.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bcf13c13e6b546427722c21b1bd08876a2b75525591b9d1fbed020c2451bad1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/gltf.py: genesis/utils/gltf.py changed 8 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 38 in gltf.parse_glb_material at line 136. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/gltf.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":"genesis/utils/gltf.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"88a37b2c7c7fde6f04e2afcf285cbd19391298376aea3bece6eea61eb9f345b3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/gjk.py: genesis/engine/solvers/rigid/collider/gjk.py changed 9 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 31 in gjk.func_gjk_contact at line 148. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/gjk.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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"05e1c7d9e398f8f2323b2cec4a266537f6b11baaa58212625165e1f663208f01"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/usd/usd_rigid_entity.py: genesis/utils/usd/usd_rigid_entity.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 60 in usd_rigid_entity._parse_link at line 166. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/usd/usd_rigid_entity.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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1d897069e8b504d6e9310cf4cf63b54fa8727778cb18f3a0752e99b761cdb0f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/solver_breakdown.py: genesis/engine/solvers/rigid/constraint/solver_breakdown.py changed 14 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 15 in solver_breakdown._func_update_constraint_forces at line 77. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/solver_breakdown.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":"genesis/engine/solvers/rigid/constraint/solver_breakdown.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30ef31d61fce77f4a8901e20284b853025d4501f1c892e387c56b82e8a7e5ee"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/sensors/point_cloud_tactile.py: genesis/engine/sensors/point_cloud_tactile.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 39 in point_cloud_tactile._kernel_point_cloud_proximity_taxel_bvh at line 351. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/sensors/point_cloud_tactile.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":"genesis/engine/sensors/point_cloud_tactile.py"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"08461bc705c7816608de63ef56c541a45a0a89b8bd4878a34aaf83283056c853"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/recorders/trajectory.py: genesis/recorders/trajectory.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 32 in TrajectoryFileWriter.build at line 510. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/recorders/trajectory.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":"genesis/recorders/trajectory.py"},"region":{"startLine":510}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9d267f75ac53bb96e2371d9c6f74da0ab7e756acf5d4f2594bad814a47c7b68"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/ext/pyrender/viewer.py: genesis/ext/pyrender/viewer.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 30 in Viewer.start at line 1153. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/ext/pyrender/viewer.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":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1153}}}],"partialFingerprints":{"codehealthFindingId/v1":"e14ed94498fd1e74389a335516f971141ceec7fb9f25ae3c9572a3f012f30079"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/simulator.py: genesis/engine/simulator.py changed 9 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in Simulator.build at line 158. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/simulator.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":"genesis/engine/simulator.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd8804672a14c13aac26561eff34627f32ee495b1f1564af3ac16f5b32f20954"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/constraint/noslip.py: genesis/engine/solvers/rigid/constraint/noslip.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 29 in noslip.func_noslip_update_row at line 239. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/constraint/noslip.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":"genesis/engine/solvers/rigid/constraint/noslip.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b00d2a54ce9325a92486e5212fbff31269fd422be2b72ad7c79dc2823babbf4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/terrain.py: genesis/utils/terrain.py changed 7 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 23 in terrain.parse_terrain at line 18. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/terrain.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":"genesis/utils/terrain.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f56d8620ca646e0905c7d37e385d46fec546ea5a076b2c2b2faea2b53e0af58"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/serialization.py: genesis/utils/serialization.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 38 in serialization._load_value at line 456. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/serialization.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":"genesis/utils/serialization.py"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"cceb1f63c40bbc979c5f5e5070f70bd859e9578b779780cf2afb208fba63429b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/vis/raytracer.py: genesis/vis/raytracer.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 36 in Raytracer.build at line 213. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/vis/raytracer.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":"genesis/vis/raytracer.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bfc57ef269da156932315bb36553672917229cb3613b5b5b58d605baf8e0f8c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: examples/sensors/tactile_franka.py: examples/sensors/tactile_franka.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 24 in tactile_franka.main at line 177. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- examples/sensors/tactile_franka.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":"examples/sensors/tactile_franka.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"932465e7ea4764f8cf95a3a55194b97e40563462cb195bf1dd8c7ee244411326"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: examples/sensors/tactile_sandbox.py: examples/sensors/tactile_sandbox.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 28 in tactile_sandbox.main at line 236. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- examples/sensors/tactile_sandbox.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":"examples/sensors/tactile_sandbox.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"c19d87584029d151727ce8732e6695bf8853ea26830ba39b160dadb907489981"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/diff_gjk.py: genesis/engine/solvers/rigid/collider/diff_gjk.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 26 in diff_gjk.func_extended_epa at line 345. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/diff_gjk.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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"942ca0a2113f7693896c5e10e4ecfd01d38038615fe5e8436ccf4a89c7936cc5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/collider/multi_contact.py: genesis/engine/solvers/rigid/collider/multi_contact.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 64 in multi_contact.func_multi_contact at line 19. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/collider/multi_contact.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":"genesis/engine/solvers/rigid/collider/multi_contact.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4a68c34ec57dd2812d6782849a37604a78c325d49d883d978a978e5195c24e5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/vis/rasterizer_context.py: genesis/vis/rasterizer_context.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 21 in RasterizerContext.update_rigid at line 537. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/vis/rasterizer_context.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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4e5d9fb5142929b928b64f891f78e31fa6d1e8adb24418381e5984230e3bb80"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/utils/path_planning.py: genesis/utils/path_planning.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 25 in RRTConnect.plan at line 895. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/utils/path_planning.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":"genesis/utils/path_planning.py"},"region":{"startLine":895}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e2cf1ce49e86cbde26e37fe027397dd523b0026a3df665d42a3ba57da784cf6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/interactive_scene.py: genesis/engine/interactive_scene.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in InteractiveScene._apply_rebuild at line 269. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/interactive_scene.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":"genesis/engine/interactive_scene.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"be0eaa8ef1b340b99215a072966565a29ce58983d7c0c6240e9a952e0ff4b4f7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/vis/viewer_plugins/plugins/mouse_interaction.py: genesis/vis/viewer_plugins/plugins/mouse_interaction.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 16 in MouseInteractionPlugin.on_draw at line 217. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/vis/viewer_plugins/plugins/mouse_interaction.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":"genesis/vis/viewer_plugins/plugins/mouse_interaction.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4e6196e44870befba0dc8424574e3ae636e818f321a205fed411893b004b3b2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/couplers/sap_coupler.py: genesis/engine/couplers/sap_coupler.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 23 in SAPCoupler.build at line 244. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/couplers/sap_coupler.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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"88093613cb0ef348af88fff90ec8265ab9bf3303e28b70c805be8cadd0406368"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/recorders/plotters.py: genesis/recorders/plotters.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 22 in MPLLinePlotter._update_plot at line 567. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/recorders/plotters.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":"genesis/recorders/plotters.py"},"region":{"startLine":567}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f0af50309a2f4a871582b22517ac6dde59bef0c0ddf55d777c8b3dd87f264f0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/sensors/temperature.py: genesis/engine/sensors/temperature.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 19 in TemperatureGridSensor.build at line 520. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/sensors/temperature.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":"genesis/engine/sensors/temperature.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"7417f99bd50ff546d7f95d044f78fb866feaa958840ae331587306c6a7d02b6f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/solvers/rigid/abd/manual_bw.py: genesis/engine/solvers/rigid/abd/manual_bw.py changed 3 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 22 in manual_bw.func_forward_kinematics_link_bw at line 17. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/solvers/rigid/abd/manual_bw.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":"genesis/engine/solvers/rigid/abd/manual_bw.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7e93e5ef67da0598be34428f33c10bbd4718089b46112e47fe07422d39e3649"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/ext/pyrender/offscreen.py: genesis/ext/pyrender/offscreen.py changed 3 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 22 in OffscreenRenderer.render at line 65. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/ext/pyrender/offscreen.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":"genesis/ext/pyrender/offscreen.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"257ce03a6eac2bee002282a32a7ba0e32ef67115f2a0ae560a2964866b311eb3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/entities/rigid_entity/rigid_joint.py: genesis/engine/entities/rigid_entity/rigid_joint.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 16 in RigidJoint.dofs_length at line 306. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/entities/rigid_entity/rigid_joint.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":"genesis/engine/entities/rigid_entity/rigid_joint.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"337c2a0beb5618e738bbc527f5a4ab59ed421555994717458abcf594b8715c0a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/ext/pyrender/jit_render.py: genesis/ext/pyrender/jit_render.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 31 in JITRenderer.set_primitive at line 517. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/ext/pyrender/jit_render.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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"d79bc644563e0f8386771c15abef186f83263024b238b5ce019d0177e1c28b24"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/sensors/sensor_manager.py: genesis/engine/sensors/sensor_manager.py changed 3 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 19 in SensorManager.build at line 133. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/sensors/sensor_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":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"c483c1eaa6d273b50a4d5cd283058424c92f3fa1037d673e17d53620c0bc414b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/ext/pyrender/scene.py: genesis/ext/pyrender/scene.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in Scene.add_node at line 381. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/ext/pyrender/scene.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":"genesis/ext/pyrender/scene.py"},"region":{"startLine":381}}}],"partialFingerprints":{"codehealthFindingId/v1":"d32f2d92dc26d86ff888c7345906c231a0429287fbdf3e32f125afdde5eae367"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: examples/ipc/ipc_robot_grasp_cube.py: examples/ipc/ipc_robot_grasp_cube.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 17 in ipc_robot_grasp_cube.main at line 7. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- examples/ipc/ipc_robot_grasp_cube.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":"examples/ipc/ipc_robot_grasp_cube.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"91cf18702f1321938607e5ee9dd2167cf7b498076ff6953f929aa75b7bc1fa43"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: genesis/engine/sensors/raycaster.py: genesis/engine/sensors/raycaster.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 16 in RaycastContext.activate at line 235. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/sensors/raycaster.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":"genesis/engine/sensors/raycaster.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"66d01d0eb81973494585cdc94d6aa3fedbb2759dfb4b82e346b67a92b10bbca1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: examples/rigid/grasp_bottle.py: examples/rigid/grasp_bottle.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 15 in grasp_bottle.main at line 8. 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-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- examples/rigid/grasp_bottle.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":"examples/rigid/grasp_bottle.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2f1ca0f095293ed8b7657f7f509800d787be944ca7bd7f858cc786f0c59b5d1"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: genesis/engine/entities/rigid_entity/inertial.py: genesis/engine/entities/rigid_entity/inertial.py changed 3 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 9 (its worst body is inertial.finalize_inertial at line 191), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201C[BUG FIX] Fix dynamics of attached entities and resolve assets identically in every precision. (#3311)\u201D; \u201C[BUG FIX] Recover a usable inertia for URDF links stating a zero mass or inertia. (#3261)\u201D; \u201C[BUG FIX] Fix COM frames of fixed links on aligned bodies breaking thrust points. (#3283)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/entities/rigid_entity/inertial.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":"genesis/engine/entities/rigid_entity/inertial.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd3701307a825dd7698d2fff0d97af22e5e473bfb7ac392802a7ceada74470be"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: genesis/engine/entities/fem_entity.py: genesis/engine/entities/fem_entity.py changed 3 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 11 (its worst body is FEMEntity.set_position at line 260), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201C[BUG FIX] Support envs_idx mask in FEM vertex constraints. (#3241)\u201D; \u201C[BUG FIX] Support FEM vertex constraints and topology queries in multi-entity scenes. (#3239)\u201D; \u201C[MISC] Fix support of FEM entities in Nyx plugin. (#3131)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 15:52:48 \u002B02:00\u0027 --until=\u00272026-10-20 15:52:48 \u002B02:00\u0027 --full-history --no-merges -- genesis/engine/entities/fem_entity.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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"2afb7493b5689a873ea7584eef5eee9455a8e0d7a099d22dc361cb763d4aa17b"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 17 significant file(s) lose their only recent owner: genesis/engine/solvers/rigid/constraint/linesearch.py, genesis/recorders/trajectory.py, genesis/utils/watertighten.py, genesis/engine/solvers/rigid/constraint/island.py, genesis/utils/serialization.py, genesis/utils/sdf.py, genesis/utils/particle.py, genesis/ext/pyrender/light.py (\u002B9 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4958035c123f6bc1a7b4154c6ecca39d301f5607aa17fe478a59a3851eab4a08"}},{"ruleId":"D16","level":"note","message":{"text":"Further sole-owners (lower concentration): 1 other contributor(s) are each the sole owner of a small amount of code below the off-boarding threshold \u2014 folded into the bus-factor score and metrics (18 single-owned of 191 analysed files in total, 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; 191 of the 265 production source files in this repository met that bar). They are anonymized user #2 (1 file(s)) \u2014 spread or document their files in the same way, at lower priority than the named off-boarding risks above. The files folded here: genesis/engine/sensors/joint_torque.py."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6eac528f2429e724e1a97ed868f79eefbcf1888dab4af9a9e673429369bb5b2f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The grip closes on position because force control on the fingers behaves erratically 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":"examples/ipc/ipc_robot_cloth_teleop.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"918dbaf67aa0a49c21f3aa940fcd0dcbf31084b90d52bfa6fab5410ae0e94be9"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Forcing rendering device is not working reliably on all machines \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":"examples/rigid/ddp_multi_gpu.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"b84e8df3b2c7dba43fde075df77abc76482f6300dfbed22fd74f6c0ddf66a10e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Switch to \u0027enum.StrEnum\u0027 once Python 3.10 is dropped, so that the name of a theme needs no conversion. \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":"genesis/styles.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"354676fca547b0eed7cc6205030ef310613ae170cb5009a50f8fb0eca0f86c5e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: qd.Field does not support zero-copy on Metal for \u0027torch\u003C=2.9.1\u0027. \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":"genesis/__init__.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9ed954a7372faf87614172446bd11f6ae730aac8102949d6c56869a9582a87e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Enforcing Quadrants num threads to 1 by default when running on CPU \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":"genesis/__init__.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab60e79e68c30766013989d23743662f82d5d0dbcc699da0390895c1ddd2d732"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#980 - The bound is a 32-bit integer, which caps it at 2 GiB, so a working set larger than that"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/__init__.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dc56036ed8e2b8b981a6cd7025b805a8c19e4301d4c92d2969e35d90761d68a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Turning off \u0027force_scalarize_matrix\u0027 is causing numerical instabilities (\u0027nan\u0027) on MacOS \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":"genesis/__init__.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddbd37f5536f8b1559aca7bc6cc7f0d7d3a30494d04580c547bb89018d46d07b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Turning off \u0027advanced_optimization\u0027 is causing issues on MacOS \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":"genesis/__init__.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ba8faf0e197426701359bdc6d83813c0918f8a48c0c256864cbb7de45d1be2f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: keeping as is for now \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":"genesis/engine/simulator.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"8feb7eaaeda5669383fb1d15b3b21ab1d5337b9b2ff03281f59fdb21b2a3fd32"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#981 - Quadrants frees device memory without making its CUDA context current."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/scene.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"180e20cb2c43ae83bf5e39b320d1a6ea4126795aedf66043ad72f2902743ffd9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Could be optimized to only clear cache associated the the environments being reset. \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":"genesis/engine/scene.py"},"region":{"startLine":1005}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dc865ebf5597e746c47de0fe11a97c6e8d306d72cae17e063f3453510c45caf"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: sets _next_particle = 0; not sure this is env isolation safe \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":"genesis/engine/scene.py"},"region":{"startLine":1009}}}],"partialFingerprints":{"codehealthFindingId/v1":"26b3185f885d1e56aa7314bc90776190c5ee90fc9413ca7d9ac606b16df25787"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # .copy() FIXME: For some reason forcing copy is causing some tests to fails... \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":"genesis/engine/mesh.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"3df9e2d73e4e81281e539b828695149e15df5e549bf146a8d9020da98e5b367b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Parsing PBR in obj or not \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":"genesis/engine/mesh.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d6f7607867f7621859af9e7253218ce06b71c032eb62937f9644afa5eca3451"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: support vertex/face colors in luisa \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":"genesis/engine/mesh.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"6de4f50da9e39ea2ad0bc5c42ae9d538104e1dd79a68578cc93344a59055836f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#925 - Metal lowers a fence to a control barrier, so the leaf walk, whose fences sit in divergent"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/bvh.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"70c5c68b3cf8b9ba6071f817729be06e240bd8797f494499c243e24ec115aeba"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#925 - an atomic carries a memory barrier that Metal lowers to a control barrier, so the atomics"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/bvh.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffc1cc3eb433a5f052d1dd6ff7d4f2a3c2fab55df837be4c71583b39599109bd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Dynamically added constraints are not supported for now \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"18428cf342b3f9c73ffd0ee763604618b8c9bfefd11f295352941e1b73efc1e3"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Convert collision_pair_idx to field here because SAPCoupler cannot support ndarray/field switch yet \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2f9107e2960e96a5238627e5a80742f0edb0324be694770b760c261d19159e9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Handling dynamically registered weld constraints would requiere passing \u0027constraint_state\u0027 as input. \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"87d9788f2460cf6b87fda731c2f5b9f867333261b6e4c4329432c34d2e8b418e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This following two rigid solves are duplicated with the one in rigid_solver.py:func_solve_mass_batched \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1138}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f794968ca7752159f1f5919f4d2397dc9aa0f99f1f403430bbe7d6cbb4cd3a5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Maybe support different constraints for each batch in the future. \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":1953}}}],"partialFingerprints":{"codehealthFindingId/v1":"72e4fc7ad85b161e8791fa3f743ef6a3d7ef00f814f53d819c0fc462de07dca6"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME This function is similar to the one in constraint_solver.py:add_collision_constraints. \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2272}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a3ceaf7a94e050c19c7d44512f1816322948757499626b1937d620265575d94"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO Check surface element only instead of all elements \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2593}}}],"partialFingerprints":{"codehealthFindingId/v1":"571318146b211607f9afebdbe8b472ec8842e876f98635a2589ed023c4968dd2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO Check surface element only instead of all elements \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":3295}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2a0ab0c3e90e88041d7f6149a0d89e10ef05ff263948bb6cab5bc5c0049bb46"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO A better way to handle corner cases where pressure and pressure gradient are ill defined \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2658}}}],"partialFingerprints":{"codehealthFindingId/v1":"fac83e9fd6e5eccab2f76530c7d0713141b100adc71206aae058f9e24f67b406"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME This is an approximated value, different from Drake, which actually calculates the distance \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":"genesis/engine/couplers/sap_coupler.py"},"region":{"startLine":2949}}}],"partialFingerprints":{"codehealthFindingId/v1":"27f86cb6799b7da1de157d832dcf6ca6f11fedfd75a6a6ac788b5859bd38a206"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: all collisions are on vertices instead of surface and edge \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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":504}}}],"partialFingerprints":{"codehealthFindingId/v1":"96797bedacd658443631c4f0d3e58e91d2a95de4ccd6b6614617c4ae25d31006"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # FEM \u003C-\u003E SPH TODO: this doesn\u0027t work 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":"genesis/engine/couplers/legacy_coupler.py"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"02f1bb33be86f7b37b8587ab840c6a9b2851a69a5433c1a4d23187ad81066092"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: consider deriving from Genesis joint properties instead of hardcoding. \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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"295bdfe9fdea6962e58ae4a991154836b4d4e5688532c338286a468d6174c529"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: \u0027Solver.set_gravity\u0027 is not honored either, and goes through: it writes a solver buffer the IPC world \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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"58ad335432d341128afa67907b2c8ed5639253e5a633e96412efd3aa82797d35"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: It is currently necessary to enforce zero velocity to avoid double time integration by Rigid solver \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":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":1029}}}],"partialFingerprints":{"codehealthFindingId/v1":"93d737c38d05a86f8928b30d05a8db567d32ed438274100abfdc95d3a2bd64ab"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/particle_entity.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebb1a735df2903540fd8bc8ba498d8e666fe38ee5f8c9078dc05138705cd237c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a28213bbc20a2fd751350d83cc828d6821026a9fedd2f4ddd4b144348fa7f97"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":502}}}],"partialFingerprints":{"codehealthFindingId/v1":"be870bdc689fce9efcd98e8230de59ad0885e4ceb079fb327dfdbd77b76cbeb5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":540}}}],"partialFingerprints":{"codehealthFindingId/v1":"567c5bf550bf4198eb2e038a653d00a431f592ab91fbabacfece4f443cf2d4f6"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":577}}}],"partialFingerprints":{"codehealthFindingId/v1":"35f79a46eef10aebad13a0ed93cea4a1ae730ee0702b762c579bb37116d0ee46"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e90692fd3906e952307ea690577dc0327d4fdf78d192094ef851e4a63030c9f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":649}}}],"partialFingerprints":{"codehealthFindingId/v1":"56ad0edc39832c87c265bfc4140db36ee585edf3aba15414d44c8a84d70c7433"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/engine/entities/rigid_entity/drone_entity.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ec0a91563cb8ea953b75281913f80807c900951d5c2a0de589f994271310040"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This check is too expensive \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":"genesis/utils/misc.py"},"region":{"startLine":973}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5a46ce558b17a4e93f00b1a30b29287cbb6dced85a0cdd9f6f5cc51a9c2291d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: merge with self._solver.get_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":"genesis/engine/entities/mpm_entity.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7e1f9cc054feca0b43dcf749cfee42974b95ac7e4dd7d8ad77e5903ebe63297"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: # HACK hardcoded \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"c151c134d8cce76d30d2c8e42f1938e9653a087264fd0a9fbc6982a4729a872b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: need FEM and PBD \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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e82e006433a9174d8822d393ea95a8b1f5649a53509edc63667276ee9ada073"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: test with different dt \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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"3109c00e65fa356f19f15a52da4244267438c7c142733b38d21e0012ac705875"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: hack to avoid \u0060ValueError: No backends available for boolean operations!\u0060 \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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":565}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0bf7406cb9d094120fd963c5d00ba3e561f0c520665d5c5e75161524117ea19"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: check if this is 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":"genesis/engine/entities/hybrid_entity.py"},"region":{"startLine":661}}}],"partialFingerprints":{"codehealthFindingId/v1":"532b42ea1015e7095472b0a592a7a86f2d24568da7cc6c186562cf3582b1dbba"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Quadrants \u0027fill\u0027 method is very inefficient. Try using zero-copy if possible. \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":1045}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa490dda1c62e1582365c096157db08d431de9365d47255b9835a5285a925c2e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: not well-tested \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":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":1126}}}],"partialFingerprints":{"codehealthFindingId/v1":"2797bcd148f148fa35f0f772a6a2d375c1447bdcce76aa3cc2899727bf007d10"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Remove this branch after implementing \u0027get_verts\u0027. \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":"genesis/engine/entities/rigid_entity/rigid_link.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f20726125e30ace63af717c175a2d571fc9d39e86dbe78c333579976f0c6b8e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Remove this branch after implementing \u0027get_verts\u0027. \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":"genesis/engine/entities/rigid_entity/rigid_entity.py"},"region":{"startLine":2167}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b0f7378dce8a7915485c96cad768683fc6fb6c0e7469a39f1bc3526f1266395"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This pattern not ideal because the inertial mass may be unknown at this point. \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":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":1042}}}],"partialFingerprints":{"codehealthFindingId/v1":"4711b824b33ec9af9eadc2a4894ee34d7726575ff037b40bb36aa11978c73b68"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This formula could be simplified since flag = 1.0 systematically. \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":"genesis/engine/entities/tool_entity/mesh.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf1fe514855db4cfba2005b12e5049b0845da04115012ca55125c2f69412c36f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Resolution should be made private in mixin, so that it cannot be set by the user directly. \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":"genesis/engine/sensors/imu.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b55efda06c18418cd345340c90ff601d56eb22e4263168ea2ae8fa75a46382c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: the frame cache keys on a single timestep for the whole batch, so a partial-env reset invalidates \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":"genesis/engine/sensors/camera.py"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a6ccf0fccabbb0f0133db15798773dcc720e1518d59b757ceb3aa41d1deab4f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Support per-particle density \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4835ccf63800acb5dbf925112157dd02b04992f3058ec47a0b395b6269d348f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make the neighbor density different for multiphase fluid \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7c4dfe74e6d1c7ca8c6e2cb5e333f2825c7242e235e7616f58fa44c259fca1d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: if warm start \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"e859939d2b6d6761e48e191e47360cd8c41bbc345698d80ddfae453703e5d716"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: if warm start \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":541}}}],"partialFingerprints":{"codehealthFindingId/v1":"a761cf41f007d2e3c6299a05119dcc25f6b5dca59d56230ade90b7b9a5cdf5ae"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: warm start \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"383ca7e5c9b41d16e192e28062158720e9c0f70499a26330377c3ae17fec0345"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make the neighbor density0 different for multiphase fluid \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2747c688b3541dd19d6ce3d59154b1fe2f5490fb83741e4f3c30c40b16a10ee"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: if warmstart \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":"genesis/engine/solvers/sph_solver.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"00f1b1a24bdba8b03721cd2e7081d6aa354f5b09b27868e86738fc13d94e862c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: support sparse reset under requires_grad. Quadrants\u0027 differentiable framework needs the grid state at \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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"4665c471246c9ad01409e6219d42e50d534d5eca756357dca9faea1a173956a6"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: AOS, which does not match other Genesis structs. Old, untested code. We prefer not to touch for now. \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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f0b5a5555ff2e60e74a63ed6f682398531e3669e57d46b66f473db487c2a5b1"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: AOS, which does not match other Genesis structs. Old, untested code. We prefer not to touch for now. \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":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"89499eba18fa685adec813d94b16539bbccc41e128b3f8b640f9f4f9f9602777"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: AOS, which does not match other Genesis structs. Old, untested code. We prefer not to touch for now. \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":"genesis/utils/path_planning.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a917f59d25325784981e9572e492068dc133de3ef6b839a949056cfc1ce2f73"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: AOS, which does not match other Genesis structs. Old, untested code. We prefer not to touch for now. \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":"genesis/utils/path_planning.py"},"region":{"startLine":680}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c935e8305fedf58f69119de1f321af1d5b0a8ce7923519167fe77ceca3a032f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: validate the J = det(F_tmp) shortcut composes with quadrants autograd before enabling it 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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"760ebcc97fb4cd4cb446c6c2243ab61965030f2ac734036a17cd07deb294b11b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Use existing errno mechanism 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":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a02f5106c7e5fd52388755bce9be0787afadfcbc02d1b87091245aa1d07557a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: a field is what a kernel taking the solver as a template can read, since Quadrants resolves no \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":"genesis/engine/solvers/base_solver.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"93463c7e20b2cb6542ea4174f285b6557ba2c0b957b201f7f0c9268123ea3a63"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: when the migration is finished, we will remove the about two lines \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"38e44c89843a7eea4cf9c7dbb861acad0c9bef0916e78cecb49c38ecf450e244"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#946 - a graph refuses the ndarrays that own a gradient, so a scene tracking gradients"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1281}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c78363247bdb9a2400c661b2b9efdb700c120302e1f68c3967a30b6812a31d4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#946 - a graph refuses the ndarrays that own a gradient, so a scene tracking gradients"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":853}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2360a68bb97702db09eb28d68445f69b371e73c9f7e0e0a09a070ba2e58fb08"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: support batching \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1410}}}],"partialFingerprints":{"codehealthFindingId/v1":"86747e803b97722732617690fffbae09b1ee2eee0dde365365c785cb68026631"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: the anchor of an aligned root keeps its mass block diagonal (see _init_tree_fields). A center of \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":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":2301}}}],"partialFingerprints":{"codehealthFindingId/v1":"027e543776f13a41cd8ee54bc266e825bb31c63a18403baf013ea1209b651d5f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: the line below does not 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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":526}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d77a78667cda002a2a2f6cf5d94713d441f24a48bb9f662c6ee55a0d37d22e4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: move to rigid global info \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":"genesis/engine/solvers/rigid/abd/misc.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"d04bb63cd84b8360e60e34f146512dc39c75d45075747cc786338eb2ed8dc596"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # silently drops their gradient. TODO: once every sub-stage reverses correctly under autodiff, drop these kernels and \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":"genesis/engine/solvers/rigid/abd/forward_kinematics.py"},"region":{"startLine":1255}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf962dd582041665103cd28689558d3ade69e06278aa85e8c747ce77121a83d4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Diagonal coeffs of L are ignored in computations, so no need to update them. \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":851}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc79a2385793a9f7f6995db9019fe19cbb96affd581f85435c7f9a71e1e34d65"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Diagonal coeffs of L are ignored in computations, so no need to update them. \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":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":929}}}],"partialFingerprints":{"codehealthFindingId/v1":"12476f2af0dab4c1d92487c046186c508045e460ce56776119e74e247623ad40"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Parameter pruning for ndarray is buggy for now and requires match variable and arg names. \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":"genesis/engine/solvers/rigid/abd/diff.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"40a28ec083845c204ad194f0ef0783e35861c861b47e8b9234867e494c40c751"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Make this more efficient by only taking care of releavant qs/dofs. \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":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":919}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4da21ad41f3773980c89c86d8c9e8db90488f1af8e0feb5501e1326b45fbe5e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Ten vertices per face and 40 support queries raise the area spanned by the contacts on a 32-sided face from \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":1978}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5dc1121985abcf6c257787ba312ebf236b21e268d2882d389d77c5b138766ec"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Add support of smooth refinement to differentiable contact. \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":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":2733}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4e4e796a4c388f0ba2472b2e3993890af629930cc2ffb6d7cf58bc1e9f1271b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#925 - every lane of the block issues the claim atomic, the other lanes adding 0, instead"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/narrowphase.py"},"region":{"startLine":3777}}}],"partialFingerprints":{"codehealthFindingId/v1":"f011309bde5fffbd4aa10cd9d2ef1240143354a20948ef84085db18ce251a8b6"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#856 - see the scratch states of GJK in gjk.py."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"903836cadddff6b6813032f744127cd61baf687c00e7ad77ac7d9f3de4d96467"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The search of the third portal vertex can cycle when the penetration is below CCD_EPS and a geometry\u0027s \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":"genesis/engine/solvers/rigid/collider/mpr.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b1ea1619eec157d430887237f9c6d6c04c205c55a73c431dc8754fe2c8f516c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: On the Metal backend, reading a fixed-size vector at a run-time index inside a dynamic loop returns 0.0 \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":"genesis/engine/solvers/rigid/collider/gjk_utils.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea8e0483409b4c38149633c2bce30fdffd78368497482fdc7c0bf55c4464dd59"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Adjust these values based on the case study. \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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a9ca732b315ce3d755c73fbded82191640eb04a0dbef4e192efd9344e350603"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Adjust these values based on the case study. \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":"genesis/utils/array_class.py"},"region":{"startLine":2000}}}],"partialFingerprints":{"codehealthFindingId/v1":"b76df4e0a4590f2288352e94c4af55253eaeb7d6a5a77ccaaa44df664c0eda78"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#856 - a kernel cannot take None for a struct argument, so every state is allocated at the"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"deb198d11f9a68c44ac7d3e940d6d5fff63e8bcb8080c72a7bc9686530939ce5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: When we use if statement here, it leads to a bug in some backends (e.g. x86 cpu). Need to investigate. \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":"genesis/engine/solvers/rigid/collider/gjk.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"29be6bafaecb88c02cdc74db6d25679f506abbcb596179b7f39b9c0f73aaf1ab"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Can we stabilize 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":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":821}}}],"partialFingerprints":{"codehealthFindingId/v1":"96816c1b22c8a650437f576ac9c87dde06c5424a5f4688364368ac11427f248f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Better implementation from Quadrants for this kind of reduction. \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":"genesis/engine/solvers/rigid/collider/contact.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"e30ebbf8bf501a358ea198db94f0bd202f962d542e4f927f8901ee81953b195d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Links should be considered adjacent if connected by only fixed joints. \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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"61cd003c7ca56b3ae92b7b14f684f4973872825ef5adb015e5f90d58025b7348"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: MPS gathers zeros through an expanded index reading a zero-copy view of the quadrants \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":"genesis/engine/solvers/rigid/collider/collider.py"},"region":{"startLine":920}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea9ae864d9716f09dadd90587f7d42e78900afb63bb68fa413b50e23f907d11e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO \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":"genesis/engine/solvers/rigid/collider/box_contact.py"},"region":{"startLine":614}}}],"partialFingerprints":{"codehealthFindingId/v1":"44ee8e7a92aa87d1c79539509e97ad2ec88b3ba95b4949be7853d5187e534038"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: a good unittest and a better implementation from Quadrants for this kind of reduction \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7a745f1e6ee66ae2b60beb9da4148c96cdeabd0044a578535b44adc92bb40e4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The reference engine anchors the tangent frame of a plane-capsule contact to the capsule axis, \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":961}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ef0b807d9bb8aacd4bc159a8a66830019b54aac0a026e30c0a135f72c17a551"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: sparse mode \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2026}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5eebbb88e5cf1746fda546bcc0cab569e02c9ae3afdf8bdfc08d0d27374968a"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: sparse mode \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2076}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1bdda760dc6d443e54f33a62665d9ce9dbe861c1b2a8ef3e093bae3085ac6f7"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The condition \u0060if dofs_info.frictionloss[I_d] \u003E EPS:\u0060 is not correctly evaluated on Apple Metal \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":2077}}}],"partialFingerprints":{"codehealthFindingId/v1":"279cea44a8491f1e8e9569e141e09a281e846f3ed2a1c23f94f85367c60aa404"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Remove the MuJoCo compatibility gate once on MuJoCo 3.11, which carries this criterion natively. \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":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5720}}}],"partialFingerprints":{"codehealthFindingId/v1":"6abdfe5ba33b0b607dd88068268883b4327ff0f0c535e9277339aca3eab9c8ef"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Remove the MuJoCo compatibility gate once on MuJoCo 3.11, which carries this criterion natively \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":"genesis/engine/solvers/rigid/constraint/linesearch.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a0d64d7261a00c5360d0564416d683196f366e9816b0b54740bf53e67c21b74"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants debug builds check a loop-invariant access before the loop runs, so the empty dof loop of a \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":"genesis/engine/solvers/rigid/constraint/island.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"04ec93e2e2c7fcfeb5739c0f447a231ce3371fbfcc2856e28e6c2c2c2da68cf4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO : should this be removed to always return a scene? \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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbd131ca4bb6cd1424727e79ac0c2c8a30a4b0054ea0f42db3bae807edecd487"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: probably need to support 8 and 12 columns for quads \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":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"73dd3f497fd60918fa48612988983a1c976fa209239e6e49d56ed9f23b2e4ce9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO OPENGL BUG? \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":"genesis/ext/pyrender/texture.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"41ffa71d4bef3d82a10471eb644f02e6c17fe1bd284574d1da2929b5ed824120"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO OPENGL BUG? \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":"genesis/ext/pyrender/texture.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b91699c1393c17a8d980ef95bef83fb41ac916340bf938c6bf39050d78c49ba"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO HANDLE INDEXING INTO OTHER UV\u0027s \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":"genesis/ext/pyrender/texture.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aeb191a153ed55a14b4935ee6f64798a8c078f57b35245ab4cc51ff6c1dd0f4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO JOINTS AND WEIGHTS \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":"genesis/ext/pyrender/primitive.py"},"region":{"startLine":440}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d5962f2f6d9d11732d4f8f5eebc7f77c2a8ce26ce61aee611917cbceb021d03"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO TMP \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":"genesis/ext/pyrender/material.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1080ab6ed086e395a449458a3621305bbfffd77acc5bf07db12539b70b5dd8b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Note that enabling GL_BLEND yield non-deterministic results on Nvidia GPU. \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":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":859}}}],"partialFingerprints":{"codehealthFindingId/v1":"90a2eb82625968307b94e9ff18b753848e4f9633ee2288db6a033942a3ce3333"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO MAKE THIS MORE EFFICIENT, glBufferSubData is broken \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":"genesis/ext/pyrender/font.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"735988268b7ae8c6ac496cf151891e03f47c2c6534e3ee4fe627f5e7e09ed520"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Scene.dump() has bug that uses copy without include_cache=True, \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":"genesis/ext/urdfpy/utils.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"cba605a3156c624d49db2f3a396c628f144b2e88f713e18c4629fd87d93033ad"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This is a temporary hack. Due to some unknown reason, the unbind operation is super slow for gs.Tensor \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":"genesis/grad/tensor.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"de45eb08057ee09e0743e8d66fbb1fdbe942456057d7cb8686ed8b76be2c4a5b"}},{"ruleId":"D17","level":"warning","message":{"text":"XxxComment: # XXX: Kept for more debug options. \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":"genesis/logging/time_elapser.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"21071f4df8ccc1d20cfa85efb409f0bff4cce55abf8f4236b22d737dab77a136"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: re-allow once CoACD 1.0.12 lands with the fix. \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":"genesis/options/misc.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb99ac923f25a0db74f0ca48a900a83529315f8dc3702ef61a113780534d781b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Resolution should be made private or converted to properties in mixin to prevent setting them directly \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":"genesis/options/sensors/options.py"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"90ac0f7abd5b03fe2537ebbb6d6d49063897ea3851ee856095f3ef0fadcf8d39"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#970 - a 0-d field has no zero-copy view, and reading one per frame runs a copy kernel. The"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/trajectory.py"},"region":{"startLine":561}}}],"partialFingerprints":{"codehealthFindingId/v1":"f73734c1576b00fb63989fbb4453f069c13685d8bf98cf9509df555364e7357d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: get_triangle_vertices/bvh_ray_cast/update_aabbs duplicate their visual counterparts below. The two paths \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":"genesis/utils/raycast_qd.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"5908f42375d0cdf77f52230406671fdc3040b817ae3fbf398344c86d1b11cfc5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Running in subprocess or manually reclaiming free-ed head memory is necessary to avoid unbounded growth \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":"genesis/utils/particle.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e323b04acebfaa2687ad9ca09d563e268864c557681313dd411f86537b97f3a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: MuJoCo 3.10 weighs a childless body sliding on the world along its own axes as 1 / mass, leaving out the \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":"genesis/utils/mjcf.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"5243129890ad2a48dabbf086cbbafb8d8d54a01b963a953c0a458a57028c692a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Do not redirect stderr on Windows OS when running pytest, otherwise it will raise this 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":"genesis/utils/misc.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"53c565b3033acfe5749670c310e060ea5d736051c101259cd11df884b9a8b0fa"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants should expose a query of the GPU core count and layout for every backend. \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":"genesis/utils/misc.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"7af3e998d56b8d642452f76055084935b16e52d72c1d49c314b02d975216602c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#976 - the shared memory of a block is a 64 KiB lower bound on AMDGPU, which caps the tiles of"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/misc.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6548c7128cab18d8c81ef46544003d170d04fb29c82fb1d9b80be0aa696a51c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: torch exposes no allocation granularity of the local data share (LDS), which AMD sets per \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":"genesis/utils/misc.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"85232ab424e84d1cd3416ae2a1aabe036e15d11d58880c4c98f48880c00fb90b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: torch exposes no cap on the resident blocks of a streaming multiprocessor, which NVIDIA sets per \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":"genesis/utils/misc.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"a11dc06e5f4d8c0c3abcc3b9b43b970431a086c26a8d8faf288b6b131a9f78c0"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Ideally one should detect if slicing would require a copy to avoid enforcing copy 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":"genesis/utils/misc.py"},"region":{"startLine":758}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a93ca9feb263ce1955bdf1c8a55c266a479ed137089044756fc51ef986e02c0"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Ideally one should detect if slicing would require a copy to avoid enforcing copy 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":"genesis/utils/misc.py"},"region":{"startLine":822}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d4033539eb28b8633d8fcfb672017679d0faed653d65bf1aa76430a706363b9"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: DLPack may return old values on Apple Metal if sync is not systematically called manually \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":"genesis/utils/misc.py"},"region":{"startLine":787}}}],"partialFingerprints":{"codehealthFindingId/v1":"07a838557ed771c6db91b88009c670e8a36c877238f5fae883c0c2a016f4a96e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Parse occlusion \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":"genesis/utils/gltf.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"39f7da980b0985f94e03f3a073ca011f04b44ac214cd54bad2e6ac93a1ac4f44"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Parse them! \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":"genesis/utils/gltf.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"801a0b90b62d953ee2b7abf515d805ae746bb4848525bf12e0135a3f8c6174a5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Ideally, a taylor expansion should be used to handle angle ~ 0.0 \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":"genesis/utils/geom.py"},"region":{"startLine":1987}}}],"partialFingerprints":{"codehealthFindingId/v1":"b946a1aa1e4f7e80887ae9802736ca808f9411c0ab13a5d8c281faa5b8f72b98"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Taylor expansion should be used to handle angle ~ 0.0 \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":"genesis/utils/geom.py"},"region":{"startLine":2015}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5c2adab66d9a305cbdf3dc4dc297a8522bcb15525268b04499adea3eb0c81bb"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#941 - a Python-scope fill of a field still being declared closes its SNode tree, one tree per filled"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/array_class.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"de33a6b3d67c8527cfa36f12cc224188b350d9daa36a865232ad18c484416b04"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#963 - Metal silently mis-addresses the tensors above 2 GiB instead of raising."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/array_class.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dde09557b81bceb86ded932e7ae7dd773d6940884f60a64333c4a1c36a6d5dc"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Add a better split between kinematic and Genesis \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":"genesis/utils/array_class.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b6abd3366a8643cd1adf6d20e9ed9120825ebf53c1095940dd98676cd18e08b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Optimize storage to only allocate memory half of the Hessian matrix to sparse memory resources. \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":"genesis/utils/array_class.py"},"region":{"startLine":993}}}],"partialFingerprints":{"codehealthFindingId/v1":"e61af1676fede043b747820421ca8705fa93fb1a5d727f3fc27100d62b8e6ebd"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Define GJKState and MujocoCompatGJKState that derives from the former but defines additional attributes \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":"genesis/utils/array_class.py"},"region":{"startLine":1862}}}],"partialFingerprints":{"codehealthFindingId/v1":"672b7b9ad7eaf24c1a2dc41c73084d6bd43749ce54d24ae68051103d1f0051dd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use attribute \u0022state:\u003CINSTANCE_NAME\u003E:physics:positiion\u0022 to parse init_qpos (but it is IsaacSim specific) \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a9b870cd836bf4a7f648e02f545ac89d8df83a02c12656a7edd485cd3c23987"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: use drive.GetTypeAttr().Get() to parse force or velocity. \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"47759866d562a312a631ecbcd0979c655f053877fb112f32bc52915fa3c0f26d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement target solving in rigid solver. (GetTargetPositionAttr()) \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":455}}}],"partialFingerprints":{"codehealthFindingId/v1":"18fdf69883252df13fe056beecfd083cfbc317cdd32077c9b41a69b83acce150"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: parse actuator in USD articulation, now all joints are considered to have actuators \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":"genesis/utils/usd/usd_rigid_entity.py"},"region":{"startLine":481}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a318d6d5cea14afe72dd224a8edf43444cc490a62465eba7a925938e0aa71d9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: discard degenerated faces \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":"genesis/utils/usd/usd_geometry.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"705918b5a374732e5f322fa9ba5d385d9db41e8fcb8a06092ebb908ed4edb2d1"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: material_id is also reserved for group_by_material option. \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":"genesis/utils/usd/usd_context.py"},"region":{"startLine":356}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdc33daa0a9ede19a67cfda5d91e69617b9054109cf6ccb09b1974b67288017f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: set portable root to avoid extension conflicts \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":"genesis/utils/usd/usd_bake.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2ac016b97c461f2c1d2ca2e173116e13b7d03c4c9e037df997210c8cd0fd36d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: make this more principled \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":"genesis/vis/raytracer.py"},"region":{"startLine":781}}}],"partialFingerprints":{"codehealthFindingId/v1":"26a5108ecfa24c86e36dc1e8513b39c3969ace66631175286241704cdd3ac139"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: need to support multi-env visulaization for tet mode (it\u0027s using static node) \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":"genesis/vis/rasterizer_context.py"},"region":{"startLine":897}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4d45ad639d51f784808e34b59d6a3b89aaea75e2d14d10c98d272474996ac7d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: For some reason, it is necessary to update the camera twice... \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":"genesis/vis/camera.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"74283f0aea70946ecaa503cfeccf3b6276ad3d77f48cbcb592a98caef8a0591f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Avoid converting to numpy \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":"genesis/vis/camera.py"},"region":{"startLine":555}}}],"partialFingerprints":{"codehealthFindingId/v1":"bee0f6a1ccc629bcedd86eccdaa9e80665b8a9b8614e368ca6bf66e929437cda"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Use a kernel to do it efficiently \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":"genesis/vis/batch_renderer.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ba0f157b3bbf9c286f7684086e82d65b2c105c00df6647bbf0e372aba12cffd"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Use a kernel to do it efficiently \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":"genesis/vis/batch_renderer.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"f00d41850e7fb94cdc23c924f8fcde8c5af11482e9d4520af121b5ea1c46a3a4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Use a kernel to do it efficiently \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":"genesis/vis/batch_renderer.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad8fbec7715eff5b77ffbd655c34a9cc4a93bc0860946346070c226e3c1676ca"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: support batch rgba \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":"genesis/vis/batch_renderer.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"7213a89b651cc5c09ec160ba80b12b5e45e5fb3160b80b856cc56d7b3a7e0593"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: quadrants#887 - a host-side read is refused while another thread traces a kernel, so the first"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/vis/viewer_plugins/raycast.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"d720cbe05361a641dea0aeb6b408b31bcedf1b2001262130d9771f6e598ce812"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: segfault on exit \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":"tests/test_examples.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3db54bda48467c1267cf8d461c4c0729749439569415b0b076e608aecbe187a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: segfault on exit (corrupted double-linked list) \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":"tests/test_examples.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5883c54a328367052e6e5e102cb227dac35c212169eb7c91e240dd53060d0f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Enabling multi-threading in benchmark is making compile time estimation unreliable \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":"tests/conftest.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbb8a670e286282c0e5c648b6034e582e0704e8ff71292592dfe3ba55760718d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: There is no easy way for Intel ARC device. Ignore device visibility issue for now... \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":"tests/conftest.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"2286ae6d7342beab8a50174dba9eb894c2495fbde9a920d35e6badb81dc23d37"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Must set temporary cache even if caching is forcibly disabled because this flag is not always honored \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":"tests/conftest.py"},"region":{"startLine":918}}}],"partialFingerprints":{"codehealthFindingId/v1":"fed7c6fb0560a31eacb6b132cfa934dbba0d17b6684689fbfc7a0a7054530e65"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Entire scene reset is still slow currently because \u0027partial=False\u0027 by default. \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":"tests/benchmarks/test_rigid.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"31a916edb3b2d2df484ab68d395b849462864530279141e32a895ed17b31d099"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # the burial side). FIXME: replace the reference value with an analytical bound. \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":"tests/core/test_utils.py"},"region":{"startLine":1006}}}],"partialFingerprints":{"codehealthFindingId/v1":"29fcb678e2b27fb562dedde63b972012aaff985fd33176333df4c69df8e130d4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Hijack video writter to keep track of all the frames that are being recorded \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":"tests/core/test_recorders.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"1776c94e48a0a52c86d306c80bb0d56db93f6de2eeffc15c2b2411191b984d3e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This test is crashing on Linux (x86 \u0026 aarch64) Github-hosted runners \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":"tests/coupling/test_hybrid.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"5049e7f4baec180cd7b3429fe7cb0bbf41dc167da795a4cb64eda60fc0d692d0"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Compute theoretical deformation to be able to reduce the tolerance \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":"tests/deformable/test_fem.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b459780340ecc0c55170f88d236a695d4d3eec2372a01fcd4d890d3ca1c60c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Compute theoretical penetration depth to be able to reduce the tolerance \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":"tests/deformable/test_fem.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd82cf05628f85df119e227e94352004e2ed8870bd63f3c399cdb7d7f17519f9"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Why it is not possible to achieve better accuracy? \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":"tests/integration/test_integration.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"654c3e6aefb5754b5ee41573248ab2cf7c980123801fbfd9790fab1e338a568a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This test does not pass for sphere entity... \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":"tests/ipc/test_rigid.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ca54693fd09bcf0b54b38e3ee53c483b39a3f2f4b76099431826dbd78c38ea"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This test does not pass for sphere entity... \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":"tests/ipc/test_rigid.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"19c9121e96836af8df211661aa2597f6b2f642341e788a2bb79b59f1651fa443"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: For some reason it actually can... \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":"tests/ipc/test_rigid.py"},"region":{"startLine":795}}}],"partialFingerprints":{"codehealthFindingId/v1":"753a10599a6cff866855148939fac5f85cae635fdc1c1c4d9a0481bcf3e451b5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Why the tolerance is must so large if no fixed ?! \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":"tests/ipc/test_rigid.py"},"region":{"startLine":805}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d0ff940d9ca7cbf7c90cd36cc30a1b7c695de54be0930489a312f2892faff0d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The estimated force is not very accurate. Is it possible to do better? \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":"tests/ipc/test_deformable.py"},"region":{"startLine":403}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5a2c622027bbbf60019273d1c5da5535973bf000d89c6b563b13ee8e2db9995"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Why does the tolerance has to be so lax for this unit test to pass?! \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":"tests/parsers/test_usd.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cd30ba67fdcfab370c31e0a36ef0b5cee8e5ba25993d46022cb7f21a0df5c1f"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The STL files are actually different from the glTF... \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":"tests/parsers/test_mesh.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"62955186b986144717aa51dfdf6b97966f205055bfee8c4e529ccc737ef241d5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This test is taking too much time on some platform (~1200s) \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":"tests/parsers/test_mesh.py"},"region":{"startLine":923}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b3d8894ce998e317c86d40d124db1fa05a34d1cb02955593572f47fb0303e0d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Add more tests for validating the underlying physical behavior of DFSPH. \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":"tests/particles/test_sph.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdec4c6710264dd2d53376c9a0c6f4369c733faf788b6f694b0c535305b51d9e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Tolerance must be increased whe using Apple\u0027s Software Rendering, probably due to an OpenGL bug... \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":"tests/rendering/test_offscreen.py"},"region":{"startLine":1066}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c5a3168a0aeb3be027ba7c8b592eb0ce3b6ce0124c496e19958faa992844deb"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Use a more accurate model to predict final velocity. \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":"tests/rendering/test_interactive_viewer.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"01bc3463c0ccdcec80ddcb9b13fb1fa038d9077c7bcbeb03e6635d2cad5203a5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: On the macOS CI runners the GPU is a virtualized \u0022Apple Paravirtual device\u0022. This test drives that \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":"tests/rendering/test_dynamic_meshes.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e983cb9fb07741a5ab27071cf5ef202ce325786e109a5155c173ad75c9eda0b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Collision detection is very unstable for \u0027stepping_stones\u0027 pattern. \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":"tests/rigid/test_terrain.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"34d9a5efa753fedae0698d2b4ac63a0f38e04357be683bd479cd7f4912d51acf"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: It should not be larger than \u0027vertical_scale\u0027 \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":"tests/rigid/test_terrain.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"07224edb616859dcb52d4fb9301962a2707f8d1fbb27cb24eef14a13df3a8778"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: , \u0022chain_capsule_hinge_capsule\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":"tests/rigid/test_mujoco_parity.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"117f6a2016ce2c69ed8f0dc1170e5895eccf416f45061b5c4b2e71de403108b4"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # gs.constraint_solver.Newton,  # FIXME: This test is not passing because collision detection is too sensitive \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":"tests/rigid/test_mujoco_parity.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"028d173f5446e9b8d83b283a54b048fa3a1ed99026a9e9350ce4ecf8f63e6b81"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Mujoco is detecting collision for some reason... \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":"tests/rigid/test_mujoco_parity.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1cae318e4caa55d825d398c6f9407d9ffddbbea3530e5da0aaac6bc99906cb0"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Implement a more robust plan planning algorithm \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":"tests/rigid/test_kinematics.py"},"region":{"startLine":636}}}],"partialFingerprints":{"codehealthFindingId/v1":"59928d9005edba142ea6462e2ea0a5064cd8b02929e70c4caf40e8ace03c85ab"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: pytorch#TBD - \u0027any\u0027 over an empty dimension returns uninitialized memory on MPS, so the contacts are \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":"tests/rigid/test_islands.py"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"51f3ed32208ce668a905bebcac1da9d6360595ad5ee5faf9054aadd55c68d675"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # The arms stop against each other instead of swinging through each other. FIXME: pytorch#TBD - \u0027any\u0027 over an \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":"tests/rigid/test_heterogeneous.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"931db0d2506baa4573722ff96e06b423848bfedb18154bcc4e18a0eaa692e3d3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Cannot afford GPU test for this one \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":"tests/rigid/test_dynamics.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0d7420b4a6e37a774d02810d4c48fd2844f9179d8c26f5b4271752af89cbd81"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: We do NOT raise exception anymore when setting control targets that would have no 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":"tests/rigid/test_control.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"379bd1f55a83cf4838304919aeba4b9ddab9854716847e5bb42013f33e243a0e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The box test only checks that the body wedges at the L-corner equilibrium (position \u002B zero velocity). \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"e49cbd7474e0027c0651109d6600480b84cb28b62a4dbbc4b4a73383e529b33c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The total energy should be not strictly decreasing but is not... relaxing the condition \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"7519ef4232d58d758b44a26a32679317ba0374e711fd0890c25adf1c40e66937"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: There is spurious residual motion on both paths that prevents the objects from truly settling \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":787}}}],"partialFingerprints":{"codehealthFindingId/v1":"afd09dc1f9b4eb46b12aa4e30f6ba6beabe6e41939770ed1d9b0f12d446a3e22"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The cup is falling on Windows OS because the convex decomposition provided by CoACD is different than \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8d18452751d022df79d98ff8e2910ba568066fafee33f4bdeca0df7ca41e719"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Rare (~5% of initial-pose draws) stem-through-wall traps exceed this bound by design: a thin feature \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":938}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5e8241fa5f518b8d213559a79eb04e5aae2175d0e5132341569a6e51ce7a4ca"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Why the angular velocity threshold has to be so large without any visual 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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":972}}}],"partialFingerprints":{"codehealthFindingId/v1":"08e22dc12ed2731f30a762cdf776a0a5f89288992a28b3fb9c90f705ada5779a"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Both path pumps net positive contact energy over this window. \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":978}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1e46c0dad2b011a9cb7c7bec9c834317aed6ad82a7d744514889156e47108d2"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Both paths suffer from fictitious energy injection. \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":"tests/rigid/test_collision_nonconvex.py"},"region":{"startLine":982}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8740c3aab103235dbf0e314d49fcbc5be7510b1ef7a8881705d2f5e781cb11b"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The top ball is slightly rotating around z-axis (~0.5degree) \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":"tests/rigid/test_collision.py"},"region":{"startLine":1406}}}],"partialFingerprints":{"codehealthFindingId/v1":"196edf4e79c3cd7a376be34af217d95f293197b464418e8bc198679f399aa099"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: The tolerance must be very high when using 32bits precision. This means that our computation of the \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":"tests/rigid/test_asset_loading.py"},"region":{"startLine":1095}}}],"partialFingerprints":{"codehealthFindingId/v1":"03f7e7f20c6478b7f5bd4ed368caf9c485a059000a01c39df5a8b48e09182a67"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: None of the robots being tested for now have linear joints... \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":"tests/rigid/test_asset_loading.py"},"region":{"startLine":1113}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7e462e18482bcfa1c5f69160852e5b88e563039493138c30c12b4f17d9d8484"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Scaling of bounds depending on the type of joint should be explicitly checked. \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":"tests/rigid/test_asset_loading.py"},"region":{"startLine":1114}}}],"partialFingerprints":{"codehealthFindingId/v1":"698c0bb0d60827d2d544bcf882ad55356b32680b491b46c44e055b425c1188a5"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Not sure why tolerance must be increased for tests to pass \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":"tests/rigid/test_api.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"1daa9a4adcdd626db9893694024f961c285a5a0bcdefd67b83f73447d019f41c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: pytorch#TBD - \u0027any\u0027 over an empty dimension returns uninitialized memory on MPS, so the contacts \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":"tests/rigid/test_api.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"169525edd7b7ffa23ee1b42996447cb54ec056218f46255ccfd50e58f920825d"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Adding CoM offset on box is disturbing contact force computations on box_2 for some reason... \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":"tests/sensors/test_contact.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e1399037cd8f78e6736fc8043f301a872ae691ea4d8986c0993a2448722465c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This test fails without any entities in the scene. \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":"tests/sensors/test_camera.py"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"60d9f35c94850163c0453f8b5182b51183ec477db60ebe6ded1fa156be4047f0"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Genesis gives every contact at least the sliding-friction basis, so a geom asking for a frictionless \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":"tests/utils/simulators.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"327fcffa11607697868b79fbf3ebfd809b02b871f893eb712ef960754cfbf6fb"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Genesis has no tendons, so a tendon\u0027s range contributes no constraint row on its side. Releasing the range \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":"tests/utils/simulators.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"99cad8dc5d07cd9b0b2a8c11abbf12b3d232f155ee0316e50a211e86215b312c"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: only supporting 1DoF per actuator \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":"tests/utils/mujoco_parity.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"365144f5c0b4b895854cda14e970c288b614b230f8d8df3ac840f99034095ff7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: 1 stiffness per joint in Mujoco, 1 stiffness per DoF in Genesis \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":"tests/utils/mujoco_parity.py"},"region":{"startLine":434}}}],"partialFingerprints":{"codehealthFindingId/v1":"680c1d6f69ade6f64f574a0fb255f719db5c762667a8b563fd929160dcb6dc5e"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Masking geometries and equality constraints is not supported for now \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":"tests/utils/mujoco_parity.py"},"region":{"startLine":469}}}],"partialFingerprints":{"codehealthFindingId/v1":"af2cacd0a7cb531e1d5326f506468740d5acb111b120736ce01f89416bd9a3e9"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: For some reason, mujoco is sometimes (seemingful) wrongly reporting 0... \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":"tests/utils/mujoco_parity.py"},"region":{"startLine":708}}}],"partialFingerprints":{"codehealthFindingId/v1":"09d1c46f4b8701b9f07553520d62ec81bebb0243bd780008b9d585c45f7ee97f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Validating mesh files is more tricky. Ignoring them for now. \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":"tests/utils/assets.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c089d636365c70946362f076b92585c47e5b7e10683a5ae9cdaff1ae6fb1b16"}},{"ruleId":"D20","level":"note","message":{"text":"No ADRs found: No ADRs found. No recognised ADR directory (\u0060docs/adr/\u0060, \u0060docs/decisions/\u0060, \u0060adr/\u0060, \u0060docs/rfcs/\u0060, an \u0060ADR0001/\u0060 folder, or their siblings) exists anywhere in this tree. What was searched, so you can tell an empty log from a search that missed one: every directory under the tree (build output, dependencies and VCS metadata excepted), for a document that is either any non-index page inside a recognised ADR directory, whatever its name and however deeply nested (\u0060docs/adr/use-postgres.md\u0060, \u0060docs/adr/2024/0001-x.md\u0060); or a file anywhere whose name is ADR-shaped (\u00600001-use-postgres.md\u0060, \u0060adr-012-caching.md\u0060); or, when neither turned anything up, a document carrying the decision-record signature (an \u0022Architecture Decision Record\u0022 heading, or Status / Context / Decision / Consequences as section headings). A decision log that clears none of these \u2014 unnumbered files outside any recognised directory, without those headings \u2014 is not seen by this check and this row is then wrong. If that is your case, say so rather than renaming anything; otherwise, consider recording architectural decisions in \u0060docs/adr/\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d2bea044ff79d7d275f5a91a6e2f548586178eaf480274c33960ad020c854631"}},{"ruleId":"D26","level":"note","message":{"text":"Projects may be oversized for their cohesion: 1 of 1 project(s) overshoot their size bounds, lowering Project Cohesion to 0.0/10. The most over is \u0060(repository root)\u0060 (136173 LoC, 871 module-visible types across 58 directories). Review these for cohesion \u2014 draw the boundary inside the module first (group each responsibility into its own package or directory and keep the cross-boundary members non-public), since splitting a published package moves types between packages and breaks consumers."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5a94650dc74886a0f1f08eb9fb6775f1fc395279ef7e901c970c9d26f767a72"}},{"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":"fefc9a67896e55fdf0fc4bada82ae71eda6c195301956e5f6d93b314091a28bf"},"properties":{"commitSha":"73f9d2d2ba958ebd64d57e18ebd9480d14346895"}},{"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":"d90d30ef8de200d674d16c4e42c30ee5d5e07ee1a1c2c2dfa23bcfe67238629e"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"d6ed58a5b5c3b65169f12b4c23aec635b96e8ad6c839160fa532362ff76cba34"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"76f72b0423843bf1a6befca15907812c4e320539bdc94e1934d1b128fd1ad341"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"f0f8b157ffa635b2a867c0f98396f32f42f3b6a31b1caf06e40899e78086cf7f"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"6f9911d70621d0bd2ba2e9119445ba1d7720b5b5e008154d646873d8cc2c3f31"},"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"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-4","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"3acf81c700f810ee6c2ac7f5c7de69006449e6836d8762289d37a71488a3c897"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"0fc88134e85d2bba1af3e88e64815c88c05272f8afe84fb421b6bda0a690400a"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"6f38ef6cf1690c4820cc7f43e5b414df17d16d75c36d7a0f68f3ad0ff0ad696b"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"83f59d8170b46424cafd73202895713e90fcd2823cad7032018be2cdda870ede"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"41ef3da52fd363f35d5c45b57d597c1cf7eb5d7e71878fc62d7520e782c02d10"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"d989b2c97ad4f572bd4038c9fae509faf5ff11d1eaae9bc0e42e3b011302aa58"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"4cc055e248a6e3f3f11769beea7274f76b19d7b6c40129fe5ca87184d3d3fbef"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"4a35fb5798b7c44272cca62f232fe75935a6a60ad4a6715ee68e42fd9ed3b0ff"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"1151c8080827ccea7beee3d77d92114f52280342dc90e9f83bb51c5701009792"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"10801a260d9f21062acba972337b894b19c09ee35fb93438861b895f49072efb"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"b4237eca797b3d8c42a7416e4aa04504f283ed8e66fde5e1db6c29438918895e"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"ff867bbe15e7961596db123f419bb6da4359bdfcc76645c545d253ae3d7cadd7"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"a65dda5d44f24122300284a58bd29aec0c28f84289c8b15dc6c1d5f3fb5a9660"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9351a92c6787e1612092abb1ff1c3909f9f6aefb1e98ba431ca8dffe42816ebe"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"f7898283901777bb1a3ef5d3c013b9ff2819bf6fb290c6fdd70251d4ccfa2fec"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"4ae6ac057fce16e467447c07e976030039c71288ca4a6ed48686ef99092c43fd"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"4c854cbc6130ba4e07104bf70a0596348d0dff7c558733cac1b46b4bae50a5ee"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"b61b75db317b8201375a5a3132ec8f7180a60d94d9743c169cb71e40b2479227"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"d402faca53012f207f4f54f90378cbaa6aa0391cc20f1bbfa29a2692334abaee"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"f8aa09d277cf3cbda5db0db42b5aad1d5014562a050b6c3e243c29e09a3dc463"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"23554f25ad033c15895de07b58f3403ffafcebd6c17ed9b1b1c3e852ece7d973"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"230a1a90482d43db85dc7fc6a13ab9e8fedea5d44333feb887ae7eb2b733f6ca"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"e1e2b1da3d93a554251b2f245e34abf2b21336b37019c90566027535935f614c"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"cc3f396a49eb71927a5f999fd979d92dfa442768f190f1c88c9f226b9c208491"},"taxa":[{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"de35745b12b6bd2625e9b1640b387b97e7852ceecbb575f8ed3ebc42225791f4"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"8fc175bda5ca5b545c47072cd875ded656debca2eac3554a6a7a41c8201c837d"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"e272db4a4c4d5db34e85b33927b42f5e64c84192135ccfab951cbe4a48269f3f"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"35b53e1d61c7752d74428f6616bcef88007c020d15917624753f18d27f9ce592"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"675c3bdc9520bfd4b92d8a7f5c0db1b0e2bb3507d4a3bb69a87593a06f853076"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"173de5223036e060077ab07bdbcd20c15bfc4cffd8eed852f2f1eb16b466f35d"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"e70c4a911647a3e68ccce765594f0e72c8a73b1b45274f40e53786ec0e4b1988"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"8b0f8c77a877524e889c98aeab7c557e7b23d2d781d0e73bf8dc10d1a2e4e38b"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9cc355a573ebc3155914231a44d8b725291f44c7439fd8ada192ed30073d2b19"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"cb004e464fc687cf54390146c8d76101b4b054c890dcbcf2646dc571f9788641"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"0819308039f5ff4e73a73b385c3778177e6be6f0b559efa4f6c271bb504af8db"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"4b536279ff99205bdd11650217f0f232ab452fc56447eb9e6f5e160061712103"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"943c996989bf1d3e17142eb0cde6a13ee9ad6ae4abf94531acaa9e29cf451ed5"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"fc2c90cd0081c9c10cd541b9751e26d6b7f44cd81f3ea3c22e9f957211e0ec14"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"29dfc5dc35b00ce95c7bc2d033d86f06e2fef635a0f5811dc8e5e9873c7cf01f"},"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"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"89ef25b5f94d33bf08a05aee9784f4279551f05de1624b3894a7ce6ed8dedb56"},"taxa":[{"id":"CWE-913","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":"e6d8b4dbed0c3eee1a03e10c2420a7f9afef5b4140e8222b3be83f6856995f1c"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"bf4bdfb49472900d9ae769d8b2c1e5a1f2926a5cc2e77bef942e51c83d42fd3b"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"20cfc07099e9ce6bb433da65f2c7e83c16bb25a04b9545be78542dd0b2deca39"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"65551ca1e9777ebe65c9fceedf8b589467e7891665e7e346dc5f42cc37edab02"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"cfd3c8ccf4907280de202e716f26014811d7ef989355bc9b1968a88f55585528"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"5aed6a0429e51f32ed4c83053759c62bf92925171d7951099bf6049e6174227f"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"00656a043b853dd8af65a30ee07a813eb7f4216fee15291c6020b752991036b8"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"706203a9cfb16468b0954d6e7ab535e5ed842eea96c2079b935f9b33964cc5b4"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"58767ef2b357572a67bf1d86f0a297f9a94504f711feec25fbb4841ea759af09"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"94bc8cef1d35defa0fb5302acf9c13bce609f198c083c73ec95dc02c4ce7c4fd"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"eb464fc5698cbb3e608a6762836f7fe78f767091507d769968ddd4f96f9ebd7f"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"5ac41998987a99ed1e0d1b6353672e1b01f812c10ea7a0531f06bd35178f2e32"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"f63eeddee8572add97ad35751ae2bce83f5246b78dbecd62cb02fe467edab2b0"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"407a5e151d1b4b101779bc8b6a94f583aa802cc056ef718e33370007ee691d86"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"f4eaefeb637ab0556c942d830a37b64f321492777c23172512eef11576d1abc5"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"6e69892036eef5bab2ac61670f69dd456937c8a4c2e545896f11e251e856dc5b"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"3ceade2915918161aafa48066801d185fb0082f573f657e5ed044baa110d7325"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"1c88e3489a2b7f238002edc9aa651ca5e299df01ae20b63919b179ed3337a000"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"c4e11a733c38395cd743e33efefba0473d73cf003b8fb966dcff98139a1532b3"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"993f56ae766492af728ccddbc72f36d9c9cb8fa06978f644b20d3b8dd42e5f87"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"c2f0e183582b61fe5d59944b223123013a1f8104e66643d76ec423b638f50f9f"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9666679efef2cac7178e485faff3ea38922f43dd5dc344633c4073bad6e7e46a"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"3ff2da953c0cd98a177e3a5a704585c73628b43fdf73dec594df61c11451374a"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"c707b3c657f9e51a16dd09c11daa65b96e8f66276b26c46fa17af3841ebe4068"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9d39d439c4586e1c6ad906ffd2c670bdd7e3f6f8e9b62396463496c45f1a8750"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"c7af01967fd1302b587fda6d5c64cc352db643974212836dc7acd013ed52a25c"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"7e9a6289256dc69003a8b463971e36b6df4592556d014e3d7a702725e3a8b19e"},"taxa":[{"id":"CWE-502","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"124261c39e0e5507fec2496673abc8bd8f72244ced73f1edc385e02dda067bcf"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"3df8b722c5d2244ab758a5053634ce6f9a9b6c70c411155e8fc83925ddd73ccb"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9752c8078c172186c9f39104e481c90cbae33a8e789d7e2cb7e0bc6e1de9aa39"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/material.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1df0a7032ddafec4ef2f23d3493497a8fd599cd60faf9dc2bd864ff421628fee"}},{"ruleId":"D34","level":"note","message":{"text":"Further orphaned files (smaller): 6 smaller file(s) also have no living knowledge \u2014 folded into the freshness score and metrics rather than raised one row each \u2014 most significant first: genesis/engine/force_fields.py, genesis/ext/pyrender/camera.py, genesis/ext/pyrender/font.py, genesis/ext/pyrender/trackball.py, genesis/ext/pyrender/utils.py, genesis/ext/pyrender/sampler.py (7 orphaned of 191 analysed files in total, 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; 191 of the 265 production source files in this repository met that bar). 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":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/force_fields.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7010fd01b817292f7c5c577d5b4f9382804427cd0cea559e01dd1f745ee41f05"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/camera.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9814b95cc2386b7f9f678a63887a8a15d64b281dd4cd0f8644bc8b31d548133c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/font.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01085d366b568a4f7c8e70c0101ac40eefec9c5b7f701beb2233751a630ecd70"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/trackball.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"574ba91d45804b9621158053883faf0c4336543c57df514f3a180c20131b0463"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/utils.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"06a13d01dd949e913700fbe3ebccf77bae73ca1f78a620e3ab831be7f95844eb"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/sampler.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbb813a3aabbe5d5cf95fd6d06d26139bb0a8fb20d576b2f85069da9eb7e4079"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: rigid_solver.py \u2192 hybrid_entity.py, pbd_solver.py, broadphase.py, diff_gjk.py, sph_solver.py: \u0060genesis/engine/solvers/rigid/rigid_solver.py\u0060 changes together with 5 other files \u2014 \u0060genesis/engine/entities/hybrid_entity.py\u0060, \u0060genesis/engine/solvers/pbd_solver.py\u0060, \u0060genesis/engine/solvers/rigid/collider/broadphase.py\u0060, \u0060genesis/engine/solvers/rigid/collider/diff_gjk.py\u0060, \u0060genesis/engine/solvers/sph_solver.py\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 5 separate couplings, not 5 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 5."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/rigid_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"730f3f4a88146ac4ca6d2f806c404c2a906538408d3bd1aae6fe6927fe79b3f0"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: mpm_solver.py \u2192 legacy_coupler.py, pbd_solver.py, sph_solver.py: \u0060genesis/engine/solvers/mpm_solver.py\u0060 changes together with 3 other files \u2014 \u0060genesis/engine/couplers/legacy_coupler.py\u0060, \u0060genesis/engine/solvers/pbd_solver.py\u0060, \u0060genesis/engine/solvers/sph_solver.py\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 3 separate couplings, not 3 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 3."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/mpm_solver.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"81d2791965cdd0d66ba3a2d856c12fb156c23f5d4c90a9ade8ee057a87c4d4b9"}},{"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"},"taxa":[{"id":"CICD-SEC-9","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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"},"taxa":[{"id":"CICD-SEC-8","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"ae720aff866ceba9a77e88060077d18ff285b03b4b012fd4bf821d68ee9ae3aa"},"taxa":[{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"9b7727f43727579d6e84cebac72afbf60ef34b2f29c4bd3f518219f56686d3cd"},"taxa":[{"id":"CICD-SEC-4","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"9f2edb65ca5a2c2a1893d63d33bcc6356d3c8a6557aecac23a22b4e76ccef8c3"},"taxa":[{"id":"CICD-SEC-4","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"74f08b03260ddbfe3a0595f96571aef4db439814e25cb558a04d91f814bd7448"},"taxa":[{"id":"CICD-SEC-4","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"fe274ba5adebde25ca0b3db842e44cbb1aaeb7cfecfbb7215cd452596ba1f4c2"},"taxa":[{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"4f1e7684f8281bd255ddef97105c7055c2ebae06964c8745716b83e174debe83"}},{"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"},"taxa":[{"id":"CICD-SEC-3","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"34ac0483cf1123b122d8c38c3339c27303db0b2efef5cbc8ec01427569618472"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier_after_merging.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"62672de691aa148bc2532e1f3d42bda3fcac363f88b1b2bf4e1553d12002280e"}},{"ruleId":"AC3","level":"error","message":{"text":"\u003Chtml\u003E without a lang: The page declares no language, so assistive tech can\u0027t pick the right pronunciation. Add lang (e.g. lang=\u0022en\u0022)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier.html"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd817d79bd8e2b5bf97c4e6b02658e0ebdd5dd2f73895d51dbd752e338e3c91a"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier.html"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29d742a1767e999ffffce455bf0aa975f48ec3bc2e197b166de722757ec3c03e"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"56d09a782091b5c3cb03f264eef58c8fda8ad260b1ed03a12fbafe4ec460eb3d"}},{"ruleId":"AC3","level":"error","message":{"text":"\u003Chtml\u003E without a lang: The page declares no language, so assistive tech can\u0027t pick the right pronunciation. Add lang (e.g. lang=\u0022en\u0022)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier_after_merging.html"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f51e5437638f75d68931ad79a1ebc542885955a00a5dfc5db489c3354492cf73"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier_after_merging.html"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"77456430d2546e9d34b20b1b1886d242f339436d44d3eef2f1f212412f87ecb7"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/urdf/3763/tree_hier_after_merging.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6996dcdf4ae9445c57b58cf1c5f3e28155e5e9e5aef3cd4e20494bdddfdd5a20"}},{"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\u0027s spread across several top-level directories, so there\u0027s no one place that says \u0027this is the product\u0027."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fdf7f5b24e313364d10170a5c2542959902fe0d26ed70edef3eaa10ec5bcdb1d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md runs \u0060powershell -ExecutionPolicy ByPass -c \u0022irm https://astral.sh/uv/install.ps1\u0060, but \u0060https:/astral.sh/uv/install.ps1\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"b85864071a30ab325207b0475304e4f6aa1b79c8e2996b50e4173a6d35a328ea"}},{"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 52748 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"}},{"ruleId":"P6","level":"note","message":{"text":"No changelog: No CHANGELOG/HISTORY/RELEASES file \u2014 what shipped when isn\u0027t easy to reconstruct for support or audit. (Versioning/tagging makes releases traceable, but a changelog records the what.)"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dda5aa5aed8cbb292c3ef2b733bc138f614293ae6426c85e98bf31ef330d9415"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060(gjk_state.polytope.nfaces_map[i_b] == 0) or (i_f_nearest == -1)\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/collider/diff_gjk.py, genesis/engine/solvers/rigid/collider/epa.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"9713ba69ab38a285e0e47c35d78dd731ce03beee2b0a58345edc66fd00f66f07"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060_tgt_actu is not None and _tgt_actu.requires_grad\u0060 appears character-identically in 2 files \u2014 genesis/engine/entities/fem_entity.py, genesis/engine/entities/mpm_entity.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":759}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce4d204c571a0070733ccc6f3ec799331c4af582e636631dc78e58434c98b9e1"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060_tgt_pos is not None and _tgt_pos.requires_grad\u0060 appears character-identically in 3 files \u2014 genesis/engine/entities/fem_entity.py, genesis/engine/entities/particle_entity.py, genesis/engine/entities/tool_entity/tool_entity.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":765}}}],"partialFingerprints":{"codehealthFindingId/v1":"d20e2ba9c9970a5cae5f299a0617373409f0f75894d6af1f76e32d1a6e2e06e8"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060_tgt_vel is not None and _tgt_vel.requires_grad\u0060 appears character-identically in 3 files \u2014 genesis/engine/entities/fem_entity.py, genesis/engine/entities/particle_entity.py, genesis/engine/entities/tool_entity/tool_entity.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/fem_entity.py"},"region":{"startLine":762}}}],"partialFingerprints":{"codehealthFindingId/v1":"508e08b4bf5c2efbeb946b11dddf686e8f147acbf7b70b1e84660daf55de1716"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060constraint_state.n_constraints[i_b] \u003E 0 and constraint_state.improved[i_b]\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/constraint/solver.py, genesis/engine/solvers/rigid/constraint/solver_breakdown.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":3385}}}],"partialFingerprints":{"codehealthFindingId/v1":"92407a0fbffc7bd848e95766b5cd363346220339f88d80a7810123a748e9e400"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060dyn_info.joints.type[I_j] == gs.JOINT_TYPE.REVOLUTE or dyn_info.joints.type[I_j] == gs.JOINT_TYPE.PRISMATIC\u0060 appears character-identically in 3 files \u2014 genesis/engine/solvers/rigid/abd/inverse_kinematics.py, genesis/engine/solvers/rigid/constraint/backward.py, genesis/engine/solvers/rigid/constraint/solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/inverse_kinematics.py"},"region":{"startLine":644}}}],"partialFingerprints":{"codehealthFindingId/v1":"62f4b41978144aeab308593614d0a8d05f61e7da78e7807a65da360abdcf38c0"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060dyn_info.links.parent_idx[I_l] == -1 and dyn_info.links.is_fixed[I_l]\u0060 appears character-identically in 3 files \u2014 genesis/engine/solvers/rigid/abd/accessor.py, genesis/engine/solvers/rigid/abd/inverse_kinematics.py, genesis/engine/solvers/rigid/abd/misc.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/accessor.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"05f0e825b0efe6a90109b98344c49871945d4f1a9ef7ee146cdaf014ea31d93d"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060dyn_info.links.root_idx[I_l] == i_l_root and func_is_awake_link(i_l, i_b, dyn_state, rigid_config)\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/abd/forward_dynamics.py, genesis/engine/solvers/rigid/abd/forward_kinematics.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/abd/forward_dynamics.py"},"region":{"startLine":1717}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f2771cbb8743d0b3d1c1b8f8ae40d5daca7b7baed78a28934f0b3e017869309"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060g_info[\u0022contype\u0022] or g_info[\u0022conaffinity\u0022]\u0060 appears character-identically in 2 files \u2014 genesis/engine/entities/rigid_entity/description.py, genesis/utils/mjcf.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/entities/rigid_entity/description.py"},"region":{"startLine":951}}}],"partialFingerprints":{"codehealthFindingId/v1":"d05f857d1d7fc139be1ef492b2c8aeb93f3721813d0c2042b88b4f28480caac4"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060geom_type == gs.GEOM_TYPE.SPHERE or geom_type == gs.GEOM_TYPE.CAPSULE\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/collider/diff_gjk.py, genesis/engine/solvers/rigid/collider/gjk.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":853}}}],"partialFingerprints":{"codehealthFindingId/v1":"abff76a9775a97109a864db9b1e1842a3d35775727adf38cc455a6bb76b9147a"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060gjk_state.polytope_verts.id1[i_b, i] == gjk_state.polytope_verts.id1[i_b, wi] and gjk_state.polytope_verts.id2[i_b, i] == gjk_state.polytope\u2026\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/collider/diff_gjk.py, genesis/engine/solvers/rigid/collider/epa.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/collider/diff_gjk.py"},"region":{"startLine":436}}}],"partialFingerprints":{"codehealthFindingId/v1":"c09d823fc1a79d51b466ca8f45860b2c7ea0f9db27c91c51514ba09abaa1875a"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060gs.use_zerocopy and gs.backend == gs.metal\u0060 appears character-identically in 3 files \u2014 genesis/engine/simulator.py, genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/simulator.py"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"e028d285b65feabf9b2fd9094d8346a799847e314f02c5f2cfa38a62e7f8a291"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060isinstance(envs_idx, torch.Tensor) and envs_idx.dtype == torch.bool\u0060 appears character-identically in 4 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/collider/collider.py, genesis/engine/solvers/rigid/constraint/solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1524}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cd79328a2fa756cfb2a2f4dae8bba5cbe95cf3533898025c0e4bdb7760b1bb5"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060isinstance(mesh.visual, trimesh.visual.texture.TextureVisuals) and mesh.visual.uv is not None\u0060 appears character-identically in 2 files \u2014 genesis/engine/mesh.py, genesis/ext/pyrender/mesh.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/mesh.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"cafc1cce1d9dca8732f0af5eb18bb5849b5e96bce6be605b03fa042dbe6ac022"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060mask and isinstance(mask[0], torch.Tensor)\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1213}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c4f3d7165b34f2c03a4f88f428d29e548a8b0d0e312e89cb7d3a510544ad188"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060node.mesh is None or len(node.mesh.primitives) != 1\u0060 appears character-identically in 2 files \u2014 genesis/ext/pyrender/jit_render.py, genesis/ext/pyrender/scene.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/jit_render.py"},"region":{"startLine":1462}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ea4a9ed006a00f8cd2d00771c8affc7e2535b6c496352795efbe65fd9f0fca0"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060not IS_OLD_TORCH or envs_idx.dtype == torch.bool\u0060 appears character-identically in 4 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/collider/collider.py, genesis/engine/solvers/rigid/constraint/solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1248}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac86057dee9b09e2d8dfc36de41ddd3fffd1a8bfb1b437f13f5f9e279fb26a43"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060not force_render and self._t \u003E= self.scene.sim.cur_step_global\u0060 appears character-identically in 3 files \u2014 genesis/vis/rasterizer_context.py, genesis/vis/raytracer.py, genesis/vis/visualizer.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/vis/rasterizer_context.py"},"region":{"startLine":1195}}}],"partialFingerprints":{"codehealthFindingId/v1":"2504d3c60f0b688d5cd05210cc3a048b9097454726daf1fa724f8633b3286d7c"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060not qs_mask or isinstance(qs_mask[0], slice)\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1199}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ab130c24e83930ebf5cf48baa9a1d6768686ca35a43523b42fc084c9cbe6b37"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060not self._options.batch_dofs_info and envs_idx is not None\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1481}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f767a5f28b269043edab00a8cf3e23217fa69f077e789d230ddb13e6a1ff03b"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060not self.is_active or self._n_vverts == 0\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/fem_solver.py, genesis/engine/solvers/pbd_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/fem_solver.py"},"region":{"startLine":1123}}}],"partialFingerprints":{"codehealthFindingId/v1":"b23753a25ff06295fd64c0bb1b0cb8615cfe6454abebddcfcba875a6d2e199c2"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060relative and not self._links_offset_pos_is_identity[idx].all()\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1107}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b8358d2c17a36274ce2ccc38d4a297d1d16ed66695c7cf0c40ffa0f64a2cdcb"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060relative and self._links_offset_pos_is_identity[idx].all()\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/kinematic_solver.py, genesis/engine/solvers/rigid/rigid_solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/kinematic_solver.py"},"region":{"startLine":1071}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f5d75738c37544cba83cb4ab83b0d03af9ada952c8b7740466f8f721fa6531d"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060rigid_config.para_level \u003C gs.PARA_LEVEL.ALL and rigid_config.backend != gs.metal\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/constraint/backward.py, genesis/engine/solvers/rigid/constraint/solver.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/backward.py"},"region":{"startLine":680}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ed61695bb9e36d9db12bc5fc80a47a10a23e3aaef73b9e9a42c5a5bde587d9e"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060rigid_config.solver_type == gs.constraint_solver.Newton and not rigid_config.enable_elliptic_friction\u0060 appears character-identically in 2 files \u2014 genesis/engine/solvers/rigid/constraint/solver.py, genesis/engine/solvers/rigid/constraint/solver_breakdown.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/solvers/rigid/constraint/solver.py"},"region":{"startLine":5174}}}],"partialFingerprints":{"codehealthFindingId/v1":"69e5f2d6f60693627069df6fe6cf125b4992b78a5618e2dc0684572c6f300354"}},{"ruleId":"X17","level":"warning","message":{"text":"Recursive walk over a caller-supplied document has no depth cap: \u0060iter_data\u0060 is public and takes \u0060owner: object\u0060 from its caller, and it calls itself at line 240 (\u0060iter_data\u0060) with a piece of \u0060owner\u0060 \u2014 and nowhere in \u0060iter_data\u0060 is there a depth parameter, a descent counter, or any other cap. The walk therefore spends one stack frame per LEVEL of the value it is handed, so the nesting of the caller\u0027s document \u2014 not this code \u2014 decides how deep the stack goes. Python\u0027s parsers accept far more nesting than its stack allows: \u0060json.loads\u0060 turns 3,000 bytes of brackets into 1,500 levels and \u0060xml.etree.ElementTree\u0060 parses tens of thousands, while a walk like this one raises \u0060RecursionError\u0060 once it passes the interpreter\u0027s default limit of 1,000 frames. Wherever that exception lands, the work fails: a request errors, and outside any \u0060try\u0060 the worker or the program exits with it. Raising \u0060sys.setrecursionlimit\u0060 only moves the number the document has to beat. Thread a depth argument through \u0060iter_data\u0060 and reject the value past a fixed maximum, or rewrite the descent with an explicit stack."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/array_class.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"63e8e369f040c44aede017cfc5125a854cd75c91c37b70df83645f111d6cf313"}},{"ruleId":"X19","level":"warning","message":{"text":"Process-global state is restored only on the happy path: \u0060init_context\u0060 changes state that belongs to the whole PROCESS and changes it back at the end of the same body \u2014 the \u0060DISPLAY\u0060 environment variable (set at line 227, put back at line 231) \u2014 which says the change was meant to last no longer than this call. But the restore is an ordinary statement on the straight-line path, not a \u0060finally\u0060, so it is skipped by any exception raised in between: the process then keeps the overwritten value for the rest of its life, and every later relative path, \u0060subprocess\u0060 launch, \u0060os.environ\u0060 read or \u0060print\u0060 in ANY module sees it. That failure is silent and remote from its cause \u2014 the function that breaks is not the function that moved the value. The window is not private while it is open either: the working directory, the environment, the umask and \u0060sys.stdout\u0060 are per-process, not per-thread, so a concurrent thread sees the moved value too. The durable fix is not to widen the restore but to stop mutating the global: pass the value to the operation that needs it \u2014 the \u0060cwd=\u0060 and \u0060env=\u0060 arguments of \u0060subprocess.run\u0060/\u0060Popen\u0060 scope both to the CHILD, absolute paths built with \u0060os.path.join\u0060 or \u0060pathlib\u0060 need no working directory, and a stream handed to the code that writes needs no \u0060sys.stdout\u0060. Where the global genuinely must move, \u0060contextlib.chdir\u0060 (3.11\u002B), \u0060contextlib.redirect_stdout\u0060 or a \u0060try\u0060/\u0060finally\u0060 makes the restore run on every path."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/platforms/egl.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b264fd55f6df2a90543742406bf9e2f863499cf504686bfd74af28d0905cccf"}},{"ruleId":"X23","level":"note","message":{"text":"Diagnostic log message is built whether or not it is wanted: \u0060debug\u0060 at line 400 is called with an argument built by \u0060set(self._coup_type_by_entity.values())\u0060 (line 400), whose cost grows with the collection it walks. Python evaluates a call\u0027s arguments BEFORE entering the method, so that join/projection runs in full every time this line is reached \u2014 and then the level check inside the logger discards the string it produced, because debug is a level a shipped configuration normally leaves off. Nothing here decides beforehand whether the message is wanted: no \u0060isEnabledFor(logging.DEBUG)\u0060 test, no debug flag, no \u0060lambda\u0060 the logger calls only when the level is on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd96e927387ca18defc27bb6b6ae55af4f82f846e6b7b82b148b275ffb508fa8"}},{"ruleId":"X23","level":"note","message":{"text":"Diagnostic log message is built whether or not it is wanted: \u0060debug\u0060 at line 402 is called with an argument built by \u0060\u0022\u2026\u0022.join(commands)\u0060 (line 402), whose cost grows with the collection it walks. Python evaluates a call\u0027s arguments BEFORE entering the method, so that join/projection runs in full every time this line is reached \u2014 and then the level check inside the logger discards the string it produced, because debug is a level a shipped configuration normally leaves off. Nothing here decides beforehand whether the message is wanted: no \u0060isEnabledFor(logging.DEBUG)\u0060 test, no debug flag, no \u0060lambda\u0060 the logger calls only when the level is on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7b4208593dd4a889fb20f1cea18de04892f32678cdeac328d27c73cc9684867"}},{"ruleId":"X23","level":"note","message":{"text":"Diagnostic log message is built whether or not it is wanted: \u0060debug\u0060 at line 155 is called with an argument built by \u0060\u0022\u2026\u0022.join(traceback.format())\u0060 (line 155), whose cost grows with the collection it walks. Python evaluates a call\u0027s arguments BEFORE entering the method, so that join/projection runs in full every time this line is reached \u2014 and then the level check inside the logger discards the string it produced, because debug is a level a shipped configuration normally leaves off. Nothing here decides beforehand whether the message is wanted: no \u0060isEnabledFor(logging.DEBUG)\u0060 test, no debug flag, no \u0060lambda\u0060 the logger calls only when the level is on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/vis/viewer.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"0902c5ba57536dd22e7877511f710d445148812c6be3eab0edda3af7d46b9639"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060except Exception\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/repr_base.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe08dab187a50d86c0fab13e88d343e096b3183fcc7236e85d306421120a3bf2"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060except Exception\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/sensor_manager.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"3347648672cc7e5e77d0fefa53df712616c85562a65cf0586b1aedae9a0ec424"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. On a teardown path letting it propagate is not an option (throwing out of \u0060__del__()\u0060 masks the failure already in flight and abandons the rest of the cleanup), so make the swallow deliberate instead: narrow the catch to the exception this release can actually raise, and record it through whatever this codebase already uses to report problems \u2014 or, if it truly cannot matter, say why in a comment on the catch."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/sensors/base_sensor.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"76441cb4ca42f52590a2058a507604c03af153b60cdf71a30c8d261b589a7e50"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":516}}}],"partialFingerprints":{"codehealthFindingId/v1":"adda6454e5acfd6cf2cafe444641aadae506566f760c91e53ee5a876daba8353"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"2779f3a19f57cd6105d421544c46ea051e12827243f30f4b1d7e1390d5885fc2"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/_trimesh_patch.py"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac467c2576614a4c2f45b38afb0e0ba494199d8e383205d884162c7c0e9e2bea"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":662}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f53096f5bbe5f82d543f2dff06dfc5dd402714f93eaf874d87adeaab87aa49e"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb30e2f1f117b31090559e5c7bae6ab030fb0ec89147a22c7241162550f6ff54"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":700}}}],"partialFingerprints":{"codehealthFindingId/v1":"a884c7dae7595fe3354b21fb43a3b851129dd87dd8a00d69dd9861b28b16a6fd"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":704}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d9f5957ba446bf65052d2301abd309338aa0f11e12b44159b5b0fd1918faa57"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":708}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2fbe5e51917f588e29180218f63e103cd3ed3df7a61bbd11018ed15db3c0f60"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1221}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b6fb8635e0034f4c1cc9f3f00285166129f15b12fb7f412632fb4f179fdf18"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1225}}}],"partialFingerprints":{"codehealthFindingId/v1":"63340f6217d164da9c09e757b10808c2de7025cc3625d6bd84724a3f3e9d1428"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/viewer.py"},"region":{"startLine":1307}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfda9fe0a5c296e2dc6894ffbe6975d4aea4c45f328ffc4dea37de65790aeecc"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/offscreen.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"affaf522e0cbd5b7b140a2e2ea234f093d6ae2c77ef9daca7f9c0823f26356c5"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. On a teardown path letting it propagate is not an option (throwing out of \u0060__del__()\u0060 masks the failure already in flight and abandons the rest of the cleanup), so make the swallow deliberate instead: narrow the catch to the exception this release can actually raise, and record it through whatever this codebase already uses to report problems \u2014 or, if it truly cannot matter, say why in a comment on the catch."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/offscreen.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"47b01601618022d04c919a75de0d4d908fd93735a2e3a57900a08f9d7ac5e519"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060except Exception\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"81204e757c473c13bfa0c3e3a39a6838c5f83a42fd92de486a571d81714e58eb"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":286}}}],"partialFingerprints":{"codehealthFindingId/v1":"d418ba9b86d2a03cce798261fe4589e1b4df9bfb655831012f4f3c4dd1b39108"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/platforms/pyglet_platform.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c4b6796cd0c4b40dbe00e68e136642a66b28f0f55a022411ed6f9f677d685ae"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/platforms/pyglet_platform.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7c6a9a4d9e34090b38c1475ad66c43241433b7386831796ee2d3d39ec5fb95e"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/platforms/pyglet_platform.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"b98a17b875a6e73b37b8f350ce1a66a39051228a7783ca6c3ce050fa1d3c633b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. On a teardown path letting it propagate is not an option (throwing out of \u0060__del__()\u0060 masks the failure already in flight and abandons the rest of the cleanup), so make the swallow deliberate instead: narrow the catch to the exception this release can actually raise, and record it through whatever this codebase already uses to report problems \u2014 or, if it truly cannot matter, say why in a comment on the catch."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/platforms/base.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"e94a9ac450f8425c3af86d9e2d5dfaa5f9ba416d5aa894b9630daa3936e7399c"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060except Exception\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/misc.py"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2f3d8b18103fc2520f92b945c517572033c543ed815cb178f0159a6dee8105d"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/vis/viewer.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"dca564c8ed11a7092ab4aa168a322fa49561ce7a6ffaac9ad8bbdcd5f8c90b0f"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 104 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/__init__.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"94f923593a47269b65383cbea93eadb169b6ffdb09b95bda572a14f5481c2dea"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 443 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.error(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.error(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/__init__.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ef08bd301c4578b41ef2d4789ce4b80c21c8549df47f771cc2aa661a15c85c1"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 293 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/tower/generate_tower.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"49d453e95f43da24776d04db587eaf791d6d84cc45541ca96ae51a7b49c4c986"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 320 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/tower/generate_tower.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5055fd8dfd656ca30e8608018bed0d7238b7b011999cce9394db24cd76adff8"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 402 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/assets/tower/generate_tower.py"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fbae7613c86b45b319ed7d200834ea8db3d36589b4986164dedc6deba791cb8"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 243 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cebe2e5721c2c1cc90f775119a6c1ec0672cf4f24b2e70c72c4ebfb38e65eee"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 249 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb3a1a4993daaa14f9018e2564ceeea9ae872aef7f0d04d94edfea48e9d506bd"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 255 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"63e89faa55289e9c59967066d770c143a041bfc6c87510f5ca4b2d4fddac046f"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 262 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d4995c2218170895e384d9b38fc279a3b964aa385373e3ae970b3541309bdd7"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 400 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"b15d9ba255c6edb8acadb9eaca9a906c27ff637c45b1529b7f385993e1012abb"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 427 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"afb32ebb6e4130418975ab75a78fdc68898c24555604287124290d41bed6800b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 600 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"b41243613d45a7c41187b79976678092ca360c2afa0fc9068d0d6acb151d8618"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 682 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":682}}}],"partialFingerprints":{"codehealthFindingId/v1":"0145f7e1f2512742d8fbd915b371625a851da102a0802d39aa951b68849f68ed"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 788 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":788}}}],"partialFingerprints":{"codehealthFindingId/v1":"4358f2d61a712c183d74e57e487fd24c0ee5e8281828bd2032fac1a70b8a89a9"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 801 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/engine/couplers/ipc_coupler/coupler.py"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"335d90ad57e50746cc0c7dc87c41321c14f88768bfcae761deedc79552548a8f"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 525 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/trajectory.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb24650859393eb6bcb904bcd8ed05b4dbca6c90900eb2ad7053ebdd9a155a88"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 193 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/plotters.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"efde33e00f7fd9623f2054c1ecdf1d1548744ec6ffb1275a55a56e2a5321dee2"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 260 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/plotters.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"39b1018c4fb1b671e6ffc663c12b87850feb1a2c6a8d7461ca9aec5b1a6a9c63"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 418 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/plotters.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"68a715d0f5c98aa98f807e7d12991ef5820ad44ffe23281dbd661909d7679fec"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 79 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/recorders/file_writers.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b51fbddb8deebb98767b5fa66162a133c9f2a2673c53fd538a55aff1e71df13"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 178 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/video_encoder.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"a37f6c43b0453ed44a2e7f93e7657cdf3fb7d0a199fe801bfc2bc2ed16f43ee7"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 87 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/misc.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b4b12aa4f3816ef6bf094982c76cdf8d7e64f7c09161d1f51d36773662364cc"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 56 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"347ef03108e9d2ff9936e2cd03010c5cdc65c99686eea9cf1262a77c8b292325"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 58 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"1694bee717d97f32554ffa3c754e7e6d1f362b44c648f3ca5d295eb7192cd626"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 145 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.info(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.info(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c99da69a79f28a273af2f1bf9f4cfa0b19f207ab69553846cc6323f6eb846e4"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 314 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bae5b25a775baf16049c43f440d546c80a7efd2f2c796c25cad308968dfe5b5"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 402 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.debug(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.debug(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"d978d2c89d9f52b7f2db45e4625ac3e312885373a13dbdd67466e3d167d55e5b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 416 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"09c32a6ff5dd9019bfdaf168311998846eee9a67b04635c3307bc93065e5cf36"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 423 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"3613c0fbf490e1e4a159e8c4356b0f1d272805bc6be4e1edd9cc23057a5794ea"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 434 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":434}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ea989bd5674a2476366f440e1fdc44baaa21fc96820e83c6352024ecdb51f3"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 473 is handed an f-string as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the record is filtered out. Pass the values beside a constant message instead: \u0060logger.warning(\u0022order %s moved to %s\u0022, order_id, status)\u0060 with the standard library\u0027s \u0060logging\u0060, which keeps the message and its arguments apart on the record, or \u0060log.warning(\u0022order moved\u0022, order_id=order_id, status=status)\u0060 with structlog."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/utils/usd/usd_context.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"01fb1313ad291781323265a4b423d557063f3e2d8e80fc1d35fe1cec26fef31c"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_get_clipboard\u0060 (in \u0060_init_imgui\u0060) swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"genesis/ext/pyrender/overlay/plugin.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"32c16f183195ab1f2e22f761215edd2cf13c69cef569116d0ffa33ef6c4c36b0"}}],"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-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-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-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"Missing Support for Integrity Check","shortDescription":{"text":"Missing Support for Integrity Check"},"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":"Deserialization of Untrusted Data","shortDescription":{"text":"Deserialization of Untrusted Data"},"helpUri":"https://cwe.mitre.org/data/definitions/502.html"},{"id":"CWE-611","guid":"1afbae66-ea29-2d59-aaa2-134e3ae2e85a","name":"Improper Restriction of XML External Entity Reference","shortDescription":{"text":"Improper Restriction of XML External Entity Reference"},"helpUri":"https://cwe.mitre.org/data/definitions/611.html"},{"id":"CWE-732","guid":"1da27e8f-b330-7650-ab63-bd61953eae5d","name":"Incorrect Permission Assignment for Critical Resource","shortDescription":{"text":"Incorrect Permission Assignment for Critical Resource"},"helpUri":"https://cwe.mitre.org/data/definitions/732.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)","shortDescription":{"text":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)"},"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":"Inclusion of Functionality from Untrusted Control Sphere","shortDescription":{"text":"Inclusion of Functionality from Untrusted Control Sphere"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-913","guid":"062167e8-5db3-0857-a865-a1fc4aad34bc","name":"CWE-913","shortDescription":{"text":"CWE-913"},"helpUri":"https://cwe.mitre.org/data/definitions/913.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":"Improper Control of Generation of Code (\u0027Code Injection\u0027)","shortDescription":{"text":"Improper Control of Generation of Code (\u0027Code Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]},{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61","version":"2025","organization":"OWASP Foundation","informationUri":"https://top10.owasp.org/2025/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10:2025 web application security risks."},"taxa":[{"id":"A01:2025","guid":"df693558-c822-0452-8f7b-4d53cb6bcc59","name":"Broken Access Control","shortDescription":{"text":"Broken Access Control"},"helpUri":"https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/"},{"id":"A02:2025","guid":"668dee9e-41bc-6354-97d0-fdf8f40c50c1","name":"Security Misconfiguration","shortDescription":{"text":"Security Misconfiguration"},"helpUri":"https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/"},{"id":"A03:2025","guid":"168e227c-7735-2e57-bc6e-997affe644c5","name":"Software Supply Chain Failures","shortDescription":{"text":"Software Supply Chain Failures"},"helpUri":"https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/"},{"id":"A05:2025","guid":"87e86033-3231-8458-8e4a-5cb82743553a","name":"Injection","shortDescription":{"text":"Injection"},"helpUri":"https://top10.owasp.org/2025/A05_2025-Injection/"},{"id":"A07:2025","guid":"334ddd78-539d-d35c-83dd-253647eb7eaf","name":"Authentication Failures","shortDescription":{"text":"Authentication Failures"},"helpUri":"https://top10.owasp.org/2025/A07_2025-Authentication_Failures/"},{"id":"A08:2025","guid":"84b0c297-710e-9a5f-9335-936ecb260c36","name":"Software or Data Integrity Failures","shortDescription":{"text":"Software or Data Integrity Failures"},"helpUri":"https://top10.owasp.org/2025/A08_2025-Software_or_Data_Integrity_Failures/"}]},{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35","organization":"OWASP Foundation","informationUri":"https://owasp.org/www-project-top-10-ci-cd-security-risks/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10 CI/CD Security Risks."},"taxa":[{"id":"CICD-SEC-3","guid":"458c83a6-ebf7-cf55-8cc3-b4d949bbf271","name":"Dependency Chain Abuse","shortDescription":{"text":"Dependency Chain Abuse"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-03-Dependency-Chain-Abuse"},{"id":"CICD-SEC-4","guid":"c859d8ea-8b24-a157-9406-94929c10397a","name":"Poisoned Pipeline Execution (PPE)","shortDescription":{"text":"Poisoned Pipeline Execution (PPE)"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-04-Poisoned-Pipeline-Execution"},{"id":"CICD-SEC-6","guid":"f2ee2486-b260-2952-a41f-6b67fa713940","name":"Insufficient Credential Hygiene","shortDescription":{"text":"Insufficient Credential Hygiene"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-06-Insufficient-Credential-Hygiene"},{"id":"CICD-SEC-8","guid":"b6b2dacf-a168-4957-876e-a8c73ee00eb0","name":"Ungoverned Usage of 3rd Party Services","shortDescription":{"text":"Ungoverned Usage of 3rd Party Services"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-08-Ungoverned-Usage-of-3rd-Party-Services"},{"id":"CICD-SEC-9","guid":"b3d36727-0395-5b51-94c4-5e173d62eab3","name":"Improper Artifact Integrity Validation","shortDescription":{"text":"Improper Artifact Integrity Validation"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-09-Improper-Artifact-Integrity-Validation"}]}],"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":87,"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."]}]}